数字电路设计: FPGA实现倍频

Verilog实现倍频

这篇博客讲怎么用D触发器和异或门组成的倍频器,并用Verilog实现验证;

1. 原理:

CLK时钟要想实现倍频,那么CLK每变化一次,对应的CLK_out就必须变化两次;因此采用D触发器,且CLK的上升沿,下降沿均有效,且均会引起CLK_out两次的变化;因此,需要在加入一个组合逻辑电路,CLK变化时,时序逻辑引起CLK_out从0->1,时序逻辑部分的输出作为输入,通过组合逻辑使CLK_out从1->0, 这样每次CLK变化时,CLK_out都会出现一个短时间的脉冲变化,从而达到倍频效果。

如图,手画了一下,我们将~Q与D相连,那么每次输入时钟信号时, Q都会翻转, Q和CLK通过一个异或门,输出到D触发器的时钟信号上,那么此时CLK的每次变化,都会使D触发器收到一个上升沿,而 Q翻转后又会将异或门的输出变回0,导致CLK每次变化都会在异或门的输出端产生一个脉冲信号,该脉冲信号是CLK的两倍。(也不知道这种电路设计出自哪儿,没找到出处)

2. 代码实现

module double_f(

input clk,

input rst,

output clk_out

);

reg Q;

wire NOR_clk;

always@(posedge NOR_clk or negedge rst)

begin

if(!rst)

Q <= 0;

else

Q <= ~Q; // #0.3 Q <= ~Q,通过加延时可以显示出来波形

end

assign NOR_clk = Q^clk;

assign clk_out = NOR_clk; //clk_out的频率是clk的两倍

endmodule

3.测试(testbench)

module test(

);

reg rst;

reg clk;

wire clk_out;

wire clk_;

wire rst_;

reg Q;

initial

begin

rst = 1;

clk = 0;

#5

rst = 0;

#20

rst = 1;

end

assign clk_ = clk;

assign rst_ = rst;

always #5 clk = ~clk;

double_f f(

.clk(clk_),

.rst(rst_),

.clk_out(clk_out)

);

always@(posedge clk_out or negedge rst) #由于clk_out的脉冲宽度特别小,所以我们用Q来捕获它的上升沿

begin

if(!rst)

Q <= 0;

else

Q <= ~Q;

end

endmodule

仿真波形如图所示:

由于clk_out的脉冲是延时导致的,而一般FPGA的延时很短,因此clk_out的脉冲长度很短,Xilinx仿真结果不显示这么短的脉冲,为了方便观看,clk_out每经历一次上升沿,Q就改变一次,因此Q的频率是clk_out的1/2, 因此由图可知clk_out的频率是clk的两倍.