2.2 连续赋值、过程赋值

4、赋值

Verilog HDL有两种为变量赋值的方法

一种叫做连续赋值(Continuous Assignment),另一种叫做过程赋值(Procedural Assignment)。

过程赋值又分为阻塞赋值(Blocking Assignment)和非阻塞赋值(Nonblocking Assignment)。

4.1 连续赋值

连续赋值是为线网型变量提供驱动的一种方法,它只能为线网型变量赋值,并且线网型变量也必须用连续赋值的方法赋值。

最基本的格式:assign # [延时量] 线网型变量名 =赋值表达式

赋值表达式可以是 a.标量   b.向量线网  c.向量寄存器    d.函数调用;

执行过程:连续赋值语句总是处于激活状态,只要右侧表达式中的任意一个操作数发生变化,表达式就会被立即重新计算,并且将结果赋值给对象。

wire a,b;
assign a = b;

wire [7:0] a,b;
assign a = b;

wire [7:0] a,b;
assign a[3] =b[1];

wire [7:0] a,b;
assign a[3:0] =b[3:0];

wire a,b;
wire [1:0]c;
assign c = {a,b};

 

4.2 过程赋值

过程赋值提供了为寄存器型变量赋值的方法,出现的位置是在各种块结构中,例如always块、 initial块等。

经过赋值后,变量(reg,integer,real,time)的取值保持不变,直到另一条赋值语句对变量重新赋值为止。

过程赋值又分为阻塞赋值和非阻塞赋值两种。

1、阻塞赋值

阻塞赋值方式,使用“=”为变量赋值。

“阻塞”是指在当前的赋值完成前阻塞其他类型的赋值任务。但如果右端表达式含有延时语句,则在延时没结束前不会阻塞其他赋值任务。

赋行值按顺序执行,只有上一条语句执行完成(赋值结束),才会执行(赋值)下一条语句;在赋值结束以前不可以进行其它操作,在赋值结束后才继续后面的操作。这个过程好像阻断了程序的运行,因而被称为阻塞赋值。
显然,连续的阻塞赋值操作是顺序完成的。

如a=b,在每个右端表达式计算完后立即赋给左端变量,也就是在该语句结束时就完成了赋值操作。

2、非阻塞赋值

非阻塞赋值使用“<=”为变量赋值,在执行到连续的非赋值语句时,仅仅对“<=” 右端表达式进行评估,但并不立即赋值给左端,然后继续执行后面的操作,当块结构结束后所有的非阻塞赋值同时进行赋值。这个过程好像没有阻断程序的运行,因而被称为非阻塞赋值。

执行步骤:
(1)读取操作数,计算右侧表达式的值并保存在临时变量中;
(2)对左侧的赋值由仿真器调度到相应的仿真时刻;
(3)每个赋值操作在被调度的仿真时刻完成。
典型应用:流水线建模 互斥数据传输
问题:仿真速度下降  内存使用量增加

对组合逻辑建模采用阻塞式赋值;

最时序逻辑建模采用非阻塞式赋值;

用多个always块分别对组合和时序逻辑建模。

 

5、过程模块

begin..end 块内语句是串行执行的,fork..join 是并行执行的;

case语句的分支是并行执行,if语句的选择分支是串行执行。

(1)initial模块

在仿真时,initial模块只执行一次,如果有两个initial模块,同时开始从0时刻执行。

initial 
    forever begin  // forever语句必须写在initial模块中,用于产生周期性波形。
        #5 clk = ~clk;   //延时控制
        a = 0;
        ...
    end
    ...
end

(2)always模块

一直重复执行的。括号内是多个触发条件,只要有一个成立,就启动块内启动执行。

always @(a or b or posedge clk or negedge y) begin
    ...
end

(3)task模块

(4)function模块

 

6、语句块

(1)begin..end 块内语句是串行执行的

(2)fork..join 是并行执行的

并行:各自独立地同时开始执行。

posted @ 2019-01-14 20:47  Aurora_l  阅读(3517)  评论(0编辑  收藏  举报