verilog学习笔记(一)

因为参与的新项目需要用fpga,所以自己学了一下verilog语言。整理一些比较基础的内容。

verilog程序最重要的结构就是模块module,它在形式上与c语言的函数很像,但是由于verilog是面向硬件的语言,因此在设计思想上与c语言是有一定的差别的。

一个verilog模块通常必须有的变量:clk时钟,rst置位,input输入,output输出

 下面是一些verilog中常用的声明。

Parameter常量

Wire输入输出信号缺省时默认是wire,是assign关键字指定的组合逻辑信号

Wire [n:1]   a1,...,ai  每个总线有n个线路,共i个总线

Reg always块里的指定信号,常代表触发器寄存器

Reg[4:1] a   一个4位的名为areg信号 编号从14由低位到高位

Reg变量可以是正数或负数,但是在运算时视为正数

如果需要中间赋值或运算,需声明成reg类型

一个verilog模块的主要结构如下

Module 模块名(端口列表);

Wire reg 和其他类型声明;

Assign数据流声明;

Always initial块,行为语句   #verilog中各个always块都是并行执行的,不存在谁先谁后的关系
...
任务和函数...
...
Endmodule
always @(posedge clk)  #上升沿到来时触发

verilog数据常量定义:
数字表达式:<位宽><进制><数字>
b:二进制 4'b1110 表示4位二进制数1110
h:十六进制 8'hef4ha
'd:十进制  2'd34d15(不能写164位宽最大15)

顶层程序调用底层modulec语言函数格式类似,通过module定义的端口传递参数,但是使用思想不同。

模组类名 实例名(端口变量)

端口变量尽量书写规范

.a(A)  #.模组定义端口变量(实际变量)

Case语句的本质是分支比较,两个值的比较,若分支和case后面的值相等则运行相应分支语句,因此case后面的值可以是常值。

verilog文件开头一般有timescale

`timescale 仿真时间单位/时间精度

verilog基本运算:

 verilog有两种赋值符号分别是<=和=。

 <=是非阻塞赋值,在always块完成后才赋值;
=是阻塞赋值,赋值完成后才进入下一句;
一般时序逻辑用<=,组合逻辑用=。

~ 按位取反 比如:11110 取反后为00001
!逻辑取反 ,如!非0 0 0 1

&&:代表逻辑与。

&:代表与门运算(按位与)

^异或处理,对一个变量里面1的个数是奇数偶数的判断,偶数为0,奇数为1

实际是对该变量相邻位逐一求异或。

1 组合逻辑:

组合逻辑的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原本的状态无关,逻辑中不牵涉跳变沿信号的处理,组合逻辑的verilog描述方式有两种:

1):always @(电平敏感信号列表)

always模块的敏感列表为所有判断条件信号和输入信号,但一定要注意敏感列表的完整性。在always 模块中可以使用ifcase for 等各种RTL 关键字结构。由于赋值语句有阻塞赋值和非阻塞赋值两类,建议读者使用阻塞赋值语句“=”always 模块中的信号必须定义为reg 型,不过最终的实现结果中并没有寄存器。这是由于在组合逻辑电路描述中,将信号定义为reg型,只是为了满足语法要求。

2):assign描述的赋值语句。

信号只能被定义为wire型。

2 时序逻辑:

时序逻辑是Verilog HDL 设计中另一类重要应用,其特点为任意时刻的输出不仅取决于该时刻的输入,而且还和电路原来的状态有关。电路里面有存储元件(各类触发器,在FPGA 芯片结构中只有D 触发器)用于记忆信息,从电路行为上讲,不管输入如何变化,仅当时钟的沿(上升沿或下降沿)到达时,才有可能使输出发生变化。

与组合逻辑不同的是:

1)在描述时序电路的always块中的reg型信号都会被综合成寄存器,这是和组合逻辑电路所不同的。

2)时序逻辑中推荐使用非阻塞赋值“<=”

3)时序逻辑的敏感信号列表只需要加入所用的时钟触发沿即可,其余所有的输入和条件判断信号都不用加入,这是因为时序逻辑是通过时钟信号的跳变沿来控制的。

(*keep = "true"*)

有时候在chipscope中很难找到你预期的信号,这往往是被综合器优化掉了,或者更改了信号名.有效的方法是在源代码中加上约束语句,这样就不用对代码做大的改动.

fifo:

Fist in first out。先入先出的数据缓存器,没有外部读写地址线,可同时读写。

同步FIFO和异步FIFO

同步FIFO只有一个时钟,也就是说写端和读端的时钟是一样的。

异步FIFO读端和写端两个时钟则是不一样的。包括同频异相,异频异相。

FIFO用途

数据缓冲器。比如你写端burst一个数据,没有fifo缓冲的话就炸了。Fifo会把写端的突发数据缓存,读端可以慢慢的读出来。

跨时钟域。异步fifo主要使用在不同时钟域的边缘,用来同步数据到另一个时钟域。

对于异步读写时钟不同的fifo需要求fifo深度,深度是写需要的时间内读端没有读完的数据量(word),下面是在网上找到的一个比较好的解释fifo深度的例子

猜你喜欢

转载自www.cnblogs.com/btc1996/p/12204858.html