题解 | #任意小数分频#
任意小数分频
https://www.nowcoder.com/practice/24c56c17ebb0472caf2693d5d965eabb
`timescale 1ns/1ns module div_M_N( input wire clk_in, input wire rst, output wire clk_out ); parameter M_N = 8'd87; parameter c89 = 8'd24; // 8/9时钟切换点 parameter div_e = 5'd8; //偶数周期 parameter div_o = 5'd9; //奇数周期 reg [7:0] cyc_cnt; reg [3:0] clk_cnt; reg flag_div ; // 8/9分频标志。当div_flag==0 时是8分频;当div_flag==1时是9分频; reg clk_out_r ; //*************code***********// // cyc_cnt: 对clk_in进行计数,达到M_N后清零。 always@(posedge clk_in or negedge rst)begin if(!rst) cyc_cnt<=0; else if(cyc_cnt==M_N-1) cyc_cnt<=0; else cyc_cnt<=cyc_cnt+1'b1; end // flag_div: 8/9分频标志。当flag_div==0时是8分频;当flag_div==1时是9分频。 cyc_cnt==M_N-1或者cyc_cnt==c89-1 时该标志位翻转 always@(posedge clk_in or negedge rst)begin if(!rst) flag_div <=0; else if(cyc_cnt==M_N-1||cyc_cnt==c89-1) flag_div <=~flag_div ; else flag_div <= flag_div ; end // clk_cnt: 用于产生分频输出。当flag_div==0时,计数最大值是div_e-1;当flag_div==1时,计数最大值是div_o-1 // always@(posedge clk_in or negedge rst)begin // if(!rst) // clk_cnt<=0; // else if(~div_flag) // if(clk_cnt==div_e-1) // clk_cnt<=0; // else // clk_cnt<=clk_cnt+1'b1; // else if(clk_cnt==div_o-1) // clk_cnt<=0; // else // clk_cnt<=clk_cnt+1'b1; // end always@(posedge clk_in or negedge rst) begin if(~rst) clk_cnt <= 0; else if(~flag_div) clk_cnt <= clk_cnt==(div_e-1)? 0: clk_cnt+1; else clk_cnt <= clk_cnt==(div_o-1)? 0: clk_cnt+1; end // clk_out_r。根据clk_cnt和flag_div产生分频输出 always@(posedge clk_in or negedge rst) begin if(~rst) clk_out_r <= 0; else if(clk_cnt==0||clk_cnt==4) clk_out_r <= ~clk_out_r; else clk_out_r <= clk_out_r; end assign clk_out =clk_out_r; //*************code***********// endmodule