精华内容
下载资源
问答
  • Verilog十大基本功0(阻塞赋值与非阻塞赋值阻塞赋值与非阻塞赋值超级详细讲解 本文共分为三部分: 第一部分是正确使用阻塞与非阻塞赋值的基本原则。 第二部分是阻塞与非阻塞赋值对应的电路行为逻辑。 第三部分是...

    Verilog十大基本功0(阻塞赋值与非阻塞赋值)阻塞赋值与非阻塞赋值超级详细讲解

    本文共分为三部分:
    第一部分是正确使用阻塞与非阻塞赋值的基本原则。
    第二部分是阻塞与非阻塞赋值对应的电路行为逻辑。
    第三部分是阻塞与非阻塞赋值的原理简介。

    第一部分 正确使用阻塞与非阻塞赋值的基本原则(Golden Rule)
    编码原则很多,就阻塞非阻塞赋值而言,新手最需要牢记的是其中三条:
    1、时序逻辑一定用非阻塞赋值”<=”,一旦看到敏感列表有 posedge 就用”<=”。
    2、组合逻辑一定用”=” ,一旦敏感列表没有 posedge 就用”=”,一旦看到 assign 就用”=”。
    3、时序逻辑和组合逻辑分成不同的模块,即一个 always 模块里面只能出现非阻塞赋值”<=”或者”=”。如
    果发现两种赋值并存,一个字”改”,心存侥幸可能会给后续工作带来更多麻烦。

    以上三条,对新手而言不必追求为什么,需要的就是条件反射的照章办事。最后说一句,新手可能记不
    住哪个符号是阻塞赋值,哪个是非阻塞赋值,大家可以数数, ”非阻塞赋值”一共 5 个字,“阻塞赋值“ 4
    个字,所以非阻塞用的符号”<=”比阻塞赋值用的符号”=”长。


    第二部分 阻塞与非阻塞赋值对应的电路行为逻辑
    第一节给出了三条最基本的编码原则,有个朋友可能会想,按照这三条编码原则写出来的代码会按怎样
    的逻辑工作呢?这一节就是回答这个问题。

    首先解释一下阻塞赋值与非阻塞赋值的含义。
    所谓的阻塞赋值”=”就是说, 在这个语句没有执行完之前,后面的语句是不执行的。 
    这里执行的含义是指完成变量值的更新。
    非阻塞赋值”<=”是指, 所有的语句可以并发执行,而前面的值是否执行完毕不会影响后面的语句,
    换句话说,语句的顺序是无关紧要的。

    举个例子,假设一个模块,有 2 个寄存器, b 和 c,初值都是 1。 a 为输入信号线。在某个时刻,因为某
    种原因,模块被触发执行。对于组合逻辑而言,一般是输入信号值变了,对于时序逻辑而言,一般是时
    钟沿到了。

    首先看组合逻辑:假设输入 a = 2;
    always@(a ,b)
    begin
      b = a;
      c = b;
    end

    由于是阻塞赋值,所以首先执行完第一句 b=a,执行完成之后 b=2。接着执行 c=b,执行完成后 c=2,一
    次仿真结束后 b=c=2;

    对于时序逻辑而言,依然假设 a =2;
    always@(posedge clk)
    begin
      b <= a;
      c <= b;
    end

    由于是非阻塞赋值,首先执行第一句 b<=a,这时候 a = 2,但是还没有执行完第一句的时候,第二句 c<=b
    也执行了,由于第一句没有执行完, b 的值还是 1,这时候赋值给 c 的值也是 1。执行完毕的结果就是
    c=1,b=2.等到模块再次被触发的时候 c 的值更新为 2。

    第三部分 阻塞与非阻塞赋值的原理简介
    有个朋友可能就会问了,凭啥第一句执行到一半就该第二句执行呢?到底是第一句先完成赋值呢还是第二句
    先完成赋值?答案是,谁先完成赋值都没关系,结果是一样的。

    为什么说结果一样呢? 因为两种赋值方式分别是按照下面的顺序执行的。

    阻塞赋值,就跟 C 语言一样,严格按照代码书写的先后顺序执行,所有值都是立即更新,并且在下面的
    语句中按照新值执行。

    而时序电路就不一样了,大家可以这么理解时序逻辑的代码行为,一次执行分为两轮:
    第一轮是所有的左值都先赋给临时变量,
    第二轮用输入值以及和右值同名的临时变量值去更新左值。

    比如上面的例子,第一轮,赋给临时变量: tempc=c;tempb=b。
    第二轮,临时变量更新左值, b = a;c = tempb;output = tempc。
    从上面的分析也可以看出,组合逻辑的结果与代码顺序直接相关,而时序逻辑与代码顺序没有关系。这就是所
    谓的顺序执行(组合逻辑)与并发执行(时序逻辑)。

    为了进一步理解这两种赋值方式的行为,下面用对应的电路进行说明,以前面的代码为例。大家首先闭
    上眼睛想想,对应的电路是什么样子的呢?

    其实答案很简单,对于阻塞赋值来说,如图一所示,综合的结果就是一根导线,当然,可能有反相器,
    buf 什么的,反正还是可以看作一根线。

    到这里,应该就很容易理解顺序执行的行为方式了。
    有细心的朋友可能会问,如果换种写法呢?

    always@(a,b)
    begin
      c = b;
      b = a;
    end

    很显然,这种电路的行为跟之前是不一样的,从逻辑来看会产生类似于非阻塞赋值的结果,但很显然不
    满足非阻塞赋值并发执行的特点。如果把输入电平 a 触发改成时钟边沿触发 posedge clk,出来的就是寄
    存器,但这违反了时序逻辑不用阻塞赋值的原则,所以严重不推荐。至于这种组合逻辑描述方式出来的
    电路是啥我也不知道,大家可以自己综合看看,或者哪位高人补上~~应该注意的是,如果想象不出这种
    怪异的 coding 方式会产生何种电路,就不要这么写,因为实现这种逻辑最好的办法是采用非阻塞方式描
    述。

    而对于非阻塞赋值而言,综合出来的结果就是 2 个寄存器。对 b,c 赋值的过程就是寄存器
    输入采样的过程,很显然两个采样是同时进行的,而且一次时钟沿只会采样一次,所以输入值 a 会首先
    被采样到 b,再在下一个时钟被采样到 c.

    总结一下:
    关于两种赋值方式,首先讲述了代码执行的过程,然后用直连线和寄存器分别对应了两种描
    述方式。应该指出的是,非阻塞赋值用寄存器的类比是完全准确的,而阻塞赋值用直连线的类比却未必
    准确,只不过因为一般认为直连线是从输入到输出依次更新的,而且没有传输以外的延迟,所以这种类
    比有助于新人理解,虽然不够严密。大家熟悉了之后就应该按照更严谨的方式去理解。

    补充一下,如果写出下面这样的代码,在时序电路中使用阻塞赋值的话,综合出来就只有一个寄存器,不是两个,寄
    存器的输入 D 端是 a,输出 Q 端是 b 和 c,两个信号在同一根线上

    always@(posedge clk)
    begin
      b = a;
      c = b;
    end

    所以这样的写法很容易造成设计和综合结果不匹配的情况,即使不是要设计两级寄存器,也最好不要用阻塞赋值。

    另外一个就是,脑袋里面需要有时序逻辑和组合逻辑的框图。
    将组合逻辑和时序逻辑分开写,组合逻辑用=,时序逻辑用<=,
    时序逻辑内的判断越简单越好,尽量都放在组合逻辑里面做,时序逻辑只负责 flop 一下。
    所以,最重要的是, 新手应该严格按照规则来,见到 posedge 就写 <= ,而根本不考虑 = ,免得综合出怪东西来。
    这种代码应该严格杜绝,呵呵~~
    ————————————————
    版权声明:本文为CSDN博主「Times_poem」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Times_poem/article/details/52032890

    展开全文
  • 阻塞赋值阻塞赋值

    万次阅读 多人点赞 2019-06-17 16:13:11
    Verilog语言中最容易被误解的构造之一是非阻塞赋值。 即使是非常有经验的Verilog设计人员也不能完全理解在IEEE兼容的Verilog模拟器中如何安排非阻塞分配,并且不了解应该何时以及为何应该使用非阻塞赋值。 本文详细...

    1.0简介

    编码指南:
    指南:在为生成组合逻辑[1]而编写的always块中使用阻塞赋值。
    指南:在为生成顺序逻辑[1]而编写的always块中使用非阻塞赋值。
    竞争:
    如果两个或多个计划在同一模拟时间步骤中执行的语句在IEEE Verilog标准允许的情况下更改语句执行顺序时会产生不同的结果,则会发生Verilog竞争。

    在本文中,将使用以下缩写:
    RHS - 方程右侧的表达式或变量将缩写为RHS方程,RHS表达式或RHS变量。
    LHS - 方程左侧的表达式或变量将缩写为LHS方程,LHS表达式或LHS变量。

    2.0阻塞赋值&非阻塞赋值

    2.1阻塞赋值

    在Verilog HDL的概念中阻塞赋值操作符用等号(即=)表示。
    在赋值时先计算等号右手方向(RHS)部分的值,这时赋值语句不允许任何别的Verilog语句的干扰,直到现行的赋值完成时刻,即把RHS赋值给LHS(等号左手方向)的时刻,它才允许别的赋值语句的执行。一般可综合的阻塞赋值操作在RHS不能设定有延迟(即使是零延迟也不允许)。从理论上讲,它与后面的赋值语句只有概念上的先后,而无实质上的延迟。若在RHS上加延迟,则在延迟期间会阻止赋值语句的执行,延迟后才执行赋值,这种赋值语句是不可综合的,在需要综合的模块设计中不可使用这种风格的代码。
    问题
    如果在一个过程块中阻塞赋值的RHS变量正好是另一个过程块中阻塞赋值的LHS变量,这两个过程块又用同一个时钟沿触发,这时阻塞赋值操作会出现问题,即如果阻塞赋值的顺序安排不好,就会出现竞争。若这两个阻塞赋值操作用同一个时钟沿触发,则执行的顺序是无法确定的。
    为了说明这一点,请查看示例1中的Verilog代码。

    module fbosc1 (y1, y2, clk, rst);
        output y1, y2;
        input clk, rst;
        reg y1, y2;
    always @(posedge clk or posedge rst)
         if (rst) y1 = 0; // reset
         else y1 = y2;
    always @(posedge clk or posedge rst)
         if (rst) y2 = 1; // preset
         else y2 = y1;
    endmodule
    

    Example 1 - Feedback oscillator with blocking assignments

    根据IEEE Verilog标准,可以按任何顺序安排两个始终块。 如果在复位后执行第一个always块,则y1和y2都将取值1.如果第二个always块在复位后首先执行,则y1和y2都将取值0.这显然代表一个Verilog 竞争条件。

    2.2非阻塞赋值

    非阻塞赋值操作符用小于等于号(即<=)表示。
    为在赋值操作时刻开始时计算非阻塞赋值符的RHS表达式,赋值操作时刻结束时更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的Verilog非阻塞赋值语句都能同时计算RHS表达式和更新LHS。非阻塞赋值允许其他的Verilog语句同时进行操作。
    非阻塞赋值是由时钟节拍决定,在时钟上升到来时,执行赋值语句右边,然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边,注意:是begin—end之间的所有语句,一起执行,且一个时钟只执行一次。
    为了说明这一点,请查看示例2中的Verilog代码

    module fbosc2 (y1, y2, clk, rst);
        output y1, y2;
        input clk, rst;
    reg y1, y2;
    always @(posedge clk or posedge rst)
        if (rst) y1 <= 0; // reset
         else y1 <= y2;
    always @(posedge clk or posedge rst)
        if (rst) y2 <= 1; // preset
         else y2 <= y1;
    endmodule
    

    Example 2 - Feedback oscillator with nonblocking assignments
    同样,根据IEEE Verilog标准,可以按任何顺序安排两个始终块。 无论在复位后哪个块始终首先启动,都将在时间步的开始时评估两个非阻塞RHS表达式,然后在同一时间步的末尾更新两个非阻塞LHS变量。 从用户的角度来看,这两个非阻塞语句的执行是并行发生的。

    2.3区别

    非阻塞赋值
    always@(posedge clk)
    begin
    b<=a;
    c<=b;
    end
    阻塞赋值
    always@(posedge clk)
    begin
    b=a;
    c=b;
    end
    两种不同的赋值方式结果是不同的,非阻塞赋值b<=a;c<=b;两条语句是同时执行的,而阻塞赋值b=a;c=b;两条语句先执行b=a后执行c=b。

    3.0编码准则

    Clifford在《Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!》
    一文中有给出八条编码准则:
    1)时序电路建模时,用非阻塞赋值;
    2)锁存器电路建模时,用非阻塞赋值;
    3)用always块建立组合逻辑模型时,用阻塞赋值;
    4)在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值;
    5)在同一个alway块中,不要即用非阻塞又用阻塞赋值;
    6)不要在一个以上的always块中为同一个变量赋值;
    7)用$strobe系统任务来显示用非阻塞赋值的变量值;
    8)在赋值时不要使用#0延迟。

    4.0 举例

    准则1)时序电路建模时,用非阻塞赋值;

    在这里插入图片描述
    图2显示了简单的顺序流水线寄存器最简单的时序电路)的框图。 示例5 - 示例8显示了工程师可能选择使用阻塞赋值四的种不同编码方式。
    在例5中,顺序排序的阻塞分配将使输入值d放在下一个posedge clk上每个寄存器的输出上。 在每个时钟边沿,输入值无延迟地直接传输到q3输出。 这显然不会对流水线寄存器进行建模,实际上会合成一个寄存器! (见图3)。
    在这里插入图片描述

    module pipeb1 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) begin
    q1 = d;
    q2 = q1;
    q3 = q2;
    end
    endmodule
    

    Example 5 - Bad blocking-assignment sequential coding style #1
    在示例6中,已仔细排序阻塞分配,以使模拟正确地像流水线寄存器一样运行。 该模型合成了图2所示的流水线寄存器。

    module pipeb2 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) begin
    q3 = q2;
    q2 = q1;
    q1 = d;
    end
    endmodule
    

    Example 6 - Bad blocking-assignment sequential coding style #2 - but it works!
    在示例7中,阻塞分配已拆分为单独的always块。
    允许Verilog以任何顺序模拟always块,这可能导致此管道模拟错误。 这是Verilog的竞争条件! 以不同顺序执行always块会产生不同的结果。 但是,这个Verilog代码将合成到正确的流水线寄存器。 这意味着预合成和后合成模拟之间可能存在不匹配。 pipeb4示例或同一个始终块语句的任何其他顺序也将合成到正确的管道逻辑,但可能无法正确模拟。

    module pipeb3 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) q1=d;
    always @(posedge clk) q2=q1;
    always @(posedge clk) q3=q2;
    endmodule
    

    Example 7 - Bad blocking-assignment sequential coding style #3

    module pipeb4 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) q2=q1;
    always @(posedge clk) q3=q2;
    always @(posedge clk) q1=d;
    endmodule
    

    Example 8 - Bad blocking-assignment sequential coding style #4
    如果四个阻塞分配示例中的每一个都用非阻塞赋值重写,则每个都将正确模拟并合成所需的流水线逻辑。

    module pipen1 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) begin
    q1 <= d;
    q2 <= q1;
    q3 <= q2;
    end
    endmodule
    

    Example 9 - Good nonblocking-assignment sequential coding style #1

    module pipen2 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) begin
    q3 <= q2;
    q2 <= q1;
    q1 <= d;
    end
    endmodule
    

    Example 10 - Good nonblocking-assignment sequential coding style #2

    module pipen3 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) q1<=d;
    always @(posedge clk) q2<=q1;
    always @(posedge clk) q3<=q2;
    endmodule
    

    Example 11 - Good nonblocking-assignment sequential coding style #3

    module pipen4 (q3, d, clk);
    output [7:0] q3;
    input [7:0] d;
    input clk;
    reg [7:0] q3, q2, q1;
    always @(posedge clk) q2<=q1;
    always @(posedge clk) q3<=q2;
    always @(posedge clk) q1<=d;
    endmodule
    

    Example 12 - Good nonblocking-assignment sequential coding style #4

    由此可见,对流水线逻辑进行编码时 ,非阻塞赋值会比阻塞赋值好,虽然阻塞赋值也可以通过严谨的拍序实现。

    准则2)锁存器电路建模时,用非阻塞赋值;

    类似的分析表明,使用非阻塞分配来模拟锁存器也是最安全的。

    准则3)用always块建立组合逻辑模型时,用阻塞赋值;

    使用Verilog对组合逻辑进行编码的方法有很多种,但是当使用always块对组合逻辑进行编码时,应该使用阻塞分配。

    例19中的代码构建了三个顺序执行语句的y输出。
    由于非阻塞分配在更新LHS变量之前评估RHS表达式,因此tmp1和tmp2的值是在进入此始终块时这两个变量的原始值,而不是在模拟时间步骤结束时将更新的值。
    y输出将反映tmp1和tmp2的旧值,而不是始终块的当前传递中计算的值。

    module ao4 (y, a, b, c, d);
    output y;
    input a, b, c, d;
    reg y, tmp1, tmp2;
    always @(a or b or c or d) begin
    tmp1 <= a & b;
    tmp2 <= c & d;
    y <= tmp1 | tmp2;
    end
    endmodule
    

    Example 19 - Bad combinational logic coding style using nonblocking assignments
    将temp1和temp2放入敏感信号列表,当非阻塞赋值更新更新事件队列中的LHS变量时,always块将自触发并用新计算的tmp1和tmp2值更新y输出。 在通过always块两次后,y输出值现在将是正确的。 通过始终块的多次传递等同于降低的模拟性能,并且如果存在合理的替代方案则应该避免。

    module ao5 (y, a, b, c, d);
    output y;
    input a, b, c, d;
    reg y, tmp1, tmp2;
    always @(a or b or c or d or tmp1 or tmp2) begin
    tmp1 <= a & b;
    tmp2 <= c & d;
    y <= tmp1 | tmp2;
    end
    endmodule
    

    Example 20 - Inefficient multi-pass combinational logic coding style with nonblocking assignments
    一个更好的开发习惯,即不需要多次遍历always块的习惯,就是只使用写入模型组合逻辑的always块中的阻塞赋值。

    module ao2 (y, a, b, c, d);
    output y;
    input a, b, c, d;
    reg y, tmp1, tmp2;
    always @(a or b or c or d) begin
    tmp1 = a & b;
    tmp2 = c & d;
    y = tmp1 | tmp2;
    end
    endmodule
    

    Example 21 - Efficient combinational logic coding style using blocking assignments
    示例21中的代码与示例19中的代码相同,只是非阻塞分配已被阻塞分配替换,这将保证只有一次通过always块后,y将输出正确的值;

    准则4)在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值

    使用非阻塞分配有时可以方便地将简单组合逻辑与时序逻辑电路组合。 将组合和时序代码组合到单个always块中时,将always块编码为具有非阻塞赋值的顺序始终块,如例22所示。

    module nbex2 (q, a, b, clk, rst_n);
    output q;
    input clk, rst_n;
    input a, b;
    reg q;
    always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;
    else q <= a ^ b;
    endmodule
    

    Example 22 - Combinational and sequential logic in a single always block

    在例22中实现的相同逻辑也可以实现为两个单独的始终块,一个用阻塞赋值编码的纯组合逻辑,一个具有用非阻塞赋值编码的纯时序逻辑,如例23所示。

    module nbex1 (q, a, b, clk, rst_n);
    output q;
    input clk, rst_n;
    input a, b;
    reg q, y;
    always @(a or b)
    y = a ^ b;
    always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;
    else q <= y;
    endmodule
    

    Example 23 - Combinational and sequential logic separated into two always blocks

    准则5)在同一个alway块中,不要即用非阻塞又用阻塞赋值;

    Verilog允许阻塞和非阻塞赋值在always块内自由混合。 通常,即使Verilog允许,在同一个总块中混合阻塞和非阻塞赋值也是一种糟糕的编码风格。
    例24中的代码将正确模拟和综合,因为阻塞赋值不是与非阻塞赋值相同的变量。 虽然这可行,但clifford不鼓励这种编码风格。

    module ba_nba2 (q, a, b, clk, rst_n);
    output q;
    input a, b, rst_n;
    input clk;
    reg q;
    always @(posedge clk or negedge rst_n) begin: ff
    reg tmp;
    if (!rst_n) q <= 1'b0;
    else begin
    tmp = a & b;
    q <= tmp;
    end
    end
    endmodule
    

    Example 24 - Blocking and nonblocking assignment in the same always block - generally a bad idea!
    示例25中的代码很可能在大多数情况下正确模拟,但Synopsys工具将报告语法错误,因为阻塞赋值被赋值给与非阻塞赋值之一相同的变量。 必须修改此代码才能合成。

    module ba_nba6 (q, a, b, clk, rst_n);
    output q;
    input a, b, rst_n;
    input clk;
    reg q, tmp;
    always @(posedge clk or negedge rst_n)
    if (!rst_n) q = 1'b0; // blocking assignment to "q"
    else begin
    tmp = a & b;
    q <= tmp; // nonblocking assignment to "q"
    end
    endmodule
    

    Example 25 - Synthesis syntax error - blocking and nonblocking assignment to the same variable

    准则6)不要在一个以上的always块中为同一个变量赋值;

    即使使用非阻塞赋值,从多个always快对同一变量进行多次赋值也是Verilog竞争条件。
    在示例26中,两个始终块正在对q输出进行分配,两者都使用非阻塞分配。 由于这些始终块可以按任何顺序进行调度,因此模拟输出是竞争条件。

    module badcode1 (q, d1, d2, clk, rst_n);
    output q;
    input d1, d2, clk, rst_n;
    reg q;
    always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;
    else q <= d1;
    always @(posedge clk or negedge rst_n)
    if (!rst_n) q <= 1'b0;
    else q <= d2;
    endmodule
    

    Example 26 - Race condition coding style using nonblocking assignments
    综合工具运行这段代码的时候会报错:
    Warning: In design ‘badcode1’, there is 1 multiple-driver net with unknown wired-logic type.
    当忽略警告并编译示例26中的代码时,推断出两个触发器,其输出馈送2输入和门。 在该示例中,预合成模拟甚至不与后合成模拟紧密匹配。

    准则7)用$strobe系统任务来显示用非阻塞赋值的变量值;

    Myth:“使用带有非阻塞赋值的$ display命令不起作用”
    Truth:在所有$ display命令之后更新非阻塞赋值

    module display_cmds;
    reg a;
    initial $monitor("\$monitor: a = %b", a);
    initial begin
    $strobe ("\$strobe : a = %b", a);
    a = 0;
    a <= 1;
    $display ("\$display: a = %b", a);
    #1 $finish;
    end
    endmodule
    

    上面模拟显示,在执行非阻塞赋值更新事件之前,$ display命令在活动事件队列中执行。
    $display: a = 0
    $monitor: a = 1
    $strobe : a = 1

    准则8)在赋值时不要使用#0延迟

    Myth: “#0强制分配到时间步的末尾”
    Truth: #0强制分配给“非活动事件队列

    module nb_schedule1;
    reg a, b;
    initial begin
    a = 0;
    b = 1;
    a <= b;
    b <= a;
    $monitor ("%0dns: \$monitor: a=%b b=%b", $stime, a, b);
    $display ("%0dns: \$display: a=%b b=%b", $stime, a, b);
    $strobe ("%0dns: \$strobe : a=%b b=%b\n", $stime, a, b);
    #0 $display ("%0dns: #0 : a=%b b=%b", $stime, a, b);
    #1 $monitor ("%0dns: \$monitor: a=%b b=%b", $stime, a, b);
    $display ("%0dns: \$display: a=%b b=%b", $stime, a, b);
    $strobe ("%0dns: \$strobe : a=%b b=%b\n", $stime, a, b);
    $display ("%0dns: #0 : a=%b b=%b", $stime, a, b);
    #1 $finish;
    end
    endmodule
    

    模拟显示,在执行非阻塞赋值更新事件之前,在非活动事件队列中执行了#0-delay命令。

    0ns: $display: a=0 b=1
    0ns: #0 : a=0 b=1
    0ns: $monitor: a=1 b=0
    0ns: $strobe : a=1 b=0
    1ns: $display: a=1  b=0
    1ns: #0 : a=1 b=0
    1ns: $monitor: a=1 b=0
    1ns: $strobe : a=1 b=0
    
    展开全文
  • 阻塞赋值和非阻塞赋值

    千次阅读 2019-05-11 19:17:06
    一、阻塞赋值 阻塞赋值的操作符为=; 阻塞赋值的执行可以认为是只有一个步骤的操作:所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后在开始赋值的。 ...

    一、阻塞赋值

    阻塞赋值的操作符为=;
    阻塞赋值的执行可以认为是只有一个步骤的操作:所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后在开始赋值的。
    阻塞赋值在语句结束后立即完成赋值操作;
    阻塞赋值常用于组合逻辑电路的设计

    二、非阻塞赋值

    非阻塞赋值的操作符为<=;
    非阻塞赋值的操作可以看作为两个步骤的过程:
    1)在赋值时刻开始时,计算非阻塞赋值RHS表达式。
    2)在赋值时刻结束时,更新非阻塞赋值LHS表达式。
    非阻塞赋值常用于时序逻辑电路的设计

    三、总结:

    阻塞赋值是顺序执行的,而非阻塞赋值是并行执行的 ;

    展开全文
  • 文章主要介绍Verilog中阻塞赋值和非阻塞赋值的正确使用方法。
  • FPGA中阻塞赋值与非阻塞赋值原理实验
  • 1 阻塞赋值:语句顺序执行,不能同时进行,称之为阻塞,用于组合逻辑 阻塞赋值使用的赋值运算符为“=”。阻塞赋值的过程是立刻执行的,即阻塞赋值运算符右侧表达式求值完后立刻会更新至运算符左侧,并且这个执行的...

    1 阻塞赋值:= 语句顺序执行,不能同时进行,称之为阻塞,用于组合逻辑

    阻塞赋值使用的赋值运算符为“=”。阻塞赋值的过程是立刻执行的,即阻塞赋值运算符右侧表达式求值完后立刻会更新至运算符左侧,并且这个执行的过程不受其他语句执行的影响,其后的语句只有当前的赋值操作执行完成后才能顺序执行。
    2.非阻塞赋值:<= 语句按节拍同时并发执行,用于时序逻辑

    展开全文
  • 阻塞赋值的执行可以认为是只有一个步骤的操作,即计算RHS并更新LHS,且不允许其他语句的干扰。
  • 最近学到了关于verilog的阻塞赋值与非阻塞赋值的一些区别,经过网上查阅与仿真实验,有了一些理解。希望能够记下来。
  • Verilgo 阻塞赋值与非阻塞赋值 时间:2018.8.21 地点:信电院办 内容:verilgo 中阻塞赋值和非阻塞赋值的区别以及应用 阻塞赋值与非阻塞赋值: 1.阻塞赋值“=”(组合逻辑电路),非阻塞赋值“&lt;=”...
  • 阻塞赋值与非阻塞赋值的不同 阻塞赋值: = 非阻塞赋值:<= 可以理解为:阻塞赋值有顺序,非阻塞赋值没有顺序,下面我们用实例来讲解: 阻塞赋值源码(截取) 解读:clk上升沿或者rst_n下降沿到来...
  • (1)阻塞赋值基本概念 (2)非阻塞赋值基本概念 2、可综合风格的Verilog模块编程的8个原则,可解决综合后仿真的大部分竞争冒险现象。 (1)时序电路建模时,用非阻塞赋值; (2)锁存器电路建模时,用非阻塞赋值;...
  • 据说阻塞赋值和非阻塞赋值是Verilog语言中最难理解的知识点之一,我也觉得,从网上翻阅了资料,也看过一些视频。 以下从两个典型的例子以及多个角度去分析得到与验证阻塞赋值与非阻塞赋值的区别,以及各自的特点。 ...
  • begin end之间的赋值语句有阻塞赋值和非阻塞赋值之分。 阻塞赋值:语句顺序执行,前面的执行完才可以执行后面的。赋值符号:= 如: 其中赋值语句1会阻塞赋值语句2,即只有当赋值语句1执行完才能执行赋值语句2。 ...
  • 例解阻塞赋值&非阻塞赋值 先简单介绍一下阻塞赋值与非阻塞赋值: 1.非阻塞(Non_Blocking)赋值方式( 如 b <= a; ) 块结束后才完成赋值操作。 b的值并不是立刻就改变的。 这是一种比较常用的赋值方法。(特别...
  • 8. 请简要描述阻塞赋值和非阻塞赋值的区别? 答:赋值主要由2部分组成,一是右值的计算,二是左值的更新。首先阻塞赋值在完成右值计算之后,立刻完成左值更新,之后才执行下一条语句;而非阻塞赋值会在完成语句块内...
  • 1.阻塞赋值 ●如果多个阻塞赋值语句顺序出现在begin-end语句中,则前面的语句在执行时将完全阻塞后面的语句,直到前面语句的赋值完成以后,才会执行下一表达式。 ●赋值操作符是“=”的过程赋值是阻塞性过程赋值。 ...
  • 1. 阻塞赋值 使用一般使用的=进行赋值 always@(clk) begin b = a; c = b; end 在前面的a赋值给b的语句没有完成之前,后面的赋值语句不进行操作,就像被阻塞了一样,称为阻塞赋值 以上代码会产生的电路结构: 2...
  • 阻塞赋值和非阻塞赋值《Verilog数字系统设计教程》第3版 夏宇闻4.9 赋值语句和块语句4.9.1 赋值语句第14章 深入理解阻塞和非阻塞赋值的不同14.2 Verilog模块编程要点14.5 移位寄存器模型《Verilog HDL高级数字设计...
  • 小黑同学 明德扬FPGA科教关于阻塞赋值和非阻塞赋值的问题,明德扬的学员提得比较多,今天小黑老师专门给大家普及一下阻塞赋值和非阻塞赋值的相关知识。一、概述1、阻塞赋值对应的电路往往与触发沿没有关系,只与电平...
  • 1.1 FPGA阻塞赋值与非阻塞赋值用法 1.1.1 本节目录 1)本节目录; 2)本节引言; 3)FPGA简介; 4)FPGA阻塞赋值与非阻塞赋值用法; 5)结束语。 1.1.2 本节引言 “不积跬步,无以至千里;不积小流,无以成...
  • 罗成:Verilog语法之六:阻塞赋值与非阻塞赋值​zhuanlan.zhihu.com通过上面的文章先了解下,阻塞赋值和非阻塞赋值的区别。b<=a; c<=b; 非阻塞赋值b=a; c=b; 阻塞赋值阻塞赋值中阻塞的意思是要等一会儿,阻塞...
  • 过程赋值语句,又分为阻塞赋值和非阻塞赋值语句。 1. 阻塞赋值   阻塞赋值的语法如下: 寄存器变量 = 表达式 ; 右边表达式的逻辑计算和对左边寄存器变量的赋值是一个统一操作中的两个小操作,这两个小操作之间...
  • 关于阻塞赋值和非阻塞赋值的问题,明德扬的学员提得比较多,今天小黑老师专门给大家普及一下阻塞赋值和非阻塞赋值的相关知识。 一、概述 1、阻塞赋值对应的电路往往与触发沿没有关系,只与电平的变化有关系。 阻塞...
  • 实验目的:掌握阻塞赋值与非阻塞赋值的区别 1.实验原理: 在Verilog HDL语言中,信号有两种赋值方式:非阻塞赋值阻塞赋值; 其中有两个要点: 1.在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路...
  • Verilog阻塞赋值与非阻塞赋值

    万次阅读 多人点赞 2014-05-06 09:05:14
    1.阻塞赋值与非阻塞赋值; 2.代码测试; 3.组合逻辑电路和时序逻辑电路。   阻塞赋值与非阻塞赋值: 1.阻塞赋值“=”(组合逻辑电路),非阻塞赋值“”(时序逻辑电路); 2.Verilog模块编程的8个原则: (1)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 958
精华内容 383
关键字:

阻塞赋值