分频

分频 

当分频为2的整数次幂时   8分频:将一个3位的计数器最高位输出,也就是计数长度为8
module divider #(parameterN=3) (
input clk,
input rstn,
output clk_div,
);
reg [N-1] div_reg;
always@(posedge clk or negedge rst_n) begin 
    if (!rstn) begin 
      div_reg<=1'b0;
end
    else  begin
    div_reg<=div_reg+1'b1;
end
end
assign clk_div=div_reg[N-1];
endmodule


不考虑占空比   任意数  一个最大计数长度为N(从0计数到N-1)的计数器,其最高位的输出,是输入频率的N分频。
module divide #(paremeter N=3)(
input clk,
input rstn,
output clk_div
);
reg [N-1:0] div_reg;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin 
    div_reg<=1'b0;
    end
    else if (div_reg==3'b4) begin   #5分频
    div_reg<=1'b0;
    end 
    else  begin
    div_reg<=div_reg+1'b1;
end
end
assign clk_div=div_reg[N-1];
endmodule

偶数倍分频(占空比50%module divider #(parameterN=6) (
input clk,
input rstn,
output clk_div,
);
reg [N-1] div_cnt;
reg   div_reg;
always@(posedge clk or negedge rst_n) begin 
    if (!rstn) begin 
      div_reg<=1'b0;
     div_cnt<=1'b0;
    end
    else if (div_cnt==(N>>1)-1) begin 
     div_cnt<=1'b0;
     div_reg<=~div_reg;
    end
    else  begin
    div_reg<=div_reg+1'b1;
end
end
assign clk_div=div_reg;
endmodule

奇数倍分频 占空比50%

module divide #(parameterN=5) (
input clk,
input rstn,
output clk_div,
);

reg sig_r ;  //定义一个上升沿翻转的信号
reg sig_f ; //定义一个下降沿翻转的信号

reg [N-1]    cnt_r ;
reg [N-1:0]    cnt_f;//下降沿计数器

wire clk_f;
assign clk_f =~clk; 

always@(posedge clk_r negedge rst_n) begin   //上升沿计数
    if (!rstn) begin 
      sig_r<=1'b0;
     sig_r<=1'b0;
    end
    else if (cnt_r==(N>>1)-1) begin 
      sig_r<= ~sig_r;
      cnt_r<= cnt_r+1'b1;
    end
    else if (cnt_r==(N-1) )begin 
      sig_r<= ~sig_r;
      cnt_r<= 1'b0;
    end
    else  begin
    div_reg<=cnt_r+1'b1;
end

always@(posedge clk_f negedge rst_n) begin   //下降沿计数
    if (!rstn) begin 
      sig_f<=1'b0;
     sig_f<=1'b0;
    end
    else if (cnt_f==(N>>1)-1) begin 
      sig_f<= ~sig_f;
      cnt_f<= cnt_f+1'b1;
    end
    else if (cnt_f==(N-1) )begin 
      sig_f<= ~sig_f;
      cnt_f<= 1'b0;
    end
    else  begin
    div_reg<=cnt_f+1'b1;
end

assign clk_div = sig_f || sig_r ;

endmodule


assign clk_out = (fre_div == 1'b1)? clk_in : (fre_div[0]? clk_odd : clk_even)


占空比50%的任意整数分频

module test#(parameter N=1)(//N分频
input clk,
input rst_n,
output clk_div
);

//奇数分频
reg sig_r ;//定义一个上升沿翻转的信号
reg sig_f ;//定义一个下降沿翻转的信号
reg [N-1:0]    cnt_r;//上升沿计数器
reg [N-1:0]    cnt_f;//下降沿计数器

wire clk_f ;
assign clk_f = ~clk ;//用来触发下降沿计数器的时钟
                    //由于同时使用上升沿和下降沿触发器不好,因此我们为同一边沿,都使用上升沿触发
                    //只不过是将时钟进行反向

always @(posedge clk or negedge rst_n)begin//上升沿计数
    if(rst_n == 1'b0)begin
        sig_r    <= 0 ;
        cnt_r    <= 0 ;
    end
    else begin
        cnt_r    <= cnt_r + 1 ;
        if( cnt_r == (N-1)/2 )begin
            sig_r    <= ~sig_r ;
        end else if ( cnt_r == (N-1) )begin
            sig_r    <= ~sig_r ;
            cnt_r    <= 0 ;
        end
    end
end

always @(posedge clk_f or negedge rst_n)begin//下降沿计数
    if(rst_n == 1'b0)begin
        sig_f    <= 0 ;
        cnt_f    <= 0 ;
    end
    else begin
        cnt_f    <= cnt_f + 1 ;
        if( cnt_f == (N-1)/2 )begin
            sig_f    <= ~sig_f ;
        end else if ( cnt_f == (N-1) )begin
            sig_f    <= ~sig_f ;
            cnt_f    <= 0 ;
        end
    end
end

//偶数分频
reg div_reg ;
reg [N-1:0] div_cnt        ;//分频计数器
always @(posedge clk or negedge rst_n)begin
    if (rst_n == 1'b0 )begin
        div_cnt    <= 0 ;
        div_reg    <= 0 ;
    end
    else begin
        div_cnt    <= div_cnt + 1'b1 ;
        if(div_cnt == (N/2 - 1))begin
            div_cnt    <= 0;
            div_reg    <= ~div_reg ;
        end
    end
end
assign clk_div = (N == 1)?clk : ( N%2 == 1)?(sig_f || sig_r ): div_reg;     //这里用来输出分频值。对2的取余操作是综合的

endmodule
module sim_test;
             reg clk;
             reg rst_n;
             wire clk_out;
             
      test  sim_test(
        .clk(clk),
        .rst_n(rst_n),
        .clk_div(clk_div)
    ); 
             
             initial 
                    begin
                          clk_in = 1'b0;
                          rst_n = 1'b1;
                          #20 rst_n = 1'b0;
                          #20 rst_n = 1'b1;
                    end
              
             always #10 clk = ~clk;
             
endmodule

 

posted @ 2021-09-09 10:28  Q强  阅读(349)  评论(0)    收藏  举报