書いた回路は何個のゲートになるか
合成とは、ハードウェア記述言語で書いた回路を、実際のゲートとフリップフロップの組に変える作業です。できたセルの数は、回路の大きさと消費電力の目安になります。
同じ働きでも、書き方によって数が変わります。数を数える道具が、yosys です。
このレッスンのゴール
メモ
合成の結果を読んで、セルの数とラッチの有無を言える。
重要な言葉
| ことば | いみ |
|---|---|
| 合成 | 記述を、ゲートとフリップフロップの組に変えること |
| ネットリスト | 合成でできた、部品とつながりの一覧 |
| セル | ネットリストの部品。ゲートやフリップフロップ |
| フリップフロップ | クロックの立ち上がりで、1ビットを覚えるセル |
| ラッチ | クロックなしで値を覚え続けてしまう、意図しないセル |
| yosys | 合成をして、セルを数える道具 |
学生が入力するセルは、このプレビューでは空白です。
hdl gates がセルの数を出す
ラボの hdl gates は、yosys で回路を合成して、できたセルを数えます。引数は、ファイル名と、一番上のモジュールの名前です。
最初に、配られた半加算器と4ビットのカウンターを数えます。カウンターのセルの内訳を見て、フリップフロップの数と、桁数を比べましょう。
ラボのフォルダに入る
cd ~/hdlここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
半加算器を数える
hdl gates half_adder.v half_adderここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
カウンターを数える
hdl gates counter.v counterここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
セルの名前の読み方
| セルの名前 | 意味 |
|---|---|
| $_AND_ | AND ゲート |
| $_XOR_ | XOR ゲート |
| $_NOT_ | 反転のゲート |
| $_SDFF_PP0_ | 同期リセット付きのフリップフロップ |
| $_DFF_P_ | ふつうのフリップフロップ |
| $_DLATCH_P_ | ラッチ |
学生が入力するセルは、このプレビューでは空白です。
同じ働きでもセルの数は変わる
(a & b) | (a & ~b) は、a が1なら1、0なら0を出します。つまり、ただの a と同じです。
合成の道具が、自動でそこまで簡単にしてくれるとは限りません。2つの書き方を並べて、数えてみましょう。
長い書き方を書く
printf "module long_way(input a, input b, output y);\n assign y = (a & b) | (a & ~b);\nendmodule\n" > /tmp/long_way.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
長い書き方を数える
hdl gates /tmp/long_way.v long_wayここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
短い書き方を書く
printf "module short_way(input a, input b, output y);\n assign y = a;\nendmodule\n" > /tmp/short_way.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
短い書き方を数える
hdl gates /tmp/short_way.v short_wayここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ラッチは書き忘れから生まれる
下のファイルは、en が1のときだけ q を決めます。en が0のとき、q はどうなるでしょうか。何も書かれていないので、前の値を覚え続けるしかありません。
これがラッチです。クロックのない、意図しない記憶で、設計の誤りです。
ラッチができる記述
// en が0のとき、q の値が決まっていない。
module latchy(input en, input d, output reg q);
always @(*) if (en) q = d;
endmodule
ラッチの記述を書く
printf "module latchy(input en, input d, output reg q);\n always @(*) if (en) q = d;\nendmodule\n" > /tmp/latchy.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ラッチを数える
hdl gates /tmp/latchy.v latchyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
else を足した記述を書く
printf "module fixed(input en, input d, output reg q);\n always @(*) if (en) q = d; else q = 1'b0;\nendmodule\n" > /tmp/fixed.vここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
else を足すと数える
hdl gates /tmp/fixed.v fixedここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
出力を決めない場合があっても、シミュレーションは動くので、大丈夫だと思いがちです。しかし合成すると、意図しないラッチができます。if には、必ず else をつけて、どの場合でも出力を決めましょう。
さらに挑戦: 4ビットの加算器
課題が通ったら、4ビットの足し算を書いて数えましょう。module add3(input [3:0] a, input [3:0] b, output [4:0] s); に、assign s = a + b; を1行書くだけです。
セルがいくつできるか、予想してから hdl gates で数えます。1ビットの足し算を4つつなぐと、何個要るかも考えましょう。