同步复位?异步复位?我很困惑!我怎么知道该用哪一种?
摘要
本文将研究同步复位和异步复位的优缺点。将探讨每种类型复位的使用情况,然后给出每种类型复位的正确使用建议。
本文还将详细介绍一种有趣的同步技术,使用数字校准来同步多个 ASIC 设计上的复位。
1.0 resets, Resets, RESETS都是复位
在测试、验证、制造和集成到消费者、教育、政府和军事环境中的系统中,不希望出现的复位几乎每天都在发生。这种复位通常被称为“蓝屏死机”,原因是某软件公司的操作系统、软件程序以及操作系统软件所运行的硬件之间的不兼容。
为什么要关心这些恼人的复位呢?为什么要用一整篇论文来讨论这样一个微不足道的话题呢?任何使用过安装了特定操作系统的 PC 的人都知道,硬件复位非常方便。它将通过对系统中具有或需要复位的每个芯片应用系统复位,使计算机恢复到已知的工作状态(至少是暂时的)。
对于单个 ASIC,复位的主要目的是强制 ASIC 设计(行为,RTL 或结构)进入已知的工作状态。一旦 ASIC 被构建,复位 ASIC 的需求由系统、ASIC 的应用和 ASIC 的设计决定。例如,许多数据路径通信 ASIC 被设计为与输入数据流同步,处理数据,然后输出数据。如果同步丢失,ASIC 会通过一系列操作重新获取同步。如果这种类型的 ASIC 设计正确,使得所有未使用的状态都指向 “开始获取同步” 状态,那么它可以在系统中正常工作而无需复位。如果 ASIC 中的状态机在综合阶段利用了 “不关心” 逻辑,则需要在上电时对这种 ASIC 进行系统复位。
作者认为,一般来说,无论系统是否需要,ASIC 中的每个触发器都应该是可复位的。此外,作者更倾向于按照本文中详细介绍的准则使用异步复位。这些准则也有例外。在某些情况下,当在高速应用中使用跟随触发器(移位寄存器触发器)时,可能会从某些触发器中移除复位,以实现更高性能的设计。这种类型的环境需要在复位有效期设置多个时钟以使 ASIC 进入已知状态。
在为 ASIC 设计选择复位策略之前,必须考虑许多设计问题,例如是否使用同步或异步复位,每个触发器是否接收复位,如何布置和缓冲复位树,如何验证复位树的时序,如何使用测试扫描向量对复位进行功能测试,以及如何在多个时钟域之间应用复位。
此外,在需要特定复位释放顺序的多个 ASIC 之间应用复位时,必须采用特殊技术来调整芯片和电路板制造的差异。本文的最后部分将讨论这个问题。
2.0 一般触发器编码风格注意事项
2.1 具有非复位跟随触发器的同步复位触发器
每个 Verilog 程序块或 VHDL 进程应该只模拟一种类型的触发器。换句话说,设计师不应该将可复位触发器与跟随触发器(无复位触发器)混在一起。跟随触发器是一种简单的数据移位寄存器。
在例 1a 的 Verilog 代码和例 1b 的 VHDL 代码中,触发器用于捕获数据,然后其输出通过跟随触发器传递。本设计的第一阶段采用同步复位。第二阶段是跟随触发器,不会复位,但由于两个触发器在同一个 always 块中,因此复位信号 rst_n 将用作第二个触发器的数据使能。这种编码风格将生成多余的逻辑,如图 1 所示。
Example 1a - Bad Verilog coding style to model dissimilar flip-flops
module badFFstyle (q2, d, clk, rst_n);
output q2;
input d, clk, rst_n;
reg q2, q1;
always @(posedge clk)
if (!rst_n) q1 <= 1'b0;
else begin
q1 <= d;
q2 <= q1;
end
endmodule
Example 1b - Bad VHDL coding style to model dissimilar flip-flops
library ieee;
use ieee.std_logic_1164.all;
entity badFFstyle is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
q2 : out std_logic);
end badFFstyle;
architecture rtl of badFFstyle is
signal q1 : std_logic;
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (rst_n = '0') then
q1 <= '0';
else
q1 <= d;
q2 <= q1;
end if;
end if;
end process;
end rtl;
对跟随触发器进行建模的正确方法是使用示例 2a 中所示的两个 Verilog 块或示例 2b 中所示的两个 VHDL 进程。这些编码风格将生成图 2 所示的逻辑。
Example 2a - Good Verilog coding style to model dissimilar flip-flops
module goodFFstyle (q2, d, clk, rst_n);
output q2;
input d, clk, rst_n;
reg q2, q1;
always @(posedge clk)
if (!rst_n) q1 <= 1'b0;
else q1 <= d;
always @(posedge clk)
q2 <= q1;
endmodule
Example 2b - Good VHDL coding style to model dissimilar flip-flops
library ieee;
use ieee.std_logic_1164.all;
entity goodFFstyle is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
q2 : out std_logic);
end goodFFstyle;
architecture rtl of goodFFstyle is
signal q1 : std_logic;
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (rst_n = '0') then
q1 <= '0';
else
q1 <= d;
end if;
end if;
end process;
process (clk)
begin
if (clk'event and clk = '1') then
q2 <= q1;
end if;
end process;
end rtl;
应该注意的是,例 1a 和例 1b 中的代码生成的额外逻辑只是使用同步复位的结果。如果使用了异步复位,那么两种编码风格将综合为相同的设计。不同触发器的生成很大程度上取决于 HDL 代码中使用的敏感度列表和 if-else 语句。关于敏感度列表和 if-else 编码风格的更多细节将在 3.1 节中详细介绍。
2.2 触发器建模风格
每个触发器建模不应该在其自己的程序块/过程中独立建模。应该使用单个过程块/进程来描述给定函数甚至函数组的所有触发器。应该使用多个过程块/过程来对给定模块中的宏观级功能划分进行建模。这条准则的例外是前面章节(2.1 节)中讨论的跟随触发器,其需要多个过程块/进程才能有效。
2.3 赋值操作符指南
在 Verilog 中建模触发器时,所有在 always 块内进行的赋值都应该使用非阻塞赋值操作符。同样,在 VHDL 中建模触发器,应该使用信号赋值。
3.0 同步复位
在本文的研究过程中,收集并回顾了 ESNUG 和 SOLV-IT 的相关文章。大约 80% 以上的文章集中在同步复位问题上。在许多 SNUG 的论文中,发表者会这样宣称。“我们都知道,在 ASIC 中进行复位的最佳方法是严格使用同步复位”,或者 “异步复位不好,应该避免”。然而,几乎没有证据证明这些说法是正确的。使用同步复位有一些优点,但也有缺点。异步复位也是如此。设计师必须使用适合设计的方法。
同步复位的前提是复位信号只会影响或复位有效时钟边沿上触发器的状态。复位可以应用于触发器,作为产生触发器 d 输入的组合逻辑的一部分。如果是这种情况,那么为复位建模的编码风格应该是 if /else 优先级风格,在 if 条件中进行复位,而在 else 部分中进行所有其他组合逻辑。如果不严格遵守这种风格,可能会出现两个问题。首先,在一些基于逻辑的仿真器中,仿真器会阻止复位到达触发器。这只是一个仿真问题,而不是硬件问题,但请记住,复位的主要目标之一是在仿真中将 ASIC 置于已知状态。其次,由于复位树的高扇出,相对于时钟周期,复位可能是一个 “延迟到达的信号”。虽然复位将在复位缓冲树中进行缓冲,但更明智的做法是限制复位到达本地逻辑后必须遍历的逻辑数量。这种风格的同步复位可以用于任何逻辑或库。示例 3 显示了这种风格的同步复位的实现,作为可执行的可加载计数器的一部分。
Example 3a - Verilog code for a loadable counter with synchronous reset
module ctr8sr ( q, co, d, ld, rst_n, clk);
output [7:0] q;
output co;
input [7:0] d;
input ld, rst_n, clk;
reg [7:0] q;
reg co;
always @(posedge clk)
if (!rst_n) {co,q} <= 9'b0; // sync reset
else if (ld) {co,q} <= d; // sync load
else {co,q} <= q + 1'b1; // sync increment
endmodule
Example 3b - VHDL code for a loadable counter with synchronous reset
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ctr8sr is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
ld : in std_logic;
q : out std_logic_vector(7 downto 0);
co : out std_logic);
end ctr8sr;
architecture rtl of ctr8sr is
signal count : std_logic_vector(8 downto 0);
begin
co <= count(8);
q <= count(7 downto 0);
process (clk)
begin
if (clk'event and clk = '1') then
if (rst_n = '0') then
count <= (others => '0'); -- sync reset
elsif (ld = '1') then
count <= '0' & d; -- sync load
else
count <= count + 1; -- sync increment
end if;
end if;
end process;
end rtl;
第二种同步复位方式是基于具有同步复位引脚的触发器。有时会出现这种情况,但更多的时候使用上面讨论的第一种风格去实现。
3.1 代码风格和示例电路
例 4a 的 Verilog 代码和例 4b 的 VHDL 代码显示了建模同步复位触发器的正确方法。请注意,复位不是敏感度列表的一部分。对于 Verilog 来说,从敏感度列表中省略复位是使复位同步的方式。对于 VHDL,从敏感度列表中省略复位,并检查 “if clk’event and clk = 1” 语句后的复位,使复位同步。请注意,通过使用 if-else 编码风格,reset 被赋予了高于任何其他赋值的优先级。
Example 4a - Correct way to model a flip-flop with synchronous reset using Verilog
module sync_resetFFstyle (q, d, clk, rst_n);
output q;
input d, clk, rst_n;
reg q;
always @(posedge clk)
if (!rst_n) q <= 1'b0;
else q <= d;
endmodule
Example 4b - Correct way to model a flip-flop with synchronous reset using VHDL
library ieee;
use ieee.std_logic_1164.all;
entity syncresetFFstyle is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
q : out std_logic);
end syncresetFFstyle;
architecture rtl of syncresetFFstyle is
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (rst_n = '0') then
q <= '0';
else
q <= d;
end if;
end if;
end process;
end rtl;
对于采用同步复位方式 #1 设计的触发器(复位是通过 d 输入的数据进行门控的),Synopsys 有一个开关,设计人员可以使用它来帮助建模具有同步复位的触发器。
编译器指令:sync_set_reset
一般来说,作者建议仅在需要时使用 Synopsys 开关。然而,我们的同事 Steve Golson 指出,sync_set_reset 指令不会影响设计的功能,因此直到门级仿真时才会发现它的遗漏,当发现故障时需要在项目进度的后期重新综合设计。由于该指令在每个模块中只需要使用一次,所以建议将其添加到每个模块中并同步复位。
几年前,另一个 ESNUG 贡献者建议添加 compile_preserve_sync_resets = “true” 编译器指令。虽然这个指令在几年前可能是有用的,但从 Synopsys 3.4b 版本开始,它就停止使用了。
3.2 同步复位的优点
同步复位将综合成更小的触发器,特别是如果复位与产生 d 输入的逻辑进行门控。但是在这种情况下,组合逻辑门的数量会增加,所以总的门的数量节省可能不是那么显著。如果设计紧凑,则每个触发器的一个或两个门的面积节省可以确保 ASIC 适合于模具。然而,在今天巨大的模具尺寸的技术中,每个触发器的一个或两个门的节省通常是无关紧要的,并且不会成为设计是否适合模具的重要因素。
当使用基于循环的仿真器时,同步复位可以更容易地工作。正是由于这个原因,在复位方法学手册(RMM)的第 3.2.4 节(第 2 版,第 1 版的第 3.2.3 节)中推荐同步复位。
同步复位通常确保电路 100% 同步。
同步复位确保复位只能发生在有效时钟边沿。这个时钟可以作为小的复位故障的过滤器;然而,如果这些小的故障发生在有效时钟边沿附近,触发器仍可能会进入亚稳态。
在某些设计中,复位必须由一组内部条件产生。对于这些类型的设计,建议使用同步复位,因为它可以过滤时钟之间的逻辑故障。
通过使用同步复位和多个时钟作为复位过程的一部分,触发器可以在复位缓冲树中使用,以帮助缓冲树的延时保持在一个时钟周期内。
3.3 同步复位的缺点
同步复位可能需要一个脉冲拉伸器来保证复位脉冲宽度足够宽,以确保在时钟的有效边沿期间复位。
设计师必须评估仿真的乐观和悲观情况。如果复位是由 ASIC 中的组合逻辑生成的,或者如果复位必须遍历许多层级的本地组合逻辑,这可能存在问题。在仿真过程中,基于复位是如何产生的,或者复位是如何应用于一个功能块的,复位可能被 X 掩盖。ESNUG 的许多文章讨论了这个问题。大多数仿真器不能解决某些 X-logic 条件,因此会阻塞同步复位。
从本质上讲,同步复位需要一个时钟来复位电路。对于某些设计风格来说,这可能不是缺点,但对于其他设计风格来说,这可能存在问题。如果 ASIC/FPGA 具有内部三状态总线,则时钟引起复位条件的要求是重要的。当芯片上电时,为了防止内部三态总线上的总线竞争,芯片必须有一个上电的异步复位。
4.0 异步复位
异步复位是作者首选的复位方法。但是,单独使用异步复位可能非常危险。许多工程师喜欢将复位应用于电路并使逻辑进入已知状态的想法。异步复位的最大问题是复位释放,也称为复位移除。这个主题将在第 5.0 节中详细阐述。
异步复位触发器将复位引脚集成到触发器设计中。复位引脚通常为低电平有效(当附加到触发器复位引脚的信号达到逻辑低电平时,触发器进入复位状态)。
4.1 代码风格和示例电路
例 5a 的 Verilog 代码和例 5b 的 VHDL 代码显示了对异步复位触发器建模的正确方法。请注意,复位是敏感度列表的一部分。对于 Verilog 来说,将复位添加到敏感度列表中可以使复位成为异步。为了使异步触发器的 Verilog 仿真模型能够正确地仿真,敏感度列表应该只在异步复位信号的前沿有效。因此,在例 5a 中,将在复位的前沿输入 always 过程块,然后 if 条件将检查正确的复位电平。
Synopsys 要求,如果敏感度列表中有任何信号是边缘敏感的,那么敏感度列表中的所有信号都必须是边缘敏感的。换句话说,Synopsys 强制使用正确的编码风格。Verilog 仿真没有这个要求,但如果敏感度列表对不仅仅是有效时钟边缘和复位前沿敏感,仿真模型将不正确。此外,只有时钟和复位信号可以在敏感度列表中。如果包含其他信号(合法的 Verilog,非法的 Verilog RTL 综合编码风格),仿真模型对于触发器的仿真将不正确,Synopsys 将在读取模型进行综合时报告错误。
对于 VHDL,在 “if clk’event and clk = 1” 语句之前,包括敏感度列表中的复位和检查复位,使复位异步。还请注意,通过使用 if/else 编码风格,复位优先于任何其他赋值(包括时钟)。由于 VHDL 敏感度列表和触发器编码风格的性质,可以在敏感度列表中包含额外的信号,而不会直接对仿真和综合产生不良影响。然而,良好的编码风格建议只有能直接改变触发器输出的信号才应该在敏感度列表中。这些信号是时钟和异步复位。所有其他信号将减慢仿真速度并会被综合忽略。
Example 5a - Correct way to model a flip-flop with asynchronous reset using Verilog
module async_resetFFstyle (q, d, clk, rst_n);
output q;
input d, clk, rst_n;
reg q;
// Verilog-2001: permits comma-separation
// @(posedge clk, negedge rst_n)
always @(posedge clk or negedge rst_n)
if (!rst_n) q <= 1'b0;
else q <= d;
endmodule
Example 5b - Correct way to model a flip-flop with asynchronous reset using VHDL
use ieee.std_logic_1164.all;
entity asyncresetFFstyle is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
q : out std_logic);
end asyncresetFFstyle;
architecture rtl of asyncresetFFstyle is
begin
process (clk, rst_n)
begin
if (rst_n = '0') then
q <= '0';
elsif (clk'event and clk = '1') then
q <= d;
end if;
end process;
end rtl;
综合异步复位的方法将取决于设计复位缓冲树的方法。如果复位是直接从外部引脚驱动的,那么通常在复位引脚上 set_drive 0 并在 reset net 上执行 set_dont_touch_network 将保护 net 不被综合修改。然而,至少有一篇 ESNUG 文章指出,情况并非总是如此。一个 ESNUG 贡献者指出,有时可能还需要在 reset net 上执行 set_resistance 0。我们的同事 Steve Golson 指出,你可以在 net 上执行set_resistance 0,或创建一个自定义一个 resistance=0 的 wireload 模型并使用指令把它应用到复位输入端口:
set_wire_load -port_list reset
最近更新的一篇 SolvNet 文章还指出,从 Synopsys 发布的 2001.08 版本开始,理想 net 的定义略有变化,可以使用 set_ideal_net 命令创建理想 net,并且“没有时间更新,没有延迟优化,也没有 DRC 修复”。
另一位同事 Chris Kiegle 报告说,在 v2001.08 之前设计的 net 上执行 set_disable_timing 有助于清理时间报告,这似乎得到了另外两篇 SolvNet 文章的支持,一篇与综合有关,另一篇与物理综合有关,这两篇文章建议同时使用 set_false 命令和 set_disable_timing 命令。
4.2 建模具有异步复位和异步置位的 Verilog 触发器
关于在 Verilog 中建模异步复位,这里还需要注意一点。在 Verilog 中包含异步置位和异步复位的触发器仿真模型可能无法正确仿真。一般来说,大多数同步设计都没有包含异步置位和异步复位的触发器,但有时需要这样的触发器。例 6 的编码风格可用于纠正 Verilog RTL 仿真,其中 reset 和 set 同时断言,reset 首先被移除。
首先注意,这个问题只是一个仿真问题,而不是一个综合问题(综合推断出正确的触发器与异步置位/复位)。仿真问题是由于 always 块只在有效边缘输入置位、复位或时钟信号。如果复位为有效状态,接着是 set 变为有效状态,然后复位为非有效状态;触发器应该首先进入复位状态,再进入置位状态。由于这两个输入都是异步的,一旦复位被移除,置位就应该是有效的,但在 Verilog 中不会出现这种情况,因为没有办法触发 always 块,直到下一个上升时钟边缘。
对于那些允许同时断言 reset 和 set,然后首先移除 reset 的罕见设计,此仿真问题的修复方法是使用 translate_off/translate_on 指令中包含的自校正代码对触发器进行建模,并强制输出为这一条件的正确值。这里最好的建议是尽可能避免需要同时使用异步置位和异步复位的触发器的情况。示例 6 中的代码显示了将正确仿真并保证综合前和综合后仿真之间的匹配。这段代码使用 translate_off/translate_on 指令强制为异常条件输出正确的输出。
Example 6 – Verilog Asynchronous SET/RESET simulation and synthesis model
// Good DFF with asynchronous set and reset and self-
// correcting set-reset assignment
module dff3_aras (q, d, clk, rst_n, set_n);
output q;
input d, clk, rst_n, set_n;
reg q;
always @(posedge clk or negedge rst_n or negedge set_n)
if (!rst_n) q <= 0; // asynchronous reset
else if (!set_n) q <= 1; // asynchronous set
else q <= d;
// synopsys translate_off
always @(rst_n or set_n)
if (rst_n && !set_n) force q = 1;
else release q;
// synopsys translate_on
endmodule
4.3 异步复位的优点
使用异步复位的最大优点是,只要器件库具有可异步复位的触发器,数据路径就保证是干净的。那些对数据路径时序有限制的设计,无法承受在数据路径中增加门和额外的延迟,因为同步复位要插入额外的逻辑。当然,如果器件库具有同步复位输入的触发器,并且设计人员可以让 Synopsys 实际使用这些引脚,那么此论点就不成立了。使用异步复位,可以保证综合器不会将复位添加到数据路径中。例 7 中的代码推断出不会添加到数据路径中的异步复位。
Example 7a- Verilog code for a loadable counter with asynchronous reset
module ctr8ar ( q, co, d, ld, rst_n, clk);
output [7:0] q;
output co;
input [7:0] d;
input ld, rst_n, clk;
reg [7:0] q;
reg co;
always @(posedge clk or negedge rst_n)
if (!rst_n) {co,q} <= 9'b0; // async reset
else if (ld) {co,q} <= d; // sync load
else {co,q} <= q + 1'b1; // sync increment
endmodule
Example 7b- VHDL code for a loadable counter with asynchronous reset
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ctr8ar is
port (
clk : in std_logic;
rst_n : in std_logic;
d : in std_logic;
ld : in std_logic;
q : out std_logic_vector(7 downto 0);
co : out std_logic);
end ctr8ar;
architecture rtl of ctr8ar is
signal count : std_logic_vector(8 downto 0);
begin
co <= count(8);
q <= count(7 downto 0);
process (clk)
begin
if (rst_n = '0') then
count <= (others => '0'); -- sync reset
elsif (clk'event and clk = '1') then
if (ld = '1') then
count <= '0' & d; -- sync load
else
count <= count + 1; -- sync increment
end if;
end if;
end process;
end rtl;
异步复位的另一个优点是电路在有或没有时钟存在的情况下都可以复位。
作者的经验是,通过使用本节中描述的异步复位的编码风格,综合器会自动区分。也就是说,通常不需要添加任何综合属性来使综合工具映射到具有异步复位引脚的触发器。
4.4 异步复位的缺点
工程师们给出了很多理由来解释为什么异步复位是不好的。
复位方法学手册(RMM)建议不要使用异步复位,因为它们不能与基于循环的仿真器一起使用。这是不正确的。基于周期的仿真器的基础是所有输入在时钟边缘上改变。由于定时不是基于周期的仿真的一部分,异步复位可以简单地应用于非有效时钟边缘。
对于 DFT,如果异步复位不是直接从 I/O 引脚驱动的,那么来自复位驱动的 reset net 必须禁用 DFT 扫描和测试。这是第 6 节所示的同步器电路所必需的。
一些设计师声称,使用异步复位的设计很难进行静态时序分析。复位树必须对同步复位和异步复位进行定时,以确保复位的释放可以在一个时钟周期内发生。必须在布局完成后对复位树进行时序分析,以确保满足此时序要求。
异步复位的最大问题是它们是异步的,在复位断言和撤销断言时都是异步的。断言不是问题,撤销断言才是问题。如果在触发器的有效时钟边缘或附近释放异步复位,则触发器的输出可能会进入亚稳态,因此 ASIC 的复位状态可能会丢失。
另一个问题,由于噪声或系统复位故障,异步复位可能是虚假复位。有关复位故障的可能解决方案,请参阅 8.0 节。如果这是系统中的一个实际问题,那么人们可能会认为使用同步复位是解决方案。对于同步复位存在一个不同但相似的问题,如果这些伪复位脉冲发生在时钟边缘附近,触发器仍然可以进入亚稳态。
5.0 异步复位问题
在与同事讨论本文主题时,工程师首先表示,由于他所从事的工作都是 FPGA,因此它们没有与 ASIC 相同的复位问题(误解)。他接着说,他总是有一个异步系统复位,可以覆盖一切,使芯片进入已知状态。然后工程师被问到,如果复位的释放发生在时钟边缘或时钟边缘附近,导致触发器进入亚稳态,FPGA 或 ASIC 会发生什么。
太多的工程师只是应用异步复位,认为没有问题。他们在受控的仿真环境中测试了复位,一切正常,但在系统中,设计间歇性地失败。设计者没有考虑在系统(非受控环境)中释放复位可能导致芯片进入亚稳态,从而使复位全部失效。必须注意复位的释放,防止复位释放时芯片进入亚稳态。当使用同步复位时,复位的前后沿都必须远离时钟的有效沿。
如图 5 所示,异步复位信号将以异步方式解除对时钟信号的断言。这种情况有两个潜在的问题:(1)违反复位恢复时间;(2)复位移除发生在不同的时钟周期中。
5.1 复位恢复时间
复位恢复时间是指从复位解除到时钟信号再次高电平的时间。Verilog-2001 标准有三个内置命令来建模和测试恢复时间和信号去除定时检查:$recovery, $removal 和 $recrem(后者是恢复和去除定时检查的组合)。
恢复时间也被称为 ”PRE 或 CLR 在 CLK↑ 之前的非活动建立时间“ 形式的 tsu 建立时间。
缺少恢复时间可能会导致寄存器数据输出出现信号完整性或亚稳态问题。
5.2 复位移除遍历不同的时钟周期
当复位移除与上升时钟沿异步时,复位信号和时钟信号中任何一方或双方传播延迟的细微差异都可能导致一些寄存器或触发器在其他寄存器或触发器之前退出复位状态。
6.0 异步复位同步释放
指南:每个使用异步复位的 ASIC 都应该包含一个复位同步释放电路!!
如果没有复位同步器,即使在仿真过程中复位有效,异步复位在最终系统中的有效性也无法保证。
图 6 中的复位同步器逻辑旨在充分利用异步和同步复位方式的优点。
外部复位信号异步复位一对主复位触发器,主复位触发器又通过复位缓冲树异步驱动主复位信号到设计中的其余触发器。整个设计将被异步复位。
复位移除是通过解除复位信号来完成的,然后允许通过复位同步器对第一个主复位触发器(绑定高位)的 d 输入进行时钟处理。复位移除后,通常需要两个上升时钟沿来同步移除主复位。
需要两个触发器将复位信号与时钟脉冲同步,第二个触发器用于去除可能由复位信号被异步移除且太靠近上升时钟边缘引起的亚稳态。正如第 4.4 节所讨论的,这些同步触发器必须保持在扫描链之外。
现在对时序的更仔细的检查表明,复位分布时序是 clk-q 的传播延迟、通过复位分布树的总延迟以及满足目标寄存器和触发器的复位恢复时间的总和,如图 7 所示。
异步复位同步释放电路的代码如例 8 所示。
Example 8a - Properly coded reset synchronizer using Verilog
module async_resetFFstyle2 (rst_n, clk, asyncrst_n);
output rst_n;
input clk, asyncrst_n;
reg rst_n, rff1;
always @(posedge clk or negedge asyncrst_n)
if (!asyncrst_n) {rst_n,rff1} <= 2'b0;
else {rst_n,rff1} <= {rff1,1'b1};
endmodule
Example 8b - Properly coded reset synchronizer using VHDL
library ieee;
use ieee.std_logic_1164.all;
entity asyncresetFFstyle is
port (
clk : in std_logic;
asyncrst_n : in std_logic;
rst_n : out std_logic);
end asyncresetFFstyle;
architecture rtl of asyncresetFFstyle is
signal rff1 : std_logic;
begin
process (clk, asyncrst_n)
begin
if (asyncrst_n = '0') then
rff1 <= '0';
rst_n <= '0';
elsif (clk'event and clk = '1') then
rff1 <= '1';
rst_n <= rff1;
end if;
end process;
end rtl;
7.0 复位分布树
复位分布树和时钟分布树一样需要注意,因为在典型的数字设计中,复位输入负载通常和时钟输入负载一样多,如图 8 所示。复位树的时间要求对于同步和异步复位方式都是通用的。
时钟分布树和复位分布树之间的一个重要区别是需要密切平衡多个复位之间的偏移。与时钟信号不同,只要与任何复位信号相关的延迟足够短,以便在一个时钟周期内传播到所有复位负载,并且仍然满足所有目标寄存器和触发器的恢复时间,那么复位信号之间的偏移就不是关键的。
在分析时钟树时序和 clock-q-reset 树时序时必须小心。为复位树(同步或异步复位)计时最安全的方法是从时钟树的叶时钟为内部主复位触发器计时,如图 9 所示。在大多数情况下,没有足够的时间让时钟脉冲遍历时钟树,为复位驱动触发器计时,然后让复位遍历复位树,所有这些都在一个时钟周期内完成。
为了帮助加快复位到达所有系统触发器的速度,复位驱动器触发器使用一个早期时钟进行时钟处理,如图 10 所示。必须进行布局后时间分析,以确保异步复位的复位释放和同步复位的断言和释放不会对触发器的时钟产生冲击;这意味着复位必须不违反建立时间并保持在 flops 上。通常在布局完成和两棵树的真实时间可用之前,无法进行这样的详细时间调整。
8.0 复位毛刺过滤
正如本文前面所述,异步复位的最大问题之一是它们是异步的,因此带有一些必须根据复位源来处理的特征。对于异步复位,任何足以满足触发器最小复位脉冲宽度的输入都将导致触发器复位。如果复位线出现故障,这会出现问题。这里展示的是一种方法,我将过滤掉故障,但它是丑陋的!这个解决方案需要一个数字延迟(意味着延迟会随着温度、电压和工艺而变化)来过滤掉小故障。复位输入电路也应该是一个施密特触发电路,以帮助故障滤波。图 11 显示了这种方法的实现。
为了增加延迟,一些供应商提供了一个延迟硬宏,可以手工实例化。如果没有这种东西,设计人员可以在优化后手动将延迟实例化到综合设计中——记住,在插入延迟之后不要再优化这个块,否则它将被删除。当然,可以应用 don’t touch 指令来防止它们被删除。第二种方法是在模块中实例化一个慢速缓冲区,然后多次实例化该模块以获得所需的延迟。
并非所有系统都需要此故障过滤器。设计人员必须研究系统需求,以确定是否需要延迟。
9.0 用于异步复位的 DFT
将测试设计(DFT)功能应用于设计是一个两步的过程。首先,将设计模块中的触发器连接在一起,形成可从外部 I/O 引脚访问的扫描链,这称为扫描插入。扫描链通常不是功能设计的一部分。其次,运行一个软件程序来生成一组扫描向量,当应用于扫描链时,将测试和验证设计。这个软件程序被称为自动测试程序生成或 ATPG。扫描矢量的主要目的是为晶圆和模具的制造测试以及最终封装部件的测试提供铸造矢量。
应用 ATPG 矢量创建测试的过程基于:
- 将已知状态扫描到芯片中的所有触发器中,
- 将触发器从扫描移位模式切换到功能数据输入模式,
- 应用一个功能时钟,
- 将触发器切换回扫描移位模式,以在扫描下一个测试向量时扫描出一个功能时钟的结果。
DFT 过程通常需要两个控制引脚。将设计置于 “测试模式”。该引脚用于屏蔽不可测试的逻辑,如内部生成的异步复位、异步组合反馈循环和许多其他需要特别注意的逻辑条件。在整个测试过程中,该引脚通常保持不变。第二个控制引脚是移位使能引脚。
为了使 ATPG 矢量工作,测试程序必须能够控制芯片扫描链上触发器的所有输入。这不仅包括时钟和数据,还包括复位引脚(同步或异步)。如果复位直接从 I/O 引脚驱动,则复位保持在非复位状态。如果复位是内部产生的,则主内部复位由测试模式信号保持在非复位状态。如果在 ATPG 期间没有屏蔽内部产生的复位,则在扫描期间可能发生复位条件,导致芯片中的触发器复位,从而丢失正在扫描的矢量数据。
即使异步复位保持在 ATPG 的非复位状态,这并不意味着 reset/set 不能作为 DFT 过程的一部分进行测试。在锁定 reset with test 模式并生成 ATPG 矢量之前,可以手动生成一些矢量来创建 reset/set 测试矢量。测试 DFT 的异步复位所需的过程非常直接,并且可以使用某些 DFT 工具自动完成。如果扫描工具没有自动测试异步复位/置位,则必须手动设置。手动测试异步复位/置位的基本步骤如下:
- 在扫描链中扫描所有的信号
- 产生和释放异步复位
- 扫描出结果并扫描全零
- 产生和释放异步复位
- 扫描出结果
- 将复位输入置为非复位状态,然后应用 ATPG 生成的矢量。
此测试方法将扫描异步重置和设置的测试。这些手动生成的向量将被添加到 ATPG 向量中,为制造测试提供更高的故障覆盖率。如果设计使用具有同步复位输入的触发器,那么稍微修改上述手动异步复位测试将得到同步复位环境的类似测试。在应用复位时,在上面的步骤中添加一个功能时钟。所有其他步骤将保持不变。
对于本文讨论的复位同步器电路,两个同步器触发器不应包含在扫描链中,而应使用上述手动过程进行测试。
10. 多时钟复位问题
对于多时钟设计,每个时钟域应使用单独的异步复位同步释放电路和复位分布树。这样做是为了确保复位信号确实可以保证满足每个时钟域中每个寄存器的复位恢复时间。
如前所述,异步复位断言不是问题。问题是优雅地移除复位和复位后所有逻辑的同步启动。
根据设计约束,可以采用两种技术:(1)非协调复位移除,(2)顺序协调复位移除。
10.1 非协调复位移除
对于许多多时钟设计来说,与在另一个时钟域中移除复位相比,在一个时钟域中移除复位的确切时间并不重要。通常在这些设计中,任何跨越时钟边界的控制信号都是通过某种类型的 request-acknowledge 握手序列传递的,并且从一个时钟域到另一个时钟域的延迟确认不会导致硬件的无效执行。对于这种类型的设计,创建单独的异步复位同步器(如图 12 所示)就足够了,可以按任何顺序移除 arst_n、brst_n 和 crst_n ,对设计不会产生影响。
10.2 顺序协调复位移除
对于一些多时钟设计,复位去除必须有序和适当的顺序。对于这种类型的设计,可能需要创建如图 13 所示的优先级异步复位同步器,以确保在复位被移除之后,所有的 aclk 域逻辑都在 bclk 逻辑之前被激活,bclk 逻辑也必须在 cclk 逻辑激活之前被激活。
对于这种类型的设计,只有最高优先级的异步复位同步器输入被绑定为高。其他异步复位同步器输入与来自高优先级时钟域的主复位相关联。
11.0 多 ASIC 复位同步
有多个 ASIC 的设计需要在所有多个 ASIC 上精确移除同步复位。满足这种类型设计的一种方法是使用不同的异步复位同步方案,该方案只需要一个复位移除触发器,而不是第 6.0 节中描述的两个触发器,加上数字校准的同步延迟,以正确顺序从多个 ASIC 中移除复位。
考虑数字存储示波器(DSO)上数据采集板的实际设计。简单地说,DSO 是一种测试仪器,它探测模拟信号,连续地对信号进行采样和模数(A2D)转换,并尽可能快地将采样的数字数据连续地存储到存储器中。在请求的触发条件发生后,与触发条件相关的其余数据被存储到存储器中,然后 DSO 控制逻辑(通常是商用微处理器)访问数据并在屏幕上绘制数据值的波形以供视觉检查。
对于这种类型的实际设计,数据采集板包含四个数字解复用(demux) ASIC,每个 ASIC 捕获四分之一的数据样本发送到内存,如图 14 所示。
对于这个数字采集系统,一旦复位被移除,ASIC 必须开始捕获数据并生成内存地址以将数据写入内存。数据采集和地址生成都在连续运行,捕获数据样本并覆盖先前写入的内存位置,直到触发电路使地址计数器停止并保存最近捕获的数据。通常,触发器设置为保持并显示 90% 的波形为触发前数据,10% 的波形为触发后数据。由于通常不可能预测触发何时发生,因此有必要在复位去除后持续采集数据,直到触发信号停止数据采集。
本设计中使用的高速数据采集方法是使用四个 demux ASIC 来捕获数字化波形的每四个点。由于 demux ASIC 通常以非常快的时钟速率运行,并且由于每个 demux ASIC 还必须生成相应的地址计数值以将数据样本存储到内存中,因此重要的是,所有四个 demux ASIC 都必须以正确的顺序启动各自的地址计数器,以确保存储在内存中的数据样本可以轻松回读,以便在 DSO 显示器上绘制波形。
这种类型的设计的问题是在同一时间(在同一个相对时钟周期)准确移除四个 ASIC 的复位信号,以便四个 ASIC 捕获正确排序的数据样本,对应于所有四个 ASIC 上的地址 #0,然后是所有四个 ASIC 上的地址 #1,以此类推。因此,存储到内存中的数据可以从内存中读取 (在触发 DSO 后),在 DSO 屏幕上以正确的顺序来显示一个准确波形。
对于这种类型的设计,有许多因素会影响正确的复位移除,从而影响写入内存的数据值的正确顺序。
首先,对于高速设计(DSO 在探测其他高速电路时,为了保证数据样本的数量,必须使用高速设计),复位信号到四个 ASIC 的相对路径长度必须保持在非常严格的公差范围内;因此,电路板布局是一个重要问题。
第二,制造 ASIC 批次内部或批次之间的工艺变化可能会产生超过最短 ASIC 时钟周期的延迟。在制造过程中选择四个 ASIC 会导致四个具有不同相对延迟的设备放置在同一数据采集板上。放置在一块板上的四个 ASIC 的相对处理速度无法保证(没有人知道四个 ASIC 中哪一个是最快的)。
第三,不同测试环境中的温度波动也会增加延迟的差异。在 DSO 外壳内的所有 ASIC 的相对位置可能会导致这种高速系统的显著温度差异。
第四,拆除 DSO 的盖子以排除原型故障可能会导致四个 ASIC 之间的温度变化不同于关闭盖子时的温度变化。
对于实际设计,一个通用的复位信号(reset_n)被连接到所有四个 demux ASIC 来断言复位,但是复位信号没有从 demux ASIC 中进行热复位。一个单独的同步信号用于标记每个 demux ASIC上 的复位移除权限。
使用图 15 所示的逻辑处理多 ASIC 复位移除同步逻辑。这种逻辑对于主 ASIC 和从 ASIC 都是通用的。
断言 reset (rst_n 在图 15 中变低)异步复位主复位信号,mstrst_n 通过复位树驱动到所有 ASIC(包括主 ASIC 和从 ASIC)上的其余可复位逻辑;因此,复位是异步和即时的。
每个 ASIC 有三个引脚专用于复位移除同步。
每个 ASIC 上的第一个引脚是专用的主/从选择引脚。当这个引脚置高时,ASIC 被置于主模式。当引脚被置低时,ASIC 被置于从模式。
每个 ASIC 上的第二个引脚是 sync_out 引脚。在从 ASIC 上,sync_out 引脚未使用并且悬空。当 reset 被移除时(当 reset_n 变高时),主 ASIC 产生 sync_out 脉冲。sync_out 信号被驱动出主 ASIC,并通过电路板连接绑定到主 ASIC 和从 ASIC 上的 sync_in 输入。sync_out 引脚是控制主 ASIC 和从 ASIC 上的复位移除的引脚。
每个 ASIC 上的第三个引脚是 sync_in 引脚。sync_in 引脚是输入引脚,用于控制主 ASIC 和从 ASIC 上的复位移除。sync_in 连接到可编程延迟块,通过复位输入上的高断言使能,传递到同步复位移除触发器。ASIC 上的下一个上升时钟沿将导致复位同步移除,允许每个 ASIC 上的地址计数器以同步和有序的方式开始计数。
如前所述,问题在于确保 sync_in 信号以正确的顺序移除四个 ASIC 上的复位。
如图 16 所示,可编程数字延迟块是一组串联的 delay-stage,每个 delay-stage 输出驱动下一个 delay-stage 输入和多路复用器上的一个输入。delay-stage 可以是简单的缓冲器,也可以是一对逆变器。选择的延迟阶段数量几乎等于三个 ASIC 时钟周期。
处理器接口用于编程延迟选择寄存器,它使多路复用器选择线路来选择哪个延迟 sync_in 信号(sdly0 到 sdly15)将被驱动到多路复用器输出并用于移除 ASIC 上的复位。
为了确定每个 ASIC 的正确延迟设置,采用了软件数字校准技术。
为了帮助校准 demux ASIC 以及数据采集板上的其他模拟设备,该板被设计为通过数据采集路径捕获可选择的板上斜坡信号。斜坡信号用于校准四个 demux ASIC 上的延迟。
在图 17 - 图 19 中,仅用四个 demux ASIC 中的两个显示了软件可编程的数字校准过程。
ASIC #1 的初始延迟设置为 11(以驱动 sdly11 信号到多路复用器输出)。ASIC #2 给出另一个延迟设置,数据采集板捕获斜坡信号。如果 ASIC #2 上的延迟设置过小,例如如图 17 所示的延迟值为 0-4,则 ASIC #2 捕获的斜坡值将比 ASIC #1 采样的数据点更早采样。ASIC #2 捕获的每个斜坡数据点大于 ASIC #1 捕获的下一个数据点,这一事实表明了这一点。
如果 ASIC #2 上的延迟设置在正确的范围内,例如如图 18 所示的延迟值 5-11,则与 ASIC #1 采样的数据点相比,ASIC #2 捕获的斜坡值将以正确的顺序进行采样。ASIC #2 捕获的每个斜坡数据点比 ASIC #1 捕获的前一个数据点大,比 ASIC #1 捕获的下一个数据点小,这一事实表明了这一点。
如果 ASIC #2 上的延迟设置太大,例如如图 19 所示的延迟值为 12-15,则 ASIC #2 捕获的斜坡值将比 ASIC #1 采样的数据点晚采样。ASIC #2 捕获的每个斜坡数据点小于 ASIC #1 捕获的下一个数据点,这一事实表明了这一点。
一旦 ASIC #2 确定了正确的范围,则选择范围中的中心点作为 ASIC #2 的 sync_in 延迟设置。中心点是该范围内最安全的设置,因为该设置大约是复位移除同步触发器的前一个和下一个上升时钟沿之间的半个周期。
在确定正确的 ASIC #2 设置后,必须确定围绕初始设置的正确 ASIC #1 范围(图 17 中使用的设置为 11),以找到正确的 ASIC #1 中点设置。在确定正确的 ASIC #1 设置后,使用类似的过程来找到 ASIC #3 的正确延迟设置,然后找到 ASIC #4 的正确设置。
在数字校准后,不需要使用第二个复位移除同步触发器,因为使用了中频设置来确保触发器恢复时间得到满足,并确保不会出现亚稳态问题。
图 20 显示了带有每个 ASIC 的主/从引脚和 sync_in/sync_out 引脚的四总线 ASIC 设计的完整框图,以及它们的连接方式。
在实际设计中,在为其中一个数据采集原型板上的四个 ASIC 确定一组有效的中点延迟设置后,将这些值编程到 ROM 中,并用作所有板子的初始设置,并跟踪初始设置的变化。有趣的是,每个板的校准延迟值很少偏离初始数据采集原型板的原始设置超过一两个延迟等级。
12.0 总结
使用异步复位是保证可靠的复位断言的最可靠的方法。尽管异步复位是一种安全可靠的复位电路的方法,但是如果操作不当,释放异步复位可能会导致严重的问题。
使用异步复位进行设计的正确方法是添加复位同步释放逻辑,以允许设计的异步复位,并确保同步复位释放,以允许正常设计功能的安全恢复。
只要在测试期间可以控制异步复位,使用 DFT 进行异步复位仍然是可以实现的。