アフィリエイト広告
アフィリエイト広告

VerilogHDL ブロッキング代入とノンブロッキング代入

次の例題は、ブロッキング代入とノンブロッキング代入の動作の違いを調べろ、というもの。

【問題8】 ブロッキング代入とノン・ブロッキング代入
「10進カウンタ」と「7セグメントLEDデコーダ」の接続を例に、大規模回路などの設計に用いられる“モジュール階層構造”について解説。

「=」がブロッキング代入で、「<=」がノンブロッキング代入。小なりイコール、ではない (;´Д`)

ブロッキング代入とノンブロッキング代入

ブロッキング代入「=」は、上から順番に実行される。ノンブロッキング代入「<=」は、同時に実行される。
組み合わせ回路では、信号は各ゲートを順にとおってくる。順序回路では、クロックがはいると一斉に信号が走る。だからあれよ、シフトレジスタで、クロックがはいると各段のデータが一斉にシフトする、って。ノンブロッキングって、そんな感じ。

回路記述

ブロッキング代入の回路と、ノンブロッキング代入の回路を用意しました。

ブロッキング代入
  1. module DFF(
  2.   input wire CLK, D,
  3.   output reg X, Y, Z
  4. );
  5.   always @(posedge CLK) begin
  6.     X = D;
  7.     Y = X;
  8.     Z = Y;
  9.   end
  10. endmodule
ノンブロッキング代入
  1. module DFF(
  2.   input wire CLK, D,
  3.   output reg X, Y, Z
  4. );
  5.   always @(posedge CLK) begin
  6.     X <= D;
  7.     Y <= X;
  8.     Z <= Y;
  9.   end
  10. endmodule

違いは、7~9 行目。
たとえば、D=1、X=0、Y=0、Z=0 としたとき、ブロッキング代入では、

X = D = 1 → Y = X = 1 → Z = Y = 1

と、すべて 1 になる。
対して、ノンブロッキング代入では並列に処理するので、

X <= D = 1
Y <= X = 0
Z <= Y = 0

となり、Y、Z の値は変化しない。

テストベンチ

  1. module DFF_TEST;
  2.   reg CLK, D;
  3.   wire X, Y, Z;
  4.   parameter CYCLE = 10;
  5.   integer i;
  6.   DFF DFF(CLK, D, X, Y, Z);
  7.   always begin
  8.     CLK = 0; #(CYCLE/2);
  9.     CLK = 1; #(CYCLE/2);
  10.   end
  11.   initial begin
  12.     for(i=0; i<3; i=i+1) begin
  13.       D = 0; #(CYCLE*5);
  14.       D = 1; #(CYCLE*3);
  15.     end
  16.     D = 0; #(CYCLE*3);
  17.     $finish;
  18.   end
  19.   initial begin
  20.     $dumpfile("dff_test.vcd");
  21.     $dumpvars(0, DFF_TEST);
  22.   end
  23. endmodule

D を印加する部分を for() 文にしてみました。まぁ、これぐらいの処理はべたに書いたほうがよいと思います。ここは、お勉強。

シミュレーション結果

ブロッキング代入

図 1 ブロッキング代入のシミュレーション波形

ブロッキング代入では、入力 D にしたがって、全部の出力が変化します。

回路にすると、こんな感じかな。あ、これ論理合成とかじゃなくて、自分で考えただけだから、間違ってるかも。

ノンブロッキング代入

ノンブロッキング代入では、クロックにしたがって一斉に信号が動くので、出力がシフトレジスタのようになります。

シフトレジスタだから、こんな回路。

D=1、X=0 とすると、クロックが入って回路の遅延時間後に X=1 になる。クロックが入ったときはまだ X=0 なので、2段目の入力は 0。つぎのクロックのときには X=1 になっている。
シフトレジスタの動作のしくみですね。

どちらの代入を使う?

むずかしいことは言わない。

  1. 混ぜて使わない
  2. 組み合わせ回路 (assign) では「=」ブロッキング代入
  3. 順序回路 (always) では「<=」ノンブロッキング代入
  4. テストベンチでは「=」ブロッキング代入

それだけを守ってれば、よさそう。

タイトルとURLをコピーしました