二分频比较简单,其实就是在系统时钟触发沿到来后,直接让输出取反即可;
三分频属于奇数分频,有1:1占空比和非对称占空比之分。
1.假设为偶数分频,则利用计数器累积到(N/2-1)时,将输出值取反,并将计数器清零即可实现;
2.假设为奇数分频,则分别将上升沿和下降沿在计数到((N-1)/2)的时候将输出值取反相或在输出即可。
具体如下:
module div_3(
input clk,
input rst,
output clk_out3,
output clk_out2
);
reg [1:0] step1,step2;
reg clk_out2_r=0;
always@(negedge clk) begin //下降沿时计时取反
if(rst) begin
step1<=2'b00;
clk_out2_r<=0;
end
else begin
clk_out2_r<=~clk_out2_r;//二分频关键点,当时钟上升沿到来后,使输出取反一次即可;
case(step1)
2'b00: step1<=2'b01;
2'b01: step1<=2'b10;
2'b10: step1<=2'b00;
default: step1<=2'b00;
endcase
end
end
always@(posedge clk) begin //上升沿时计时取反
if(rst) begin
step2<=2'b00;
end
else begin
case(step2)
2'b00: step2<=2'b01;
2'b01: step2<=2'b10;
2'b10: step2<=2'b00;
default: step2<=2'b00;
endcase
end
end
assign clk_out3=step1[0] | step2[0]; //三分频输出
assign clk_out2=clk_out2_r; //二分频输出
testbench:
module div_3_test;
reg clk;
reg rst;
wire clk_out3;
wire clk_out2;
initial begin
clk=0;
rst=0;
end
always #10 clk=~clk;
always #1000 rst=~rst;
div_3 div_3_0(
.clk(clk),
.rst(rst),
.clk_out3(clk_out3),
.clk_out2(clk_out2)
);
endmodule
仿真波形:
可以看到三分频的一个周期对应了时钟CLK的三个周期,二分频的一个周期对应了时钟CLK的两个时钟周期。且都是50%的占空比。
可以看到仿真波形的三分频和二分频的时钟与系统时钟相差180度,其实可以在testbench里面将CLK的初始值设为1,然后在上升沿时在将二分频的输出值取反即可,如下: