备忘_数字IC_verilog_分频
1.偶数
要实现一个N分频(N为偶数)的分频器,可以先写一个计数器,当计数到(N/2-1)时,让输出状态翻转,并将计数器清零,这样输出的信号就是输入时钟的N分频
偶数分频器示例,20分频即N=20,占空比50%
module clk_div(
clk,
rst,
div,
clk_out
);
input clk; //50MHZ
input rst;
input div; //divide number ,int
output clk_out;
reg clk_out = 1'b0;
reg [31:0] cnt;
wire [31:0] div;
always @(posedge clk) begin
if (rst) begin
cnt <= 32'b0;
clk_out <= 1'b0;
end
else if (cnt == ((div/2) - 32'd1)) begin
clk_out <= ~clk_out;
cnt <= 32'b0;
end
else begin
cnt <= cnt + 1'b1;
end
end
endmodule
2.奇数
如果对占空比没有明确的要求,则可以直接对上升沿计数,计数到(N-1)/2 时让输出翻转,计数到(N-1)时让输出状态再次翻转,并将计数器清零,这样就可以得到一个占空比为2:3的N分频(N为奇数)的分频器。而如果要实现50%的占空比,可以通过“错位相或”的方法实现。具体方法是用刚才的方法先通过对上升沿计数产生一个占空比为不是50%的N分频器,再用同样的方法对下降沿计数产生一个占空比也不是50%的N分频器,最后将这两个分频器的输出进行“或”运算,就可以得到占空比为50%的奇数N分频器
奇数分频器示例,5分频,占空比50%
module clk_div1(
clk,
rst,
div,
clk_p,
clk_n,
clk_out
);
input clk,rst,div;
output clk_out,clk_p,clk_n;
//wire clk_out = 1’b0;
reg clk_p = 1’b0;
reg clk_n = 1’b0;
reg [31:0]cnt_p = 32’d0;
reg [31:0]cnt_n = 32’d0;
wire [31:0] div;
always @(posedge clk or posedge rst) begin
if (rst) begin
cnt_p <= 32’b0;
clk_p <= 1’b0;
end
else if (cnt_p == ((div-1’b1)/2)) begin
clk_p <= ~clk_p;
cnt_p <= cnt_p + 32’d1;
end
else if (cnt_p == (div-1’b1)) begin
clk_p <= ~clk_p;
cnt_p <= 1’b0;
end
else cnt_p <= cnt_p + 32’d1;
end
always @(negedge clk or posedge rst) begin
if (rst) begin
cnt_n <= 32’b0;
clk_n <= 1’b0;
end
else if (cnt_n == ((div-1’b1)/2)) begin
clk_n <= ~clk_n;
cnt_n <= cnt_n + 32’d1;
end
else if (cnt_n == (div-1’b1)) begin
clk_n <= ~clk_n;
cnt_n <= 1’b0;
end
else cnt_n <= cnt_n + 32’d1;
end
assign clk_out = clk_p | clk_n;
endmodule
3.任意分频——基于相位累加原理
相位累加器主要用在直接数字频率合成器(DDS)中,其中的几个主要的参数为输入频率fc,输出频率fo,计数器位宽N,频率控制字K(即计数器递增步长)。它们之间的关系为:fo=(fcK)/(2N)。假设输入频率fc为50MHz,计数器位宽N为32,要产生1kHz的信号,则K=(fo*2N)/fc=85.9fo=85900。当计数值小于等于((2N)/2)时,输出低电平,当计数值大于((2N)/2)时,输出高电平,依次循环,就可以产生占空比为50%的1kHz信号
任意分频示例,输出1kHz,占空比50%
module div_free(clk_out, clk, rst_n);
input clk, rst_n;
output clk_out;
reg clk_out;
reg [31:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 0;
else cnt <= cnt + 32’d85900; //计数器步长 K
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
clk_out <= 1’b0;
end
else if(cnt < 32’h7FFF_FFFF)
clk_out <= 1’b0;
else clk_out <= 1’b1;
endmodule
4.小数/分数 分频
脉冲删除小数分频
小数均可以化为分数
以13/4分频为例,我们首先要想明白什么是13/4分频。什么是2分频呢?就是每两个输入时钟得到一个输出时钟,4分频就是4/1即四个输入时钟得到一个输出时钟,因此13/4分频其实就是13个输入时钟得到4个输出时钟,想明白这一点很重要。
13/4分频其实就是13个输入时钟得到4个输出时钟,因此脉冲删除小数分频相对比较简单。意思就是在13个输入时钟里我删掉9个时钟周期,这样就输出了4个时钟周期了
1.设置寄存器cnt位宽自定,我用的[7:0],初始值为0;
2.在clk_in的上升沿+4,并判断是否大于13,若大于13在下一周期-13;
3.cnt小于13时候,删除脉冲信号delete=1,大于13时候delete=0;
module clk_divfloat(
clk,
rst,
clk_out
);
parameter fenzi = 13;
parameter fenmu = 4;
input clk,rst;
output clk_out;
reg [31:0] cnt = 32’d0;
reg delete = 1’b0;
always @(posedge clk or posedge rst) begin
if (rst) begin
cnt <= 32’d0;
delete <= 1’b0;
end
else if (cnt > fenzi) begin
cnt <= cnt + fenmu - fenzi;
delete <= 1’b0;
end
else begin
cnt <= cnt + fenmu;
delete <= 1’b1;
end
end
assign clk_out = delete ? 1’b1 : clk;
endmodule