演算回路を書く
📌 このページの概要と目標
概要: シフトや乗算、大小比較など演算回路の記述を学び、論理合成して回路規模を確認する。
目標:
- 以下の回路の記述ができる
- 組み合わせ回路によるシフト回路
- 乗算回路
- 大小比較回路/一致比較回路
- 組み合わせ回路で作るROM
- 生成される回路の規模と、演算子や演算ビット幅との関連を説明できる
修了判定: 8ビットのシフト回路、一致比較回路、乗算回路を論理合成して回路規模の大小関係を確認する
1. 組み合わせ回路によるシフト回路
シフト回路や乗算回路みたいに「計算する回路」は、1行で書けちゃうから簡単に見えるよね?🐾
でも、実は裏でとんでもなく巨大な回路ができているかもしれないから要注意だよ!
シフト回路は入力信号dinをsftで指定したビット数だけ左シフトしてdoutに出力する回路です。左シフトして空になった下位ビットには0が入ります。
graph LR
subgraph 8ビットシフト回路
SFT[shift]
end
DIN[din
8bit] -->|8| SFT SVAL[sft
3bit] -->|3| SFT SFT -->|8| DOUT[dout
8bit] style SFT fill:#e3f2fd,stroke:#1976d2,stroke-width:2px;
8bit] -->|8| SFT SVAL[sft
3bit] -->|3| SFT SFT -->|8| DOUT[dout
8bit] style SFT fill:#e3f2fd,stroke:#1976d2,stroke-width:2px;
シフト動作の例
| 信号 | 値(2進) | 値(16進) |
|---|---|---|
| din | 1 0 1 1 0 1 0 1 | 8'hb5 |
| sft | 3(3ビット左シフト) | |
| dout | 1 0 1 0 1 0 0 0(下位3ビットに0が挿入) | 8'ha8 |
シフト回路(8ビット入出力・3ビットシフト量)
module shift( din, sft, dout );
input [7:0] din;
input [2:0] sft;
output [7:0] dout;
assign dout = din << sft;
endmodule
⚠️ シフト回路の注意点
- シフト動作は1行のassign文で記述できる(左シフト演算子
<<を使用) - 入出力ビット数が多いと論理合成後の回路規模が大きくなる
- 演算回路全般に言えることだが、論理合成を実施して回路規模が適切かどうか確認する習慣をつけること
2. 乗算回路
2つの入力a、bを掛け合わせた結果をqに出力します。4ビット入力 × 4ビット入力の場合、出力は最大8ビット幅が必要です。
graph LR
subgraph 4ビット乗算回路
MUL[multi]
end
A[a
4bit] -->|4| MUL B[b
4bit] -->|4| MUL MUL -->|8| Q[q
8bit] style MUL fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
4bit] -->|4| MUL B[b
4bit] -->|4| MUL MUL -->|8| Q[q
8bit] style MUL fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
module multi( a, b, q );
input [3:0] a, b;
output [7:0] q;
assign q = a * b;
endmodule
⚠️ 乗算回路の注意点
- 乗算演算子(
*)で入力aとbを掛け合わせ、結果を出力qに代入 - 入出力ビット数が多い場合、論理合成後の回路規模が大きくなる
- ASICメーカーやFPGAメーカーがあらかじめ乗算回路ブロックを用意している場合がある
- 論理合成で生成された回路規模と比較して、より小さくなる方を使用するのがよい
3. 大小比較回路と一致比較回路
2つの入力を比較し、その結果を1ビットの値として出力します。どちらもassign文1行で記述できます。
graph TD
subgraph 大小比較回路
direction LR
GT[comp_GT
>] A1[a
8bit] -->|8| GT B1[b
8bit] -->|8| GT GT -->|1| GT_OUT[a_gt_b
1bit] end subgraph 一致比較回路 direction LR EQ[comp_EQ
==] A2[a
8bit] -->|8| EQ B2[b
8bit] -->|8| EQ EQ -->|1| EQ_OUT[a_eq_b
1bit] end style GT fill:#fff3e0,stroke:#f57c00,stroke-width:2px; style EQ fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
>] A1[a
8bit] -->|8| GT B1[b
8bit] -->|8| GT GT -->|1| GT_OUT[a_gt_b
1bit] end subgraph 一致比較回路 direction LR EQ[comp_EQ
==] A2[a
8bit] -->|8| EQ B2[b
8bit] -->|8| EQ EQ -->|1| EQ_OUT[a_eq_b
1bit] end style GT fill:#fff3e0,stroke:#f57c00,stroke-width:2px; style EQ fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
大小比較回路(a > b)
module comp_GT( a, b, a_gt_b );
input [7:0] a, b;
output a_gt_b;
assign a_gt_b = (a > b) ? 1'b1 : 1'b0;
endmodule
一致比較回路(a == b)
module comp_EQ( a, b, a_eq_b );
input [7:0] a, b;
output a_eq_b;
assign a_eq_b = (a == b);
endmodule
| 回路 | 演算子 | 出力が1になる条件 | 出力信号名 |
|---|---|---|---|
| 大小比較(GT) | >(関係演算子) | a > b のとき | a_gt_b |
| 一致比較(EQ) | ==(等号演算子) | a == b のとき | a_eq_b |
💡 記述の構造は同じ
大小比較回路と一致比較回路は、assign文の内容以外は同じ構造で記述できます。条件演算子(
? :)を使う方法と、等号演算結果を直接代入する方法の2スタイルがあります。
4. 組み合わせ回路で作るROM
入力としてアドレスが与えられ、そのアドレスに対応するあらかじめ決められた値dataを出力する回路です。functionを使って記述しますが、always文でも記述可能です。
以下は4ビットアドレス入力、8ビットデータ出力のROM(アドレス0〜15に0の二乗値を格納)の例です。
graph LR
subgraph ROMモジュール
R[rom]
end
ADDR[addr
4bit] -->|4| R R -->|8| DATA[data
8bit] style R fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px;
4bit] -->|4| R R -->|8| DATA[data
8bit] style R fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px;
module rom( addr, data );
input [3:0] addr;
output [7:0] data;
function [7:0] romout;
input [3:0] addr;
begin
case( addr )
0: romout = 0;
1: romout = 1;
2: romout = 4;
3: romout = 9;
4: romout = 16;
5: romout = 25;
6: romout = 36;
7: romout = 49;
8: romout = 64;
9: romout = 81;
10: romout = 100;
11: romout = 121;
12: romout = 144;
13: romout = 169;
14: romout = 196;
15: romout = 225;
default: romout = 8'hxx;
endcase
end
endfunction
assign data = romout( addr );
endmodule
💡 ROMの回路規模について
- 入力アドレス信号をcaseの比較値とし、対応する値をfunctionの戻り値
romoutに代入 - assign文で出力
dataへ結果を代入 - ASICメーカーやFPGAメーカーがあらかじめROMブロックを用意している場合がある
- 乗算回路同様、論理合成の結果をみて回路規模が小さくなる方を使用する
5. 修了判定:論理合成結果の確認
実際に論理合成した「ゲート数(回路規模)」を見てみよう🐾
乗算回路(掛け算)がどれだけ巨大な回路になるか、その目で確かめてみてね!
⚠️ 修了判定
設問:8ビットのシフト回路・一致比較回路・乗算回路を論理合成ツールで合成し、ゲート数(回路規模)の大小関係を確認する。
| 回路 | 使用ファイル | 論理合成結果(ゲート数) |
|---|---|---|
| シフト回路 | shift.v | 54 |
| 一致比較回路 | comp_eq.v | 29 |
| 乗算回路 | multi.v | 615 |
各回路の論理合成レポート詳細
シフト回路(shift)
*************************************
レポート : area
回路 : shift
*************************************
ポート数: 19
ネット数: 49
セル数: 38
セル種類: 8
組み合わせ回路: 54
非組み合わせ回路: 0
合計: 54
一致比較回路(comp_eq)
*************************************
レポート : area
回路 : comp_eq
*************************************
ポート数: 17
ネット数: 27
セル数: 11
セル種類: 3
組み合わせ回路: 29
非組み合わせ回路: 0
合計: 29
乗算回路(multi)
*************************************
レポート : area
回路 : multi
*************************************
ポート数: 33
ネット数: 330
セル数: 306
セル種類: 17
組み合わせ回路: 615
非組み合わせ回路: 0
合計: 615
📝 C3 まとめ: 演算回路の記述と規模比較
| 回路 | 記述方法 | 回路規模の目安 | 注意点 |
|---|---|---|---|
| シフト回路 | assign + << | 中(54ゲート) | ビット数増加で規模増大 |
| 一致比較回路 | assign + == | 小(29ゲート) | 最も軽量 |
| 乗算回路 | assign + * | 大(615ゲート) | ASICやFPGAの専用ブロックと比較すること |
| ROM | function + case | 規模はデータ量次第 | 専用ROMブロックと比較すること |
