Verilog系列:【32】Verilog中的几种赋值语句
1.连续赋值语句(Continuous Assignments)
连续赋值语句是Verilog数据流建模的基本语句,用于对线网进行赋值,等价于门级描述,是从更高的抽象角度来对电路进行描述。连续赋值语句必须以关键词assign开始。
连续赋值的主要特点是:
· 连续赋值语句的左值可以是一下类型之一:
①标量线网
②向量线网
③矩阵中的一个元素(该矩阵可以是标量线网类型的,也可以是向量线网类型的)
④向量线网的某一位
⑤向量线网的部分位
以及上述各种类型的拼接体
但是,不能是向量寄存器(reg)。
· 连续赋值语句总是处于激活状态。只要任意一个操作数发生变化,表达式就会被立即重新计算,并且将结果赋给等号左边的线网。
· 操作数可以是标量或向量的线网或寄存器,也可以是函数的调用。
2.过程赋值语句(Procedural Assignments)
过程赋值语句的更新对象是寄存器、整数、实数或时间变量等。这些类型的变量在被赋值后,其值将保持不变,直到被其他过程赋值语句赋予新值。过程赋值语句只有在执行到的时候才会起作用。过程赋值语句只能在initial或always语句内进行赋值,只能对变量数据类型赋值,同时initial和always中只能使用过程赋值语句。
过程赋值语句的左值可以是以下类型之一:
①reg、整形数、实型数、时间寄存器变量或存储器单元
②上述各种类型的位选(例如:data[3])
③上述各种类型的域选(例如:addr[31:16])
④上面三种类型的拼接
3.过程连续赋值语句(Procedural Continuous Assignments)
过程连续赋值是在过程块内对变量或线网型数据进行连续赋值,是一种过程性赋值,换言之,过程性连续赋值语句是一种能够在always或initial语句块中出现的语句。这种赋值可以改写(Override)所有其他语句对线网或者变量的赋值。这种赋值允许赋值表达式被连续的驱动进入到变量或线网中去。
过程连续赋值语句有两种类型:
①assign和deassign过程性语句:对变量进行赋值。
3.1assign和deassign语句
①assign语句
语法:assign <寄存器类型变量> = <赋值表达式>;
assign在执行时,寄存器类型变量将由赋值表达式进行连续驱动,即进入连续赋值状态。如果此时有普通的过程赋值语句对该寄存器变量进行过程赋值操作,由于过程连续赋值语句assign的优先级高于普通过程赋值语句,所以出于连续赋值状态的寄存器变量将忽略普通过程赋值语句对它的过程赋值操作,其逻辑状态仍然由过程连续赋值语句内的赋值表达式所决定。
②deassign语句
语法:deassign <寄存器类型变量>
上述语句执行过程如下:
s0:在0时刻,out被赋值为0,并且保持这个取值;
s1:在10时刻,s1开始执行,实现了对变量out的连续赋值操作,因此从10时刻开始,out将处于连续赋值状态;
s2:在20时刻,s2开始执行,将覆盖s1产生的作用,所以从20时刻开始,out将由c & d连续驱动;
s3:s3操作覆盖掉s2操作;
3.2 force和release语句
①force语句
语法:force <寄存器变量或者线网数据> = <赋值表达式>>;
force语句应用于寄存器类型变量时,则在force语句执行后,该寄存器变量将强制由<赋值表达式>进行连续驱动,进入被连续赋值的状态,此时将忽略其他较低优先级的赋值语句对该寄存器变量的赋值操作,直到执行一条release语句来释放对该寄存器变量的连续赋值为止。
②release语句
语法:release <寄存器变量或者线网数据>;
③示例:
s0:实现对变量var_reg1的过程赋值操作,即var_reg1被赋值为3'b000;
s1:执行assign过程连续赋值语句,用来实现对变量var_reg2的连续赋值,从而var_reg2将被连续赋值为3'b001;
s2:在执行本条语句时,var_reg1未被assign语句进行过连续赋值操作,因此var_reg1被force连续赋值为3'b100;
s3:执行本条语句后,var_reg2被force连续赋值为3'b100;
s4:执行本条语句时,因为变量var_reg1将退出连续赋值的状态,因为var_reg1未曾被assign语句进行过连续赋值操作,故var_reg1取值保持不变,即保持force状态时的值3'b100;
4. 赋值语句的区别
4.1 连续赋值语句和过程赋值语句之间的区别
· 连续赋值语句由assign来标示,而过程赋值语句不能包含这个关键词;
· 连续赋值语句中左侧的数据类型必须是线网数据类型,而过程赋值语句中的被赋值数据类型则必须是寄存器类型的变量;
· 连续赋值语句不能出现在过程块(initial或always)中,而过程赋值语句可以;
· 连续赋值语句主要用来对组合逻辑电路进行建模以及对线网数据间的连接进行描述,而过程赋值语句主要用来对时序逻辑电路进行行为描述;
· 连续赋值语句对被赋值线网型数据的赋值是“连续”的(即赋值表达式的任何变化都会在立刻反应在线网数据的取值上),而过程性赋值语句,只有在过程赋值语句被执行时才执行赋值操作,语句执行完后被赋值变量的取值不再受到赋值表达式的影响(注意这里的一次是指:在initial块中,过程性赋值只顺序执行一次,而在always块中,每一次满足always的条件时,都要顺序执行一次该always块中的语句。)。
· 连续赋值与过程赋值的区别
| 过程赋值 | 连续赋值 |
assign | 无assign(过程性连续赋值除外) | 有assign |
符号 | 使用“=”或“<=” | 只使用“=” |
位置 | 在always语句或initial语句中均可出现 | 不可出现于always语句和initial语句 |
执行条件 | 与周围其他语句有关 | 等号右端操作数的值发生变化时 |
用途 | 驱动寄存器 | 驱动线网 |
· 过程连续赋值语句只能用在过程块(initial过程快或always过程块)内,而连续赋值语句不能出现在过程块中。
· 过程连续赋值语句可以对寄存器类型变量进行连续赋值(其中force-release语句还可以对线网进行连续赋值),但是其赋值目标不能是变量或线网的某一位或某几位,而连续赋值语句只能对线网数据进行赋值,赋值目标可以是线网型数据的某一位或某几位。