FPGA学习篇之分频器
前言
分频器是数字电路中最常用的基本电路之一,目的是对输入时钟进行分频,输出任何低于输入时钟的频率。在FPGA设计中,可以采用锁相环来获得任何占空比、相位可调的时钟信号。在代码编写中,我们可以通过计数器来对时钟进行简单的分频。
一、偶数分频
采用最大计数长度位N的计数器,将最高位作为输出,则可以对输入频率进行2N分频。
module divider #(parameter cfactor = 4)(
input clk_in,
input rst_n,
output clk_out
);
reg [7:0] cnt; // 最大支持256分频
reg clk_loc;
assign clk_out = (cfactor == 1) ? clk_in : clk_loc ;
always@(posedge clk_in or negedge rst_n)
if(!rst_n)
cnt <= 'h0;
else if(cnt < cfactor - 1)
cnt <= cnt + 1'b1;
else
cnt <= 'h0;
always@(posedge clk_in or negedge rst_n)
if(!rst_n)
clk_loc <= 1'b1;
else if(cnt == cfactor/2 -1)
clk_loc <= 1'b0;
else if(cnt == cfactor -1)
clk_loc <= 1'b1;
endmodule
二、奇数分频
上面的代码如果进行奇数分频,会出现占空比不是1:1的情况,在代码中生成两个占空比不为1:1的时钟,再将它们相与,便会得到一个占空比位1:1的奇数分频时钟。
module divider_odd #(parameter cfactor = 5)(
input clk_in,
input rst_n,
output clk_out
);
reg [7:0] cnt; // 最大支持256分频
reg clk1;
reg clk2;
assign clk_out = clk1 & clk2;
always@(posedge clk_in or negedge rst_n)
if(!rst_n)
cnt <= 'h0;
else if(cnt < cfactor - 1)
cnt <= cnt + 1'b1;
else
cnt <= 'h0;
always@(posedge clk_in or negedge rst_n)
if(!rst_n)
clk1 <= 1'b1;
else if(cnt == cfactor/2)
clk1 <= 1'b0;
else if(cnt == cfactor -1)
clk1 <= 1'b1;
always@(negedge clk_in or negedge rst_n)
if(!rst_n)
clk2 <= 1'b1;
else if(cnt == cfactor/2)
clk2 <= 1'b0;
else if(cnt == cfactor -1)
clk2 <= 1'b1;
endmodule
总结
在FPGA设计中,由于分频过后的时钟没有经过全局时钟网络,所以在高速设计中直接使用计数分频后的时钟可能存在风险。为了避免风险,可以将输出时钟改为输出使能信号,让需要低频率时钟的部分仍然使用高频率时钟来触发,同时加入分频后产生的使能信号作为动作条件,这样可以增加设计的稳定性。