数字二倍频电路

fengbohan1 发布于 2022-08-29 15933 次阅读


数字二倍频电路

结构框图

数字二倍频.jpg

以异或门为例进行分析。

t0时刻:Q=0;此时clk_o = clk ^ Q = clk ^ 0 = clk;

t1时刻:clk 时钟上升沿来临,传递到寄存器时钟端。clk_o 拉高,寄存器状态更新。Q=1;

t2时刻:Q=1的状态传递到寄存器的时钟端。此时clk 仍然处于高电平状态。clk_o = clk ^ Q = 1 ^1 = 0。clk_o开始拉低。触发器状态不更新。

所以clk_o的高电平持续时间就是t2-t1。

t3时刻:clk 下降沿来临,此时clk_o = clk ^ Q = clk ^ 1 = ~clk; 传递到寄存器时钟端,寄存器检测到上升沿,寄存器状态更新。Q=0;

t4时刻:Q=0的状态传递到寄存器的时钟端。此时clk 仍然处于低电平状态。clk_o = clk ^ Q = 0 ^0 = 0。clk_o开始拉低。触发器状态不更新。

所以clk_o的高电平持续时间就是t4-t3。

实际上clk_o的高电平持续时间就是从寄存器输出经过异或门(同或门)传递到寄存器时钟输入端的延时时间。

Verilog代码

设计代码

`timescale 1ns/1ns

module top
    (
    input     wire clk ,
    input     wire rst_n,

    output    wire clk_o
    );
//*************code***********//
reg q_r=0;
always @(posedge clk_o or negedge rst_n) begin
    if(!rst_n) 
        q_r <= 0;
    else
        q_r <= ~q_r;
end

// 同或门 实现
// assign # 2 clk_o = ~(clk ^ ~q_r);

// 异或门 实现
assign # 2 clk_o = clk ^ q_r;

//*************code***********//
endmodule

仿真代码

`timescale 1ns/1ns
module testbench ();

    localparam T = 10;

    initial begin
        $dumpfile("wave.vcd");
        $dumpvars(0, testbench);
    end

    initial begin
        #(5000*T) $finish(2);
    end

    reg clk = 0;
    always #(T/2) clk = ~clk;

    reg rst_n = 0;
    initial begin
        #(5*T) rst_n = 1;
    end

    reg [1:0] rst_n_r;
    always @(posedge clk or negedge rst_n)begin
        if(!rst_n)
            rst_n_r <= 0;
        else begin
            rst_n_r[0] <= 1;
            rst_n_r[1] <= rst_n_r[0];
        end
    end

top u_top(
    .clk    ( clk    ),
    .rst_n  ( rst_n_r[1]  ),
    .clk_o  ( clk_o  )
);

endmodule

仿真图

截图_选择区域_20220829170305.png

如果不加延时,仿真看不到clk_o的波形。我代码中设置延时2ns。

因为功能仿真中默认延时为零,所以clk_o的高电平持续时间也为零。自然就无法看到对应的波形。