SSブログ

Quartusで遊ぼう (8) [プログラム三昧]このエントリーを含むはてなブックマーク#

WS000219-320.png

Verilog の代入には、 <= と = の二種類が使われています。 これって、何が違うんでしょうかね。

どっちが早い?

以下は、トランジスタ技術誌にあった mStack モジュールを一部書き直したものです。

  always@(posedge clk or posedge reset) begin
    if(reset) begin
        stack1 <= 9'h0;
        stack2 <= 9'h0;
    end else if(Q) begin
      if (push) begin
        stack1 <= datain;
        stack2 <= stack1;
      end else if(pull) begin
        stack1 <= stack2;
        stack2 <= 9'h0;
      end
    end
  end

"push" がアサートされると、 datain の値が stack1 に代入され、さらに stack1 の値が stack2 に代入されています。 通常の C などの言語では、 stack1 にも stack2 にも datain の値が代入されますが、この例では、そうはなりません。

このノンブロッキング代入と呼ばれる代入文は、代入のきっかけとなる事象(この場合には "clk" の立ち上がり)以前の値を使って右辺を計算し、すべての右辺値の計算が終わってから実際の代入を行います。 そのため、この HDL で "push" がアサートされたときには、 datain の値が stack1 に代入され、それまで stack1 に入っていた値が stack2 に入るというシフト・レジスタ状の動作をします。

WS000191.png

RTLレベルでシミュレーションを行うと、こうなりました。 "push" がアサートされているタイミングで、 stack1 と stack2 の値がそれぞれ変化する様子がわかります。

ブロッキング代入を使ったら

それでは、ノンブロッキング代入の代わりにブロッキング代入を使ったら、どうなるでしょうか。

    :
        stack1 = 9'h0;
        stack2 = 9'h0;
    end else if(Q) begin
      if (push) begin
        stack1 = datain;
        stack2 = stack1;
      end else if(pull) begin
        stack1 = stack2;
        stack2 = 9'h0;
    :
WS000192.png

RTL レベルでシミュレーションを行うと、こうなりました。 "push" がアサートされた時の動作を見ると、 datain の値が stack1 と stack2 に突き抜けているのがわかります。 実際の回路では、レーシングと呼ばれる現象です。

論理合成ではエラーが出ない

設計者にとっては、レーシングを起こす回路は誤りと認識されるのですが、機械にはわかりません。 そのため、論理合成時にはエラーが出ず、 stack1 と stack2 に datain の値が代入される HDL 記述どおりの回路ができてしまいます。

こればかりは、しっかりとテスト・パターンを書いて検証して気をつけるしかなさそうです。

参考文献

トランジスタ技術 (Transistor Gijutsu) 2008年 12月号 [雑誌]

トランジスタ技術 (Transistor Gijutsu) 2008年 12月号 [雑誌]

  • 作者:
  • 出版社/メーカー: CQ出版
  • 発売日: 2008/11/10
  • メディア: 雑誌

付録 : 「Quartus で遊ぼう」索引

Quartus で遊ぼう (1)
Altera の EPM2210F324 が話題になっているので、私も使ってみました。 ただし、ハードウェアは購入していないので、ソフトウェアで遊んだだけです。
Quartus で遊ぼう (2)
「Quartus で遊ぼう」の二回目は、組み合わせ論理回路の合成を調べます。
Quartus で遊ぼう (3)
論理合成後の状態を表示してくれるツールを探しました。
Quartus で遊ぼう (4)
前回作成した4値のアップ・ダウンカウンタで論理合成後に使われているフリップ・フロップは、何個(何ビット)でしょうか?
Quartus で遊ぼう (5)
今回は、ワン・ホット・コードを使ったステート・マシンでグリッチが発生すかどうかを観測します。
Quartus で遊ぼう (6)
トランジスタ技術誌に「リセット信号生成回路」のHDL記述がありました。 この記述は、ちょっともったいないですよ。
Quartus で遊ぼう (7)
トランジスタ技術誌に書かれていたインストラクション・デコーダは、3項演算子が連なっていました。 もっと、別の書き方はできないかな。
Quartus で遊ぼう (8)
Verilog の代入には、 <= と = の二種類が使われています。 これって、何が違うんでしょうかね。
Quartus で遊ぼう (9)
2進数の足し算で、キャリーを取り出したい時、どうしましょうか。
Quartus で遊ぼう (10)
作らせてみました。 リップル・キャリーカウンタ。
Quartus で遊ぼう (11)
先ごろ、請求していた"DVD"が届きました。

nice!(0)  コメント(2)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 2

Sim

<=と=をまぜちゃうと、シミュレータによって動作が変わっちゃうんですよね。エラーやwarningも出ないこと多いし、見落としやすい罠ですね><

by Sim (2008-11-24 12:56) 

noritan

おおかた、「エッジセンスには <= 、レベルセンスには = 」で間違いないかとは思いますが、人間が目でチェックするにも限界があるので、ぜひ、ルール・チェッカ・プログラムが欲しいところです。

by noritan (2008-11-24 22:34) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。