はじめに
この記事は、Hardware Description Language Advent Calendar 2024 の22日目の記事となります。
アドベントカレンダのリストを見ていて、今、Hardware Description Languageに来た初心者の記録です。
ChatGPT先生に教えてもらう
ChatGPT先生に嘘を教えられている可能性は否定できないので、誤りがありましたら有識者の方のコメントをお願いいたします。
なるほど。Verilogはどんな文法なんだろう
聞いてみよう。
module モジュール名 (入力, 出力);
// ポート(入力と出力)の宣言
input 入力名;
output 出力名;
// 内部の回路や信号の宣言
wire 信号名;
// 回路の動作を記述
assign 出力名 = 入力名;
endmodule
module AND_Gate (a, b, y);
input a, b; // 入力信号
output y; // 出力信号
assign y = a & b; // AND演算
endmodule
module Testbench;
reg a, b; // 入力信号のシミュレーション用変数
wire y; // 出力信号
// AND_Gateモジュールをインスタンス化
AND_Gate U1 (a, b, y);
initial begin
// シミュレーションでの入力値を設定
a = 0; b = 0;
#10; // 10単位時間待つ
a = 0; b = 1;
#10;
a = 1; b = 0;
#10;
a = 1; b = 1;
#10;
$finish; // シミュレーション終了
end
endmodule
なるほどテストベンチを作って確認するのね。
拡張子は何?
// ヘッダーファイル defines.vh
`define AND_GATE_DELAY 10
// ソースファイル and_gate.v
`include "defines.vh" // ヘッダーファイルを読み込む
module AND_Gate (a, b, y);
input a, b;
output y;
assign #`AND_GATE_DELAY y = a & b; // 定義された遅延を使用
endmodule
なるほど。
入力と出力が同じ引数のような書き方なのは気になる
module モジュール名 (入力信号, 出力信号);
input 入力信号; // 入力ポート
output 出力信号; // 出力ポート
endmodule
module AND_Gate (a, b, y);
input a, b; // 入力ポート
output y; // 出力ポート
assign y = a & b; // AND演算
endmodule
int add(int a, int b) {
return a + b;
}
module Top_Module;
wire a, b, y;
// ANDゲートのインスタンス
AND_Gate U1 (a, b, y); // 外部信号a, b, yをAND_Gateのポートに接続
endmodule
信号線を書いているということね。でもその信号線が、入力なのか出力なのか、信号線の名前だけ見たのでは、分からんのでは?
褒められた!
module AND_Gate (a, b, y);
input a, b; // 入力ポートを内部で宣言
output y; // 出力ポートを内部で宣言
assign y = a & b; // AND演算
endmodule
module AND_Gate (input a, input b, output y);
assign y = a & b; // AND演算
endmodule
なるほど腑に落ちた。
納得です。
何か試してみたい。練習問題を検索してみる。
itmediaさんの素晴らしい記事を発見。
module logic_circuit (
input A,
input B,
input C,
output X
);
wire or_out;
wire not_out;
// ORゲート
assign or_out = A | B;
// NOTゲート
assign not_out = ~C;
// ANDゲート
assign X = or_out & not_out;
endmodule
ChatGPTの方はANSIでロジックを1つ1つ書いている。
一方、模範解答の方はnon ANSIでロジックをまとめて書いている。
という感じか。
テストベンチをChatGPT先生に作ってもらおう。
module logic_circuit_tb;
// テストベンチ用信号
reg A;
reg B;
reg C;
wire X;
// 被テストモジュールのインスタンス化
logic_circuit uut (
.A(A),
.B(B),
.C(C),
.X(X)
);
// テストケース
initial begin
// 波形を出力
$dumpfile("logic_circuit_tb.vcd");
$dumpvars(0, logic_circuit_tb);
// 初期状態
A = 0; B = 0; C = 0;
#10; // 10タイムユニット待機
A = 0; B = 0; C = 1;
#10;
A = 0; B = 1; C = 0;
#10;
A = 0; B = 1; C = 1;
#10;
A = 1; B = 0; C = 0;
#10;
A = 1; B = 0; C = 1;
#10;
A = 1; B = 1; C = 0;
#10;
A = 1; B = 1; C = 1;
#10;
// シミュレーション終了
$finish;
end
endmodule
おお。網羅しているっぽい。
いざ実行!
これ動かすのはどうしたら良いのか。
Google先生で見つけた以下のサイトでトライしてみる。
使い方の参考にさせてもらったブログ
先ほどのコードを左、テストベンチを右に、貼り付ける。
左のペインで適当なSimulatorを選択する。
左上の青色のRunボタンを押すと・・
やったぁ!波形が出たぞ。
あってるのかな・・
波形と対比して入力が000のとき0で・・・
っと・・・。おお。全部正しい。
以上、「Hardware Description Language」に今来た私が試したこと(ChatGPT先生と共に)でした。
最後までご覧いただきましてありがとうございました!。