Verilog assign文で組み合わせ論理を設計する:実践例集
Verilogの assign 文は通常、wire データ型の信号を継続的に駆動するために使用され、組み合わせ論理として合成されます。ここでは assign 文を使ったさらなる設計例を紹介します。
例 #1:シンプルな組み合わせ論理
以下のコードは、出力ワイヤ z が assign 文で継続的に駆動され、デジタル方程式を実現するシンプルなデジタル組み合わせ論理を実装します。
module combo (
input a, b, c, d, e,
output z
);
assign z = ((a & b) | (c ^ d) & ~e);
endmodule
モジュール combo は合成ツールで以下のハードウェア回路図に展開され、組み合わせ論理がデジタルゲートで実装されていることがわかります。
テストベンチ
テストベンチは設計をシミュレートし、期待通りに動作するか検証するプラットフォームです。for ループと10時間単位の遅延文を使って、全入力組み合わせを設計モジュールに駆動します。
module tb;
reg a, b, c, d, e;
wire z;
integer i;
combo u0 (.a(a), .b(b), .c(c), .d(d), .e(e), .z(z));
initial begin
a <= 0; b <= 0; c <= 0; d <= 0; e <= 0;
$monitor ("a=%0b b=%0b c=%0b d=%0b e=%0b z=%0b", a, b, c, d, e, z);
for (i = 0; i < 32; i = i + 1) begin
{a, b, c, d, e} = i;
#10;
end
end
endmodule
シミュレーションログ
ncsim> run a=0 b=0 c=0 d=0 e=0 z=0 a=0 b=0 c=0 d=0 e=1 z=0 a=0 b=0 c=0 d=1 e=0 z=1 ...(全32通りの組み合わせ)... a=1 b=1 c=1 d=1 e=1 z=1 ncsim: *W,RNQUIE: Simulation is complete.
例 #2:半加算器
半加算器モジュールは2つのスカラ入力 a, b を受け取り、組み合わせ論理で出力 sum とキャリービット cout を代入します。sum は a と b のXOR、cout は両者のANDで得られます。
module ha (input a, b, output sum, cout);
assign sum = a ^ b;
assign cout = a & b;
endmodule
テストベンチ・シミュレーションログ
ncsim> run a=0 b=0 sum=0 cout=0 a=0 b=1 sum=1 cout=0 a=1 b=0 sum=1 cout=0 a=1 b=1 sum=0 cout=1 ncsim: *W,RNQUIE: Simulation is complete.
例 #3:全加算器
全加算器は上記の半加算器モジュールで構築することも、assign 文で組み合わせ論理を直接適用して sum と cout を駆動することもできます。
module fa (input a, b, cin, output sum, cout);
assign sum = (a ^ b) ^ cin;
assign cout = (a & b) | ((a ^ b) & cin);
endmodule
シミュレーションログ
ncsim> run a=0 b=0 cin=0 sum=0 cout=0 a=0 b=0 cin=1 sum=1 cout=0 a=0 b=1 cin=0 sum=1 cout=0 a=0 b=1 cin=1 sum=0 cout=1 a=1 b=0 cin=0 sum=1 cout=0 a=1 b=0 cin=1 sum=0 cout=1 a=1 b=1 cin=0 sum=0 cout=1 ncsim: *W,RNQUIE: Simulation is complete.
例 #4:2x1多重化器
シンプルな2x1多重化器は三項演算子を使って、どちらの入力を出力 c に代入するか決定します。sel が1なら a、0なら b で出力を駆動します。
module mux_2x1 (input a, b, sel, output c);
assign c = sel ? a : b;
endmodule
例 #5:1x4逆多重化器
逆多重化器は sel と f 入力の組み合わせで異なる出力信号を駆動します。各出力信号は別々の assign 文で駆動されます。一般に同じ信号を異なる assign 文で駆動することは推奨されません。
module demux_1x4 (
input f, input [1:0] sel,
output a, b, c, d
);
assign a = f & ~sel[1] & ~sel[0];
assign b = f & sel[1] & ~sel[0];
assign c = f & ~sel[1] & sel[0];
assign d = f & sel[1] & sel[0];
endmodule
例 #6:4x16デコーダ
module dec_3x8 (
input en, input [3:0] in,
output [15:0] out
);
assign out = en ? 1 << in : 0;
endmodule
イネーブル en が1のとき、入力 in に対応するビットのみが1になります(ワンホットエンコーディング)。
シミュレーションログ
ncsim> run en=0 in=0x0 out=0x0 ... en=1 in=0x0 out=0x1 en=1 in=0x1 out=0x2 en=1 in=0xf out=0x8000 ncsim: *W,RNQUIE: Simulation is complete.
Verilog
- Raspberry Piでサーバークローゼットの温度を正確に監視
- スイッチ付き回路:基本電気回路の実践ガイド
- 集積回路:デジタル論理ゲートの基礎
- プログラマブルロジックコントローラ(PLC):産業システムのための現代的デジタル制御
- ブール代数の理解:論理基礎からデジタル回路まで
- カルノー図によるロジック簡略化のマスター
- 科学的記数法での乗算と除算:マスターする
- インダストリー4.0の洞察:Bosch.IOのベレナ・マユントケ氏へのQ&A - IoT、自動化、未来の工場
- VHDLとVerilogのマスター:クリーンな組み合わせ・順序ロジックの書き方
- 実践Verilogゲートレベル設計:AND/OR/NOTゲートと2×1マルチプレクサ
- Verilog $timeformatのマスター:精度と表示制御