首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阻塞和非阻塞分配

阻塞和非阻塞分配
EN

Stack Overflow用户
提问于 2014-07-25 03:22:08
回答 1查看 588关注 0票数 0

我有以下代码与阻塞(代码1)和非阻塞(代码2)分配在始终块。

但在这两种情况下,输出是不同的。为什么?

我知道事件队列,但可能无法理解在事件队列中放置“clk@ (clk)”语句的位置。

代码语言:javascript
复制
// Code 1
module osc2 (clk, d);
    output clk;
    reg clk;
    input d;
    initial 
        begin
            #10 clk = 0;
            $monitor ("%d %b", $time, clk);
        end
    initial #100 $finish;       
    always @ (clk) #10 clk = ~clk;
endmodule

// Output of Code 1
10 0
20 1

// Code 2
module osc2 (clk, d);
    output clk;
    reg clk;
    input d;
    initial 
        begin
            #10 clk = 0;
            $monitor ("%d %b", $time, clk);
        end
    initial #100 $finish;       
    always @ (clk) #10 clk <= ~clk; 
endmodule

// Output of Code 2
10 0
20 1
30 0 (goes on upto 90)
90 0
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-25 23:19:37

为了便于解释,我解析了前两个循环的内容和展开的组件,以便进行分解。下面的代码将模拟。

always @ (clk) #10 clk = ~clk;

代码语言:javascript
复制
initial while (1) // to see the loop, functionally equivalent to 'always' 
  begin           // procedural block
    begin : loop0_unraveled
      @(clk);       // suspend continuation of loop until change in clk
      #10;          // suspend continuation of loop 10 time units
      clk = ~clk;   /* eval '~clk' now
                     * update clk now
                     */
    end
    begin : loop1_unraveled
      begin // this block is functionally equivalent to '@(clk)'
        reg smpl_clk;      // local variable
        smpl_clk = clk;    // sample 
        $display("%t::Pre-Suspend  : smpl_clk=%b clk=%b", $time, smpl_clk, clk);
        wait(clk != smpl_clk); // suspend continuation of loop until
             /*  1. no other blocking statements can execute, go to next region
              *  2. All other regions are empty
              *  3. Remaining events are block
              *  4. Nothing left to do, exit simulation
              */
        $display("%t::Post-Suspend : smpl_clk=%b clk=%b", $time, smpl_clk, clk);
      end
      #10;           // unreachable
      clk = ~clk;
    end
end

always @ (clk) #10 clk <= ~clk;

代码语言:javascript
复制
initial while (1) // to see the loop, functionally equivalent to 'always' 
  begin           // procedural block
    begin : loop0_unraveled       
      @(clk);       // suspend continuation of loop until change in clk
      #10;          // suspend continuation of loop 10 time units
      clk <= ~clk;  /* eval '~clk' now,
                     * update clk after all blocking statements are suspended
                     */
    end
    begin : loop1_unraveled
      begin         // this block is functionally equivalent to '@(clk)'
        reg smpl_clk;      // local variable
        smpl_clk = clk;    // sample 
        $display("%t::Pre-Suspend  : smpl_clk=%b clk=%b",$time, smpl_clk, clk);
        wait(clk != smpl_clk); // suspend continuation of loop until true
             /*  1. no other blocking statements can execute, go to next region
              *  2. In NBA region update clk
              *  3. Go back to active region
              *  4. Eval true, continue
              */
        $display("%t::Post-Suspend : smpl_clk=%b clk=%b", $time, smpl_clk, clk);
      end
      #10;           // reached
      clk <= ~clk;
    end
end                  // Go to top of the loop

正如我已经提到的here,自触发块在实践中并不常见。时钟发生器通常被植入类似于:

代码语言:javascript
复制
initial begin
  #10 clk = 0;
  forever #10 clk = ~clk;
end

代码语言:javascript
复制
always #10 clk = (clk===1'b0);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24947494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档