题解 | #任意小数分频#
任意小数分频
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

