Quartusで遊ぼう (2) [プログラム三昧]
「Quartus で遊ぼう」の二回目は、組み合わせ論理回路の合成を調べます。
組み合わせ論理回路とは、何ぞや
論理合成で回路を作成する場合、全ての回路は二つの種類に分けることが出来ます。 ひとつが組み合わせ論理 (combinational logic) で、もうひとつが非組み合わせ論理 (non-combinational logic) です。
非組み合わせ論理は、フリップ・フロップのようにクロックに従って動作する回路を示します。 原則としてクロックが来なければ出力が変化することがありません。
一方、組み合わせ論理は、入力の変化がすぐに出力に影響するものをいいます。 AND-OR-NOT を組み合わせてつくった回路は、組み合わせ論理になるはずです。
もちろん、 AND-OR-NOT を駆使してフリップ・フロップをつくることも出来ます。 出来ますが、安全な回路を論理合成させる場合にはやってはいけない事になっています。
ROM は、組み合わせ論理回路である
ROM (Read Only Memory) とは、アドレス入力に従って、一意にデータ出力を行う回路です。 そのため、紛れもなく、組み合わせ論理回路であるといえます。 逆に、どんな組み合わせ論理回路も ROM で表現することができます。 ここでは、 ROM を合成させて、出来上がりの状態を調べてみます。
1bit × 16word の場合
最初は、 1bit × 16word 構成の ROM を合成してみます。
module rom1x16(data, addr); output data; input[3:0] addr; // Pseudo register reg data; // ROM codes always @(addr) begin case (addr[3:0]) 4'b0000: data = 1'b0; 4'b0001: data = 1'b1; 4'b0010: data = 1'b1; 4'b0011: data = 1'b0; 4'b0100: data = 1'b1; 4'b0101: data = 1'b0; 4'b0110: data = 1'b0; 4'b0111: data = 1'b1; 4'b1000: data = 1'b1; 4'b1001: data = 1'b0; 4'b1010: data = 1'b0; 4'b1011: data = 1'b1; 4'b1100: data = 1'b0; 4'b1101: data = 1'b1; 4'b1110: data = 1'b1; 4'b1111: data = 1'b0; endcase end endmodule
論理圧縮が出来ないようにパターンを作成してみました。 この論理を合成させると、以下のようなサマリが表示されました。
Flow Status Successful - Tue Nov 18 18:57:28 2008 Quartus II Version 8.1 Build 163 10/28/2008 SJ Web Edition Revision Name rom1x16 Top-level Entity Name rom1x16 Family MAX II Device EPM2210F324C3 Timing Models Final Met timing requirements Yes Total logic elements 1 / 2,210 ( < 1 % ) Total pins 5 / 272 ( 2 % ) Total virtual pins 0 UFM blocks 0 / 1 ( 0 % )
Logic Element は、2210個のうちの1個しか使われていません。 MAX II のデータシートによると、 Logic Element (LE) には、4入力1出力の LUT (Look-Up Table) が内蔵されているため、このぐらいの容量であれば、一個の LE で構成できます。
8bit × 16word の場合
次は、出力ビット幅を変えてみます。 8ビットの出力を出させてみました。
module rom8x16(data, addr); output[7:0] data; input[3:0] addr; // Pseudo register reg[7:0] data; // ROM codes always @(addr) begin case (addr[3:0]) 4'b0000: data = 8'h01; 4'b0001: data = 8'h02; 4'b0010: data = 8'h04; 4'b0011: data = 8'h08; 4'b0100: data = 8'h10; 4'b0101: data = 8'h20; 4'b0110: data = 8'h40; 4'b0111: data = 8'h80; 4'b1000: data = 8'h40; 4'b1001: data = 8'h20; 4'b1010: data = 8'h10; 4'b1011: data = 8'h08; 4'b1100: data = 8'h04; 4'b1101: data = 8'h02; 4'b1110: data = 8'h01; 4'b1111: data = 8'h00; endcase end endmodule
これを合成させると、このようになりました。
Total logic elements 8 / 2,210 ( < 1 % ) Total pins 12 / 272 ( 4 % ) Total virtual pins 0 UFM blocks 0 / 1 ( 0 % )
単純に Logic Element の数がビット幅分になっただけのようです。 以降の実験では、1ビット出力のものだけ検証していきます。
1bit × 32word の場合
次は、アドレス入力を一本増やして、 1bit × 32word 構成の ROM を合成してみます。
module rom1x32(data, addr); output data; input[4:0] addr; // Pseudo register reg data; // ROM codes always @(addr) begin case (addr[4:0]) 5'b00000: data = 1'b0; 5'b00001: data = 1'b1; 5'b00010: data = 1'b1; 5'b00011: data = 1'b0; 5'b00100: data = 1'b1; 5'b00101: data = 1'b0; 5'b00110: data = 1'b0; 5'b00111: data = 1'b1; 5'b01000: data = 1'b1; 5'b01001: data = 1'b0; 5'b01010: data = 1'b0; 5'b01011: data = 1'b1; 5'b01100: data = 1'b0; 5'b01101: data = 1'b1; 5'b01110: data = 1'b1; 5'b01111: data = 1'b0; 5'b10000: data = 1'b1; 5'b10001: data = 1'b0; 5'b10010: data = 1'b0; 5'b10011: data = 1'b1; 5'b10100: data = 1'b0; 5'b10101: data = 1'b1; 5'b10110: data = 1'b1; 5'b10111: data = 1'b0; 5'b11000: data = 1'b0; 5'b11001: data = 1'b1; 5'b11010: data = 1'b1; 5'b11011: data = 1'b1; 5'b11100: data = 1'b1; 5'b11101: data = 1'b0; 5'b11110: data = 1'b0; 5'b11111: data = 1'b1; endcase end endmoduleサマリは、このようになりました。
Total logic elements 3 / 2,210 ( < 1 % ) Total pins 6 / 272 ( 2 % ) Total virtual pins 0 UFM blocks 0 / 1 ( 0 % )
Logic Element の数は、3個に増えました。 これは、例えば、 addr[4] が 0 の場合の出力を得るのに一個、 addr[4] が 1 の場合の出力を得るのに一個、これらの出力を束ねるために一個、使われたものと推測されます。
1bit × 128word の場合
最後は、アドレス入力を二本増やして、 1bit × 128word 構成の ROM を合成してみます。
module rom1x128(data, addr); output data; input[6:0] addr; // Pseudo register reg data; // ROM codes always @(addr) begin case (addr[6:0]) 7'h00:data=1'b0; 7'h01:data=1'b1; 7'h02:data=1'b1; 7'h03:data=1'b0; 7'h04:data=1'b1; 7'h05:data=1'b0; 7'h06:data=1'b0; 7'h07:data=1'b1; 7'h08:data=1'b1; 7'h09:data=1'b0; 7'h0A:data=1'b0; 7'h0B:data=1'b1; 7'h0C:data=1'b0; 7'h0D:data=1'b1; 7'h0E:data=1'b1; 7'h0F:data=1'b0; 7'h10:data=1'b0; 7'h11:data=1'b0; 7'h12:data=1'b0; 7'h13:data=1'b1; 7'h14:data=1'b0; 7'h15:data=1'b1; 7'h16:data=1'b1; 7'h17:data=1'b0; 7'h18:data=1'b0; 7'h19:data=1'b1; 7'h1A:data=1'b0; 7'h1B:data=1'b0; 7'h1C:data=1'b1; 7'h1D:data=1'b1; 7'h1E:data=1'b0; 7'h1F:data=1'b1; 7'h20:data=1'b1; 7'h21:data=1'b0; 7'h22:data=1'b0; 7'h23:data=1'b1; 7'h24:data=1'b1; 7'h25:data=1'b1; 7'h26:data=1'b1; 7'h27:data=1'b0; 7'h28:data=1'b0; 7'h29:data=1'b0; 7'h2A:data=1'b1; 7'h2B:data=1'b0; 7'h2C:data=1'b1; 7'h2D:data=1'b0; 7'h2E:data=1'b1; 7'h2F:data=1'b1; 7'h30:data=1'b1; 7'h31:data=1'b1; 7'h32:data=1'b1; 7'h33:data=1'b0; 7'h34:data=1'b1; 7'h35:data=1'b1; 7'h36:data=1'b0; 7'h37:data=1'b1; 7'h38:data=1'b1; 7'h39:data=1'b0; 7'h3A:data=1'b1; 7'h3B:data=1'b1; 7'h3C:data=1'b0; 7'h3D:data=1'b1; 7'h3E:data=1'b1; 7'h3F:data=1'b1; 7'h40:data=1'b1; 7'h41:data=1'b0; 7'h42:data=1'b1; 7'h43:data=1'b1; 7'h44:data=1'b0; 7'h45:data=1'b0; 7'h46:data=1'b1; 7'h47:data=1'b0; 7'h48:data=1'b1; 7'h49:data=1'b1; 7'h4A:data=1'b1; 7'h4B:data=1'b0; 7'h4C:data=1'b1; 7'h4D:data=1'b0; 7'h4E:data=1'b0; 7'h4F:data=1'b1; 7'h50:data=1'b0; 7'h51:data=1'b1; 7'h52:data=1'b1; 7'h53:data=1'b1; 7'h54:data=1'b0; 7'h55:data=1'b0; 7'h56:data=1'b0; 7'h57:data=1'b1; 7'h58:data=1'b1; 7'h59:data=1'b1; 7'h5A:data=1'b0; 7'h5B:data=1'b1; 7'h5C:data=1'b0; 7'h5D:data=1'b1; 7'h5E:data=1'b0; 7'h5F:data=1'b0; 7'h60:data=1'b0; 7'h61:data=1'b1; 7'h62:data=1'b0; 7'h63:data=1'b0; 7'h64:data=1'b1; 7'h65:data=1'b0; 7'h66:data=1'b0; 7'h67:data=1'b0; 7'h68:data=1'b0; 7'h69:data=1'b0; 7'h6A:data=1'b0; 7'h6B:data=1'b1; 7'h6C:data=1'b0; 7'h6D:data=1'b0; 7'h6E:data=1'b1; 7'h6F:data=1'b0; 7'h70:data=1'b1; 7'h71:data=1'b1; 7'h72:data=1'b0; 7'h73:data=1'b1; 7'h74:data=1'b0; 7'h75:data=1'b1; 7'h76:data=1'b0; 7'h77:data=1'b0; 7'h78:data=1'b0; 7'h79:data=1'b1; 7'h7A:data=1'b1; 7'h7B:data=1'b0; 7'h7C:data=1'b0; 7'h7D:data=1'b0; 7'h7E:data=1'b0; 7'h7F:data=1'b1; endcase end endmodule
サマリは以下のようになりました。
Total logic elements 13 / 2,210 ( < 1 % ) Total pins 8 / 272 ( 3 % ) Total virtual pins 0 UFM blocks 0 / 1 ( 0 % )
論理圧縮をさせないように、パターンを工夫した結果、 LE の数を13個まで増やすことが出来ましたが、これが上限であるかどうかは、定かではありません。 128ビットのROMを構成するのに最低限必要な8個の LE の出力を、5個の LE で束ねたものと推測されます。 実際に、どういう方法で束ねたのかは、わかっていません。
考察
以上の実験から、ROMを構成した場合に必要となる Logic Element の数は、ROMの総ビット数 ÷ 8 程度であると考えられます。 実際には、論理圧縮などされて、さらに少ない数の LE が使用されると思われます。
参考文献
トランジスタ技術 (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"が届きました。
「マスクROMと言うかデコーダーを構成すると、使用するLEの数は出力の本数に大きく依存する」と言う事なのではないかなぁ。
つまり8bit出力なら最低でも8個のLEを使用すると。
by hamayan (2008-11-19 08:17)
たとえば、4-to-16デコーダを作らせたら、確実にLEを16個も消費してしまいます。LEの数は出力の数に比例します。
一方、入力の数と消費するLEの数には明らかな関係があるわけではなく、論理圧縮できる論理であれば、LEの数を減らすことができます。7ビット入力のパリティ計算機は、LE2個になりました。これが、 128word ROM の下限です。
効率が悪そうなのは、5入力のデコーダです。入力が少ない割に、どんなに頑張っても、多段の構成になってしまいます。LEを効率よく使うには、入力の数を少なくするシステム設計が必要になりそうです。
by noritan (2008-11-19 09:43)