///
1,FPGA_Verilog基础篇:Verilog发展进程-CSDN博客
2,FPGA_Verilog基础篇:理解Verilog的四值逻辑-CSDN博客
3,FPGA_Verilog基础篇:Verilog中数值的表示-CSDN博客
4,FPGA_Verilog基础篇:信号声明类型-CSDN博客
5,FPGA_Verilog基础篇:模块的端口声明-CSDN博客
6,FPGA_Verilog基础篇:verilog语言的操作符-CSDN博客
7,FPGA_Verilog基础篇:verilog基本逻辑运算-CSDN博客
8,FPGA_Verilog基础篇:verilog关系操作的逻辑运算实现-CSDN博客
9,FPGA_Verilog基础篇:veriolg算术运算-CSDN博客
10,FPGA_Verilog基础篇:verilog移位操作-CSDN博客
11,FPGA_Verilog基础篇:关系操作符简介-CSDN博客
12,FPGA_Verilog基础篇:拼接运算符简介-CSDN博客
13,FPGA_Verilog基础篇:verilog数值的位宽扩展规则-CSDN博客
14,FPGA_Verilog基础篇:verilog移位与拼接实现-CSDN博客
15,FPGA_Verilog基础篇:verilog双向inout接口表示_fpga inout端口-CSDN博客
16,FPGA_Verilog基础篇:verilog之锁存器和触发器-CSDN博客
17,FPGA_Verilog基础篇:verilog之for循环-CSDN博客
18,FPGA_Verilog基础篇:verilog之函数用法-CSDN博客
19,FPGA_Verilog基础篇:verilog之任务用法-CSDN博客
20,FPGA_Verilog基础篇:verilog之任务与函数用法比较-CSDN博客
21,FPGA_Verilog基础篇:verilog之宏define介绍-CSDN博客
22,FPGA_Verilog基础篇:verilog之条件编译指令介绍-CSDN博客
23,FPGA_Verilog基础篇:verilog之参数parameter介绍-CSDN博客
24,FPGA_Verilog基础篇:verilog之本地参数localparam-CSDN博客
25,FPGA_Verilog基础篇:verilog之generate生成块-CSDN博客
26,FPGA_Verilog基础篇:verilog之常数规则-CSDN博客
27,FPGA_Verilog基础篇:verilog中整数运算的位宽和符号规则-CSDN博客
28,FPGA_Verilog基础篇:verilog中的字符串表示-CSDN博客
29,FPGA_Verilog基础篇:verilog中带整数的算术表达式分析-CSDN博客
30(结束篇),FPGA_Verilog基础篇:verilog中的数值运算规则总结-CSDN博客
///
Verilog的所有信号声明都属于两个基本的类型:线网类型(net/wire)和寄存器类型。一般的说法是:
1)线网与我们实际使用的电线类似,它的数值一般只能通过连续赋值,由赋值右侧连接的驱动源决定。线网在初始化之前的值为x,如果未连接驱动源,则该线网变量的当前数值为z,即高阻态。线网类型的变量有以下几种:wire、tri、wor、trior、wand、triand、tri0、tri1、supply0、supply1、trireg,其中wire作为一般的电路连接使用的最为广泛,而其它几种用于构建总线,即多个驱动源连接到一条线网的情况,或搭建电源、接地等。
2)寄存器类型与线网不同,它可以保存当前的数值,直到另一个数值被赋值给它。在保持当前数值的过程中,不需要驱动源对它进行作用。如果未对寄存器变量赋值,它的初始值则为x。
verilog中所说的寄存器类型变量与真实的硬件寄存器是不同的,寄存器类型变量指的是一个存储数值的变量。如果要在一个过程(initial或always)里对变量赋值,这个变量必须是寄存器变量。寄存器类型的变量有以下几种:reg、integer、time、real,其中reg作为寄存器变量使用的最广泛。
最开始学习verilog时,我们都有一个初浅的理解:wire类型对应的是组合电路,reg类型对应的是时序电路。但随着认识程度的加深,后来就会发现这种认识是大错特错的!
什么时候使用wire?什么时候使用reg?其实规则很简单。在verilog中,任何过程赋值的左侧变量必须声明为reg,除此之外使用的变量必须声明为wire,没有例外!
1,wire类型
wire类型声明很简单,比如:
wire a;
wire b;
wire c,d;
博主小飞在这里强调一下,同样位宽的wire信号可以在一行里一起定义。另外wire类型信号不允许初始化,但下文要说的reg类型信号则允许。
2,reg类型
reg型变量总是让人误解为“register”(寄存器)。但是后面咱们会说到,组合逻辑也有被定义为“reg”的。因此到目前为止,不知道verilog官方当初为什么要用reg这三个字母来定义,咱们就暂且糊涂吧。
reg类型声明如下:
reg a;
reg b = 1’b1;
reg c,d;
同样位宽的reg信号可以在一行里一起定义。另外reg类型信号允许初始化,和wire类型完全相反。
3,向量(vector)、数组(array)的声明和引用
1bit位宽的信号不能很好的描述电路,比如一组并行的数据就需要多个bit来描述,因此就引入了向量的概念。向量形式的数据在硬件描述语言中十分重要。Verilog中,标量指的是只具有1bit位宽的变量,如上面举例的wire和reg声明,而向量表示具有多个比特位宽的wire或reg变量。如果用户没有特别指定信号位宽,系统就默认它为1bit位宽的标量。
4,wire型向量
wire [3:0] a;//合法
wire [0:3] b;// 合法
wire [4:1] c;// 合法
wire [4:1] d,e;// 合法,同一行定义
5,reg型向量
reg [15:0] a,b;//同一行定义
reg [7:0] c = 8’d10;//初始化
6,数组
向量设计的本义是为了表述多bit位宽的标量,而数组设计是为了方便实现RAM存储。Verilog-2001对数组的定义和访问做出了极大的调整:
A: 数组的元素可以是标量,也可以是向量
B: 数组的维数可以是一维,二维……多维
C: 数组的引用可以针对某个元素或某个元素的一部分
D: 通常一维数组称为memory
下面举例说明:
reg x[11:0];//一维数组,12个元素,每个元素1bit reg型
wire [0:7] y[5:0];//一维数组,6个元素,每个元素8bit wire型
reg [31:0] x[127:0];//一维数组,128个元素,每个元素32bit reg型
reg [23:0] image_rgb[0:1203][ 0:1203]//二维数组
在verilog-2001中,wire和reg变量都可以声明为数组,而且数组可以是多维的,既可以引用单个元素(full array-word),也可以引用单个元素的几位,而且多维数组是可以综合的。但是引用数组中的多个元素依旧是非法的,也就是说你不能通过引用数组的一部分来初始化数组的一部分,也不能引用整个数组来初始化数组。一维数组必须用一个或两个索引变量来访问,二维数组必须用两个或3个索引变量来访问等等。
例子:使用多维数组表示图像数据
reg [23:0] image[0:599][0:799];
wire [23:0] pixel = image[y][x];
wire [7:0] color_x = image[y][x][23:16];
wire [7:0] color_y = image[y][x][15:8];
wire [7:0] color_z = image[y][x][7:0];
//也可以用如下的新表示方法:非常适合参数化设计
wire [7:0] color_x = image[y][x][16 +:8];
wire [7:0] color_y = image[y][x][8 +:8];
wire [7:0] color_z = image[y][x][0 +:8];
//reg [15:0] big_vect;
//big_vect[lsb_base_expr +: width_expr]
//big_vect[msb_base_expr -: width_expr]
关于“+:”和与之相反的“-:”具体用法,小飞将在后续博文中再详细说明~
点赞加关注博主(ID:FPGA小飞)的博文,咱们一起学习、一起进步吧~