assign和deassign语句构成了一类过程性连续赋值语句,只能用于对寄存器类型变量的连续赋值操作,不能用来对线网类型数据进行连续赋值操作。
①assign语句
语法:assign <寄存器类型变量> = <赋值表达式>;
assign在执行时,寄存器类型变量将由赋值表达式进行连续驱动,即进入连续赋值状态。如果此时有普通的过程赋值语句对该寄存器变量进行过程赋值操作,由于过程连续赋值语句assign的优先级高于普通过程赋值语句,所以出于连续赋值状态的寄存器变量将忽略普通过程赋值语句对它的过程赋值操作,其逻辑状态仍然由过程连续赋值语句内的赋值表达式所决定。
如果先后有两条assign语句对同一寄存器变量进行了过程连续赋值操作,那么第二条assign的执行将覆盖第一条assign的执行效果。
②deassign语句
语法:deassign <寄存器类型变量>;
deassign语句是一条撤销连续赋值语句,用来结束对变量的连续赋值操作。当deassign语句执行后,原来由assign语句对该变量进行的连续赋值操作将失效,寄存器变量被连续赋值的状态将得到解除,该变量又可以由普通过程赋值语句进行赋值操作了。这里需要注意一点,当执行该语句撤销对某寄存器变量的连续赋值后,该寄存器变量仍将保持使用该语句之前的原有值。
③示例:
上述语句执行过程如下:
s0:在0时刻,out被赋值为0,并且保持这个取值;
s1:在10时刻,s1开始执行,实现了对变量out的连续赋值操作,因此从10时刻开始,out将处于连续赋值状态;
s2:在20时刻,s2开始执行,将覆盖s1产生的作用,所以从20时刻开始,out将由c & d连续驱动;
s3:s3操作覆盖掉s2操作;
s4:当deassign语句得到执行,变量out连续赋值状态被解除,其取值将保持最后一次assign语句赋予的值,即“e & f”;
3.2 force和release语句
force和release语句与assign和deassign语句类似,也是一种过程连续赋值语句。这组赋值语句不仅能对寄存器类型变量产生作用,还能对线网类型数据进行连续赋值操作。
①force语句
语法:force <寄存器变量或者线网数据> = <赋值表达式>>;
force语句应用于寄存器类型变量时,则在force语句执行后,该寄存器变量将强制由<赋值表达式>进行连续驱动,进入被连续赋值的状态,此时将忽略其他较低优先级的赋值语句对该寄存器变量的赋值操作,直到执行一条release语句来释放对该寄存器变量的连续赋值为止。
force语句应用于线网数据时,则force语句执行后,对应的线网数据将得到<赋值表达式>的连续驱动,此时将忽略该线网数据上较低优先级的驱动,直到有一条release语句执行为止。
②release语句
语法:release <寄存器变量或者线网数据>;
release语句执行后,原先由force语句对变量或者线网施加的过程连续赋值将失效,变量将解除被被连续赋值的状态,较低优先级的赋值语句的赋值操作将有效。
③示例:
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;
s5:执行本语句时,因为var_reg2在执行s3之前已经由s1实现了连续赋值,所以在本条语句s5执行后,变量var_reg2将恢复到由assign语句s1确定的连续赋值状态,即3'b001;
4. 赋值语句的区别
4.1 连续赋值语句和过程赋值语句之间的区别
- 连续赋值语句由assign来标示,而过程赋值语句不能包含这个关键词;
- 连续赋值语句中左侧的数据类型必须是线网数据类型,而过程赋值语句中的被赋值数据类型则必须是寄存器类型的变量;
- 连续赋值语句不能出现在过程块(initial或always)中,而过程赋值语句可以;
- 连续赋值语句主要用来对组合逻辑电路进行建模以及对线网数据间的连接进行描述,而过程赋值语句主要用来对时序逻辑电路进行行为描述;
- 连续赋值语句对被赋值线网型数据的赋值是“连续”的(即赋值表达式的任何变化都会在立刻反应在线网数据的取值上),而过程性赋值语句,只有在过程赋值语句被执行时才执行赋值操作,语句执行完后被赋值变量的取值不再受到赋值表达式的影响(注意这里的一次是指:在initial块中,过程性赋值只顺序执行一次,而在always块中,每一次满足always的条件时,都要顺序执行一次该always块中的语句。)。
- 连续赋值与过程赋值的区别:
| 过程赋值 | 连续赋值 |
assign | 无assign(过程性连续赋值除外) | 有assign |
符号 | 使用“=”或“《=” | 只使用“=” |
位置 | 在always语句或initial语句中均可出现 | 不可出现于always语句和initial语句 |
执行条件 | 与周围其他语句有关 | 等号右端操作数的值发生变化时 |
用途 | 驱动寄存器 | 驱动线网 |
4.2 过程连续赋值语句和连续赋值语句之间的区别
- 过程连续赋值语句只能用在过程块(initial过程快或always过程块)内,而连续赋值语句不能出现在过程块中。
- 过程连续赋值语句可以对寄存器类型变量进行连续赋值(其中force-release语句还可以对线网进行连续赋值),但是其赋值目标不能是变量或线网的某一位或某几位,而连续赋值语句只能对线网数据进行赋值,赋值目标可以是线网型数据的某一位或某几位。