Interface編集部
Gowin_Vol3 1部1章リスト2
// Verilog は言語仕様で、宣言されていない信号線を幅1 のwire として解釈する
// Typo 等で意図しない回路が生成されないよう、定義しない信号をエラーに設定する
`default_nettype none
// clk 入力ごとにカウントアップするタイマー
// - 内部のカウンタがCOUNT_LIMIT に達したときのみcount_max が1 を出力
// - それ以外の場合は0 を出力
module timer #(
parameter COUNT_LIMIT = 27_000_000
) (
input wire clk,
output wire count_max
);
// カウンタ本体を定義
// - COUNT_LIMIT の値に応じて必要な幅を確保
// - 初期値はゼロに設定
logic [$clog2(COUNT_LIMIT+1)-1:0] counter = 'd0;
// count_max の出力を組み合わせ回路で記載
// - counter がCOUNT_LIMIT と一致したときに1 を出力
// - それ以外の場合は0 を出力
assign count_max = (counter == COUNT_LIMIT)? 1'b1: 1'b0;
// counter の値を順序回路で記載
// - counter がCOUNT_LIMIT と一致したら値を0 に戻す
// - それ以外の場合はclk 入力ごとにカウントアップ
always_ff @ (posedge clk) begin
if (counter == COUNT_LIMIT) begin
counter <= 'd0;
end else begin
counter <= counter + 'd1;
end
end
endmodule
// 最上位モジュール
// - ボード上のLED を点滅させるモジュール
// - 点滅間隔はモジュール内部のパラメータで設定
module led_blinking (
input wire clk,
output wire [5:0] led_output
);
// 入力されるクロック周波数
localparam CLK_FREQ = 27_000_000;
// 点滅間隔をms 単位で設定
localparam BLINKING_MS = 500;
// 実装したタイマーのインスタンス
// - COUNT_LIMIT の値をクロック周波数と点滅間隔から計算
// - .* と記述することで同名のwire, logic が自動的に接続される
wire count_max;
timer #(
.COUNT_LIMIT ((CLK_FREQ / 1000) * BLINKING_MS)
) timer_i (
.*
);
// LED を点滅させるロジックを順序回路で記載
// - count_max が入力されたタイミングでled の値を反転
logic [5:0] led = 6'b101010;
always_ff @ (posedge clk) begin
if (count_max) led <= ~led;
end
// led ロジックをled_output に接続
assign led_output = led;
endmodule
// 他のモジュールに影響を与えないよう、もとの設定に戻す
`default_nettype wire