admin 管理员组

文章数量: 887021

数字电路

先从图片解释一下:

  Tsu(建立时间):触发器的时钟信号触发沿到来以前,数据稳定不变的时间。若建立时间太短,数据将不能在这个时钟触发沿被稳定输入触发器,

  Th(保持时间) :触发器的时钟信号触发沿到来以后,数据稳定不变的时间。同上。

  Tco(输出时间):触发器的时钟信号触发沿到来至稳定输出输出所需时间。

  Tmet(决断时间):亚稳态输出恢复到稳定状态输出中除去Tco的时间。当振荡结束回到稳定状态时为“0”或者“1”,这个是随机的。

  恢复时间:异步信号的变化与下一触发沿离得太近(左),本来应该在Tsu前恢复无效但没有,反而进入了Tsu,就可能使影响下一触发沿的变化结果。(亚稳态)

  去除时间:异步信号的变化与本次触发沿离得太近(右),本来应该在Th后恢复无效但没有,反而在Th内就发生了变化,就可能使影响本次触发沿的变化结果。(亚稳态)


  原因:从图可以看出来,如果data在Tsu和Th时间内不断变化(非定值),导致触发器在触发沿时不知道应该输出高电平还是低电平,输出端处于不确定状态,这便是亚稳态,当输出端恢复稳定之后,这个输出值是随机的,与输入没有逻辑关系。

  场合:复位信号(任意时间点到达寄存器),跨时钟域信号传输(时钟相移未知),异步信号检测等......

 

   后果:Q端输出在稳定下来之前可能是毛刺、振荡、固定的某一电压值。导致与其相连其他数字部件将其作出不同的判断,有的判断到“1”有的判断到“0”,有的也进入了亚稳态。

    →复位失败/跨时钟传输数据错误

   应用:实际的FPGA电路设计中,需考虑:减少亚稳态对系统的影响,减少亚稳态发生几率,亚稳态串扰的概率问题。

        常用FPGA器件的Tsu+Th约等于1ns(这解释了为什么我们写testbench时,为什么要等 ‘201ns’ 后才让reset拉低,就是避免亚稳态,使得复位信号失效)

       亚稳态产生的概率:P = (Tsu+Th)/ Tclk  

       措施:①降低系统时钟频率,提高Tclk 。②更换Tsu+Th更小的fpga器件(工艺更好)。  从而P ↓ 。

        ③引入同步机制,减少异步信号。④用边沿变化快速的时钟信号。

  消除亚稳态:

    ①异步信号:

      待补充...

    ②跨时钟域传输:采用FIFO来作为中间缓冲

      待补充...

    ③复位信号:异步复位,同步释放

         待补充...

  •  边沿检测的设计中,有两种情况可能检测不到:

    ①reset有效周期<时钟周期,且没有在触发沿有效。

    ②亚稳态输出错误,且只用一个寄存器的d端和q端来判断有无变化沿。

解决方法:

    ①减少时钟周期(可能会产生亚稳态),或修改reset的设置。(一般实际应用中reset的持续时间不会这么短,所以不会出现这种情况)

    ②对输入的数据先用两位的寄存器接收(消除亚稳态),再用边沿检测器检测。(或者直接用三位寄存器接收并检测) 

input data ;//打两拍
reg [1:0]data_receive;
always@(posedge clk)
data_receive = {datareceive[0],data};reg [1:0]edge_detector;
always@(posedge clk)
edge_detector = { edge_detector[1] , receive_data[0] } ;wire pose_dge,nege_edge ;
assign pose_edge = (edge_detector == 2'b 01) ? 1 : 0 ;
assign nege_edge = (edge_detector == 2'b 10) ? 1 : 0 ;
input data ;//三位寄存器reg [2:0]edge_detector;
always@(posedge clk)
edge_detector = { edge_detector[1:0] ,data  } ;wire pose_dge,nege_edge ;
assign pose_edge = (edge_detector[2:1] == 2'b 01) ? 1 : 0 ;
assign nege_edge = (edge_detector[2:1] == 2'b 10) ? 1 : 0 ;
  •  复位信号

1.异步复位:always@(posedge clk or negedge reset)

2.同步复位:把异步信号用寄存器同步化(即使复位信号在clk到来时才变化,跟电路其他模块一样)如下:模块化了 。后面设计时例化这个模块,就可以得到一个时钟同步的复位信号,会比原来输入的复位信号延迟两个周期。

  module Synchronize_reset( clk, reset, Reset);input clk;input reset;output Reset;reg regit;always@(posedge clk)beginregit <= reset ;Reset <= regit ;endendmodule

其实也就是连接两个寄存器来解决。

注意:好的设计都会对异步信号进行同步处理,同步一般采用N级D触发器级联处理,第一级寄存器产生亚稳态后,第二级寄存器稳定输出概率为90%,第三极寄存器稳定输出的概率为99%,以此来防止亚稳态串扰(即亚稳态一直传递下去),至于稳定输出的结果是否正确不得而知。

 

  

本文标签: 数字电路