目录
使用Verilog语言设计一个分频器电路,能够对输入时钟进行分频,得到我们所需要的时钟。
一、逻辑设计
1.端口设计
模块的输入端口包含系统时钟sys_clk、复位信号sys_rst_n;输出端口包含分频后的输出时钟信号out_clk。
2.波形图绘制
偶数分频实现原理:
假设为N(偶数)分频,计数到N/2-1,然后时钟翻转、计数器清零,如此循环就可以得到N(偶)分频。举个例子,比如晶振时钟是50Mhz时钟,想得到 一个12.5Mhz的时钟,进行四分频设计,即计数到4/2-1=1,然后时钟翻转、计数器清零,就可以得到一个12.5Mhz的时钟。
二、程序设计
根据波形图使用Verilog编写计数器(divider_4.v)代码
1.分频器代码
代码如下:
// 偶数分频器,实现4分频
module divider_4(
input sys_clk, // 系统时钟输入
input sys_rst_n, // 系统复位信号,低电平有效
output reg out_clk // 输出时钟
);
//修改N的值和计数器的位宽可以实现其他偶数分频
parameter MAXCount = 4 / 2 - 1; // N(偶数)分频,计数到 N/2-1,N = 4
reg [1:0] cnt; // 计数器
// 计数器
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) // 复位状态
cnt <= 2'd0;
else if (cnt == MAXCount)
cnt <= 2'd0;// 达到计数上限计数器清零
else
cnt <= cnt + 2'd1;// 正常计数
end
// 输出时钟翻转控制
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) // 复位状态
out_clk <= 1'b0;
else if (cnt == MAXCount) // 达到计数上限
out_clk <= ~out_clk; // 翻转输出时钟
end
endmodule
2.仿真代码
代码如下:
`timescale 1ns / 1ns
module tb_divider_4();
reg sys_clk ;
reg sys_rst_n ;
wire out_clk;
// 初始化
initial begin
sys_clk = 1'b1; // 初始化系统时钟为高电平
sys_rst_n <= 1'b0; // 复位信号
#201;
sys_rst_n <= 1'b1;
end
// 时钟周期性翻转
always #10 sys_clk = ~sys_clk;
// 实例化
divider_4 divider_4_inst(
.sys_clk (sys_clk ),
.sys_rst_n(sys_rst_n),
.out_clk (out_clk )
);
endmodule
3.仿真结果
out_clk信号在计数器计数到1时进行翻转,out_clk相邻两个上升沿间隔80ns,对应频率为,对sys_clk系统时钟的4分频,与绘制的波形图一致。
总结
在FPGA的设计中,由于板卡的晶振一般是固定的,而对于一些工程而言晶振时钟并不是都能满足设计需求,所以在项目设计中我们经常使用分频器对输入时钟进行分频,本文主要针对偶数分频器的进行设计。