题解 | 任意小数分频

奇数分频 偶数分频 均匀版(未适配本题testbench)

`timescale 1ns/1ns

module div_M_N(
 input  wire clk_in,
 input  wire rst,
 output wire clk_out
);
parameter M_N = 8'd87; 
parameter switch = 8'd24; // 8/9时钟切换点
parameter div_e = 5'd8; //偶数周期
parameter div_o = 5'd9; //奇数周期
//*************code***********//
reg [$clog2(M_N)-1:0]   cnt ;
reg                     flag;
reg [$clog2(div_e)-1:0] cnt_even;
reg [$clog2(div_o)-1:0] cnt_odd;


always@(posedge clk_in or negedge rst)
    if (~rst)
        cnt <= 7'd0;
    else if (cnt==M_N-1)
        cnt <= 7'd0;    
    else
        cnt <= cnt + 1'b1;

always@(posedge clk_in or negedge rst)
    if (~rst)
        flag <=1'b0;                        //flag低电平时偶数分频
    else if (cnt == switch -1 || cnt == M_N -1)
        flag <= ~flag; 
        
always@(posedge clk_in or negedge rst)
    if (~rst) begin
        cnt_even <='d0;
        cnt_odd <='d0;
    end
    else if (~flag) begin
        if (cnt_even == div_e -1)
            cnt_even <= 'd0;
        else
            cnt_even <= cnt_even + 1'b1;            
    end else begin
        if (cnt_odd == div_o -1)
            cnt_odd <= 'd0;
        else
            cnt_odd <= cnt_odd + 1'b1;   
    end

reg flag_odd1,flag_odd2;
always@(posedge clk_in or negedge rst)
    if (~rst)
        flag_odd1 <= 'd0;
    else if(flag) begin
        if(cnt_odd == div_o/2 || cnt_odd == div_o-1)
            flag_odd1 <= ~flag_odd1; 
    end

always@(negedge clk_in or negedge rst)
    if (~rst)
        flag_odd2 <= 'd0;
    else if(flag) begin    
        if(cnt_odd == div_o/2 || cnt_odd == div_o-1)
            flag_odd2 <= ~flag_odd2;
    end
   
assign clk_out = (~rst)? 1'b0 :
                    ~flag? ((cnt_even <= (div_e >>1) - 1 ) ? 1'b1: 1'b0) : ~(flag_odd2 | flag_odd1);
//*************code***********//
endmodule

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务