VerilogHDLでクロック分周器を記述してみる
クロック分周器
FPGAボードを使って、7セグメントLEDに結果を表示させたい時がある。
けれど、MHz〜GHzで動作されたんでは確認できない。
という事で、クロック分周器(50MHz -> 1Hz)を2つ記述してみる。
(どちらの記述も分周するのだけれど、出力される波形が微妙に違うので、
適材適所で使い分けますかね。)
クロック分周器(clk_divider.v)
/* clk_divider.v */ `define HLZ_1 // 50MHzを1HZに分周 //`define HLZ_1M // 50MHzを1MHzに分周 //`define HLZ_16M // 50MHzを16MHzに分周 //`define HLZ_32M // 50MHzを32MHzに分周 module clk_divider(input clk, rst, output en1hz); reg [25:0] cnt; always @( posedge clk or posedge rst) begin if (rst) cnt <= 26'd0; else if ( en1hz_wire ) cnt <= 26'd0; else cnt <= cnt + 26'd1; end `ifdef HLZ_1 wire en1hz_wire = (cnt==26'd49_999_999); `elsif HLZ_1M wire en1hz_wire = (cnt==26'd47); `elsif HLZ_16M wire en1hz_wire = (cnt==26'd2); `elsif HLZ_32M wire en1hz_wire = (cnt==26'd1); `else wire en1hz_wire = (cnt==26'd49_999_999); `endif assign en1hz = en1hz_wire; endmodule
clk_divider.vを論理合成した結果(Quartus PrimeのRTL Viewerで確認)
クロック分周器 その2 (clk_divider_0.v)
こちらの記述がオーソドックスな分周器かな(?)
上記の記述(clk_divider.v)に比べて、カウントする値を少なくできる。
/* clk_divider_0.v */ /* 50MHz -> 1Hz */ module clk_divider_0(input clk, rst, output reg divid_clk); reg [25:0] cnt; wire cntend = (cnt==26'd24_999_999); always @(posedge clk or posedge rst) begin if(rst) cnt <= 26'd0; else if(cntend) cnt <= 26'd0; else cnt <= cnt + 26'd1; end always @(posedge clk or posedge rst) begin if(rst) divid_clk <= 1'b0; else if(cntend) divid_clk <= ~(divid_clk); end endmodule
clk_divider_0.vを論理合成した結果(Quartus PrimeのRTL Viewerで確認)