FPGA同步和异步的区别
推荐的复位方式:异步复位、同步释放
描述代码及对应的RTL电路:
HDL源代码 对应的RTL电路
module Rst_Circuit(
Rst_n,
Clk,
D,
Q
);
input Rst_n;
input Clk;
input D;
output Q;
reg Rst_Reg_n;
reg Q;
always @(posedge Clk)
begin
//将异步复位信号先用Clk同步一下
Rst_Reg_n <= Rst_n;
end
//如果没有加"or negedge
Rst_Reg_n",将变成同步复位
always @(posedge Clk or negedge
Rst_Reg_n)
begin
if (~Rst_Reg_n)
begin
Q <= 1'd0;
end
else
begin
Q <= D;
end
end
endmodule
注:最好在模块外面将异步复位信号同步好,再送至各模块,这样各个模块内部就不需要再分别单独
同步了。 下面具体阐述一下同步、异步复位的区别,以及为什么要采用这种方式的原因。复位电路是每个数字逻辑
电路中最重要的组成部分之一。
复位电路有两个工作目的:1、 仿真的时候使电路进入初始状态或者其它预知状态;
2、 对于综合实现的真实电路,通过复位使电路进入初始状态或者其它预知状态。
一般来说,逻辑电路的任何一个寄存器、存储器结构和其它逻辑单元都必须要附加复位逻辑电路,以
保证电路能够从错误状态中恢复,可靠地工作。
常用的复位信号为低电平有效信号,在应用时外部引脚接上上拉电阻,这样能增加复位电路的抗干扰
性能。
复位方式大致分为两类,即同步复位和异步复位。这两异步复位 种复位方式各有优缺点,其应用场合也各不相同。同步复位
所谓异步复位是指当复位信号有效
沿到达时,无论时钟沿是否有效,都会
立即对目标(如寄存器、RAM等)复位。 所谓同步复位是指当复位信号发生变化时,并不立刻生异步复位的应用要点如下: 效,只有当有效时钟沿采样到已变化的复位信号后,才对所
有寄存器复位。同步复位的应用要点如下: , 指定异步复位时,只需
always的敏感
中加, 指定同步复位时,always的敏感表中仅有时入复位信号的有效沿钟沿信号,仅仅当时钟沿采到同步复位的即可,当复位信号有有效电平时,才会在时钟沿到达时刻进行效沿到达时,无论时复位操作。 钟沿是否有效,复位
都会立即发挥其功
能。 module Rst_Circuit( module Rst_Circuit(
Rst_n,
Clk, Rst_n,
D, Clk,
Q D,
); Q
input Rst_n; ); input Clk; input Rst_n; input D; input Clk;
output Q; input D;
reg Q; output Q;
always @(posedge Clk) //同步复位 reg Q;
begin //如果没有写"or
if (~Rst_n) negedge Rst_n",将变成同步
begin 复位
Q <= 1'd0; always @(posedge Clk or
end negedge Rst_n)
else begin
begin if (~Rst_n)
Q <= D; begin
end Q <=
end 1'd0;
endmodule end
else
begin
Q <=
D;
end
end
endmodule
, 如果目标器件或可用库中的触发器本身包含
同步复位端口,则在实现同步复位电路时
可以直接调用同步复位端。然后很多目标, 大多数目标器件(如器件(如PLD)和ASIC 库的触发器本身FPGA和CPLD)和并不包含同步复位端口,这样复位信号与ASIC库的触发器都输入信号组成某种组合逻辑(比如复位低包含异步复位端口,电平有效,只需复位与输入信号相与即异步复位会被直接接可),然后将其输入到寄存器的输入端。为到触发器的异步复位了提高复位电路的优先级,一般在电路描端口,如图所示: 述时使用带有优先级的if...else结构,复位
电路在第一个if下描述,其它电路在else
或else...if分支中描述。
同步复位的优点如下: 异步复位的优点如下: , 同步复位利于基于周期机制的仿真器进行仿, 由于多数目标器件(如
真; FPGA和CPLD)和
ASIC库的触发器都, 使用同步复位可以
100%的同步时序电
路,有利于时序分析,其综合结果的频率包含异步复位端口,
往往较高; 异步复位会节约逻辑
资源; , 同步复位仅在时钟的有效沿生效,可以有效
地避免因复位电路毛刺造成的亚稳态和错, 异步复位设计简单;
误。同步复位在进行复位和释放复位信号, 对于大多数FPGA,都
时,都是仅当时钟沿采到复位信号电平变有专用的全局异步复
化时才进行相关操作,如果复位信号树的位/置位资源(GSR,
组合逻辑出现了某种毛刺,此时时钟沿采Global Set Reset),
样到毛刺的概率非常低,这样通过时钟沿使用GSR资源,异步
采样,可以十分有效地过滤复位电路组合复位到达所有寄存器
逻辑产生的毛刺,增强了电路稳定性。 的偏斜(skew)最小。
同步复位的缺点如下:
, 很多目标器件(如FPGA和CPLD)和ASIC
库的触发器本身并不包含同步复位端口,
使用同步复位会增加更多逻辑资源;
, 同步复位的最大问
在于必须保证复位信号
的有效时间足够长,这样才能保证所有触
发器都能有效地复位。由于同步复位仅当
时钟沿采样到复位信号时才会进行复位操
作,所以其信号的持续时间起码要大于设
计的最长时钟周期,以保证所有时钟的有异步复位的缺点如下:
效沿都能采样到同步复位信号。事实上,
仅仅保证同步复位信号的持续时间大于最, 异步复位的作用和释放
慢的时钟周期还是不够的,设计中还要考与时钟沿没有直接关
虑到同步复位信号树通过所有相关组合逻系,异步复位生效时
辑路径时的延时,以及由于时钟布线产生问题并不明显;但是
的偏斜(skew)。这样,只有同步复位大于当释放异步复位时,
时钟最大周期,加上同步信号穿过的组合如果异步复位信号释
逻辑路径延时,再加上时钟偏斜延时,才放时间和时钟的有效
能保证同步复位可靠、彻底。如图所示,沿到达时间几乎一
假设同步复位逻辑树组合逻辑的延时为致,则容易造成触发
t1,复位信号传播路径的最大延时为t2,最器输出为亚稳态,形
慢时钟的周期为Period_max,时钟的skew成逻辑错误;
为Clk2-Clk1,则同步复位的周期Tsyn_rst, 如果异步复位逻辑树的
组合逻辑产生了毛应该满足如下公式:
刺,则毛刺的有效沿
Tsyn_rst > Period_max + (Clk2 – Clk1) + t1 + t2 会使触发器误复位,
造成逻辑错误。
推荐的复位电路设计方式是异步复位、同步释放。这种方式,可以有效地继承异步复位设计简单的优
势,并克服异步复位的上述风险和缺陷。在FPGA和CPLD等可编程逻辑器件设计中,使用异步复位、同
步释放可以节约器件资源,并获得稳定可靠的复位效果。
reg Rst_Reg_n;
reg Q;
always @(posedge Clk)
begin
Rst_Reg_n <= Rst_n; //将异步复位信号先用Clk同步一下
end
always @(posedge Clk or negedge Rst_Reg_n) //如果没有写"or negedge
Rst_Reg_n",将变成同步复位
begin
if (~Rst_Reg_n)
begin
Q <= 1'd0;
end
else
begin
Q <= D;
end
end
这里使用时钟将外部输入的异步复位信号寄存一个节拍后,再送到触发器异步复位端口的设计
的另一个好处在于,做STA(静态时序分析)分析时,时序工具会自动检查同步后的异步复位信号和时钟的到达(Recovery)/撤销(Removal)时间关系,如果因布线造成的skew导致该到达/撤销时间不能满足,
STA工具会上报该路径,帮助设计者进一步分析问题,如图所示:
我们常常听人说,要写出风格好的verilog代码。但是,究竟什么是风格好的verilog代码呢,当我认真思考这个问题的时候,我才发现,原来我只是懂verilog的语法而已,而真正的FPGA设计,还没有入门。
在写verilog的时候,我们常常会时序逻辑中加入异步复位,以期在复位时,可以将各寄存器的值复位到我们所期望的初始状态。这看似简单的代码中,其实也有很多学问。比如说这样一段代码: always@(negedge Vld_LinkClk)
begin
if(!TokenValid)
begin
DataRev8_Cnt <= 2'b00;
DataRev8_NegE[0] <= 8'h0;
DataRev8_NegE[1] <= 8'h0;
DataRev8_NegE[2] <= 8'h0;
DataRev8_NegE[3] <= 8'h0;
end
else
begin
DataRev8_Cnt <= DataRev8_Cnt + 1'b1;
DataRev8_NegE[DataRev8_Cnt] <= LinkData;
end
end
本段代码截选自本人一个项目中,并作了少量修改。可以看到TokenValid是复位信号。这段代码的功能是TokenValid为低时将这些寄存器清零,TokenValid为高时每个时钟周期DataRev8_Cnt自增,并将LinkData赋给DataRev8_NegE[DataRev8_Cnt]。
细心的看官可能会发现,在本always块中,每感事件列表中只有Vld_LinkClk,而没有TokenValid。所以,此时TokenValid只能称为同步复位信号,因为只有在Vld_LinkClk下降沿时,才有可能发生复位。
这样做好不好呢,我觉得不好,这就要从Altera的FPGA的LE结构说起了。
从cyclone 2手册上抄了一个LE的结构图下来:
可以发现,LE主要由1个触发器和1个四输入查找表组成,外加一些逻辑。
由LE的内部结构可以看出,它含有一个异步清零端和一个异步置位端。当然,从图上还可以看出,它还有同步清零和置位的逻辑(Synchronous Load and Clear Logic),这部分逻辑是组合逻辑电路。
好,介绍清楚了LE的内部结构,下面看一下上面的代码所综合出来的RTL电路,我只截选RTL
电路中DataRev8_Cnt的部分:
可以看出,复位清零的逻辑是通过一个双路选通器MUX21来完成的,当TokenValid为0时,DATAB选通输出至OUT0。
我们知道,FPGA设计中应该尽量减少组合逻辑,因为它们加了延时,并且这个延时是EDA工具难以预知的,如上图中,DATAA到OUT0这段存在延时,限制了Vld_LinkClk的提升(如果不理解为什么延时会限制Vld_LinkClk的提升,可以看一下FPGA中时序分析的基础)。
此时的时序分析结果如下图:
可以看出,Vld_LinkClk最快可以跑到165.78M,本设计的另一个时钟Sys_Clk最快可以跑到161.92M。
好,现在将同步复位改为异步复位,即把敏感事件列表中加入TokenValid:
always@(negedge Vld_LinkClk or negedge TokenValid)
这样修改后,RTL电路中DataRev8_Cnt的部分如下:
可以看出,双路选通器MUX21不见了,TokenValid直接接到了触发器的异步复位端上,完成异步复位功能。这样在数据线上就没有了组合逻辑部分,可以在一定程序上提高时钟频率上限。
此时的时序分析结果如下图:
可以看出,Vld_LinkClk最快可以跑到167M,本设计的另一个时钟Sys_Clk最快可以跑到226.96M。
Vld_LinkClk提高了一点点,而另一个时钟Sys_Clk提高了非常多。
另外,在异步复位中,复位时给寄存器所赋的值也是有讲究的。例如,将DataRev8_NegE[0]初始值赋为0xAA。
if(!TokenValid)
begin
DataRev8_Cnt <= 2'b00;
DataRev8_NegE[0] <= 8'hAA;
DataRev8_NegE[1] <= 8'h0;
DataRev8_NegE[2] <= 8'h0;
DataRev8_NegE[3] <= 8'h0;
end
此时的RTL中,复位信号连到了DataRev8_NegE[0]中初始化为0的位所对应的寄存器的清零端,初始化为1的位所对应的寄存器的置位端。
综合后的结果中,Vld_LinkClk最快可以跑到136M,另一个时钟Sys_Clk最快可以跑到226.91M。
可见,这样做会影响Vld_LinkClk。这其中的原因我还不知道,希望有人能够给出答案。
在进行初始化时,尽量初始化为0,异步复位。这样可以达到最优化的结果。
如果在复位中,不是对寄存器赋值,而是对RAM块或其它模块赋值,就需要考虑这个模块是否具有异步复位或置位端,如果有,OK。如果没有,那么就会生成许多组合逻辑电路,完成复位的功能,这将会影响逻辑最高可以跑的速度。
所以,加什么复位,加不加复位,一定要看清楚底层的结构,这将极大地改善设计的性能。这对FPGA设计者提出了一个较PC软件开发者、嵌入式开发者更为高的要求。
1.同步复位(Synchronous Reset)
来看一个简单的同步复位的D触发器,Verilog代码如下:
module d_ff (
clk,
rst_n,
datain,
dataout
);
input clk;
input rst_n;
input datain;
ouput dataout;
reg dataout;
always @ (posedge clk)
begin
if (!rst_n)
dataout <= 1'b0;
else
dataout <= datain;
end
endmodule
综合后的RTL图表如下:
Altera的MAXII系列的CPLD中,register没有同步复位资源,所以同步复位信号需要通过额外的逻辑电路实现,上面的例子,QuartusII软件自带的综合工具使用选择器实现了同步功能,但是这不是确定的,有的综合工具综合成与门,如下图:
同步复位的优点:
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 clk or negedge rst_n)
begin
if (!rst_n)
dataout <= 1'b0;
else
dataout <= datain;
end
endmodule
综合后的RTL图表如下:
异步复位的优点:
1). 无需额外的逻辑资源,实现简单,而且CPLD有针对复位信号的全局不限资源,可以保证复位管脚到各个寄存器的clock skew最小(注意不是到各个寄存器的延迟最小); 2). 复位信号不依赖于时钟。
同步复位缺点:
1). 复位信号容易受到外界的干扰;
2). 复位信号释放的随机性,可能导致时序违规,使电路处于亚稳态,如下图。
3. 异步复位同步释放(Asynchronous Reset Synchronous Release)
这种复位方式在文献中还有一种称谓:Synchronized Asynchronous Reset,这种称谓应该
在国外的技术人员中比较流行,与Altera的
师交流过程中,他们一直使用Synchronized
Asynchronous Reset这种称谓(当然也可能是个人的习惯)。 来看一个Synchronized Asynchronous 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 = reg1;
assign outb = reg2;
assign rst_n = reg4;
always @ (posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
reg3 <= 1'b0;
reg4 <= 1'b0;
end
else
begin
reg3 <= 1'b1;
reg4 <= reg3;
end
end
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
reg1 <= 1'b0;
reg2 <= 1'b0;
end
else
begin
reg1 <= dataa;
reg2 <= datab;
end
end
endmodule
综合后的RTL图表如下:
此文来源于《Implementation and Timing of Reset Circuits in Altera FPGAs》,例子程序可能代码与源代码略有出入,RTL图是用QuartusII 8.1综合的,与原文也有出入。 一、特点:
同步复位:顾名思义,同步复位就是指复位信号只有在时钟上升沿到来时,才能有效。否则,无法完成对系统的复位工作。用Verilog描述如下:
always @ (posedge clk) begin
if (!Rst_n)
...
end
异步复位:它是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。用Verilog描述如下:
always @ (posedge clk,negedge Rst_n) begin if (!Rst_n)
...
end
二、各自的优缺点:
1、总的来说,同步复位的优点大概有3条:
a、有利于仿真器的仿真。
b、可以使所设计的系统成为100%的同步时序电路,这便大大有利于时序分析,而且综合出来的fmax一般较高。
c、因为他只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。 他的缺点也有不少,主要有以下几条:
a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。
b、由于大多数的逻辑器件的目标库内的DFF都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。
2、对于异步复位来说,他的优点也有三条,都是相对应的:
a、大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。
b、设计相对简单。
c、异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR。
缺点:
a、在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
b、复位信号容易受到毛刺的影响。
三、总结:
所以说,一般都推荐使用异步复位,同步释放的方式,而且复位信号低电平有效。这样就可以两全其美了。
以前从来没有对FPGA的复位可靠性关注过,想当然的认为应该不会有什么问题。当问题真正出在复位上的时候,才又仔细地对FPGA的复位深入的了解了一下。首先我们用的复位管脚不是FPGA的全局管脚,并且复位信号上没有上拉电阻,容易受到干扰而产生毛刺,这对异步复位是相当有害的。其次,我在FPGA内部对复位的处理过于简单。
今天在网上看了一些资料,很多是关于同步和异步复位的优缺点比较。由于我在FPGA内部用的是异步复位,所以主要看了一下异步复位的缺点:1)复位信号在时钟有效沿或其
附近释放时,容易使寄存器或触发器进入亚稳态;2)容易受到毛刺的影响;3)难以仿真,难以进行静态时序分析。上面的前两条应该对我来说是影响最重要的,而第三条说老实话,我还没有到哪个阶层(嘿嘿)
异步复位,同步释放——就可以消除上面的前两条缺点。所谓异步复位,同步释放就是在复位信号到来的时候不受时钟信号的同步,而是在复位信号释放的时候受到时钟信号的同步。通过一个复位信号综合器就可以实现异步复位,同步释放。下面是一个复位信号综合器的VHDL描述:
Designer: skycanny
-- Date:2007-1-27
-- Discription: Reset Synthesizer Library ieee;
Use ieee.std_logic_1164.all;
Entity Rst_Synth is
Port
(
Clk : in std_logic;
Arst : in std_logic;
Rst_n : out std_logic );
End entity Rst_Synth;
Architecture RTL of Rst_Synth is Signal dff : std_logic; Begin
Process(Arst ,Clk )
Begin
If Arst = ‘0 then
Dff <= ‘0’;
Rst_n <= ‘0’;
Elsif Clk’envent and Clk = ‘1’ then
Dff <= ‘1’;
Rst_n <= Dff; End if;
End process;
End RTL;
使用复位信号综合器可以很好地将同步和异步复位的优点结合起来,而消除他们缺点。因此在FPGA/CPLD的逻辑设计中可以很好的提高复位的可靠性,从而保证电路工作的稳定可靠性。
re:关于FPGA复位可靠性的一些体会 2007-7-6 17:44:45 Ben 个人理解,补充一下,其实这里也是用到了用两级触发器来完成异步时钟域转换的问题,对于异步复位信号,它和时钟之间是一个异步的关系,时钟很可能找不到它的上升沿,因此容易造成亚稳态。
怎么办呢,用老方法,两级触发器。
第一级,(尽管异步,还是要采集的),采集异步复位信号的高电平,检测到高电平后给出1。(之所以不用这一个结果作为内部的复位信号,就是考虑到1级触发器是不解决问题的,
可能就是个亚稳态信号)
第二级,把第一级的结果用clk打一排,这样就避免了亚稳态。
绕来绕去还是亚稳态呀^_^
同步复位与异步复位的区别
在可编程芯片的内部,信号传输时需要时间的,即异步复位信号rst到达寄存器A和寄存器B的时间存在差异,而时钟信号因为有专用的线路不受影响;寄存器A B受到同步复位信号rst_syn时必须在时钟沿处采发生变化,这样对系统不会造成危害;而受到异步复位rst时,寄存器A B的输出马上发生改变,因为异步复位信号rst到达寄存器A和寄存器B的时间存在诧异所以A B的输出也不是同时变化的,更重要的是他们不再时钟沿上变化,这样后续逻辑可能会收到错误的结果,从而造成系统不稳定;总之,在同步设计中尽量不要使用异步逻辑。