目录
前言
数字电路中,时钟是十分重要的。我们经常需要各种频率的时钟,比如UART串口需要各种比特率等等,因此今天主要讲讲如何使用Verilog生成不同频率的时钟。
一、整数分频
整数分频最直接的方法是采用计数器分频。假设时钟分频系数为N,则计数器 <= (N/2) 时输出高电平,计数器>0时输出低电平,并在计数器==N后同步清0,从而实现将时钟进行 (N+1) 分频。
module ns_clkdiv(
input wire [19:0] clk_update_N ,
input wire clkdiv_en ,
input wire clk_i ,
output wire clk_out ,
input wire rst_n
);
wire clkdiv_clr;
wire clk_update_N_zero;
wire clk_out_high;
wire clk_out_nxt;
wire [19:0] clk_cnt_nxt;
reg [19:0] clk_cnt_r;
reg clk_out_r;
assign clkdiv_clr = (clk_cnt_r == clk_update_N);
assign clk_cnt_nxt = clkdiv_clr ? 20'b0 : clk_cnt_r + 20'b1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
clk_cnt_r <= 20'b0;
else begin
if(clkdiv_en)
clk_cnt_r <= clk_cnt_nxt;
end
assign clk_update_N_zero = ~(| clk_update_N);
assign clk_out_high = (clk_cnt_r <= (clk_update_N > 1));
assign clk_out_nxt = clk_update_N_zero ? clk_i : clk_out_high;
always@(posedge clk_i or negedge rst_n)
if(!rst_n)
clk_out_r <= 1'b0;
else begin
if(clkdiv_en)
clk_out_r <= clk_out_nxt;
end
assign clk_out = clk_out_r;
endmodule
(一)偶分频
所谓偶分频,是将基准时钟分频至原来的1\(2n),基本思路是每计满n个基准时钟(计数器0到n-1),使输出端翻转。这种分频方法一般能满足大部分的分频需求,实现起来也较为简单。例如下面代码,是将50MHz的基准时钟分频成100KHz的时钟信号,则计数器需计满249时翻转。
module divider(clk_Reference,reset_n,qout);
input clk_Reference;//基准时钟
input reset_n;//复位信号,可删去。
output reg qout;//输出分频时钟信号
reg [7:0] cnt;//分配的存储单元,位宽随需求变化。
parameter Frequency_Reference = 50_000_000;//输入基准时钟的频率
parameter Frequency_Demand = 100_000;//所需时钟的频率
parameter Number_Flip = Frequency_Reference/(2*Frequency_Demand)-1;//经计算后的计满翻转数
always @(posedge clk_Reference or negedge