使用触发器来构建时钟分隔器
触发器是一种边缘触发的存储电路。在这个项目中,我们将使用Verilog实现一个触发器,并使用几个触发器来创建一个闪烁led的时钟分频器。
内存电路
先决条件
-
是否安装了Xilinx ISE网包。
-
设置FPGA板。
-
能够使用逻辑运算符描述数字电路。
-
能够使用ISIM编写测试台和模拟电路。
-
能够模拟并模拟电路延迟。
软件
-
Xilinx ISE WebPACK.
硬件
D触发器(D-FF)
D触发器(D-FF)是最基本的内存设备之一。D-FF通常具有三个输入:定义下一个状态的数据输入,定时控制
输入触发器准确何时“记住”数据输入,以及可以使存储器重置为“0”的复位输入,无论其他两个输入如何(通常称为异步复位)。下面的图1显示了D-FF的框图。
D触发器(DFF)
过程
1.实施D-FF
在此步骤中,我们将实现具有异步重置的D-FF。
如图1中的框图所示,D触发器有三个输入:数据输入(D),时钟输入(D)CLK.),以及异步复位输入(rst,主动高),和一个输出:数据输出(问)。
模块dff(输入D,输入clk,输入rst,输出Q);
要描述触发器的行为,我们将使用“总是“ 堵塞。与组合电路相反,当发生时钟的上升沿或下降沿或复位被断言时,触发器的输出变化。换句话说,输出Q对时钟信号敏感CLK.和重置信号rst.所以我们可以这样描述电路:总是在上升沿CLK.或升起rst,如果断言rst, Q被驱动到逻辑'0',否则Q被d驱动。在Verilog代码中:
总是@(posedge(CLK.), posedge(rst))开始如果(rst==.1)问<=1“b0;别的问<=D;结束
因此,D-FF的最终Verilog实现如下:
`timescale 1ns./1 ps模块dff(输入D,输入clk,输入rst,输出Q);总是@(posedge(CLK.), posedge(rst))开始如果(rst==.1)问<=1“b0;别的问<=D;结束endmodule
时钟分频器
需要时钟信号,以使电路运行。通常,时钟信号来自晶体振荡器车载。Digilent FPGA板上使用的振荡器通常为50兆赫到100年兆赫;然而,一些外围控制器不需要这样的高频率来操作。
有一个简单的电路,可以将时钟频率划分一半。电路如图2所示
认为CLKDIV最初是很高的。作为喧嚣反转信号clkdiv,喧嚣最初低。当时钟的第一个上升沿到达时,CLKDIV由当前更新喧嚣值和更改为'0'。一旦CLKDIV改变“0”,喧嚣将通过逆变器拉到逻辑'1'。当下一个上升沿CLK.发生,CLKDIV将改为逻辑'1'和喧嚣在变频器的传播延迟后会恢复为“0”。图2中的电路的波形。在右侧示出了上面的图2。结果,期间CLKDIV(两个相邻上升边之间的时间)的周期加倍CLK.(即,频率CLKDIV是CLK.频率)。
用这个电路,我们实际上可以通过级联前一个电路来分割时钟,如下图3所示:
每个阶段将频率除以2。假设第一级的输入时钟频率是100兆赫(1,000,000Hz)。在第一阶段之后,频率变为$ \ FRAC {100MHz} {2} = 50 MHz $。在第二阶段之后,频率变为$ \ FRAC {100MHz} {2.2} \ = 25 MHz $。在N阶段之后,频率变得:
$$ \ FRAC {100MHz} {\ underBrace {2 \ CDot 2 \ CDot \ LDots \ CDot 2} _ \ text {n}} = \ frac {100,000,000} {2 ^ n} hz $$
2.实现时钟分配器闪烁LED
时钟分压器的框图如图4所示。我们从触发器中命名内部的电线CLKDIV和连接到D-FF DIN的输入的电线。每个频率CLKDIV以红色显示。
在这个图中,我们需要两个输入:车载时钟输入CLK.,以及作为复位信号的按钮rst.我们有一个输出来闪烁引领,所以让我们称之为领导.
模块clk_divider(输入时钟,输入第一,输出led);
我们需要声明我们要使用的所有内部电线。
线[26:0]喧嚣;线[26:0]CLKDIV;
我们需要实例化27个触发器和27个逆变器,以将时钟频率除以$2^27$到0.745Hz。要用逆变器实例化第一个触发器,Verilog代码应该如下所示:
dff dff_inst0.(.clk(CLK.)首要,(rst), .D(喧嚣[0]), q(CLKDIV[0]));
对于其余的26个flip-flop,您可以复制上面的代码26次,并更改每个端口将映射到的内部线路的名称。但是,我们也可以使用生成语句为在Verilog中为我们生成代码。通过观察图3所示的框图,从第二个触发器开始,rstD-FF端口始终连接到信号RST。如果端口D连接到信号DIN [i],然后CLK.端口连接到clkdiv(张)和Q端口连接到clkdiv[我].因此,我们可以生成26 D-FF,如下所示:
Genvar I;生成(i = 1; i <27; i = i + 1)开始:dff_gen_label dff dff dff_inst(.clk(clkdiv [i-1]),.rst(rst),.d(din [i]),。q(clkdiv [i]));结束终止;
我们可以使用相同的生成语句实例化27个逆变器,或者通过观察连接,总线喧嚣实际上是公共汽车的逆CLKDIV.因此,我们可以简单地写一个赋值语句,而不是写生成语句:
分配喧嚣=~ clkdiv;
将最后一级触发器的输出连接到领导.
分配了=CLKDIV[26];
所以设计的Verilog文件应该如下:
`timescale 1ns./1PS模块CLK_DIVIDER.(输入时钟,输入第一,输出led);线[26:0]喧嚣;线[26:0]CLKDIV;dff dff_inst0.(.clk(CLK.)首要,(rst), .D(喧嚣[0]), q(CLKDIV[0]));genvar我;生成为(我=1;我<27;我=我+1)开始:dff_gen_label dff dff_inst(.clk(CLKDIV[我-1])首要,(rst), .D(喧嚣[我]), q(CLKDIV[我]));结束终止;分配喧嚣=~ clkdiv;分配了=CLKDIV[26];endmodule
3.刺激电路,实现,并在车上测试
就像我们在以前的项目中设计的组合电路一样,您可以起草一个测试台,在芯片上实现之前对电路进行测试。然而,在这个测试台上,我们需要模拟时钟信号和第一个信号。时钟信号实际上是一个不断振荡的信号。以Nexys 3为例,输入时钟频率为100兆赫,即时钟的周期为10纳秒。周期的一半高,周期的一半低。换句话说,每半个周期,这里是5纳秒,时钟就会翻转。为了模拟时钟信号,我们将使用always语句,而不是将它放在initialize语句中。
`timescale 1ns./1ps ... reg clk;总是#5 CLK = ~ CLK;
在初始化块中,我们将初始化CLK.信号到0并保持rst高10ns重置时钟分频器。因此,Verilog测试台将如下所示:
`timescale 1ns./1PS模块TB.;//输入reg clk.;reg rst;//输出线领导;//实例化测试的单位(uut)clk_divider uut(.clk(CLK.)首要,(rst), .led(领导));总是#5 CLK = ~ CLK;最初的开始//初始化输入CLK.=0;rst=1;#10 rst = 0;//等待100.ns.为全球重置来完成# 100;结束endmodule
仿真波形如下图5所示。你可以在波形中看到clkdiv [0]是频率的一半吗CLK.,这clkdiv [1]是频率的一半吗clkdiv [2].
现在,您可以创建一个UCF文件,将CLK映射到LASOL上的全局时钟,RST到按钮,并导致载体引领.如果您的董事会有100件兆赫时钟,你可以看到引领每1.45秒闪烁一次。
挑战
既然您已完成此项目,请尝试这些修改:
-
你可以添加两个交换机来控制如何快引领如果switch[1:0]为0,引领闪烁频率为0.745赫兹;如果开关[1:0]是1,引领闪烁频率为1.49赫兹;如果开关[1:0]是2,引领闪烁频率为2.98赫兹;如果开关[1:0]是3,引领闪烁频率为5.96赫兹.