题解 | 任意小数分频
小数分频重点:
1、硬件无法识别小数,故8.7分频可按照87/10的方式处理,即87个原时钟周期分成10个新时钟周期
2、这样新时钟周期每个里面含有8.7个原时钟周期,8<8.7<9,故将87个再次分为8*x+9*y个周期【无法保证均匀就尽可能接近】
3、x=3; y=7
4、单数分频处理方式:如本题9分频,同第二点一样,无法均匀就尽可能接近,分成4高5低或者4低5高都行
以上~
本题思路:
1、需区分当前需8分还是9分,所以需要一个【flag】,以及判断flag反转的计数器【cnt】;
2、8分频/9分频需要一个反转信号,需要一个计数器【cnt89】作为反转条件吧;
3、题中给的输入时wire型,需新增一个reg型【clkout】;
`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; //奇数周期 //*************code***********// reg [6:0] cnt ; reg flag; reg [3:0] cnt_89; reg clkout; 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; else if (cnt == c89 -1 || cnt == M_N -1) flag <= ~flag; always@(posedge clk_in or negedge rst) if (~rst) cnt_89 <='d0; else if (~flag) begin if (cnt_89 == div_e -1) cnt_89 <= 'd0; else cnt_89 <= cnt_89 + 1'b1; end else begin if (cnt_89 == div_o -1) cnt_89 <= 'd0; else cnt_89 <= cnt_89 + 1'b1; end always@(posedge clk_in or negedge rst) if (~rst) clkout <=1'b0; else if (~flag) begin if (cnt_89 == (div_e >>1) | cnt_89 == 'd0) clkout <= ~clkout; end else begin if (cnt_89 == ((div_o -1'b1)>>1 ) | cnt_89 == 'd0) clkout <= ~clkout; end assign clk_out = clkout; //*************code***********// endmodule