Verilog 的几种赋值语句

本文对Verilog 的几种赋值语句进行归纳总结,辅以示例代码作为说明。

1、连续赋值语句(Continuous Assignments)

连续赋值语句是Verilog 数据流建模的基本语句,用于对线网进行赋值,等价于门级描述,是从更高的抽象角度来对电路进行描述。连续赋值语句必须以关键词assign开始。

连续赋值语句的特点:

  • 数据类型是以下几种类型之一:
    ① 标量线网,如 wire a; assign a = 1;
    ② 向量线网,如 wire a[7:0]; wire b[8:1]; 两种描述等价。
    ③ 矩阵中的一个元素,该矩阵可以是标量线网类型,也可以是向量线网类型。如:
    ④ 向量线网的某一位,如:
    ⑤ 向量线网的部分为,如:
    ⑥ 以上各种类型的拼接体
    ※ 注意:连续赋值语句的左值数据类型不能是向量或向量寄存器!

  • 连续赋值语句是并发执行的,与其书写顺序无关!

  • 连续赋值语句总是处于激活状态。只要等号右边的任意一个操作数发生变化,表达式就会被立即重新计算,并在经过指定延时后赋值给等号左边的操作数。
    ※ 注意:assign 赋值语句中的延时指的是赋值等待的时间!
    示例代码:

  • 操作数可以是标量或向量的线网或寄存器,也可以是函数的调用。

  • 赋值延迟用于控制对线网赋予新值的时间,根据仿真时间单位进行说明。赋值延迟类似于门延迟,对于描述实际电路中的时序是非常重要的。

2、过程赋值语句(Procedural Assignments)

过程赋值语句的特点:

  • 过程赋值语句的更新对象是寄存器、整数、实数、时间变量等。这些类型的变量在被赋值后,其值将保持不变,直到被其他过程赋值语句赋予新值。
  • 过程赋值语句只有在执行到的时候才会起作用。
  • 过程赋值语句只能在initialalways语句内进行赋值,只能对变量数据类型赋值,同时initial和always中只能使用过程赋值语句。
  • 过程性赋值语句包括两种类型的赋值语句:阻塞赋值(=)和非阻塞赋值(<=)

过程赋值语句的左值(操作数)可以是以下类型之一:
① reg、整形数、实型数、时间寄存器变量或存储器单元
② 上述各种类型的位选(例如:addr[3])
③ 上述各种类型的域选(例如:addr[31:16])
④ 上面三种类型的拼接

3、过程连续赋值语句(Procedural Continuous Assignments)

过程连续赋值是在过程块内对变量或线网型数据进行连续赋值,是一种过程性赋值。换言之,过程性连续赋值语句是一种能够在always或initial语句块中出现的语句。

这种赋值可以改写(Override)所有其他语句对线网或者变量的赋值。

这种赋值允许赋值表达式被连续的驱动进入到变量或线网中去。

过程连续赋值语句有两种类型:

(1) assign和deassign过程性语句:对变量进行赋值。
(2)force和release过程性语句:主要用于对线网赋值,也可以用于对变量赋值。

3.1 assign和deassign语句

assign和deassign语句构成了一类过程性连续赋值语句,只能用于对寄存器类型变量的连续赋值操作,不能用来对线网类型数据进行连续赋值操作。

(1)assign 语句

语法:assign <寄存器类型变量> = <赋值表达式>;

assign在执行时,寄存器变量将由赋值表达式进行连续驱动,即进入连续赋值状态。
3.1-1 如果此时有普通的过程赋值语句对该寄存器变量进行过程赋值操作,由于过程连续赋值语句assign的优先级高于普通过程赋值语句,所以处于连续赋值状态的寄存器变量将忽略普通过程赋值语句对它的过程赋值操作,其逻辑状态仍然由过程连续赋值语句内的赋值表达式所决定。
※ 优先级:过程连续赋值语句 高于 过程赋值语句

3.1-2 如果先后有两条assign语句对同一寄存器变量进行了过程连续赋值操作,那么第二条assign的执行将覆盖第一条assign的执行效果。

(2)deassign语句

语法:deassign <寄存器类型变量>;

deassign 语句是撤销连续赋值语句,用来结束对变量的连续赋值操作。当deassign语句执行后,原来由assign语句对该变量进行的连续赋值操作将失效,寄存器变量被连续赋值的状态将得到解除,该变量又可以由普通过程赋值语句进行赋值操作了。
需要注意的是,当执行该语句撤销对某寄存器变量的连续赋值后,该寄存器变量仍将保持使用该语句之前的原有值。

示例代码:
Verilog 的几种赋值语句_第1张图片
上述语句执行过程如下:

s0:在0时刻,out 被赋值为0,并且保持这个取值;

s1:在100时刻,s1开始执行,实现了对变量out 的连续赋值操作,因此从100时刻开始,out将处于连续赋值状态;

s2:在200时刻,s2开始执行,将覆盖s1产生的作用,所以从200时刻开始,out 将由b 连续驱动;

s3:s3操作覆盖掉s2操作;
由于s2 和s3 操作时并发执行的,根据3.1-2,s3 的操作结果将覆盖掉s2 的操作结果。

s4:当deassign 语句得到执行,变量out连续赋值状态被解除,其取值将保持最后一次assign语句赋予的值,即4’b1011。

以上代码执行结果波形图如下:
Verilog 的几种赋值语句_第2张图片

3.2 force和release语句

force和release语句与assign和deassign类似,也是一种过程连续赋值语句。这组赋值语句不仅能对寄存器类型变量产生作用,还能对线网类型数据进行连续赋值操作。

(1)force语句

语法:force <寄存器变量或线网数据> = <赋值表达式>>;

3.2-1 force语句应用于寄存器类型变量时,则在force语句执行后,该寄存器变量将强制由<赋值表达式>进行连续驱动,进入被连续赋值的状态,此时将忽略其他较低优先级的赋值语句对该寄存器变量的赋值操作,直到执行一条release语句来释放对该寄存器变量的连续赋值为止。

3.2-2 force语句应用于线网数据时,则force语句执行后,对应的线网数据将得到<赋值表达式>的连续驱动,此时将忽略该线网数据上较低优先级的驱动,直到有一条release语句执行为止。

(2)release语句

语法:release <寄存器变量或者线网数据>;

release语句执行后,由force语句对变量或者线网施加的过程连续赋值将失效,变量将解除被被连续赋值的状态,较低优先级的赋值语句的赋值操作将有效。

示例代码:
Verilog 的几种赋值语句_第3张图片
上述语句执行过程如下:

s0:实现对变量reg1的过程赋值操作,reg1被赋值为3’b001;

s1:执行assign过程连续赋值,实现对reg2的连续赋值,reg2被连续赋值为3’b010;

s2:执行s2时,reg1未被assign语句进行过连续赋值操作,因此reg1被force连续赋值为3’b100;

s3:执行s3后,reg2被force连续赋值为3’b100;

s4:执行s4时,reg1将退出连续赋值的状态,因reg1未曾被assign语句进行过连续赋值操作,故reg1的值保持不变,即保持force状态时的值3’b100;

s5:reg2在s3之前已经由s1实现了连续赋值,s5执行后,reg2将恢复到由s1确定的连续赋值状态,即3‘b010。

波形图如下:
Verilog 的几种赋值语句_第4张图片

4、3种赋值语句的区别

4.1 连续赋值语句 vs. 过程赋值语句

  • 连续赋值语句必须由assign 来标识,过程赋值语句没有assign 关键字;
  • 连续的操作数必须是线网类型,过程的操作数必须是寄存器类型;
  • 连续赋值不能出现在initial 或always 过程块中,过程赋值必须出现在过程块中;
  • 连续赋值主要用来对组合逻辑电路进行建模以及对线网数据间的连接进行描述,过程赋值主要用来对时序逻辑电路进行行为描述;
  • 连续赋值对线网型操作数的赋值是“连续”的(赋值表达式的任何变化都会立刻反应在线网数据的取值上);过程赋值只有在赋值语句被执行时才进行赋值操作,语句执行完后被赋值变量的取值不再受到赋值表达式的影响(这里的一次是指:在initial块中,过程性赋值只顺序执行一次;在always块中,每一次满足always的条件时,都要顺序执行一次该always块中的语句。)。
    Verilog 的几种赋值语句_第5张图片

4.2 连续赋值语句 vs. 过程连续赋值语句

  • 过程连续赋值语句只能用在过程块(initial 或always)中,连续赋值语句不能出现在过程块中。
  • 过程连续赋值语句可以对寄存器变量进行连续赋值(force-release语句还可以对线网进行连续赋值),但是其赋值目标不能是变量或线网的某一位或某几位;连续赋值语句只能对线网数据进行赋值,赋值目标可以是线网型数据的某一位或某几位。

#########################################################################################
以上就是Verilog 中关于赋值语句的内容。

你可能感兴趣的:(Verilog)