verilog 分频电路设计 -- 奇偶分频、小数分频

1、奇偶分频

module fre_div
#(parameter DIV_NUM = 5)
(
    input clk,
    input rst_n,
    output clk_div
    );
 
reg [3:0] cnt_div;
wire clk_odd_div;
reg clk_even_div;
always @(posedge clk or negedge rst_n)begin
    if(~rst_n)
        cnt_div <= 4'd0;
    else if(cnt_div == DIV_NUM - 1)
        cnt_div <= 4'd0;
    else
        cnt_div <= cnt_div + 4'd1;
end

always @(posedge clk or negedge rst_n)begin
    if(~rst_n)
        clk_even_div <= 1'd0;
    else if(cnt_div == DIV_NUM/2 - 1 | cnt_div == DIV_NUM - 1)
        clk_even_div <= ~clk_even_div;
end

reg clk_odd_div0,clk_odd_div1;
always @(posedge clk or negedge rst_n)begin
    if(~rst_n)
        clk_odd_div0 <= 1'd0;
    else if(cnt_div == (DIV_NUM - 1)/2 | cnt_div == DIV_NUM - 1)
        clk_odd_div0 <= ~clk_odd_div0;
    else
        clk_odd_div0 <= clk_odd_div0;
end

always @(negedge clk or negedge rst_n)begin
    if(~rst_n)
        clk_odd_div1 <= 1'd0;
    else if(cnt_div == (DIV_NUM - 1)/2 | cnt_div == DIV_NUM - 1)
        clk_odd_div1 <= ~clk_odd_div1;
    else
        clk_odd_div1 <= clk_odd_div1;
end    
assign clk_odd_div = clk_odd_div0|clk_odd_div1;
assign clk_div = (DIV_NUM%2) ? clk_odd_div : clk_even_div;
endmodule

testbench

module clk_tb(

    );
reg clk;
reg rst_n;
wire clk_div;
parameter DIV_NUM = 3;
fre_div 
#(.DIV_NUM(DIV_NUM))
u_fre_div(
    .clk     (clk     ),
    .rst_n   (rst_n   ),
    . clk_div( clk_div)
    );
    
always #10 clk = ~clk;
initial begin
    clk = 0;
    rst_n = 0;
    #100;
    rst_n = 1;
end
endmodule

在这里插入图片描述

2、任意小数分频
在这里插入图片描述
如19/9分频,意味着在输入时钟clk_in的19个周期内,输出需产生9个脉冲,控制输出8个二分频时钟周期和1个三分频时钟周期即可。

// M/N小数分频,M为分子,N为分母
module Dec_Freq_Div_M_N(
 input clk,
 input rstn,
 output clk_out
);

reg [5:0] cnt;
reg [3:0] cnt_a;
reg [3:0] cnt_b;
reg clk_out_reg;
assign clk_out = clk_out_reg;

// div_a和div_b分别为根据前述公式计算出来的基准分频系数
// change为2、3分频时钟的切换点
parameter M = 6'd19;
parameter change = 6'd16;
parameter div_a = 5'd2;
parameter div_b = 5'd3;

//总计数器
always @(posedge clk or negedge rstn) begin
 if(!rstn)
  cnt <= 6'b0;
 else begin
  if(cnt == M - 1'b1)
   cnt <= 6'b0;
  else
   cnt <= cnt + 1'b1;
 end 
end 

//产生2、3分频的计数器
always @(posedge clk or negedge rstn) begin 
 if(!rstn) begin
  cnt_a <= 4'b0;
  cnt_b <= 4'b0;
 end 
 else if(cnt<=change-1'b1) begin
  cnt_b <= 4'd0;
  if(cnt_a == div_a - 1'b1)
   cnt_a <= 4'd0;
  else
   cnt_a <= cnt_a + 1'b1;
 end 
 else if(cnt>change-1'b1) begin
  cnt_a <= 4'd0;
  if(cnt_b == div_b - 1'b1)
   cnt_b <= 4'd0;
  else
   cnt_b <= cnt_b + 1'b1;
 end

//输出时钟产生逻辑
always @(posedge clk or negedge rstn) begin
 if(!rstn)
  clk_out_reg <= 1'b0;
 else if(cnt<change) begin
  if(cnt_a == 4'd0 || cnt_a == div_a/2)
   clk_out_reg <= ~clk_out_reg;
  else
   clk_out_reg <= clk_out_reg;
 end 
 else if(cnt>=change) begin
  if(cnt_b == 4'd0 || cnt_b == (div_b - 1'b1)/2)
   clk_out_reg <= ~clk_out_reg;
  else
   clk_out_reg <= clk_out_reg;
 end 
end 

endmodule
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值