Verilog - clock divided by 3

Function realization

Simply implement a frequency divider of 3 for the input clock. I believe that frequency division by 2 may be the first module implemented by a FPGA beginner, but there is always a question in my mind, how to realize frequency division by 3? Recently, I accidentally discovered a blog on the Internet that explains the implementation of 3-way frequency division (sorry, I forgot the blog URL), and implemented the 3-way frequency division on Vivado according to its method.

3-way frequency module implementation

The implementation process is simple:

  1. Count 0-2 on the input clock;
  2. Generate a divided-by-3 clock with a duty cycle of 1/3 based on the count value;
  3. A divide-by-3 clock with a duty cycle of 1/3 is delayed by half a clock (using the falling edge of the input clock to trigger the delay);
  4. The divided-by-3 clock with a duty cycle of 1/3 can be ORed with its delayed clock.
    The source code is as follows:
`timescale 1ns / 1ps
//功能:实现输入时钟的1.5倍频
//输入:时钟、复位
//输出:1.5倍频时钟

module top(
    input           clk200M     ,
    input           rst_n       ,
    output          freq3      //3倍频输出信号
);
reg     [1:0]   cnt;
reg             clk_13;
reg             clk_13_r;

//cnt,计数器
always @(posedge clk200M or negedge rst_n) begin
    if(~rst_n)
        cnt <= 2'd0;
    else if(cnt == 2'd2)
        cnt <= 2'd0;
    else 
        cnt <= cnt + 'd1;
end
//clk_13,生成时钟1/3占空比的信号
always @(posedge clk200M or negedge rst_n) begin
    if(~rst_n)
        clk_13 <= 1'b0;
    else if(cnt == 2'd2)
        clk_13 <= 1'b1;
    else 
        clk_13 <= 1'b0;
end
//clk_13_r,延迟半拍clk_13
always @(negedge clk200M or negedge rst_n) begin
    if(~rst_n)
        clk_13_r <= 1'b0;
    else
        clk_13_r <= clk_13;
end
//freq3,生成3倍频信号
assign freq3 = clk_13 | clk_13_r;

endmodule

simulation

Just simulate the input clock and reset signals. No other operations are required. The source code is as follows:

`timescale 1ns / 1ps

module tb_t36;
reg         clk200M     ;
reg         rst_n       ;
wire        freq1_5     ;

top top_inst(
    .clk200M        (       clk200M),
    .rst_n          (       rst_n  ),
    .freq1_5        (       freq1_5) //1.5倍频输出信号
);

initial begin
    clk200M = 1'b0;
    rst_n = 1'b0;
    #100;
    //
    rst_n = 1'b1;

end
//时钟
always #5 clk200M = ~clk200M;
endmodule

The simulation results are shown in the figure.
Insert image description here

Guess you like

Origin blog.csdn.net/family5love/article/details/115182105