Quartusで遊ぼう (7) [プログラム三昧]
トランジスタ技術誌に書かれていたインストラクション・デコーダは、3項演算子が連なっていました。 もっと、別の書き方はできないかな。
オリジナル版の合成結果
CQ出版のWEBページからダウンロード版を取り寄せて、 "mCmdDecode" モジュールだけ合成しました。 このモジュールは、純粋な組み合わせ回路なので、クロック周波数を与えても制約になりません。 そこで、 "Settings" ダイアログの "Timing Analysis Settings → Classic Timing Analyzer Settings" のページにある、 "tpd" (Time of Propagation Delay : 伝達遅延時間)に 0ナノ秒の時間を指定しました。 これで、「出来るだけがんばれ」と解釈してくれるはずです。
その結果、 LE の消費量は70個、最大伝達遅延時間は10.304ナノ秒になりました。 けっこう、でかいね。
casez文を使ってみた
3項演算子を連ねた場合、式を左から解釈していくので原則として順序が発生してしまいます。 つまり、そのままでは、プライオリティ・エンコーダが構成されてしまうかもしれません。
これに対して、case文は、重複の無い複数の値と同時に比較して、分岐を行います。 そのため、case文に書かれた選択肢には順序がありません。 しかし、case文は比較対象のビット幅が固定なので、ドント・ケア (Don't care) を指示する事はできません。
そこで登場するのが、casez文です。 casez文では、符号 Z (高インピーダンス状態)を使ってドント・ケアを指定することができます。 符号 Z は、 ? とも書き表すことができます。 これを利用して、インストラクション・デコーダを構成します。
reg[4:0] inst; always @(cmd) begin casez (cmd) 12'b0001_11??_????: inst = `ADDWF; 12'b0001_01??_????: inst = `ANDWF; 12'b0000_011?_????: inst = `CLRF; 12'b0000_0100_0000: inst = `CLRW; 12'b0010_01??_????: inst = `COMF; 12'b0000_11??_????: inst = `DECF; 12'b0010_11??_????: inst = `DECFSZ; 12'b0010_10??_????: inst = `INCF; 12'b0011_11??_????: inst = `INCFSZ; 12'b0001_00??_????: inst = `IORWF; 12'b0010_00??_????: inst = `MOVF; 12'b0000_001?_????: inst = `MOVWF; 12'b0011_01??_????: inst = `RLF; 12'b0011_00??_????: inst = `RRF; 12'b0000_10??_????: inst = `SUBWF; 12'b0011_10??_????: inst = `SWAPF; 12'b0001_10??_????: inst = `XORWF; 12'b0100_????_????: inst = `BCF; 12'b0101_????_????: inst = `BSF; 12'b0110_????_????: inst = `BTFSC; 12'b0111_????_????: inst = `BTFSS; 12'b1110_????_????: inst = `ANDLW; 12'b1001_????_????: inst = `CALL; 12'b101?_????_????: inst = `GOTO; 12'b1101_????_????: inst = `IORLW; 12'b1100_????_????: inst = `MOVLW; 12'b1000_????_????: inst = `RETLW; 12'b1111_????_????: inst = `XORLW; 12'b0000_0000_0010: inst = `OPTION; 12'b0000_0000_0100: inst = `CLRWDT; 12'b0000_0000_011?: inst = `TRIS; default: inst = `NOP; endcase end
この記述を使って、同じ条件で合成を行うと、 LE の消費量は58個、最大伝達遅延時間は9.201ナノ秒になりました。 ずいぶん、かわったね。
inst 出力の値を指定するために、 "inst" というレジスタを宣言しています。 このレジスタは、HDL記述で便宜的に宣言されたレジスタなので、最終的な合成後のネットリストには、現れません。 "Compilation Report → Analysis & Synthesis → Resource Usage Summary" にも58個の LE が全て組み合わせロジックに使われてと書かれています。
Total logic elements 58 -- Combinational with no register 58 -- Register only 0 -- Combinational with a register 0
ただし、always 構文のセンシティビティ・リスト (Sensitivity list) の項目が足りなかったり、レジスタが設定されない条件が書かれたりした場合には、思ったとおりの論理が生成されません。 その場合、エラーが発生すれば良いのですが、黙って妙な論理を作ってしまう可能性もあるので、注意が必要です。
参考文献
- Quartus II Help Version 8.1
-
always 構文で組み合わせ回路を構成する際の条件は、 Quartus II のオンライン・マニュアルの "Creating Designes → Using AHDL, VHDL & Verilog HDL → Using Verilog HDL in the Quartus II Software → Implementing Combinational Logic → Using Always Constructs" に記述があります。
トランジスタ技術 (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"が届きました。
コメント 0