Verilog - クロックを 3 で割ったもの
機能実現
入力クロックに対して 3 の分周器を実装するだけです。周波数 2 による分周は、FPGA 初心者が最初に実装するモジュールかもしれないと思いますが、周波数 3 による分周をどのように実現するかという疑問がいつも頭の中にあります。最近、インターネット上で 3 方向の周波数分割の実装について説明しているブログを偶然発見し (ブログの URL を忘れてしまいました)、その方法に従って Vivado 上で 3 方向の周波数分割を実装しました。
3ウェイ周波数モジュールの実装
実装プロセスは簡単です。
- 入力クロックで 0 ~ 2 をカウントします。
- カウント値に基づいて、デューティ サイクル 1/3 の 3 分周クロックを生成します。
- デューティ サイクル 1/3 の 3 分周クロックは、半クロック遅延します (入力クロックの立ち下がりエッジを使用して遅延をトリガーします)。
- デューティ サイクル 1/3 の 3 分周クロックは、遅延クロックと OR 演算できます。
ソースコードは次のとおりです。
`timescale 1ns / 1ps
//功能:实现输入时钟的1.5倍频
//输入:时钟、复位
//输出:1.5倍频时钟
module top(
input clk200M ,
input rst_n ,
output freq3 //3倍频输出信号
);
reg [1:0] cnt;
reg clk_13;
reg clk_13_r;
//cnt,计数器
always @(posedge clk200M or negedge rst_n) begin
if(~rst_n)
cnt <= 2'd0;
else if(cnt == 2'd2)
cnt <= 2'd0;
else
cnt <= cnt + 'd1;
end
//clk_13,生成时钟1/3占空比的信号
always @(posedge clk200M or negedge rst_n) begin
if(~rst_n)
clk_13 <= 1'b0;
else if(cnt == 2'd2)
clk_13 <= 1'b1;
else
clk_13 <= 1'b0;
end
//clk_13_r,延迟半拍clk_13
always @(negedge clk200M or negedge rst_n) begin
if(~rst_n)
clk_13_r <= 1'b0;
else
clk_13_r <= clk_13;
end
//freq3,生成3倍频信号
assign freq3 = clk_13 | clk_13_r;
endmodule
シミュレーション
入力クロックとリセット信号をシミュレートするだけで、他の操作は必要ありません。ソースコードは次のとおりです。
`timescale 1ns / 1ps
module tb_t36;
reg clk200M ;
reg rst_n ;
wire freq1_5 ;
top top_inst(
.clk200M ( clk200M),
.rst_n ( rst_n ),
.freq1_5 ( freq1_5) //1.5倍频输出信号
);
initial begin
clk200M = 1'b0;
rst_n = 1'b0;
#100;
//
rst_n = 1'b1;
end
//时钟
always #5 clk200M = ~clk200M;
endmodule
シミュレーション結果を図に示します。