Verilog HDL学习笔记六
FPGA开发板上的晶振频率都是固定值,只能产生固定频率的时钟信号,但是实际工程中需要各种不同频率的信号,这时就需要对晶振产生的频率进行分频。比如 FPGA开发板上的晶振频率为50MHz,若想要得到1MHz的方波信号,那么就需要对晶振产生的信号进行50分频;若要实现秒计数,则需对50MHz频率进行50000000分频,形成1Hz的脉冲。
1.偶数分频
偶数分频器的设计比较简单,通常用计数器的方法来实现。比如要实现一个N分频(N为偶数)的分频器,当计数到(N/2-1)时,让输出状态翻转,并将计数器清零,这样输出的信号就是输入时钟的N分频了。
以10分频为例,即N=10,计数到4时钟反转。
//设计代码
module div_10(clk,rst_n,div_10);
input clk ;
input rst_n;
output div_10;
reg div_10;
reg [3:0] cnt;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= 4'b0;
div_10 <= 1'b0;
end
else if(cnt == 4'd4)
begin
cnt <= 4'b0;
div_10 <= ~div_10;
end
else
cnt <= cnt + 1;
end
endmodule
//测试代码
module div_10_tb;
reg clk;
reg rst_n;
wire div_10;
div_10 unit(
.clk(clk),
.rst_n(rst_n),
.div_10(div_10));
always #10 clk = ~clk ;
initial
begin
clk=1'b1; rst_n=1'b0;
#10 rst_n=1'b1;
end
endmodule
波形图如下所示:
2.奇数分频
以三分频且占空比为50%的奇数分频器为例,设计思路是:计数器为时钟上升沿触发,计数到2清零,clk1为时钟上升沿触发,当cnt清零时clk1翻转;clk2时钟下降沿触发,当cnt计数到2时clk2翻转,最后将clk1与clk2进行与运算。
N=3,占空比为50%,具体实现代码如下:
//设计代码
module div_3( input clk, input rst_n, output div_three );
reg [1:0] cnt;
reg div_clk1;
reg div_clk2;
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
cnt <= 0;
else if(cnt == 2)
cnt <= 0;
else
cnt <= cnt + 1;
end
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
div_clk1 <= 0;
else if(cnt == 0)
div_clk1 <= ~div_clk1;
else div_clk1 <= div_clk1;
end
always @(negedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
div_clk2 <= 0;
else if(cnt == 2)
div_clk2 <= ~div_clk2;
else
div_clk2 <= div_clk2;
end
assign div_three = div_clk2 ^ div_clk1;
endmodule
//测试代码
module div_3_tb;
reg clk;
reg rst_n;
wire div_three;
div_3 unit(
.clk(clk),
.rst_n(rst_n),
.div_three(div_three)
);
always #10 clk=~clk;
initial
begin
clk=1;rst_n=0;
#20 rst_n=1;
end
endmodule
波形图如下所示
若需了解其他分频方法可参考如下:
基于Verilog的偶数、奇数、半整数分频以及任意分频器设计