相关文章
Verilog基础:casex和full_case、parallel_case的使用
Verilog中的数据类型可以分为两大类:线网(net)和变量(variable)注意:在Verilog-2005标准中,寄存器类型(register)被改名为变量类型。这两类数据类型的主要区别在于它们的赋值和保存数据的方式。
1.线网(net)
线网(net)常用于表示逻辑门或模块间的连接。除了trireg之外,所有其他的线网类型均不能保存值,而线网的值是由驱动(driver)决定的,例如由连续赋值驱动或由模块驱动。如果一个线网没有驱动,那么线网的值为高阻z,但是tri0、tri1、trireg除外,tri0是0,tri1是1,而trireg会保存之前的驱动值。
线网类有以下具体类型:wire、wand、wor、tri、triand、trior、tri0、tri1、trireg、uwire、supply0、supply1。
1.1 wire和tri
wire和tri是一样的,具有同样的语法和功能,提供两个名字的意义在于区分不同方面的建模:wire用于连续赋值的驱动,而tri用于多个驱动源驱动。
当有多个相同强度的驱动源同时驱动wire或tri时出现冲突时(一个为高一个为低),他们的值是x(未知)。
1.2 wor、wand、trior、triand
线逻辑(model wired logic)类型的线网有wor、wand、trior、triand,他们用于解决多个驱动源同时驱动同一个线网出现的冲突。wor和trior实现线或逻辑,wand和triand实现线与逻辑。
wor和trior是一样的,wand和triand是一样的,只是为了不同方面的建模更加直观。
1.3 tri0、tri1
tri0用于表示带有下拉电阻的线网。当没有驱动源驱动tri0时,tri0的值是0,强度是pull。
tri1用于表示带有上拉电阻的线网。当没有驱动源驱动tri1时,tri1的值是1,强度是pull。
1.4 uwire
Verilog-2005新增了这个线网类型,它只能有驱动源,如果有多个,编译时会报错。
1.5 supply0、supply1
supply0和supply1用于模型电源,表示只能提供0值和1值的线网,多用在标准库建模中,平时不用。
1.6驱动强度
对于1和0,驱动强度包括五个等级,从强到弱依次为supply、strong、pull、weak、highz。
2.变量(variale)
变量类有以下具体类型:reg、integer、time、real、realtime。
变量是数据存储单元的抽象,具有以下特性。
变量将保持上一次的赋值结果,直到下一次赋值。
reg、time、integer的初始值是x,real和realtime的初始值是0.0。如果使用变量声明赋值(例如reg a=1'b0;),相当于在initial块中给定义的变量赋了初值。
对reg的赋值是过程赋值(阻塞赋值和非阻塞复制),且只能在过程块中赋值(always和initial),因为reg能保持每次赋给它的值,所以能被用来对触发器或锁存器等能保存数据的单元,但reg也可以用于对组合逻辑建模。
虽然reg很常用,但其他变量也有自己的用处,integer可以用来保存中间变量,time常用来保存仿真时间,常与系统任务$time一起使用。
可以把负值赋给线网和变量,但只有integer、real、realtime、reg signed、net signed可以保留符号,而time、reg(unsigned)、net(unsigned)则把他们的值当做无符号数。
integer等价于reg signed [31:0],time等价于reg signed [63:0]。real和realtime是等价的,都是64位双精度浮点数,只不过realtime常和系统任务$realtime一起使用用来保存含小数的仿真时间。
不能对real和realtime使用位选和域选。
3.向量(vector)
标量(scalar)是没有范围声明的一位线网或变量。
向量(vector)是在名字前带有范围声明的多位线网或变量。
例子:
wand w; //1位标量wand线网
wire w1, w2; //连续声明两个1位标量线网
tri [15: 0] busa; //16位向量tri线网
reg a; //1位标量变量
reg [3: 0] v; //4位向量reg变量。
注意:范围声明可以数字大的在左(MSB),也可以在右(LSB),支持负数。
reg [4: -1] b; //6位向量reg变量
reg [0: 4] c; //5位向量reg变量,最高位对应c[0]
4.数组(array)
Verilog-2001对于数组的定义和访问做了很大的加强,具有以下特性。
数组的元素可以是标量也可以是向量。
数组的维数可以是一至多维。
数组的引用可以针对某一个元素或元素的位选和域选。
通常把一维数组称为存储器(memory)。例如可以利用$readmemh和$readmemb将数据加载到存储器中。
在Verilog-1995中,可以把寄存器变量声明为一维数组,如reg [31: 0] mem[0: 127]。但是却存在着两个明显的限制:A. 线网类型不能声明为一维数组;B. 数组只能按照元素访问,不能对某个元素进行位选和域选。在Verilog-2001中,这些限制被解除了,但引用数组中的多个元素依旧是非法的,也就是说你不能通过引用数组的一部分来部分初始化,也不能引用整个数组来初始化,通常做法是利用索引变量和循环语句初始化数组。