SSブログ

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

WS000219-320.png

「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月号 [雑誌]

トランジスタ技術 (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

hamayan

「マスクROMと言うかデコーダーを構成すると、使用するLEの数は出力の本数に大きく依存する」と言う事なのではないかなぁ。
つまり8bit出力なら最低でも8個のLEを使用すると。
by hamayan (2008-11-19 08:17) 

noritan

たとえば、4-to-16デコーダを作らせたら、確実にLEを16個も消費してしまいます。LEの数は出力の数に比例します。

一方、入力の数と消費するLEの数には明らかな関係があるわけではなく、論理圧縮できる論理であれば、LEの数を減らすことができます。7ビット入力のパリティ計算機は、LE2個になりました。これが、 128word ROM の下限です。

効率が悪そうなのは、5入力のデコーダです。入力が少ない割に、どんなに頑張っても、多段の構成になってしまいます。LEを効率よく使うには、入力の数を少なくするシステム設計が必要になりそうです。

by noritan (2008-11-19 09:43) 

コメントを書く

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

トラックバック 0

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

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