在学习和使用FPGA过程中, 我们会经常使用复位信号(RESET),复位信号可以帮助FPGA的相关逻辑回到一个初始状态,代码中有同步复位和异步复位的情况,本节我们对同步复位和异步复位的异同,机理以及时序电路建模做一些研究。表1对同步复位和异步复位做了简单的比较,文中后续部分对同步复位和异步复位的逻辑建模进行比较详细的描述。
常用复位信号约定:reset 一般是高电平有效; rst_n一般是低电平有效。
1. 同步复位与异步复位的异同
同步复位与异步复位的异同见表1.
表1
| 同步复位(sync) | 异步复位(async) | |
|---|---|---|
| 使用方式 | 在时钟的上升沿/下降沿时采集 | 无论时钟处于哪种情况,甚至没有时钟的情况下,都能产生复位 |
| Verilog语法 | always @ (posedge clk) if(reset)….. or always @ (posedge clk) if(!rst_n) ……… |
always @ (posedge clk or posedge reset) if(reset) ……. or always @ (posedge clk or negedge rst_n) if(!rst_n) ……. |
| 优点 | 1)只有在时钟边沿时才有效 2)可以帮助滤掉一些高于时钟频率的毛刺 3)布线的时候,有利于提高时序收敛 |
1) 在任何时候都可以有效 2)可以连接到FPGA芯片的全局复位信号线上 3)有些情况下,系统可能没有时钟,但逻辑依然需要复位 |
| 缺点 | 1)需要reset 信号和当前的时钟同步。如果和当前的时钟不同步,需要额外增加逻辑,先将reset 信号同步,然后使用,否则综合器依然按照异步的时钟域进行时序分析 2)在没有时钟时,复位不能被执行 |
1)复位信号容易受到干扰,一个随机的毛刺,也有可能使得逻辑复位 2) 时序分析为异步时钟域, 综合器可能会收敛,也有可能会报告无法满足时序要求。在非收敛的情况下,用户可以额外增加一些时序约束,通知综合器复位信号不用和当前的时钟关联,但需要谨慎处理 |
在一些简单的FPGA中,使用同步复位和异步复位的区别不是很大。只要保证复位信号是稳定的,不会产生毛刺输出, 同时同步复位和异步复位等信号的持续时间远远大于clk 的时钟周期即可。
作为单独的模块使用可能没有什么问题,但是如果在一个大系统中, 就需要仔细观察,哪一种情况才符合要求。在FPGA设计中,需要尽量使用同步复位(但不是绝对),这样可以使得整个工程处于同步逻辑当中, 有利于系统综合。同步复位release 也不会和时钟边沿同时发生,产生亚稳态等不确定的情况。但是事情往往不会这样圆满,比如在一个系统中存在多个时钟域下的模块,这些模块的启动有先后顺序,但都希望在系统时钟下处于初始状态,这时候就需要使用异步复位。
举例:一个系统中我们有CPU的接口 (100M 时钟) ,以太网的接口(125M 时钟),USB phy 接口(60M 时钟)等, 这些时钟的频率是不能修改的,所以在FPGA内部逻辑中会存在不同的时钟频率,同时这些模块可能在某一个时钟控制下进行复位。因此,也会有大量的异步复位被使用。
2.复位信号的机理及原语模型
同步复位和异步复位在FPGA的开发中是大家经常讨论的问题,本文以复位信号在Xilinx FPGA的时序下建模为例进行介绍,Intel-Altera FPGA的建模情况类似,因此本文的Verilog程序以及得出的结论也可以适用于其它厂家的FPGA。下面以Verilog HDL及Xilinx公司提供的原语两种方法进行描述,可以看出复位信号如何影响FPGA内触发器的行为。
- 同步复位逻辑
- Verilog语言描述
reg a = 0;
always @ (posedge clk)
if(reset) a <= 0;
else a <= ~a;
对上面的程序进行分析,可以看出在对寄存器a进行复位前,时钟边沿先对reset信号进行采样,采样后的结果如果为1,则复位a, 否则将a取反。可见reset是否生效还决定于时钟边沿。
reset 需要和clk 同步, 否则综合器依然可以发现这个reset 信号的时钟域不同,从而增加了时钟约束条件,使得综合效果不理想。甚至还会出现亚稳态等因素。reset同步化可以通过下面的方法实现。
reg a = 0;
reg reset_r;
always @ (posedge clk)
reset_r<=reset;
always @ (posedge clk)
if(reset_r) a <= 0;
else a <= ~a;
-
- 所对应的原语为:
|
1 2 3 4 5 6 7 8 9 10 11 |
wire a; <span style="color: #0000ff;">FDRE</span> #( .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) ) FDRE_inst ( .Q (a), // 1-bit Data output .C (clk), // 1-bit Clock input .CE (1), // 1-bit Clock enable input .R (reset_r), // 1-bit <span style="color: #0000ff;">Synchronous</span> set input .D (~a) // 1-bit Data input ); |
注:FDRE–>Primitive: D Flip-Flop with Clock Enable and Synchronous Reset ,原语:带有同步复位和时钟使能的D触发器。
- 异步复位逻辑
- Verilog描述方法如下:
reg a = 0;
always @ (posedge clk or posedge reset)
if(reset) a<= 0;
else a <= ~a;
reset 和clk 时钟域无关,但应注意,如果复位信号有毛刺,也会产生复位效果。即使时钟信号无效时,也可以复位。但需注意复位释放时的保持时间是否一致。
-
- 原语的描述方法如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="color: #0000ff;">FDCE</span> #( .INIT(1'b0) // Initial value of register (1'b0 or 1'b1) ) FDCE_inst ( .Q (a), // 1-bit Data output .C (clk), // 1-bit Clock input .CE (1), // 1-bit Clock enable input .CLR (reset), // 1-bit <span style="color: #0000ff;">Asynchronous</span> clear input .D (~a) // 1-bit Data input ); <span style="font-size: 10pt; color: #000080;"> 注:FDCE-->Primitive: D Flip-Flop with Clock Enable and Asynchronous Clear 带时钟使能和异步复位的D触发器。 </span> |
3. 应用举例及时序建模分析
- 异步复位代码及时序模型分析
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
`timescale 1ns / 1ps module top ( input clk, output [7:0] led, input reset ); reg [7:0] led_r = 0; always @ (posedge clk or posedge reset) if(reset) led_r <= 0; else led_r <= led_r + 1; assign led = led_r; endmodule |

图1 Altera异步复位模型
如图1所示: if(reset) led_r <= 0; reset连接到dff 的clrn 端。 clrn 端 和D 端都是可以更改Q端 输出的。
- 仿真程序:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
`timescale 1ns / 1ps module tb( ); reg clk = 0; always #5 clk = ~clk; reg reset = 0; initial begin reset = 0; #22; reset = 1; #2 reset = 0; #200; $stop; end wire [7:0] led; top top_inst ( .clk (clk), .led (led), .reset (reset) ); endmodule |

图2
从图2的仿真结果可以看出,当reset 发生时,led_r = 0; 这时,无视是否有时钟(不论是否有时钟, 也不论始终是否和信号同步)。这个仿真结果这与图1的模型相匹配。由于异步复位所需的脉冲宽度很窄,因此在使用应注意 潜在的风险,即如果reset 信号叠加了毛刺,系统依然可以发生reset,这可能与原设计意图不符。
- 同步复位代码及时序逻辑模型
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
module top ( input clk, output [7:0] led, input reset ); reg [7:0] led_r = 0; always @ (posedge clk) if(reset) led_r <= 0; else led_r <= led_r + 1; assign led = led_r; endmodule |

图3 Altera同步复位电路模型
如图3所示: 同步reset 是和信号输入逻辑做运算(图3中作为数据选择器的 选择端使用), 影响dff 的D端输入, 和dff 本身的clr 没有关系。因此,必须在有时钟的时候, 输入的reset 才能影响到q端的输出。但需注意reset成为组合逻辑的一个部分,因此对于触发器的建立(setup)和保持(hold)时间的需求,reset产生的逻辑要与其它逻辑电路一并考虑。

图4
如图4所示:同步复位时, 如果reset信号比较窄(没有赶上时钟的上升沿),这时,对输出没有影响。因此, 如果使用同步reset, 必须保证reset 信号大于1个时钟周期,才能可靠的对电路复位(reset)。
提示:在仿真软件中,同步复位仿真的时间优于异步复位,在小的工程中,仿真时间几乎没有差别,但是在大的项目中,仿真时间会有很大的不同, 同步复位仿真时间 明显小于异步复位的仿真时间。