题解 | 任意小数分频
奇数分频 偶数分频 均匀版(未适配本题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
查看6道真题和解析

