【IC设计】时序逻辑的基础—锁存器、触发器

这篇具有很好参考价值的文章主要介绍了【IC设计】时序逻辑的基础—锁存器、触发器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

组合逻辑&时序逻辑

  • 波形图中,表达时序逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据位在该时钟上升沿前一时刻的值。表达组合逻辑时如果时钟和数据是对齐的,则默认当前时钟沿采集到的数据为该始终上升沿同一时刻的值。
  • 组合逻辑和时序逻辑的区别

主要是看数据工作是不是在时钟沿下进行的。在 FPGA 的设计中,复杂的电路设计都要用到时序逻辑电路,往往都是以时序逻辑电路为主,组合逻辑为辅的混合逻辑电路。

  • 组合逻辑会存在险竞争冒险,会引起电路的不稳定性和工作时的不确定性
  • 时序逻辑最基本的单元就是寄存器,寄存器一般由D触发器构成
  • 时序电路“延一拍”,key_in为高,led_out延迟一拍才变高

寄存器、触发器、锁存器辨析

  • 寄存器(register):用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果,它被广泛的用于各类数字系统和计算机中。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。 工程中的寄存器一般按计算机中字节的位数设计,所以一般有8位寄存器、16位寄存器等 ;

  • 寄存器的应用

a)可以完成数据的并串、串并转换;
b)可以用做显示数据锁存器:许多设备需要显示计数器的记数值,以8421BCD码记数,以七段显示器显示,如果记数速度较高,人眼则无法辨认迅速变化的显示字符。在计数器和译码器之间加入一个锁存器,控制数据的显示时间是常用的方法。
c)用作缓冲器;
d)组成计数器:移位寄存器可以组成移位型计数器,如环形或扭环形计数器。

https://blog.csdn.net/bleauchat/article/details/85312172

D触发器(D Flip Flop,DFF)

  • D触发器的功能:

1、在一个脉冲信号上升沿或下降沿的作用下,将信号从输入端D送到输出端Q,如果时钟脉冲的边沿信号未出现,即使输入信号改变,输出信号仍然保持原值。
2、寄存器拥有复位清零功能,复位分为同步复位和异步复位
3、能够存储一位二进制码

  • D触发器分为两种,一种是同步复位D触发器,一种是异步触发D触发器。
  • 电路符号
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
  • 真值表
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

同步复位D触发器

  • 同步复位D触发器,复位与时钟同步。即时钟上升沿到来时检测到按键的复位操作才有效
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
  • 代码实现
//同步复位D触发器
module filp_flop (
    input   wire    sys_clk,sys_rst_n,
    input   wire    key_in,  
    output  reg     led_out 
);

always @(posedge sys_clk) begin
    if(sys_rst_n == 1'b0) begin //rst低电平时复位,并且大前提是clk为上升沿。
        led_out <= 1'b0;        //sys_clk上升沿到来时,若检测到rst为低电平时复位有效
    end else begin
        led_out <= key_in;
    end 
end

endmodule

异步复位D触发器

  • 异步复位触发器,复位与时钟不同步。寄存器不关心时钟上升沿来不来,只要有按键按下,就立即执行复位操作。但是复位释放时仍需要等到时钟上升沿才能检测到key_in的值 并给led_out
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
  • 代码实现
module dff (    //异步复位
    input   wire    sys_clk,sys_rst_n,
    input   wire    key_in,  
    output  reg     led_out 
);
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0) begin //rst低电平时复位,但是大前提不需要clk为一定上升沿。
        led_out <= 1'b0;        //检测到 sys_rst_n 的下/降沿时立刻复位,不需等待 sys_clk 的上升沿来到后再复位
    end else begin
        led_out <= key_in;
    end 
end
endmodule

标准锁存器

  • 电路符号
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
// ===================================
// Description:
//  Verilog module for general latch 
//====================================

module sirv_gnrl_ltch # (
  parameter DW = 32
) (

  //input               test_mode,
  input               lden, 
  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout
);

reg [DW-1:0] qout_r;

always @ * 
begin : LTCH_PROC
  if (lden == 1'b1)
    qout_r <= dnxt;
end

assign qout = qout_r;

endmodule

标准DFF模块大合集

为什么要使用标准DFF模块

  • 寄存器是数字同步电路中最基本的单元。使用 Verilog 进行数字电路设计时,最常见的
    方式是使用 always 块语法生成寄存器。蜂鸟 E200 处理器核推荐如下原则,本原则来自于严
    谨的工业级开发标准,其要点如下。

对于寄存器避免直接使用 always 块编写,而是应该采用模块化的标准 DFF 模块进
行例化。示例如下所示,一个名为 flg_dfflr 的寄存器,除了时钟(clk)和复位信号(rst_n)
之外,还带有使能信号 flg_ena 和输入(flg_nxt)/输出信号(flg_r)。

 wire flg_r; 
 wire flg_nxt = ~flg_r; 
 wire flg_ena = (ptr_r == ('E203_OITF_DEPTH-1)) & ptr_ena; 
 //此处使用例化 sirv_gnrl_dfflr 的方式实现寄存器,而不是使用显示的 always 块
sirv_gnrl_dfflr #(1) flg_dfflrs(flg_ena, flg_nxt, flg_r, clk, rst_n); 

使用标准 DFF 模块例化的好处包括以下内容。
• 便于全局替换寄存器类型。
• 便于在寄存器中全局插入延迟。
• 明确的 load-enable 使能信号(如下例的 flg_ena)方便综合工具自动插入寄存器级别
的门控时钟以降低动态功耗(参见第 15.1.5 节了解更多此低功耗设计的信息)。
• 便于规避 Verilog 语法 if-else 不能传播不定态的问题,有关此内容可以参考第 5.3.2 节。

标准DFF代码实现

sirv_gnrl_dfflrs //带有 load-enable 使能,带有异步 reset,复位默认值为 1 的寄存器
sirv_gnrl_dfflr //带有 load-enable 使能,带有异步 reset,复位默认值为 0 的寄存器
sirv_gnrl_dffl //带有 load-enable 使能,不带有 reset 的寄存器
sirv_gnrl_dffrs //不带有 load-enable 使能,带有异步 reset,复位默认值为 1 的寄存器
sirv_gnrl_dffr //不带有 load-enable 使能,带有异步 reset,复位默认值为 0 的寄存器
sirv_gnrl_ltch //Latch 锁存器模块

sirv_gnrl_dfflrs, load-enable使能/ 异步reset/ 复位值为1
// =========================================
// Description:
//  Verilog module gnrl DFF with Load-enable and Reset
//  Default reset value is 1
// =========================================
module gnrl_dfflrs #(
    parameter DW = 8
) (
    input               lden,
    input   [DW-1:0]    dnxt,
    output  [DW-1:0]    qout,

    input               clk,
    input               rst_n
);
    
reg [DW-1:0] qout_r ;

always @(posedge clk or negedge rst_n) 
begin: DFFLRS_PORC
    if(rst_n == 1'b0) begin
        qout_r <= {DW{1'b1}};   //  Default reset value is 1
    end
    else if (lden == 1'b1) begin
        qout_r <= #1 dnxt; 
    end
end

assign qout = qout_r;

endmodule
sirv_gnrl_dfflr,load-enable使能/ 异步reset/ 复位值为0
// ===========================================================================
// Description:
//  Verilog module gnrl DFF with Load-enable and Reset
//  Default reset value is 0
// ===========================================================================
module gnrl_dfflr # (
  parameter DW = 8
) (

  input               lden, 
  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout,

  input               clk,
  input               rst_n
);

reg [DW-1:0] qout_r;

always @(posedge clk or negedge rst_n)
begin : DFFLR_PROC
  if (rst_n == 1'b0)
    qout_r <= {DW{1'b0}};   //  Default reset value is 0
  else if (lden == 1'b1)
    qout_r <= #1 dnxt;
end

assign qout = qout_r;   

endmodule
sirv_gnrl_dffl,load-enable使能/ 不带reset
// ===========================================================================
// Description:
//  Verilog module gnrl DFF with Load-enable, no reset 
// ===========================================================================
module gnrl_dffl # (
  parameter DW = 8
) (

  input               lden, 
  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout,

  input               clk 
);

reg [DW-1:0] qout_r;

always @(posedge clk)
begin : DFFL_PROC
  if (lden == 1'b1)         //no reset 
    qout_r <= #1 dnxt;
end

assign qout = qout_r;

endmodule
sirv_gnrl_dffrs,不带load-enable/ 带异步reset/ 复位值为1
// ===========================================================================
// Description:
//  Verilog module gnrl DFF with Reset, no load-enable
//  Default reset value is 1
// ===========================================================================

module gnrl_dffrs # (
  parameter DW = 8
) (

  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout,

  input               clk,
  input               rst_n
);

reg [DW-1:0] qout_r;

always @(posedge clk or negedge rst_n)
begin : DFFRS_PROC
  if (rst_n == 1'b0)
    qout_r <= {DW{1'b1}};       //Default reset value is 1
  else                          //no load-enable
    qout_r <= #1 dnxt;
end

assign qout = qout_r;

endmodule
sirv_gnrl_dffr,不带load-enable/ 带异步reset/ 复位值为0
// ===========================================================================
// Description:
//  Verilog module gnrl DFF with Reset, no load-enable
//  Default reset value is 0
// ===========================================================================
module gnrl_dffr # (
  parameter DW = 8
) (

  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout,

  input               clk,
  input               rst_n
);

reg [DW-1:0] qout_r;

always @(posedge clk or negedge rst_n)
begin : DFFR_PROC
  if (rst_n == 1'b0)
    qout_r <= {DW{1'b0}};       //  Default reset value is 0
  else                  
    qout_r <= #1 dnxt;
end

assign qout = qout_r;

endmodule
sirv_gnrl_ltch,Latch锁存器模块
// ===========================================================================
// Description:
//  Verilog module for general latch 
// ===========================================================================

module sirv_gnrl_ltch # (
  parameter DW = 32
) (

  //input               test_mode,
  input               lden, 
  input      [DW-1:0] dnxt,
  output     [DW-1:0] qout
);

reg [DW-1:0] qout_r;

always @ * 
begin : LTCH_PROC
  if (lden == 1'b1)
    qout_r <= dnxt;
end

//assign qout = test_mode ? dnxt : qout_r;
assign qout = qout_r;

`ifndef FPGA_SOURCE//{
`ifndef DISABLE_SV_ASSERTION//{
//synopsys translate_off
always_comb
begin
  CHECK_THE_X_VALUE:
    assert (lden !== 1'bx) 
    else $fatal ("\n Error: Oops, detected a X value!!! This should never happen. \n");
end

//synopsys translate_on
`endif//}
`endif//}

endmodule

变体

时钟双沿触发器*

构建一个功能类似于双边沿触发触发器的电路:
【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

知识拓展:
DDR在原有的SDRAM的基础上改进而来,SDRAM在一个CLK周期传输一次数据,而DDR在一个CLK周期传输两次数据,分别在上升沿和下降沿各传输一次数据
【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

  • 代码实现:

方法一:

//方法一简单明了,但因为触发器Tc_to_q延时的存在,输出波形会产生glitch(毛刺)
//即p、q的值还没更新,就已经执行了assign q = clk? q1:q2
module top_module (
    input clk,
    input d,
    output q
);

    reg pos_q, neg_q;
    always@(posedge clk)begin pos_q <= d;end
    always@(negedge clk)begin c<= d;end
    assign q = clk ? pos_q : neg_q; 
    
endmodule

方法二:

//推荐使用方法二进行双边检测
//方法二相较于方法一少了使用clk信号进行选择,可以避免产生毛刺,但电路也会复杂
module top_module (
    input clk,
    input d,
    output q
);
    
    reg pos_q,neg_q;
    always@(posedge clk) begin pos_q <= d ^ neg_q; end
    always@(negedge clk) begin neg_q <= d ^ pos_q; end
    assign q = pos_q ^ neg_q;

endmodule

验证结果:
【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

带字节使能的D触发器

创建16个D触发器,有时我们仅需要修改部分触发器中的值。字节使能信号控制当前时钟周期中16个寄存器中哪个字节需被修改。byteena[1]控制高字节d[15:8],而byteena[0]控制低字节d[7:0]。
resetn是一个同步,低电平有效的复位信号。
所有的D触发器由时钟的上升沿触发。

代码实现:

module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output [15:0] q
);

    always@(posedge clk)begin
        if(!resetn)begin
        	q <= 16'd0;
        end else begin
            if(byteena[1] == 1'b1)begin
            	q[15:8] <= d[15:8]; 
        	end 
            if(byteena[0] == 1'b1)begin
            	q[7:0] <= d[7:0];             
            end
        end
    end
endmodule
  • 验证结果
    Synchronous active-low reset
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
    DFF with byte enables
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

JK触发器

纪念Jack Kilby,德仪工程师,诺贝尔物理学奖获得者,发明第一块IC的人
J-K触发器是时钟边沿敏感的基本存储单元。逻辑电路和逻辑符号如下图所示:

【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发文章来源地址https://www.toymoban.com/news/detail-774823.html

  • 真值表
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发
  • 代码
module top_module (
    input clk,
    input j,
    input k,
    output Q); 

    always@(posedge clk) begin
        case({j,k})
            2'b00: Q <= Q;
            2'b01: Q <= 1'b0;
            2'b10: Q <= 1'b1;
            2'b11: Q <= ~Q;
            default: Q <= Q;
        endcase         
    end
    
endmodule
  • 验证结果
    【IC设计】时序逻辑的基础—锁存器、触发器,开发编程,IC_Design,fpga开发

参考链接

  1. 《手把手教你设计CPU.RISC-V处理器》
  2. 锁存器、触发器和寄存器
  3. 触发器详解——(二)JK触发器
  4. 一步一步带你理解DDR基本原理

到了这里,关于【IC设计】时序逻辑的基础—锁存器、触发器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 锁存器&触发器

    目录 一、锁存器(Latch):电平敏感1/0,是数字电路中的一种具有记忆功能的逻辑元件 二、触发器(Flip-Flop,FF):在时钟信号触发时才能动作的储存单元。 2.1 SR触发器:Q*=S+R\\\'Q, SR=0(约束条件)  2.2 JK触发器:Q*=JQ\\\'+K\\\'Q 2.3 T触发器:Q*=TQ\\\'+T\\\'Q 2.4 D触发器:Q*=D  三、触发器与锁

    2024年01月19日
    浏览(47)
  • FPGA之 寄存器、触发器、锁存器

    每个slice有8个存储元素,每个存储元素如下图所示:  其中四个为DFF/LATCH,可以配置为边沿触发D型触发器或电平敏感锁存器输入上图。D输入可以通过AFFMUX, BFFMUX, CFFMUX或DFFMUX的LUT输出直接驱动,也可以通过AX, BX, CX或DX输入绕过函数发生器的 BYPASS slice输入直接驱动。当配置为锁存

    2024年01月18日
    浏览(57)
  • 锁存器、D触发器、寄存器理解

    1、锁存器        锁存器对脉冲的电平敏感,也就是电平触发,在有效的电平下,锁存器处于使能状态,输出随着输入发生变化,此时它不锁存信号,就像一个缓冲器一样;在锁存器没有使能时,则数据被锁住,输入信号不起作用,此时输出一直为锁存的状态信息(锁存最后

    2024年02月09日
    浏览(44)
  • 数字电子技术之锁存器和触发器

    一、组合电路设计的一般步骤:         逻辑抽象=列出真值表=逻辑表达式=逻辑电路图 Notes:         a、可以先对逻辑表达式进行化简得到最简与或式、最简或与式、与非、或非,再对电路进行建模,从而提高电路的运行效率和可读性;         b、最基本的逻辑化简

    2024年02月06日
    浏览(51)
  • verilog学习笔记6——锁存器和触发器

    2023.8.15 信号高电平有效 R :复位端 S :置位端 表达式: Q = S + R\\\' Qn 约束条件:SR=0,也就是SR不能同时为1 信号低电平有效 R :复位端 S :置位端 表达式: Q = S\\\' + R Qn 约束条件:S+R=1,也就是SR不能同时为0 E = 0 :锁存器保持不变,锁住 E = 1 :相当于正常得SR锁存器 把S取反接到

    2024年02月12日
    浏览(46)
  • FPGA结构:LATCH(锁存器)和 FF(触发器)介绍

    如果你想学习有关FPGA的专业术语,可以参考这一篇:FPGA专业术语介绍 一句话概括,能够存储一个状态的数字电路叫做锁存器。 以下是最为基本的一个RS锁存器的具体结构: 以下是它的真值表,其中X表示不确定/无效: R {R} R (清零) S {S} S (置位) Q ( t ) {Q(t)} Q ( t ) (上一时刻的

    2024年01月25日
    浏览(56)
  • FPGA中锁存器(latch)、触发器(flip-flop)以及寄存器(register)详解

    1 定义 1.1 锁存器(latch)     锁存器是一种由电平触发的存储单元,为异步电路,数据存储的动作取决于输入信号的电平值,只要输入发生变化,输出即随之发生变化。 1.2 触发器(flip-flop)     触发器是边沿敏感的存储单元,数据存储的动作由某一信号的上升或者下降

    2024年02月12日
    浏览(42)
  • 传输门、D 锁存器、D触发器、建立时间与保持时间

    在了解setup time和hold time之前,我们应该了解D锁存器 D latch 和 D触发器 DFF 。D锁存器和DFF是由传输门 transmission gate 和反相器 inverters 组成。 The transmission gate is consists of a parallel connection of PMOS NMOS. Two gate voltage of PMOS and NMOS are the complement of each other. The effective resistance of the trans

    2023年04月16日
    浏览(44)
  • 数字世界的积木-从MOS管搭反相器,与非门,锁存器,触发器

    NMOS管的结构示意图和表示符号如图所示,在P型衬底上制作两个掺杂N型区,形成MOS管的源极S 和漏极D ,中间电极称为栅极G,栅极和衬底之间通过SiO2 绝缘层隔开。 下图为NMOS输出特性曲线,采用共源极接法,漏极特性曲线可分为三个工作区,截止区,可变电阻区,饱和区 当

    2024年02月01日
    浏览(43)
  • SR锁存器与D锁存器设计与建模

    ⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。 🔥文章和代码已归档至【Github仓库:hardware-tutorial】,需要的朋友们自取。或者公众号【AISha

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包