FGPA 第11讲 时序逻辑的开始--寄存器
时间:2024.11.18
一、学习内容
1.寄存器
组合逻辑最大的缺点就是会存在竞争冒险问题,这种竞争冒险问题是非常危险的,常常会引起电路的不稳定性和工作时的不确定性,而我们使用时序逻辑就可以极大的避免这种问题,从而使系统更加稳定。
时序逻辑最基本的单元就是寄存器。
寄存器具有存储功能,一般是由 D 触发器构成,由时钟脉冲控制,每个 D 触发器(D Flip
Flop ,DFF)能够存储一位二进制码。
D 触发器的功能为:
在一个脉冲信号(一般为晶振产生的时钟脉冲)上升沿或下降沿的作用下,将信号从输入端 D 送到输出端 Q,如果时钟脉冲的边沿信号未出现,即使输入信号改变,输出信号仍然保持原值,且寄存器拥有复位清零功能,其复位又分为同步复位和异步复位。
区分一个设计是组合逻辑电路还是时序逻辑电路主要是看数据工作是不是在时钟沿下进行的,在 FPGA 的设计中,复杂的电路设计都要用到时序逻辑电路,往往都是以时序逻辑电路为主,组合逻辑为辅的混合逻辑电路。
2.实验目标
前面章节中,我们设计并编写了使用按键控制 LED 灯的工程,在本章节我们同样使用
这个例子,虽然实验效果相同,但本章是使用 D 触发器来进行控制的,和使用组合逻辑的
控制方法有所不同。
当按键未按下时 led 灯处于熄灭状态;当按键被按下时 led 灯被点亮。
3.原理图
由原理图可知,征途 Pro 开发板的按键未按下时为高电平、按下后为低电平;LED 灯则为低电平点亮。

二、实验
1.准备工作
建立文件夹存放工程
2.绘制波形图和模块框图
模块框图
分析端口信号:D 触发器能够正常工
作一定有时钟,每当时钟的“沿(上升沿或下降沿)”来到时我们采集到稳定有效的数
据;其次还需要的就是复位信号,用于让触发器的回到初始状态把数据清零;因为是用按
键控制 led 灯的亮灭,所以输入端我们还需要一个按键控制信号;输出就只有一个控制 led灯的信号,这里我们的输入输出信号都是 1bit 的。


波形图



3.编写代码
同步复位的 D 触发器
module flip_flop
(
//端口列表
input wire sys_clk ,//由板载的晶振传入,频率是50Hz
input wire sys_rst_n ,//复位按键低电平有效,由板载的复位按键输入
input wire key_in ,
output reg led_out
);
//使用always语句进行输出信号的赋值
always@(posedge sys_clk) //时钟的上升沿
if(sys_rst_n == 1'b0)
led_out <= 1'b0;//给输出信号赋初值
// 时序逻辑中赋值语句一定要使用非阻塞赋值
else
led_out <= key_in;
endmodule


异步复位的 D 触发器
//当 always 块中的敏感列表为检测到 sys_clk 上升沿或 sys_rst_n 下降沿时执行下面的语句
always@(posedge sys_clk or negedge sys_rst_n)


4.仿真验证
`timescale 1ns/1ns
module tb_flip_flop();
//定义输入信号,输出信号
reg sys_clk ;
reg sys_rst_n;
reg key_in ;
wire led_out ;
//输入信号的初始化
initial
begin
key_in = 1'b1;
sys_rst_n <= 1'b0;
key_in <= 1'b0;
#20 //延时20ns
sys_rst_n <= 1'b1;//将复位信号拉高
#210
sys_rst_n <= 1'b0;
#40
sys_rst_n <= 1'b1;
end
//模拟系统时钟
always #10 sys_clk = ~sys_clk;
//输入信号
always #20 key_in <= {$random}%2;
//系统函数
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:key_in:%b led_out=%b",$time,key_in,led_out);
end
//模块的实例化
flip_flop flip_flop_inst
(
.sys_clk (sys_clk),
.sys_rst_n(sys_rst_n),
.key_in (key_in),
.led_out (led_out)
);
endmodule

三、实验结果
打印结果

波形图

四、知识点和小技巧
1.D触发器
D 触发器根据复位的不同分为两种,一种是同步复位的 D 触发器,另一种是异步复位的 D 触发器。这两个D触发器主要就是复位有效的条件是“立刻”执行还是等待“沿”再执行的区别。
同步复位的 D 触发器
同步复位的 D 触发器中的“同步”是和工作时钟同步的意思,也就是说,当时钟的上升沿(也可以是下降沿,一般习惯上为上升沿触发)来到时检测到按键的复位操作才有效,否则无效。
如图所示最右边的三根红色的竖线表达的就是这种效果,sys_rst_n 被拉低后 led_out 没有立刻变为 0,而是当 syc_clk 的上升沿到来的时候 led_out 才复位成功,在复位释放的时候也是相同原因。

异步复位的 D 触发器
异步复位的 D 触发器中的“异步”是和工作时钟不同步的意思,也就是说,寄存器的复位不关心时钟的上升沿来不来,只要有检测到按键被按下,就立刻执行复位操作。
如图所示最右边的两根红色的竖线表达了这种效果,sys_rst_n 被拉低后 led_out 立刻变为0,而不是等待 syc_clk 的上升沿到来的时候 led_out 才复位,而在复位释放的时候 led_out不会立刻变为 key_in 的值,因为还要等待时钟上升沿到来到时才能检测到 key_in 的值,此时才将 key_in 的值赋值给 led_out。

相同点:
相比于组合逻辑电路来讲,对于电路中产生的毛刺有着极好的屏蔽作用,如上图中间位置的一组红色竖线所示,是我们模拟在干扰情况下产生的毛刺现象,因为时序电路只有在沿到来时才检测信号是否有效,所以在两个上升沿之间的毛刺都会被自然的过滤掉,可以大大减少毛刺现象产生的干扰,提高了电路中数据的可靠性。
时序电路还有一个特点,就是“延一拍”的效果。上面两个图最左边的一组红色竖线所表达的就是这个现象。key_in 在复位后的第一个时钟的上升沿来到时拉高,我们可以发现此时 led_out 并没有在同一时刻也跟着拉高,而在之前的组合逻辑中输出是在输入变化的同一时刻立刻变化的,因为我们所画的波形图都是基于前仿真的,没有加入门延时的信息,所以很多时候数据的变化都是和时钟直接对齐的。
当表达时序逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据为在该时钟上升沿前一时刻的值;当表达组合逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据为在该时钟上升沿同一时刻的值。
仿真工具在进行 RTL 代码的仿真时也遵循这个规则,我们也可以理解为仿真寄存器是按照建立时间 Tsu(指触发器的时钟信号上升沿到来以前,数据稳定不变的最小时间)最大(一个时
钟周期),保持时间 Th(指触发器的时钟信号上升沿到来以后,数据稳定不变的最小时间)最小(为 0)的理想环境下进行的;而在仿真组合逻辑时因为没有时钟也就没有建立时间和保持时间的概念,所以数据只要有变化就立刻有效。
TIPS:
我们在画波形图的时候一定要记住这个“延一拍”的效果,否则我们绘制的波形图就会和最后的仿真结果不符,也可能会导致最后的逻辑混乱。
更多推荐
所有评论(0)