zl程序教程

您现在的位置是:首页 >  其它

当前栏目

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

实现 设计 FPGA
2023-09-11 14:20:40 时间

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的两倍.