数字二倍频电路
结构框图
以异或门为例进行分析。
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
仿真图
如果不加延时,仿真看不到clk_o的波形。我代码中设置延时2ns。
因为功能仿真中默认延时为零,所以clk_o的高电平持续时间也为零。自然就无法看到对应的波形。