概述
一、偶数分频
偶数分频可以通过计数器或者D触发器级联方式实现,使用计数器进行N倍(偶数)分频时,当计数器计数到(N-1)/2时进行反转一次。
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_cnt<=4'd0;
else if(clk_cnt==(N/2-1))
clk_cnt<=4'd0;
else
clk_cnt<=clk_cnt+1'b1;
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_div<=1'b0;
else if(clk_cnt==(N/2-1))
clk_div<=~clk_div;
D触发器级联
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_div <= 1'b0;
else
clk_div <= ~clk_div;
always@(posedge clk_div or negedge rst_n)
if(~rst_n)
clk_div_r <= 1'b0;
else
clk_div_r <= ~clk_div_r;
二、奇数分频
占空比不为50%的奇数分频可以通过奇数和moor状态机来实现,使用计数器进行N倍(奇数)分频时,当计数器计数到N/2-1和o时各进行一次反转。
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_cnt<=4'd0;
else if(clk_cnt==(N-1))
clk_cnt<=4'd0;
else
clk_cnt<=clk_cnt+1'b1;
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_div<=1'b0;
else if(clk_cnt==(N-1)/2)
clk_div<=~clk_div;
else if(clk_cnt==4'd0)
clk_div<=~clk_div;
占空比为50%的奇数分频,需要通过上升沿计数器、下降沿计数器各产生一个分频信号,将两个信号进行相与便可以得到占空比为50%的奇数分频。
reg clk_n,clk_p;
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_cnt<=4'd0;
else if(clk_cnt==(N-1))
clk_cnt<=4'd0;
else
clk_cnt<=clk_cnt+1'b1;
always@(negedge clk or negedge rst_n)
if(~rst_n)
clk_cnt_n<=4'd0;
else if(clk_cnt_n==(N-1))
clk_cnt_n<=4'd0;
else
clk_cnt_n<=clk_cnt_n+1'b1;
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_p<=1'b0;
else if(clk_cnt==(N-1)/2)
clk_p<=~clk_p;
else if(clk_cnt==4'd0)
clk_p<=~clk_p;
always@(negedge clk or negedge rst_n)
if(~rst_n)
clk_n<=1'b0;
else if(clk_cnt_n==(N-1)/2)
clk_n<=~clk_n;
else if(clk_cnt_n==4'd0)
clk_n<=~clk_n;
assign clk_div = clk_n|clk_p;
状态机实现
localparam s0 = 7'b000_0001,
s1 = 7'b000_0010,
s2 = 7'b000_0100,
s3 = 7'b000_1000,
s4 = 7'b001_0000,
s5 = 7'b010_0000,
s6 = 7'b100_0000;
reg [6:0] state,next_state;
always@(posedge clk or negedge rst_n)
if(~rst_n)
state<=s0;
else
state<=next_state;
always@(*)
case(state)
s0:next_state = s1;
s1:next_state = s2;
s2:next_state = s3;
s3:next_state = s4;
s4:next_state = s5;
s5:next_state = s6;
s6:next_state = s0;
default:next_state = s0;
endcase
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_div<=1'b0;
else
case(next_state)
s0:clk_div <= 1'b0;
s1:clk_div <= 1'b0;
s2:clk_div <= 1'b0;
s3:clk_div <= 1'b1;
s4:clk_div <= 1'b1;
s5:clk_div <= 1'b1;
s6:clk_div <= 1'b1;
default:clk_div <= 1'b0;
endcase
三、小数分频
输入频率f_in、输出频率f_out,计数器位宽N、计数器步长M之间存在f_in/f_out=(2^N)/M的关系,以M为计数步长进行计数,当计数值大于等于(2^N)/2时为高电平否则为低电平。
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_cnt <= 'h0;
else if(&clk_cnt)
clk_cnt <= 'h0;
else
clk_cnt <= clk_cnt+32'haaaa_aaaa;
always@(posedge clk or negedge rst_n)
if(~rst_n)
clk_div <= 1'b0;
else if(clk_cnt>=32'h7fff_ffff)
clk_div<=1'b1;
else
clk_div<=1'b0;
最后
以上就是欢喜大米为你收集整理的verilog实现分频器总结的全部内容,希望文章能够帮你解决verilog实现分频器总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复