HDLBits-Circuits学习小结(四)D触发器(latches and flip-flops)

news/2024/11/25 0:36:10/

目录

  • 1 D触发器基础
    • 1.1 创建D触发器
    • 1.2 D触发器与复位功能
  • 2 D触发器进阶
    • 2.1 创建有特定功能的D触发器
    • 2.2 D锁存器
  • 3 D触发器与门电路的各种操作
    • 3.1 选择器和触发器
    • 3.2 门电路与触发器
    • 3.3 边沿检测(重要)

1 D触发器基础

1.1 创建D触发器

D触发器是一种存储位的电路,并在时钟信号的(通常)上升沿定期进行更新。当使用clocked always block时,D触发器由逻辑合成器创建。
D触发器是“组合逻辑后跟触发器的blob”的最简单形式,其中组合逻辑部分只是一条线。

创建一个D触发器
D

solution:

module top_module (input clk,    // Clocks are used in sequential circuitsinput d,output reg q );//// Use a clocked always block//   copy d to q at every positive edge of clk//   Clocked always blocks should use non-blocking assignmentsalways @(posedge clk) beginq <= d;endendmodule

创建8个D触发器。所有DFF应由clk的上升沿触发。

solution:

module top_module (input clk,input [7:0] d,output [7:0] q
);always  @(posedge clk) beginq <= d;endendmodule

1.2 D触发器与复位功能

创建一个具有高电平同步复位功能的8位D触发器。所有D触发器都由时钟信号clk的上升沿触发。

异步Asynchronous:清零端与时钟无关,复位取决于clr(rst)的上升沿,always @(posedge clk or negedge rst)
同步Synchronous:复位的动作与时钟同步,复位取决于时钟的上升沿并且clr在高位,always @(posedege clk)

solution:

module top_module(input clk,input reset,            // Synchronous resetinput [7:0] d,output [7:0] q
);always @(posedge clk) beginif (reset)q <= 0;elseq <= d;endendmodule

创建具有高电平有效同步复位的8 D触发器。触发器必须重置为0x34而不是零。所有DFF应由clk的下降沿触发。

提示:将寄存器重置为“ 1”有时称为“预设”。

solution:

module top_module(input clk,input reset,input [7:0] d,output [7:0] q
);always @(negedge clk) beginif (reset)q <= 6'h34;elseq <= d;endendmodule

创建一个具有高电平异步复位功能的8位D触发器。所有D触发器都由时钟信号clk的上升沿触发。

同步和异步复位触发器之间唯一的代码差异是灵敏度列表。

solution:

module top_module(input clk,input areset,            // Asynchronous resetinput [7:0] d,output [7:0] q
);always @(posedge clk or posedge areset) beginif (areset)q <= 0;elseq <= d;endendmodule

2 D触发器进阶

2.1 创建有特定功能的D触发器

创建一个16位D触发器。有时候,只修改一组触发器的一部分是大有用处的。字节使能输入控制16个寄存器的每个字节是否应该在那个周期写入。byteena[1]控制高部分字节d[15:8],而byteena[0]控制低部分字节d[7:0]。
resetn是同步的、低电平有效。所有D触发器都由时钟信号clk的上升沿触发。

注意:这里的byteen有多种情况来控制字节的写入。

solution:

module top_module(input clk,input resetn,input [1:0] byteena,input [15:0] d,output [15:0] q
);always @(posedge clk) beginif (~resetn)q <= 0;else if (byteena[1] | byteena[0]) beginif (byteena[1])q[15:8] <= d[15:8];if (byteena[0])q[7:0] <= d[7:0];endendendmodule

2.2 D锁存器

实现下面的电路。
latch
请注意,这是一个锁存器,因此会出现一个“having inferred a latch”的Quartus警告。

关于D触发器、D锁存器的概念,不妨查看这篇文章RS锁存器,D锁存器、D触发器简介。

由这篇文章可以知道,

  • RS锁存器:当R(复位端)=S(置“1”端)=0时,输出保持不变,这保证了RS同时为0(断电)后,电路输出能够保持不变;
  • 由于RS不可能同时变为0(电路时延不可能完全相同),那么就存在先后问题,就会给电路带来不确定性!因为我们不知道是谁先变成0,就更不知道输出会变成什么样!
  • 为了解决RS锁存器带来的问题(RS不能同时为1),在此基础上,添加两个与门和一个非门,即可避免这种情况。升级版电路名字就叫D锁存器。当E端为0的时候,R端也会恒为0,S端则等于D端输入,亦即是此时输出直接等于输入。

提示:

  • 锁存器是电平敏感的(非边沿敏感的)电路,因此在always块中,它们使用电平敏感的敏感度列表。
  • 但是,它们仍然是顺序元素,因此应使用非阻塞分配
  • D锁存器在启用时的作用类似于导线(或同相缓冲器),而在禁用时保留当前值

solution:

module top_module (input d, input ena,output q);always @(*) beginif (ena)q <= d;elseq <= q;endendmodule

实现下面的电路。
q4b

solution:

module top_module(input clk,input d, input ar,   // asynchronous resetoutput q);always @(posedge clk or posedge ar) beginif (ar)q <= 0;elseq <= d;endendmodule

实现下面的电路。
q4c

solution:

module top_module(input clk,input d, input r,   // synchronous resetoutput q);always @(posedge clk) beginif (r)q <= 0;elseq <= d;endendmodule

实现下面的电路:
q4d

module top_module (input clk,input in, output out);always @(posedge clk) beginout <= in ^ out;endendmodule

3 D触发器与门电路的各种操作

3.1 选择器和触发器

我们用3个包含触发器和多路选择器的子模块来实现图中电路。要求我们写出包含一个触发器和一个多路选择器的子模块。

mux_D

module top_module(input clk,input L,input r_in,input q_in,output reg Q);wire temp;assign temp = L ? r_in : q_in;always@(posedge clk) beginQ <= temp;    endendmodule

考虑一个 n-bit 移位寄存器。如上图所示,我们还是实现包含选择器和触发器的部分。

mux_D2

module top_module(input clk,input w, R, E, L,output Q
);wire temp;assign temp = L ? R :(E ? w : Q);always @(posedge clk) beginQ <= temp;endendmodule

3.2 门电路与触发器

如下图所示的状态机,假设D触发器在状态机启动之前初始化为0,实现该电路:

Dm
提示:本题为门电路与触发器的结合,上图包含三个触发器、异或门、与门和或门。只需要注意后两个触发器输出是取反即可。

module top_module(input clk,input x,output z
); reg temp1,temp2,temp3;assign z = ~(temp1 | temp2 | temp3);always @(posedge clk) begintemp1 <= x ^ temp1;temp2 <= x & ~temp2;temp3 <= x | ~temp3;endendmodule

⭐️

JK触发器的真值表如下图所示,仅使用D触发器和门电路来实现该JK触发器。其中Qold是D触发器在时钟上升沿之前的输出。

JK
JK触发器和触发器中最基本的RS触发器结构相似,其区别在于,RS触发器不允许R与S同时为1,而JK触发器允许J与K同时为1。当J与K同时变为1的同时,输出的值状态会反转。也就是说,原来是0的话,变成1;原来是1的话,变成0。 对应表如下:
JK触发器

module top_module (input clk,input j,input k,output Q);always @(posedge clk) begincase ({j,k})2'b00: Q <= Q;2'b01: Q <= 0;2'b10: Q <= 1;2'B11: Q <= ~Q;endcaseendendmodule

3.3 边沿检测(重要)

⭐️ 输入上升沿的检测

对于每个8bit的变量,检测这些信号什么时候从0变为1(类似检测上升沿),输出应该在0到1 变化之后才有值。
下图给我们展示了输入in[1]和输出pedge[1]的时序关系图:

Edgedetect
边沿检测经常用于按键输入检测电路中,按键按下时输入信号 key 变为低电平,按键抬起变为高电平。当输入的信号为理想的高低电平时(不考虑毛刺和抖动),边沿检测就发挥了很重要的作用。

由于输入的信号为一个连续值,我们需要通过时钟进行采样。根据采样定理,采样时钟的频率需要至少为被采信号频率的 2 倍。

module top_module (input clk,input [7:0] in,output [7:0] pedge
);reg [7:0] temp;always @(posedge clk) begintemp <= in;pedge <= ~temp & in; //检测上升沿用in(in由0变为1,temp是0),检测下降沿用~in(in由1变为0,temp是1)endendmodule

⭐️ 输入上升沿、下降沿的检测

对于每个8bit的变量,检测这些信号什么时候从0变为1(类似检测上升沿),输出应该在0到1 变化之后才有值。
下图给我们展示了输入in[1]和输出pedge[1]的时序关系图:

pedge
边沿检测的特性就是两边电平发生了变化,无非是0变1上升沿,1变0下降沿。

module top_module(input clk,input [7:0] in,output [7:0] anyedge
);reg [7:0] temp;always@ (posedge clk) begintemp <= in;anyedge <= temp ^ in; //anyedge <= (~temp & in) | (temp & ~in);endendmodule

🌟 捕获

对于32bit中的每一个变量,当输入信号从一个时钟周期的1变为下一个时钟周期的0时捕获,即我们需要捕获输入信号的下降沿。

其中捕获的意思就是说在寄存器复位之前,输出一直保持为 ‘1’ 。每一个输出bit类似SR触发器:输出信号从1变0发生时会保持一个周期。

输出会在时钟上升沿和reset信号为高时复位。如果上述事件在同一时间发生,reset有更高的优先级。在下图所示的最后4个周期内,reset信号比set信号早一个周期,所以没有冲突发生。

reset
这个图大概是这个意思,out[1]是来捕获in[1]的下降沿的,即输出会在输入的下降沿后的一个周期,变为1,然后一直保持(类似于SR触发器,但是这里输出信号会长期保持)直到复位信号到来。紧接着,复位信号到来,那么输出信号在一个周期后置0,很巧的是,这时输入信号又一次产生了下降沿,于是过一个周期之后,out[1]变为了1。

根据题意,这里我们设置两个过渡的变量,一个用于记录输出捕获的in信号的下降沿,一个类似于前面一个例子中的temp,记录前一个输入的值。

solution:

module top_module (input clk,input reset,input [31:0] in,output [31:0] out
);reg [31:0] temp;wire [31:0] capture;always @(posedge clk) begintemp <= in;endassign capture = temp & ~in;integer i;always @(posedge clk) beginif (reset) out <= 0;else beginfor(i=0;i<=31;i++) beginif(capture[i])out[i] <= 1;//捕获的意思就是说在寄存器复位之前,输出一直保持为‘1’ endendendendmodule

🌟 双边沿检测

设计一个双边沿检测的触发器,时序如下图所示:
dualedge
我们现在对时钟上升沿与下降沿都已经很熟悉了。但是FPGA没有一个同时检测双边沿的触发器,而且always中的敏感列表也不支持(posedge clk or negedge clk)。

本题相当于半个时钟周期上的输入信号的变化都可以检测出来,观察图可以知道q是d延后半个周期的波形,那么也就是说检测出d变化后q将进行翻转,而不是维持不变,本题有两种解题思路,一种是用MUX,一种是用XOR。

module top_module (input clk,input d,output q
);reg q1,q2;assign q = clk ? q1 : q2; //clk是1的话,说明前一阶段clk是上升沿;是0则说明前一阶段是下降沿always @(posedge clk) beginq1 <= d;endalways @(negedge clk) beginq2 <= d;endendmodule

http://www.ppmy.cn/news/877725.html

相关文章

使用CAPL 内置函数 memcpy 和memcmp 处理数组的若干问题

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

c语言定义浮点变量i和j,2012年计算机等级考试二级C语言基础教程:数据类型、变量和运算符...

2012年计算机等级考试二级C语言基础教程:数据类型、变量和运算符 分类:计算机等级 | 更新时间:2016-07-08| 来源:转载 本节首先介绍Turbo C程序的基本组成部分; 然后介绍Turbo C的数据类型、变量类型、变量的初始化和赋值; 最后介绍Turbo C的有关操作。通过本节的学习, 可以…

LWIP的RAW API UDP通信详解(stm32f103---enc28j60)

目录 LWIPLWIP简介LWIP主要特性 ENC28J60ENC28J60简介ENC28J60特点 无操作系统LWIP移植在说移植之前&#xff0c;先说下几个重要的函数功能和数据结构enc28j60.c文件主要结构体*netif*结构体定义&#xff08;netif.h&#xff09;只列出了比较重要的字段 lwip__comm.c文件__lwip…

lwip-2.1.3在STM32F103ZE+ENC28J60有线网卡上无操作系统移植(使用STM32 HAL库)

程序下载链接&#xff1a;百度网盘 请输入提取码&#xff08;提取码&#xff1a;k6tz&#xff09; 【重要说明】 连接方式一&#xff08;推荐&#xff09;&#xff1a; 电脑有线网卡断开&#xff0c;无线网卡连无线路由器&#xff0c;无线网卡配置成自动获取IP地址。 板子的E…

A/D和D/A

从我们学到的知识了解到&#xff0c;我们的单片机是一个典型的数字系统。数字系统只能对输入的数字信号进行处理&#xff0c;其输出信号也是数字信号。但是在工业检测系统和日常生活中的许多物理量都是模拟量&#xff0c;比如温度、长度、压力、速度等等&#xff0c;这些模拟量…

用计算机归零,windows自带的计算器清零快捷键是哪个?

满意答案 a1424440649 2013.01.15 采纳率:44% 等级:12 已帮助:7308人 清零键是esc,我用的Windows7,不知道计算器一样不,你试试... 其他的还有: 按键 功能 Atl+1 切换到标准模式 Alt+2 切换到科学型模式 Alt+3 切换到程序员模式 Alt+4 切换到统计信息模式 Ctrl+E 打开…

模数转换 A/D 与数模转换 D/A介绍

模数转换 A/D 与数模转换 D/A介绍 A/D 和 D/A 的基本概念 A/D 是模拟量到数字量的转换&#xff0c;依靠的是模数转换器(Analog to Digital Converter)&#xff0c;简称ADC。D/A 是数字量到模拟量的转换&#xff0c;依靠的是数模转换器(Digital to Analog Converter)&#xff0c…

《蓝桥杯CT107D单片机竞赛板》:矩阵键盘模块

矩阵键盘模块 实验简介实验原理图实验原理 实验程序显示对应的按键值2 * 2变式矩阵按键实现独立按键2 * 2变式矩阵键盘控制蜂鸣器2 * 2变式矩阵按键控制数码管做加减操作另一种易理解的扫描矩阵按键的方法 实验简介 CT107D单片机开发板上的矩阵键盘控制, 指示灯亮灭&#xff0c…