【Day09】Blocking & Non-Blocking 的差异

Blocking vs Non-Blocking

在写一般软件语言时,都与 Verilog 中的 blocking 语句相同,是一行一行由上至下执行的,但 verilog 又有一个 non-blocking,而 non-blocking 则是同步执行的,而撰写时也要把握以下原则,才不会产生误用的情形。

  • always 用 clock 触发的区块要使用 nonblocking。
  • always 没有用 clock 触发(组合逻辑)的区块要使用 blocking。
  • assign 语句一律使用 blocking。
  • 在同一个 always block 中不可同时出现 nonblocking 及 blocking。

来看下面这个例子

non-blocking:

module blockingVSnonblocking(
  clkSys, 
  rst_n
);
input clkSys;
input rst_n;
reg [1:0]a;
reg [1:0]b;
reg [1:0]c;
always@(posedge clkSys or negedge rst_n)begin
  if(!rst_n)begin
    a <= 2'd1;
    b <= 2'd2;
    c <= 2'd3;
  end
  else begin
    a <= c;
    b <= a;
    c <= b;
  end
end
endmodule

testbench:

`timescale 10ns/1ns
module tb();
reg clkSys;
reg rst_n;

blockingVSnonblocking UUT(
  .clkSys(clkSys), 
  .rst_n(rst_n)
);

initial begin
  clkSys = 0;
  rst_n = 0;
  repeat(3)@(posedge clkSys)rst_n = 0;
  rst_n = 1;
  #100 $stop;
end

always #5 clkSys = ~clkSys;

endmodule

上方的执行结果会是

reset 後,clk 正缘来临时,程序会同步的执行,所以 {a, b, c} 的值会同步到 {c, b, a} 。


blocking:

module blockingVSnonblocking(
  clkSys, 
  rst_n
);
input clkSys;
input rst_n;
reg [1:0]a;
reg [1:0]b;
reg [1:0]c;
always@(*)begin
  if(!rst_n)begin
    a = 2'd1;
    b = 2'd2;
    c = 2'd3;
  end
  else begin
    a = c;
    b = a;
    c = b;
  end
end
endmodule

而上方的执行结果则会是

可以看出 {a, b, c} 最後都变成了 2'd3,这就是使用了 non-blocking,使程序变得有顺序性,第一行 a=c,导致第二行 b=a 时也等同 b=c 了,最後一行也是如此。


<<:  Day9 - 2D渲染环境基础篇 V[Canvas动画概论] - 成为Canvas Ninja ~ 理解2D渲染的精髓

>>:  [Day - 09] - Spring 模式注解之服务原理与开发

【课程推荐】2022/4/24 单元测试理论与实作

课程目标 本课程教授您完整的单元测试理论并搭配Open Source软件来实作练习,让您知行合一。 ...

来了解hyperviser

Hyperviser源起 (虚拟机, Virtual Machine),好像是这几十年才听到的新名词...

[Day 27] RecyclerView 下 - itmetouchhelper

重要 method onSwiped(ViewHolder, int) 当产生侧滑效果了,会回调此方...

day 4 I'm your father, coroutine父子继承关系

上面讲到job会由系统分配,但为什麽我们又能把job当作参数传入coroutine呢? 继承 在前面...

分类模型哪个好?ROC/ AUC

从上篇的confusion matrix可以延生出不同的比例,从比例我们也可以在延伸出不同的曲线来比...