Virtual machine: VMware -14.0.0.24051
Environment: ubuntu 18.04.1 Script
: makefile ( click to go )
Utility: vcs and verdi
Article directory
1. Demand
The module can realize frequency division by 2-15 times any number, and the duty cycle of the clock obtained after frequency division can be adjusted in integer cycles.
Even frequency division takes FDC = 8 frequency division as an example ( FDC分频系数
), using the rising edge of the clock to count, the maximum count value is 8 (0~8, the counter needs 4 bits, 0 means that there is no clock edge coming, 8 means that there are already 8 The clock edge is coming), the adjustable duty cycle is 1/8x100%, 2/8x100%...;
Odd frequency division adopts double edge detection, taking FDC = 3 frequency division as an example, the maximum count value is 6, adjustable The duty cycle is 1/6, 2/6….
2. Timing
三、Design and Functional Verification
(1)RTL
//-- modified by xlinxdu, 2022/04/26
module div
#(
parameter FDC = 10,
parameter TOG_CNT = 5
)(
input clk ,
input rst_n ,
output reg clk_div
);
reg [3:0] cnt;
reg [4:0] cnt_odd;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 4'b0;
end
else if((FDC%2 == 0) && (cnt < FDC))begin
cnt <= cnt + 1'b1;
end
else if(FDC%2 == 0) begin
cnt <= 4'b1;
end
end
always @(*) begin
if((FDC%2 == 0) && (cnt <= TOG_CNT))begin
clk_div = 1'b1;
end
else if((FDC%2 == 0) && (cnt > TOG_CNT))begin
clk_div = 1'b0;
end
end
always @(posedge clk or negedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_odd <= 5'b0;
end
else if((FDC%2 ) && (cnt_odd < 2*FDC))begin
cnt_odd <= cnt_odd + 1'b1;
end
else if(FDC%2 ) begin
cnt_odd <= 5'b1;
end
end
always @(*) begin
if((FDC%2) && (cnt_odd <= TOG_CNT))begin
clk_div = 1'b1;
end
else if((FDC%2) && (cnt_odd > TOG_CNT))begin
clk_div = 1'b0;
end
end
endmodule
(2)Test Bench
//-- modified by xlinxdu, 2022/04/26
`timescale 1ns/1ns
module tb_div;
reg clk;
reg rst_n;
wire clk_div;
initial begin
clk = 0;
rst_n = 1;
#10 rst_n = 0;
#10 rst_n = 1;
end
always #100 clk = ~clk;
div #(8,4) tb_div (
.clk(clk),
.rst_n(rst_n),
.clk_div(clk_div)
);
initial begin
$fsdbDumpfile("div.fsdb");
$fsdbDumpvars ;
$fsdbDumpMDA ;
#10000 $finish ;
end
endmodule
4. Result
The following test takes 8 frequency division, 50% duty cycle; 3 frequency division, 50% duty cycle as an example. Change the division factor and duty cycle by passing parameters through the test case.
(1) Divide by 8 (50%, #(8,4))
(2) Divide by 3 (50%, #(3,3))
- Result: The test waveform is the same as the timing, the data path is correct, and the functional verification is passed.
Notice: Pay attention to the calculation of the transfer value of the duty cycle when the frequency is oddly divided.
Author: xlinxdu
Copyright: This article is the original author, and the copyright belongs to the author.
Reprinting: Reprinting is prohibited without the permission of the author. Reprinting must retain this statement, and a link to the original text must be given in the article.