【Verilog】 同步复位和异步复位比较
|
同步复位 sync |
异步复位 async |
特点 |
复位信号只有在时钟上升沿到来时才能有效。 |
无论时钟沿是否到来,只要复位信号有效,就进行复位。 |
Verilog描述 |
always@(posedge CLK) |
always@(posedge CLK , negedge Rst_n) |
优点 |
1) 利于仿真器仿真。 2) 因为只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。 3) 可以使所设计的系统成为100%的同步时序电路,有利于时序分析。 |
1) 设计相对简单。 2) 因为大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。 3) 异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR。 |
缺点 |
1) 复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。
2) 由于大多数的逻辑器件的目标库内的DFF都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。 |
1) 复位信号容易受到毛刺的影响。
2) 在复位信号释放(release)的时候容易出现问题。具体就是说:若复位释放刚好在时钟有效沿附近时,很容易使寄存器输出出现亚稳态,从而导致亚稳态。 |
总结 |
推荐使用异步复位,同步释放的方式,而且复位信号低电平有效。 |
相关讨论:
1、同步电路和异步电路的区别是什么?
异步电路主要是组合逻辑电路,用于产生地址译码器、FIFO或RAM的读写控制信号脉冲,但它同时也用在时序电路中,此时它没有统一的时钟,状态变化的时刻是不稳定的,通常输入信号只在电路处于稳定状态时才发生变化。也就是说一个时刻允许一个输入发生变化,以避免输入信号之间造成的竞争冒险。电路的稳定需要有可靠的建立时间和保持时间,待下面介绍。
同步电路是由时序电路(寄存器和各种触发器)和组合逻辑电路构成的电路,其所有操作都是在严格的时钟控制下完成的。这些时序电路共享同一个时钟CLK,而所有的状态变化都是在时钟的上升沿(或下降沿)完成的。比如D触发器,当上升延到来时,寄存器把D端的电平传到Q输出端。
在同步电路设计中一般采用D触发器,异步电路设计中一般采用Latch。
2、什么是同步逻辑和异步逻辑?
同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。
电路设计可分类为同步电路和异步电路设计。同步电路利用时钟脉冲使其子系统同步运作,而异步电路不使用时钟脉冲做同步,其子系统是使用特殊的“开始”和“完成”信号使之同步。由于异步电路具有下列优点--无时钟歪斜问题、低电源消耗、平均效能而非最差效能、模块性、可组合和可复用性--因此近年来对异步电路研究增加快速,论文发表数以倍增,而Intel Pentium 4处理器设计,也开始采用异步电路设计。
异步电路主要是组合逻辑电路,用于产生地址译码器、FIFO或RAM的读写控制信号脉冲,其逻辑输出与任何时钟信号都没有关系,译码输出产生的毛刺通常是可以监控的。同步电路是由时序电路(寄存器和各种触发器)和组合逻辑电路构成的电路,其所有操作都是在严格的时钟控制下完成的。这些时序电路共享同一个时钟CLK,而所有的状态变化都是在时钟的上升沿(或下降沿)完成的。
3、什么是"线与"逻辑,要实现它,在硬件特性上有什么具体要求?
线与逻辑是两个输出信号相连可以实现与的功能。在硬件上,要用oc门来实现(漏极或者集电极开路),由于不用oc门可能使灌电流过大,而烧坏逻辑门,同时在输出端口应加一个上拉电阻。(线或则是下拉电阻)
4、什么是Setup 和Holdup时间?
5、setup和holdup时间,区别.
6、解释setup time和hold time的定义和在时钟信号延迟时的变化。
7、解释setup和hold timeviolation,画图说明,并说明解决办法。
时间(Setup Time)和保持时间(Hold time)。建立时间是指在时钟边沿前,数据信号需要保持不变的时间。保持时间是指时钟跳变边沿后数据信号需要保持不变的时间。如果不满足建立和保持时间的话,那么DFF将不能正确地采样到数据,将会出现metastability的情况。如果数据信号在时钟沿触发前后持续的时间均超过建立和保持时间,那么超过量就分别被称为建立时间裕量和保持时间裕量。
8、说说对数字逻辑中的竞争和冒险的理解,并举例说明竞争和冒险怎样消除。
9、什么是竞争与冒险现象?怎样判断?如何消除?
在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决方法:一是添加布尔式的(冗余)消去项,但是不能避免功能冒险,二是在芯片外部加电容。三是增加选通电路
在组合逻辑中,由于多少输入信号变化先后不同、信号传输的路径不同,或是各种器件延迟时间不同(这种现象称为竞争)都有可能造成输出波形产生不应有的尖脉冲(俗称毛刺),这种现象成为冒险。
10、你知道那些常用逻辑电平?TTL与COMS电平可以直接互连吗?
常用逻辑电平:TTL、CMOS、LVTTL、LVCMOS、ECL(Emitter Coupled Logic)、PECL(Pseudo/PositiveEmitter Coupled Logic)、LVDS(Low Voltage Differential Signaling)、GTL(GunningTransceiver Logic)、BTL(Backplane Transceiver Logic)、ETL(enhancedtransceiver logic)、GTLP(Gunning Transceiver Logic Plus);RS232、RS422、RS485(12V,5V,3.3V);TTL和CMOS不可以直接互连,由于TTL是在0.3-3.6V之间,而CMOS则是有在12V的有在5V的。CMOS输出接到TTL是可以直接互连。TTL接到CMOS需要在输出端口加一上拉电阻接到5V或者12V。
cmos的高低电平分别为:Vih>=0.7VDD,Vil<=0.3VDD;Voh>=0.9VDD,Vol<=0.1VDD.
ttl的为:Vih>=2.0v,Vil<=0.8v;Voh>=2.4v,Vol<=0.4v.
用cmos可直接驱动ttl;加上拉电阻后,ttl可驱动cmos.
1、当TTL电路驱动COMS电路时,如果TTL电路输出的高电平低于COMS电路的最低高电平(一般为3.5V),这时就需要在TTL的输出端接上拉电阻,以提高输出高电平的值。
2、OC门电路必须加上拉电阻,以提高输出的搞电平值。
3、为加大输出引脚的驱动能力,有的单片机管脚上也常使用上拉电阻。
4、在COMS芯片上,为了防止静电造成损坏,不用的管脚不能悬空,一般接上拉电阻产生降低输入阻抗,提供泄荷通路。
5、芯片的管脚加上拉电阻来提高输出电平,从而提高芯片输入信号的噪声容限增强抗干扰能力。
6、提高总线的抗电磁干扰能力。管脚悬空就比较容易接受外界的电磁干扰。
7、长线传输中电阻不匹配容易引起反射波干扰,加上下拉电阻是电阻匹配,有效的抑制反射波干扰。
上拉电阻阻值的选择原则包括:
1、从节约功耗及芯片的灌电流能力考虑应当足够大;电阻大,电流小。
2、从确保足够的驱动电流考虑应当足够小;电阻小,电流大。
3、对于高速电路,过大的上拉电阻可能边沿变平缓。综合考虑
以上三点,通常在1k到10k之间选取。对下拉电阻也有类似道理
//OC门电路必须加上拉电阻,以提高输出的搞电平值。
OC门电路要输出“1”时才需要加上拉电阻不加根本就没有高电平
在有时我们用OC门作驱动(例如控制一个LED)灌电流工作时就可以不加上拉电阻
OC门可以实现“线与”运算
OC门就是 集电极开路输出
总之加上拉电阻能够提高驱动能力。
11、如何解决亚稳态。?
亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平上。在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。
解决方法:
1降低系统时钟频率
2用反应更快的FF
3引入同步机制,防止亚稳态传播
4改善时钟质量,用边沿变化快速的时钟信号
关键是器件使用比较好的工艺和时钟周期的裕量要大。亚稳态寄存用d只是一个办法,有时候通过not,buf等都能达到信号过滤的效果
12、IC设计中同步复位与异步复位的区别。
同步复位在时钟沿采复位信号,完成复位动作。异步复位不管时钟,只要复位信号满足条件,就完成复位动作。异步复位对复位信号要求比较高,不能有毛刺,如果其与时钟关系不确定,也可能出现亚稳态。
13、MOORE 与 MEELEY状态机的特征。
Moore状态机的输出仅与当前状态值有关,且只在时钟边沿到来时才会有状态变化. Mealy状态机的输出不仅与当前状态值有关,而且与当前输入值有关,这
14、多时域设计中,如何处理信号跨时域。
不同的时钟域之间信号通信时需要进行同步处理,这样可以防止新时钟域中第一级触发器的亚稳态信号对下级逻辑造成影响,其中对于单个控制信号可以用两级同步器,如电平、边沿检测和脉冲,对多位信号可以用FIFO,双口RAM,握手信号等。
跨时域的信号要经过同步器同步,防止亚稳态传播。例如:时钟域1中的一个信号,要送到时钟域2,那么在这个信号送到时钟域2之前,要先经过时钟域2的同步器同步后,才能进入时钟域2。这个同步器就是两级d触发器,其时钟为时钟域2的时钟。这样做是怕时钟域1中的这个信号,可能不满足时钟域2中触发器的建立保持时间,而产生亚稳态,因为它们之间没有必然关系,是异步的。这样做只能防止亚稳态传播,但不能保证采进来的数据的正确性。所以通常只同步很少位数的信号。比如控制信号,或地址。当同步的是地址时,一般该地址应采用格雷码,因为格雷码每次只变一位,相当于每次只有一个同步器在起作用,这样可以降低出错概率,象异步FIFO的设计中,比较读写地址的大小时,就是用这种方法。如果两个时钟域之间传送大量的数据,可以用异步FIFO来解决问题。
我们可以在跨越Clock Domain时加上一个低电平使能的LockupLatch以确保Timing能正确无误。
Verilog里的同步复位与异步复位(转)
1.同步复位(SynchronousReset)
来看一个简单的同步复位的D触发器,Verilog代码如下:
module d_ff (clk, rst_n, datain,> else
dataout <= datain;
end
endmodule
综合后的RTL图表如下:
Altera的MAXII系列的CPLD中,register没有同步复位资源,所以同步复位信号需要通过额外的逻辑电路实现,
同步复位的优点:
1). 抗干扰性高,可以剔除复位信号中周期短于时钟周期的毛刺;
2). 有利于静态时序分析工具的分析;
3). 有利于基于周期的仿真工具的仿真。
同步复位缺点:
1). 占用更多的逻辑资源;
2). 对复位信号的脉冲宽度有要求,必须大于指定的时钟周期,由于线路上的延迟,可能需要多个时钟周期的复位脉冲宽度,且很难保证复位信号到达各个寄存器的时序;
3). 同步复位依赖于时钟,如果电路中的时钟信号出现问题,无法完成复位。
2. 异步复位(Asynchronous Reset)
来看一个简单的异步复位的D触发器,Verilog代码如下:
module prac ( clk, rst_n, datain, dataout );
input clk;
input rst_n;
input datain;
output dataout;
reg dataout;
always @(posedge> else
dataout <= datain;
end
endmodule
综合后的RTL图表如下:
异步复位的优点:
1). 无需额外的逻辑资源,实现简单,而且CPLD有针对复位信号的全局不限资源,可以保证复位管脚到各个寄存器的clock skew最小(注意不是到各个寄存器的延迟最小);
2). 复位信号不依赖于时钟。
同步复位缺点:
1). 复位信号容易受到外界的干扰;
2). 复位信号释放的随机性,可能导致时序违规,使电路处于亚稳态,如下图。
3. 异步复位同步释放(Asynchronous Reset Synchronous Release)
这种复位方式在文献中还有一种称谓:SynchronizedAsynchronous Reset,这种称谓应该在国外的技术人员中比较流行,与Altera的工程师交流过程中,他们一直使用Synchronized AsynchronousReset这种称谓(当然也可能是个人的习惯)。
来看一个SynchronizedAsynchronous Reset例子,Verilog代码如下:
module prac ( clk, reset_n, dataa, datab, outa, outb );
input clk;
input reset_n;
input dataa;
input datab;
output outa;
output outb;
reg reg1;
reg reg2;
reg reg3;
reg reg4;
assign outa => assign rst_n = reg4;
always @(posedge> reg4 <= 1'b0;
end
else
begin
reg3 <= 1'b1;
reg4 <= reg3;
end
end
always @ (posedge> reg2 <= 1'b0;
end
else
begin
reg1 <=> end
end
endmodule
综合后的RTL图表如下:
此文来源于《Implementationand Timing of Reset Circuits in Altera FPGAs》,例子程序可能代码与源代码略有出入,RTL图是用QuartusII 8.1综合的,与原文也有出入。
异步复位、同步释放
FPGA设计中常见的复位方式即同步复位和异步复位。在深入探讨亚稳态这个概念之前, 很多人并没有对所谓的同步复位和异步复位有太多的注意,而在实践中充分感受了亚稳态的危害之后,回过头来细细品味《Verilog HDL设计与验证》一书中关于复位的章节,可谓受益匪浅。
在以前的代码里大多使用的是异步复位。
一个简单的异步复位的例子
always @ (posedge clk or negedgerst_n)
if(!rst_n)b <= 1'b0;
elseb <= a;
我们可以看到FPGA的寄存器都有一个异步的清零端(CLR),在异步复位的设计中这个端口一般就是接低电平有效的复位信号rst_n。即使说你的设计中是高电平复位,那么实际综合后会把你的复位信号反向后接这个CLR端。
一个简单的同步复位的例子
always @ (posedge clk)
if(!rst_n)b <= 1'b0;
elseb <= a;
和异步复位相比,同步复位没有用上寄存器的CLR端口,综合出来的实际电路只是把复位信号rst_n作为了输入逻辑的使能信号。那么,这样的同步复位势必会额外增加FPGA内部的资源消耗。
那么同步复位和异步复位到底孰优孰劣呢?
只能说,各有优缺点。同步复位的好在于它只在时钟信号clk的上升沿触发进行系统是否复位的判断,这降低了亚稳态出现的概率;它的不好上面也说了,在于它需要消耗更多的器件资源,这是我们不希望看到的。FPGA的寄存器有支持异步复位专用的端口,采用异步复位的端口无需额外增加器件资源的消耗,但是异步复位也存在着隐患,特权同学过去从没有意识到也没有见识过。异步时钟域的亚稳态问题同样的存在与异步复位信号和系统时钟信号之间。
再看下面一个两级寄存器异步复位的例子
always @ (posedge clk or negedgerst_n)
if(!rst_n)b <= 1'b0;
elseb <= a;
always @ (posedge clk or negedgerst_n)
if(!rst_n)c <= 1'b0;
elsec <= b;
正常情况下,clk的上升沿c更新为b,b更新为a。一旦进入复位,b,c都清零;但是我们不能确定复位信号rst_n会在什么时候结束。如果结束于b_reg0和c_reg0的{launch edge –stup,launchedge+hold}时间只外,那么一切都会正常。但如果恰恰相反,会出现什么情况呢? rst_n的上升变化出现在了clk上升的建立保持时间上,此时clk检测到的rst_n的状态就会是一个亚稳态(是0是1不确定)。从代码里我们看到如果此时b_reg0和c_reg0认为rst_n为0,那么依然保持复位清零,而如果认为rst_n为1,那么就跳出复位。因为此时的rst_n的不确定性,就可能出现4种情况,即b_reg0和c_reg0都复位或者都跳出复位,再或者一个复位一个跳出复位。那么后者就会造成了系统工作不同步的问题,在这个简单的两级异步复位实例中这种危害表现的并不明显,但是我们试想一个大的工程项目里众多的寄存器出现如此情况又会是如何一番景象呢?
上面的分析似乎都让人意识到同步复位和异步复位都不可靠,那么如何将两者结合,取长补短呢。
异步复位、同步释放
always @ (posedge clk)
rst_nr<= rst_n; //现将异步复位信号用同步时钟打一拍
always @ (posedge clk or negedgerst_nr)
if(!rst_nr)b <= 1'b0;
elseb <= a;
always @ (posedge clk or negedgerst_nr)
if(!rst_nr)c <= 1'b0;
elsec <= b;
如此一来,既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。
另外特权同学请教过IC设计部一位资深专家,他们在设计中常用的复位方式和上面的方法类似,大体如下:
VHDL与Verilog中的同步和异步复位
这两种复位方式的区别主要看是否需要时钟的参与:异步复位不需要时钟的参与,只要复位信号一有效就立即执行复位操作;同步信号需要时钟参与,只有当时钟有效沿来时,复位信号才有效。
同步复位的最大好处是有效防止复位信号的毛刺引起的误复位操作,只要毛刺不在时钟有效沿附近出现,就不会影响电路正常工作;而若是异步复位,其复位信号的毛刺会立即引起电路复位。
异步复位可以在没有时钟的情况下完成复位,所以可以使电路在上电的时候完成对系统的复位,而且异步复位所消耗的资源比同步复位少。一般的,只要能保证复位信号的稳定,我们建议使用异步复位。
我们看一下同步和异步复位在VHDL和Verilog下的实现细节:
VHDL:
PROCESS(clk,reset)—同步复位
BEGIN
If(rising_edge(clk)) then
If(reset=’1’) then—复位信号在时钟有效沿下进行判断
--执行复位操作
End if;
End if;
END
PROCESS(clk,reset)—异步复位
BEGIN
If(reset=’1’) then—复位信号在不需要在时钟有效沿下进行判断
--执行复位操作
elsif(rising_edge(clk)) then
……….
End if;
END
Verilog:
always @ (posedge clk or posedge reset)//异步复位,在敏感信号里加复位信号
if(reset)
begin
//执行复位操作
end
else
begin
……
end
always @ (posedgeclk)//同步复位,在敏感信号不用加复位信号
if(reset)
begin
//执行复位操作
end
else
begin
……
End
同步复位和异步复位的比较
各自的优缺点:
1、总的来说,同步复位的优点大概有3条:
a、有利于仿真器的仿真。
b、可以使所设计的系统成为100%的同步时序电路,这便大大有利于时序分析,而且综合出来的fmax一般较高。
c、因为他只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。他的缺点也有不少,主要有以下几条:
a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。
b、由于大多数的逻辑器件的目标库内的DFF都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。
2、对于异步复位来说,他的优点也有三条,都是相对应的
a、大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。
b、设计相对简单。
c、异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR。
缺点:
a、在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
b、复位信号容易受到毛刺的影响。
三、总结:
所以说,一般都推荐使用异步复位,同步释放的方式,而且复位信号低电平有效。这样就可以两全其美了。
推荐的复位方式
所谓推荐的复位方式就是上文中所说的:“异步复位,同步释放”。这就结合了双方面的优点,很好的克服了异步复位的缺点(因为异步复位的问题主要出现在复位信号释放的时候,具体原因可见上文)。
其实做起来也并不难,我推荐一种我经常使用的方式吧:那就是在异步复位键后加上一个所谓的“reset synchronizer”,这样就可以使异步复位信号同步化,然后,再用经过处理的复位信号去作用系统,就可以保证比较稳定了。reset sychronizer的Verilog代码如下:
moduleReset_Synchronizer(output reg rst_n, input clk, asyncrst_n);
reg rff1;
always @ (posedge clk ,negedge asyncrst_n) begin
if (!asyncrst_n) {rst_n,rff1}<= 2'b0;
else {rst_n,rff1} <={rff1,1'b1};
end
endmodule
大家可以看到,这就是一个dff,异步复位信号直接接在它的异步复位端口上(低电平有效),然后数据输入端rff1一直为高电平‘1’。倘若异步复位信号有效的话,触发器就会复位,输出为低,从而复位后继系统。但是,又由于这属于时钟沿触发,当复位信号释放时,触发器的输出要延迟一个时钟周期才能恢复成‘1’,因此使得复位信号的释放与时钟沿同步化。 此外,还有一种方法更为直接,就是直接在异步复位信号后加一个D触发器,然后用D触发器的输出作为后级系统的复位信号,也能达到相同的效果。这里就不多说了。
3:多时钟系统中复位的处理方法)
这是一个很实际的问题,因为在较大型的系统中,一个时钟驱动信号显然不能满足要求,一定会根据系统的要求用多个同源时钟(当然也可以是非同源了)去驱动系统的不同部分。那么在这样的多时钟系统中,复位键怎么设置?它的稳定与否直接关系到了整个系统的稳定性,因此要格外注意(在我看来,复位信号在同步时序系统中的地位和时钟信号一样重要)。下面就说一下具体的处理方法,当然所遵循的原则就仍应该是上文的“异步复位,同步释放”:
1.non-coordinated resetremoval:顾名思义,就是同一个系统中的多个同源时钟域的复位信号,由彼此独立的“reset synchronizer”驱动。当异步复位信号有效时,各时钟域同时复位,但是复位释放的时间由各自的驱动时钟决定,也是就说:时钟快的先释放,时钟慢的后释放,但是各复位信号之间没有先后关系。
2.sequence coordinated resetremoval:这是相对于上述方式来说的,也就是说各时钟域的复位信号彼此相关,各个部分系统虽然也同时复位,但是却分级释放。而分级的顺序可由各个“reset synchronizer”的级联方式决定。可以先复位前级,再复位后级,也可以反过来。反正方式很灵活,需要根据实际需要而定。由于图片上传问题,我只能用程序表示了,大家凑或看吧,哈哈
例子:三级复位系统,系统中的时钟分别为1M,2M,11M:
第一级Reset_Sychronizer程序:
moduleReset_Synchronizer(output reg rst_n, input clk, asyncrst_n);
reg rff1;
always @ (posedge clk , negedge asyncrst_n)
begin
if (!asyncrst_n) {rst_n,rff1}<= 2'b0;
else {rst_n,rff1} <={rff1,1'b1};
end
endmodule
第2,3级的Reset_Sychronizer程序:
moduleReset_Synchronizer2(output reg rst_n, input clk, asyncrst_n,d);
reg rff1;
always @ (posedge clk ,negedge asyncrst_n) begin
if (!asyncrst_n) {rst_n,rff1}<= 2'b0;
else {rst_n,rff1} <={rff1,d};
end
endmodule
顶层模块的源程序:
include"Reset_Synchronizer.v"
include"Reset_Synchronizer2.v"
moduleAsynRstTree_Trans
(input Clk1M,Clk2M,Clk11M,SysRst_n, output SysRst1M_n,SysRst2M_n,SysRst11M_n);
Reset_SynchronizerRst1M(.clk(Clk1M),. asyncrst_n(SysRst_n),.rst_n(SysRst1M_n));
Reset_Synchronizer2Rst2M(.clk(Clk2M),.d(SysRst1M_n),.asyncrst_n(SysRst_n),.rst_n(SysRst2M_n));
Reset_Synchronizer2Rst11M(.clk(Clk11M),.d(SysRst2M_n),. asyncrst_n(SysRst_n),.rst_n(SysRst11M_n));
Endmodule