目录
1.0 resets, Resets, RESETS, and then there’s RESETS
2.3 Assignment operator guideline
4.2 使用Verilog对具有异步复位和异步置位的触发器建模
10.2 复位解除的sequenced coordination
本文是对Synchronous Resets? Asynchronous Resets? I am so confused! How will I ever know which to use?的学习笔记,有不确定的地方会以蓝色附上原文。
摘要
本文将研究同步和异步复位的优缺点。然后,将查看每种类型复位的使用情况,然后为每种类型复位的正确使用提出建议。
本文还将详细介绍一种有趣的同步技术,该技术使用数字校准来同步多ASIC设计上的复位释放。
1.0 resets, Resets, RESETS, and then there’s RESETS
如果不首先向最常见的复位用法致敬,就无法开始考虑复位用法和方式的讨论。这种不希望的复位几乎每天都会发生在经过测试、验证、制造并集成到消费者、教育、政府和军事环境中的系统中。这种复位是在通常被称为“死亡蓝屏”的情况下进行的,这是由于某家软件公司的操作系统、操作系统所服务的软件程序和执行操作系统软件的硬件之间的软件不兼容造成的。
为什么要关心这些烦人的小复位?为什么要花一整篇论文来讨论这样一个琐碎的话题?任何使用过加载了特定操作系统的电脑的人都知道,硬件复位非常方便。它将通过对系统中具有或需要复位的每个芯片应用系统复位,使计算机恢复到已知的工作状态(至少暂时)。
对于单个ASIC,复位的主要目的是迫使ASIC设计(行为、RTL或结构)进入已知状态进行模拟。一旦建立了ASIC,则由系统、ASIC的应用和ASIC的设计来确定对ASIC复位应用的需要。例如,许多数据路径通信ASIC被设计为与输入数据流同步,处理数据,然后输出。如果同步丢失,ASIC会通过例程重新获取同步。如果这种类型的ASIC设计正确,使得所有未使用的状态都指向“开始获取同步”状态,则它可以在系统中正常工作,而无需复位。如果ASIC中的状态机在综合阶段利用了“不在乎”的逻辑减少,则在这种ASIC通电时需要进行系统复位。(可能指因设计不周而使“开始获取同步”状态被综合忽略掉了)
作者认为,一般来说,ASIC中的每个触发器都应该是可复位的,无论系统是否需要它。此外,作者更喜欢按照本文中详细介绍的指南使用异步复位。这些准则也有例外。在某些情况下,当跟随器触发器(移位寄存器触发器)用于高速应用时,可以从一些触发器中消除复位,以实现更高性能的设计。这种类型的环境需要复位有效保持多个时钟以将ASIC置于已知状态。
在为ASIC设计选择复位策略之前,必须考虑许多设计问题,例如是使用同步复位还是异步复位,每个触发器是否会接收复位,复位树将如何布局和缓冲,如何验证复位树的时序,如何用测试扫描矢量对复位进行功能测试,以及如何在多个时钟区之间使用复位。
此外,当在需要特定复位释放顺序的多个ASIC之间使用复位时,必须采用特殊技术来调整芯片和电路板制造的差异。本文的最后几节将讨论后一个问题。
2.0 通用触发器编码方式注意
2.1 同步复位触发器与没有复位的跟随器触发器
每个Verilog过程块或VHDL进程应该只对一种类型的触发器进行建模。换言之,设计者不应将可复位触发器与跟随触发器(没有复位的触发器)混合[12]。跟随触发器是简单数据移位寄存器的触发器。
在示例1a的Verilog代码和示例1b的VHDL代码中,触发器用于捕获数据,然后其输出通过跟随触发器。此设计的第一阶段是通过同步复位进行复位。第二级是跟随器触发器并且不被复位,但是因为这两个触发器是在同一过程块/进程中infer的,所以复位信号rst_n将被用作第二触发器的数据使能。这种编码方式将生成如图1所示的无关逻辑。
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
示例1a-对不同触发器建模的错误的Verilog编码方式
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;
示例1b-对不同触发器建模的错误的VHDL编码方式
图1-错误的编码方式产生了一个不必要的可加载触发器的设计
作者注:Synplify Pro中rst_n将成为第二个触发器的“加载数据”信号,LSE中rst_n将成为第一触发器和第二触发器之间MUX的选择信号。
对跟随触发器建模的正确方式是使用如示例2a所示的两个Verilog过程块或如示例2b所示的二个VHDL过程。这些编码方式将生成如图2所示的逻辑。
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
示例2a-使用Verilog对不同触发器建模的正确编码方式
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;
示例2b-使用VHDL对不同触发器建模的正确编码方式
图2-两种不同类型的触发器,一种带同步复位,另一种不带
应当注意,由示例1a和示例1b中的代码生成的无关逻辑仅仅是使用同步复位的结果。如果使用异步复位,那么两种编码方式将合成为相同的设计,而不需要任何额外的组合逻辑。不同触发器样式的生成在很大程度上是HDL代码中使用的敏感量列表和if-else语句的函数。有关敏感量列表和其他编码方式的更多详细信息,请参见第3.1节。
2.2 Flip-flop inference style
Each inferred flip-flop should not be independently modeled in its own procedural block/process. As a matter of style, all inferred flip-flops of a given function or even groups of functions should be described using a single procedural block/process. Multiple procedural blocks/processes should be used to model macro level functional divisions within a given module/architecture. The exception to this guideline is that of follower flip-flops as discussed in the previous section (section 2.1) where multiple procedural blocks/processes are required to efficiently model the function itself.
2.3 Assignment operator guideline
In Verilog, all assignments made inside the always block modeling an inferred flip-flop (sequential logic) should be made with nonblocking assignment operators[3]. Likewise, for VHDL, inferred flip-flops should be made using signal assignments.
3.0 同步复位
在为本文进行研究时,收集并回顾了ESNUG和SOLV-IT的文章集。大约80%以上的文章集中在同步复位问题上。在许多SNUG论文中,演讲者会声称,“我们都知道,在ASIC中进行复位的最佳方式是严格使用同步复位”,或者“异步复位是糟糕的,应该避免。”然而,几乎没有证据证明这些说法是合理的。使用同步复位有一些优点,但也有缺点。异步复位也是如此。设计者必须使用适合的设计方法。
同步复位是基于这样的前提,即复位信号将仅影响或复位在时钟有效边沿上的触发器的状态。复位可以作为产生触发器的d输入的组合逻辑的一部分应用于触发器。如果是这种情况,则对复位进行建模的编码方式应该是if-else的优先级方式,复位在if条件中,所有其他组合逻辑在else部分中。如果不严格遵守这种方式,可能会出现两个问题。首先,在一些仿真器中,基于逻辑方程,逻辑可以阻止复位到达触发器。这只是一个仿真问题,而不是硬件问题,但请记住,复位的主要目标之一是将ASIC置于已知状态进行仿真。其次,由于复位树的高扇出,复位可能是相对于时钟周期的“延迟到达信号”。即使复位将在复位缓冲树中缓冲,明智的做法是限制复位到达本地逻辑后必须遍历的逻辑量。这种类型的同步复位可以与任何逻辑或库一起使用。示例3显示了这种类型的同步复位的实现,作为带有进位的可置位计数器的一部分。
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
示例3b-带同步复位的可置位计数器的Verilog代码
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;
示例3b-带同步复位的可置位计数器的VHDL代码
图3-带同步复位的可置位计数器
第二种类型的同步复位是基于具有同步复位引脚的触发器的可用性以及设计者和综合工具利用这些引脚的能力。有时会出现这种情况,但更常见的情况是,上面讨论的第一种方式是工具的实现[22][26]。
3.1 编码方式和示例电路
示例4a的Verilog代码和4b的VHDL代码展示出了对同步复位触发器建模的正确方式。请注意,复位信号不在敏感量列表中。对于Verilog来说,从敏感量列表中省略复位是使复位同步的原因。对于VHDL,从敏感量列表中省略复位,并在“if clk'event and clk=1”语句使复位同步后检查复位。还要注意的是,通过使用if-else编码样式,复位被赋予了比任何其他任务更高的优先级。
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
示例4a-使用Verilog对具有同步复位的触发器进行建模的正确方法
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
SNUG San Jose 2002 Synchronous Resets? Asynchronous Resets?
Rev 1.1 I am so confused! How will I ever know which to use?
8
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;
示例4b-使用VHDL对具有同步复位的触发器进行建模的正确方法
对于采用同步复位方式#1设计的触发器(复位将数据选通到d输入),Synopsys有一个开关,设计者可以使用它来帮助推断具有同步复位的触发器。
编译器指令:sync_set_reset
一般来说,作者建议只在需要时使用Synopsys开关,并产生影响;然而,我们的同事Steve Golson指出,sync_set_reset指令不会影响设计的功能,因此在门级模拟之前,它的遗漏不会被识别出来,因为发现故障需要在项目进度后期重新综合设计。由于每个模块只需要一次该指令,因此建议将其添加到具有同步复位的每个模块[19]。
3.2 同步复位的优点
同步复位将综合出更小的触发器,特别是如果复位是用产生d输入的逻辑门控制的。但在这种情况下,组合逻辑门数目会增长,因此总体门数目的节省可能不会那么显著。如果设计紧凑,则每个触发器一个或两个门的面积节省可以确保ASIC适合于管芯。然而,在当今具有巨大芯片尺寸的技术中,每个触发器节省一个或两个门通常是无关紧要的,并且不会成为设计是否适合芯片的重要因素。
当使用基于时钟周期的仿真器时,同步复位可以更容易地使用。正是出于这个原因,建议在《重用方法手册》[18]第3.2.4节(第2版,第1版第3.2.3节)中进行同步复位。
同步复位通常确保电路100%同步。
同步复位确保复位只能在有效时钟边沿发生。时钟可以滤除一些小的复位故障;然而,如果这些小故障发生在有效时钟边沿附近,触发器可能会进入亚稳态。
在某些设计中,复位必须由一组内部条件生成。对于这些类型的设计,建议使用同步复位,因为它可以过滤时钟之间的逻辑电路毛刺。
通过使用同步复位和多个时钟作为复位过程的一部分,可以在复位缓冲树内使用触发器来帮助缓冲树的timing保持在一个时钟周期内。
3.3 同步复位的缺点
同步复位可能需要脉冲拓宽电路来保证足够宽的复位脉冲宽度,以确保在时钟的有效边沿期间存在复位[14]。
设计者必须使用悲观和乐观的仿真器。如果复位是由ASIC中的组合逻辑生成的,或者如果复位必须遍历本地组合逻辑的许多级别,则这可能是一个问题。在仿真过程中,根据复位是如何生成的,或者复位是如何应用于功能块的,复位可以被X屏蔽。ESNUG的大量文章都谈到了这个问题。大多数模拟器不会解决某些X逻辑条件,因此会阻止同步复位[5][6][7][8][9][10][11][12][13][20]。
从本质上讲,同步复位需要一个时钟来复位电路。这对某些设计风格来说可能不是一个缺点,但对其他设计风格来说,这可能是一个烦恼。如果ASIC/FPGA具有内部三态总线,则引起复位条件的时钟要求非常重要。当芯片通电时,为了防止内部三态总线上的总线争用,芯片必须具有通电异步复位[17]。
4.0 异步复位
异步复位是作者首选的复位方法。然而,单独的异步复位可能非常危险。许多工程师喜欢将复位应用于电路并使逻辑进入已知状态的想法。异步复位的最大问题是复位释放,也称为复位移除。该主题将在第5.0节中详细阐述。
异步复位触发器在触发器设计中加入了一个复位引脚。复位引脚通常为低有效(当连接到触发器复位引脚的信号变为逻辑低电平时,触发器进入复位状态)
4.1 编码方式和示例电路
示例5a的Verilog代码和示例5b的VHDL代码展示出了对异步复位触发器建模的正确方式。请注意,复位是敏感量列表的一部分。对于Verilog来说,将复位添加到敏感度列表是使复位异步的原因。为了使异步触发器的Verilog模型能够正确仿真,敏感量列表应仅在异步复位信号的上升沿处于有效状态。
因此,在示例5a中,程序块总是将在复位的上升沿输入,然后if条件将检查正确的复位电平。
(这两句似乎有些问题,复位信号不是下降沿触发吗?)
Synopsys要求,如果敏感量列表中的任何信号都是边缘敏感的,那么敏感量列表中所有信号都必须是边缘敏感信号。换句话说,Synopsys强制采用正确的编码方式。Verilog仿真没有这一要求,但如果敏感量列表不仅仅对有效时钟边沿和复位上升沿敏感,则仿真模型将是不正确的[4]。此外,只有时钟和复位信号可以在敏感量列表中。如果包括其他信号(合法的Verilog、非法的Verilog RTL综合编码方式),则仿真模型对于触发器将是不正确的,并且Synopsys将在读取用于综合的模型时报告错误。
对于VHDL,在敏感量列表中包括复位,并在“if clk'event and clk=1”语句使复位异步之前检查复位。还要注意,通过使用if-else编码样式,复位被赋予了比任何其他任务(包括时钟)更高的优先级。由于VHDL敏感量列表和触发器编码方式的性质,可以在敏感量列表中包括附加信号,而不会直接对仿真和综合产生不良影响。然而,良好的编码方式建议只有可以直接改变触发器输出的信号才应该在敏感量列表中。这些信号是时钟和异步复位。所有其他信号将减慢仿真并被综合忽略。
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
示例5a-使用Verilog对具有异步重置的触发器进行建模的正确方法
library ieee;
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;
示例5b-使用VHDL对具有异步重置的触发器进行建模的正确方法
综合异步复位的方法将取决于复位缓冲树的设计方法。如果复位是直接从外部引脚驱动的,那么通常在复位引脚上执行set_drive 0并在复位网络上执行set_dont_touch_network来保护网络不被综合修改。然而,至少有一篇ESNUG文章表明情况并非总是如此[16]。
一个ESNUG贡献者[15]指出,有时可能还需要复位网络上的set_resistance 0。
我们的同事Steve Golson指出,您可以在网络上set_resistance 0,或者创建一个电阻为0的自定义线载模型,并使用以下命令将其应用于复位输入端口:set_wire_load -port_list reset
SolvNet最近更新的一篇文章还指出,从Synopsys 2001.08版本开始,理想网络的定义略有变化[24],set_ideal_net命令可以用于创建理想网络,“不进行定时更新,不进行延迟优化,也不进行DRC修复。”
另一位同事Chris Kiegle报告称,在v2001.08之前的设计中,在网络上执行set_disable_timing有助于清理定时报告[2],这似乎得到了SolvNet另外两篇文章的支持,一篇与综合有关,另一篇与物理综合有关,这两篇文章建议使用set_false_path和set_disable _timing命令[21][25]。
4.2 使用Verilog对具有异步复位和异步置位的触发器建模
关于Verilog中的异步复位建模,这里还需要注意一点。如果没有设计者的一点帮助,Verilog中包含异步置位和异步复位的触发器的仿真模型可能无法正确仿真。通常,大多数同步设计不具有同时包含异步置位和异步复位的触发器,但有时需要这样的触发器。示例6的编码风格可以用于校正Verilog RTL仿真,其中复位和置位同时被设为有效并且复位首先被释放。
首先要注意的是,这个问题只是一个仿真问题,而不是综合问题(综合推断出具有异步置位/复位的正确触发器)。仿真问题是由于alwasy块仅在置位、复位或时钟信号的有效边沿输入。如果复位变为有效状态,然后置位变为有效,然后如果复位变成非有效状态,则触发器应首先进入复位状态,然后进入置位状态。由于这两个输入都是异步的,一旦复位被移除,置位就应该是有效的,但在Verilog中不会是这样,因为在下一个上升时钟沿之前没有办法触发always块。
对于那些允许同时设复位和置位为有效,然后首先移除复位的罕见设计,解决这个仿真问题的方法是使用translate_off/translate_on指令中包含的自校正代码对触发器进行建模,并强制输出为这一条件的正确值。这里最好的建议是尽可能避免需要同时使用异步置位和异步复位的触发器的情况。示例6中的代码显示了将正确仿真并保证综合前和综合后仿真之间结果相同的修复方法。此代码使用translate_off/translate_on指令强制为异常条件[4]提供正确的输出。
// 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
示例6–使用Verilog的异步置位/复位仿真和综合模型
4.3 异步复位的优点
使用异步复位的最大优点是,只要供应商库具有异步可复位触发器,就可以保证数据路径是干净的。由于插入了处理同步复位的逻辑,突破数据路径时序限制的设计无法在数据路径中增加门和额外的净延迟。当然,如果供应商库有带同步复位输入的触发器,并且设计者可以让Synopsys实际使用这些引脚,那么这个论点就不成立了。使用异步复位,可以保证设计者不会将复位添加到数据路径中。示例7中的代码推断出不会添加到数据路径中的异步复位。
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
示例7a-带异步复位的可置位计数器的Verilog代码
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;
示例7b-带异步复位的可置位计数器的VHDL代码
图4-带异步复位的可置位计数器
异步复位的另一个优点是,可以在时钟存在或不存在的情况下复位电路。
作者的经验是,通过使用本节中描述的异步重置的编码方式,综合界面往往是自动的。也就是说,通常不需要添加任何综合设置来使综合工具映射到具有异步复位引脚的触发器。
4.4 异步复位的缺点
工程师们给出了许多原因来解释为什么异步复位是邪恶的。
重用方法手册(RMM)建议不要使用异步复位,因为它们不能与基于时钟周期的仿真器一起使用。这根本不是真的。基于时钟周期的仿真器的基础是所有输入在时钟沿上变化。由于时序分析不是基于时钟周期的仿真的一部分,异步复位可以简单地应用于非有效时钟的边沿。
对于DFT,如果异步复位不是直接从I/O引脚驱动的,则必须禁用来自复位驱动器的复位网络以进行DFT扫描和测试。这对于第6节所示的同步器电路是必需的。
一些设计者声称,使用异步复位的设计很难进行静态时序分析。复位树必须针对同步和异步复位进行时序分析,以确保复位的释放可以在一个时钟周期内发生。必须在布局后对复位树进行时序分析,以确保满足此时序要求。
异步复位的最大问题是它们是异步的,无论是在复位的有效还是释放。有效不是问题,释放是问题。如果异步复位在触发器的有效时钟边沿处或附近被释放,则触发器的输出可能变为亚稳态,因此ASIC的复位状态可能丢失。
异步复位可能存在的另一个问题,取决于其来源,是由于电路板或系统复位上的噪声或故障而导致的虚假复位。有关复位故障的可能解决方案,请参阅第8.0节。如果这是系统中的一个实际问题,那么人们可能会认为使用同步复位是解决方案。同步复位存在一个不同但相似的问题,如果这些伪复位脉冲发生在时钟边沿附近,触发器仍然可以变为亚稳态。
5.0 异步复位问题
在与一位同事讨论这篇论文时,这位工程师首先表示,由于他所研究的都是FPGA,因此它们没有ASIC那样的复位问题(这是一种误解)。他接着说,他总是有一个系统异步复位,可以覆盖一切,使芯片进入已知状态。然后,工程师被问到,如果复位的释放发生在时钟边沿上或附近,使得触发器进入亚稳态,FPGA或ASIC会发生什么。
太多的工程师只是使用异步复位,认为没有问题。他们在受控仿真环境中测试复位,一切正常,但在系统中,设计间歇性地失败。设计者没有考虑到系统(非受控环境)中复位的释放可能导致芯片进入亚稳态或未知状态,从而使复位失效的想法。必须注意复位的释放,以防止复位释放时芯片进入亚稳态未知状态。当使用同步复位时,复位的上升沿和下降沿都必须远离时钟的有效边沿。
如图5所示,异步复位信号将与时钟信号异步释放。这种情况有两个潜在的问题:(1)复位恢复时序违例(2)复位移除发生在不同时序元件的不同时钟周期中
图5-异步复位释放的恢复时间问题
5.1 复位恢复时间
复位恢复时间是指从复位被释放到时钟信号再次变高之间的时间。Verilog-2001标准[17]有三个内置命令来建模和测试恢复时间以及信号去除时序检查:$recovery、$remove和$recrem(后者是恢复和去除时序检查的组合)。
恢复时间也称为“CLK之前PRE或CLR非有效建立时间”形式的tsu建立时间↑”[1] 。
丢失恢复时间可能会导致寄存器数据输出的信号完整性或亚稳态问题。
5.2 穿越不同时钟周期的复位释放
当复位释放与时钟上升沿异步时,复位信号和时钟信号中的一个或两个的传播延迟的微小差异可能导致一些寄存器或触发器先于其他寄存器或触发器退出复位状态。
6.0 复位同步器
指南:每个使用异步复位的ASIC都应该包括一个复位同步电路!!
如果没有复位同步器,即使在仿真过程中复位有效,异步复位在最终系统中的作用也是无效的。
图6中的重置同步器逻辑被设计为利用异步和同步复位方式中的最佳方式。
图6-复位同步器框图
外部复位信号异步地复位一对主复位触发器,主复位触发器又通过复位缓冲树异步地将主复位信号驱动到设计中的其余触发器。整个设计将异步复位。
复位释放是通过使复位信号无效来完成的,然后复位信号允许通过复位同步器对第一主复位触发器(其被连接为高电平)的d输入进行打拍。通常在复位移除之后需要两个上升时钟沿来同步主复位的移除。
需要两个触发器来将复位信号与时钟脉冲同步,其中第二触发器用于去除任何亚稳态,该亚稳态可能是由于复位信号被异步去除并且过于接近上升时钟沿而引起的。如第4.4节所述,这些同步触发器必须保持在扫描链之外。
图7-可预测的复位移除以满足复位恢复时间
现在对时序的更仔细检查表明,复位分布时序是clk-to-q传播延迟、通过复位分布树的总延迟以及满足目标寄存器和触发器的复位恢复时间的总和,如图7所示。
复位同步器电路的代码如示例8所示。
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
示例8a-使用Verilog正确编码复位同步器
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;
示例8a-使用VHDL正确编码复位同步器
7.0 复位distribution(分布)树
复位分布树几乎需要与时钟分布树一样多的关注,因为在典型的数字设计中,复位输入负载的数量通常与时钟输入负载的数目一样多,如图8所示。复位树的时序要求对于同步和异步复位方式都是常见的。
图8-复位分布树
时钟分布树和复位分布树之间的一个重要区别是密切平衡the skew between the distributed resets的需要。与时钟信号不同,只要与任何复位信号相关联的延迟足够短,以允许在时钟周期内传播到所有复位负载并且仍然满足所有目的寄存器和触发器的恢复时间,复位信号之间的偏斜就不是关键的。
Care must be taken to analyze the clock tree timing against the clk-q-reset tree timing. The safest way to clock a reset tree (synchronous or asynchronous reset) is to clock the internal-master-reset flip-flop from a leaf-clock of the clock tree as shown in Figure 9. If this approach will meet timing, life is good. In most cases, there is not enough time to have a clock pulse traverse the clock tree, clock the reset-driving flip-flop and then have the reset traverse the reset tree, all within one clock period.
图9-由延迟缓冲时钟驱动的复位树
为了帮助加快复位到达所有系统触发器的速度,复位驱动器触发器使用更早的时钟进行打拍,如图10所示。必须进行布局后时序分析,以确保异步复位的复位释放以及同步复位的复位和释放不会超过触发器的时钟;这意味着复位必须不违反触发器上的设置和保持时间。通常,在布局完成并且两棵树的实际时间可用之前,无法进行这样的详细时间调整。
图10-与时钟分布树并行驱动的复位同步器
忽视这个问题不会使它消失。天啊,我们都认为复位是一个基本的话题。
8.0 复位故障过滤
如本文前面所述,异步复位的最大问题之一是它们是异步的,因此带有一些必须根据复位源处理的特性。对于异步复位,任何足以满足触发器最小复位脉冲宽度的输入都将导致触发器复位。如果复位线出现故障,这可能是一个真正的问题。这里介绍了一种方法,可以过滤掉故障,但它很难看!这种解决方案需要数字延迟(意味着延迟会随着温度、电压和工艺的变化而变化)来过滤小故障。复位输入焊盘也应该是施密特触发焊盘,以帮助进行故障过滤。图11显示了这种方法的实现。
图11-复位故障过滤
为了增加延迟,一些供应商提供了一个可以手动实例化的硬核。如果这样的延迟核不可用,设计者可以在优化后手动将延迟实例化到合成设计中——记住,在插入延迟后不要优化此块,否则它将被删除。当然,这些元素可以应用“don’t touch”属性来防止它们被删除。第二种方法是实例化模块中的慢缓冲区,然后多次实例化该模块以获得所需的延迟。许多变体可以扩展这一概念。
并非所有系统都需要此故障过滤器。设计者必须研究系统需求,以确定是否需要延迟。
9.0 异步复位的DFT(可测试性设计)
将可测试性设计(DFT)功能应用于设计是一个两步过程。首先,将设计中的触发器缝合在一起,形成可从外部I/O引脚访问的扫描链,这称为扫描插入。扫描链通常不是功能设计的一部分。其次,运行一个软件程序来生成一组扫描矢量,当将其应用于扫描链时,将测试和验证设计。该软件程序称为Automatic Test Program Generation(自动测试程序生成)或ATPG(这玩意不是Automatic Test Pattern Generation吗?)。扫描矢量的主要目的是给铸造厂提供测试晶圆和芯片的以及最终封装零件等产品的测试矢量。
应用ATPG向量来创建测试的过程基于:
1.将已知状态扫描到芯片中的所有触发器中
2.将触发器从扫描移位模式切换到功能数据输入模式
3.施加一个功能时钟
4.将触发器切换回扫描移位模式,以在扫描下一测试向量的同时扫描出一个功能时钟的结果
DFT工艺通常需要两个控制引脚。将设计置于“测试模式”的引脚。该引脚用于屏蔽不可测试的逻辑,如内部生成的异步复位、异步组合逻辑的反馈回路和许多其他需要特别注意的逻辑条件。该引脚通常在整个测试过程中保持恒定。第二个控制引脚是切换启用引脚。
为了使ATPG向量工作,测试程序必须能够控制芯片中扫描链上触发器的所有输入。这不仅包括时钟和数据,还包括复位引脚(同步或异步)。如果复位直接由I/O引脚驱动,则复位保持在非复位状态。如果复位是内部产生的,则内部主复位通过测试模式信号保持在非复位状态。如果内部生成的复位在ATPG期间没有被屏蔽,则复位条件可能在扫描期间发生,导致芯片中的触发器被复位,从而丢失正在扫描的向量数据。
即使ATPG的异步复位保持为非复位状态,这并不意味着复位/置位不能作为DFT过程的一部分进行测试。在用测试模式锁定复位并生成ATPG向量之前,可以手动生成一些向量来创建复位/置位测试向量。测试DFT异步复位所需的过程非常直接,并且可以使用一些DFT工具自动进行。如果故障诊断仪没有自动测试异步复位/置位,则必须手动设置。手动测试异步复位/置位的基本步骤如下:
1.将所有ones扫描到扫描链中
2.复位并释放异步复位
3.扫描出结果并扫描所有zeros
4.复位并释放复位
5.扫描结果
6.将复位输入设置为非复位状态,然后应用ATPG生成的向量。
此测试方法将扫描测试异步复位和置位。这些手动生成的向量将被添加到ATPG向量中,为产品测试提供更高的故障覆盖率。如果设计使用具有同步复位输入的触发器,那么稍微修改上述手动异步复位测试将对同步复位环境进行类似的测试。在应用复位时,将功能时钟添加到上述步骤中。所有其他步骤将保持不变。
对于本文讨论的复位同步器电路,两个同步器触发器不应包含在扫描链中,而应使用上述手动过程进行测试。
10.0 多时钟重置问题
对于多时钟设计,应为每个时钟域使用单独的异步复位同步器电路和复位分布树。这样做是为了确保复位信号确实可以保证满足每个时钟域中每个寄存器的复位恢复时间。
如前所述,异步复位不是问题。问题是优雅地释放复位,并在释放复位后同步启动所有逻辑。
根据设计的限制,可以采用两种技术:(1)non-coordinated复位释放(2)复位释放的sequenced coordination
(即不同时钟域的复位释放没有先后顺序和有先后顺序)
图12-多时钟复位释放
10.1 non-coordinated复位释放
对于许多多时钟设计,与在另一个时钟域中复位释放的时间相比,在一个时钟域内复位释放的确切时间并不重要。通常在这些设计中,任何跨越时钟边界的控制信号都通过某种类型的请求-确认握手序列,并且确认从一个时钟域到另一个时钟域的延迟不会导致硬件的无效执行。对于这种类型的设计,如图12所示创建单独的异步复位同步器就足够了,并且arst_n、brst_n和crst_n可以按任何顺序释放这一事实对设计来说都不重要。
10.2 复位解除的sequenced coordination
对于一些多时钟设计,必须按顺序和正确的顺序复位释放。对于这种类型的设计,可能需要创建如图13所示的按优先级排列的异步复位释放同步器,以确保在bclk时钟域逻辑激活之前释放arst_n并激活所有aclk时钟域的逻辑,在bclk时钟域逻辑激活之后激活cclk的逻辑。
(即如下图所示,按照a-b-c的顺序进行释放)
图13-多时钟的复位有序释放
对于这种类型的设计,只有最高优先级的异步复位同步器输入被绑定在高位。其他异步复位同步器输入连接到来自更高优先级时钟域的主复位。
11.0 多ASIC复位同步
存在具有多个ASIC的设计,其要求在所有多个ASIC上进行精确同步复位释放。满足本节中所述的这种类型的设计的一种方法是使用不同的异步复位同步方案,该方案只需要一个复位释放触发器而不是第6.0节中所描述的两个触发器,加上数字校准的同步延迟,以正确地对从多个ASIC的复位释放进行排序。
考虑数字存储示波器(DSO)上数据采集板的实际设计。简单来说,DSO是一种测试仪器,它可以探测模拟信号,连续对信号进行采样和模数(A2D)转换,并以最快的速度将采样的数字数据连续存储到存储器中。在所请求的触发条件发生后,与触发条件相关联的其余数据被存储到存储器中,然后DSO控制逻辑(通常是commercial(商用的?)微处理器)访问数据并将数据值的波形绘制到屏幕上以进行视觉检查。
对于这种类型的实际设计,数据采集板包含四个数字解复用器(demux)ASIC,每个ASIC捕获四分之一的数据样本以发送到存储器,如图14所示。
图14-具有同步复位释放问题的多ASIC设计
对于这种数字采集系统,一旦复位被移除,ASIC就必须开始捕获数据并生成存储器地址以将数据写入存储器。数据采集和地址生成都在持续运行,捕获数据样本并覆盖先前写入的存储器位置,直到触发电路导致地址计数器停止并保持最近捕获的数据。通常,触发器被设置为保持并显示波形的90%作为触发前数据和波形的10%作为触发后数据。由于通常不可能预测何时会发生触发,因此有必要在复位移除之后连续采集数据,直到触发信号停止数据采集。
该设计中用于进行高速数据采集的方法是使用四个解复用器ASIC,它们捕获数字化波形的每四个点。由于解复用器ASIC通常以非常快的时钟速率运行,并且由于每个解复用器ASIC还必须生成伴随的地址计数值以将数据样本存储到存储器,所以重要的是,所有四个解复用器ASIC都以正确的顺序启动其各自的地址计数器,以确保存储在存储器中的数据样本可以容易地读回以在DSO显示器上绘制波形。
这种类型的设计的问题是同时(在相同的相对时钟周期内)从四个ASIC器件准确地去除复位信号,使得四个ASIC捕获与所有四个ASIC上的地址-#0对应的正确排序的数据样本,随后是所有四个ASICs上的地址-#1,等等。使得存储在存储器中的数据可以以正确的顺序从存储器中读回(在触发DSO之后),以在DSO屏幕上显示准确的波形。
对于这种类型的设计,有许多因素阻碍了正确的复位释放,从而阻碍了写入存储器的数据值的正确排序。
首先,对于非常高速的设计(为了在探测其他高速电路的同时捕获足够数量的数据样本,DSO通常是非常高速设计),复位信号到四个ASIC的相对电路板走线长度必须保持在非常严格的公差内;因此,电路板布局是一个问题。
其次,制造的ASIC批次内或批次之间的工艺变化可能会产生超过超短ASIC时钟周期的延迟。在制造过程中选择要插入的四个ASIC可以导致在同一数据采集板上选择具有不同相对延迟的四个器件。放置在一块板上的四个ASIC的相对处理速度无法保证(四个ASIC中哪一个总是最快的?谁知道呢!)
第三,不同测试环境中的温度波动也会增加延迟的差异。ASIC在DSO外壳内的相对定位可能是这种高速系统温度显著差异的原因。
第四,拆除DSO的盖子以排除原型故障可能会在四个ASIC之间引入与盖子关闭时不同的温度变化。
对于实际设计,公共复位信号(reset_n)被连接到所有四个解复用器ASIC来复位,但是复位信号没有从解复用器ASIC去释放复位。使用单独的同步信号来标记每个解复用器ASIC上的复位释放许可。
图15-同步复位释放逻辑框图
使用图15中所示的逻辑来处理多ASIC同步复位释放逻辑。这种逻辑对于主ASIC和从ASIC都是通用的。
异步复位(图15中rst_n变低)驱动主复位信号mstrrst_n,主复位信号通过复位树驱动到所有ASIC(主ASIC和从ASIC)上的可复位逻辑的其余部分;因此,复位是异步和即时的。
每个ASIC有三个引脚专门用于同步复位释放。
每个ASIC上的第一个引脚是专用的主/从选择引脚。当该引脚被束缚为高时,ASIC被置于主模式。当引脚被绑定为低电平时,ASIC被置于从模式。
每个ASIC上的第二个引脚是sync_out引脚。在从ASIC上,sync_out引脚未使用,并且处于悬空状态。当复位被释放时(当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信号连接到可编程延迟块,然后通过复位输入上的high-assertion使能,然后将其传递到同步复位释放触发器。ASIC上的下一个上升时钟沿将导致复位被同步释放,从而允许每个ASIC上的地址计数器以同步有序的方式开始计数。
如前所述,问题在于确保sync_in信号以正确的顺序移除四个ASIC上的复位。
作者:这部分是在不太懂,第11节剩下的跳过就不写了,以后再说
12.0 结论
使用异步复位是保证复位可靠性的最稳妥方法。尽管异步复位是可靠复位电路的安全方式,但如果操作不当,移除异步复位可能会导致重大问题。
使用异步复位进行设计的正确方式是添加复位同步器逻辑以允许设计的异步复位,并确保复位移除的同步以允许正常设计功能的安全恢复。
只要在测试过程中可以控制异步复位,使用具有异步复位的DFT仍然是可以实现的。