电子说
复位信号几乎是除了时钟信号外最常用的信号了,几乎所有数字系统在上电的时候都会进行复位,这样才能保持设计者确定该系统的系统模式的状态,以便于更好的进行电子设计,并且在任意时刻,确保使用者总能对电路系统进行复位,使电路从初始的状态开始工作。
总结下来用途如下:
尽管复位极为重要,但是复位电路在设计中是最常忽视的方面。一个不正确设计的复位本身可以表现为一个不可重复的逻辑错误。
有关复位电平,实际上是与FPGA芯片内部的触发器结构有关,在之前的博文有提到过。作为xilinx 7系列触发器,其 R 端口既可用作同步置位/复位端口,也可用作异步预设/清除端口,但无论哪种方式,都是 「高电平有效」 。Altera的是 「低电平有效」 。
不同公司的触发器结构
如果RTL代码采用了低电平有效的复位模式,综合器将在复位信号驱动寄存器SR控制端之前的插入一个反相器(interver)。你必须使用一个查找表(look up table)来实现反向器,以利用LUT的输入端口。低电平有效的控制信号带来的额外的逻辑可能拉长了执行时间(runtime),将导致更低的FPGA资源利用率,也将影响时序和功耗。
同步低复位的代码如下:
module reset(
input clk,
input rst,
input [1:0] in,
output reg [1:0] out
);
always @ (posedge clk) begin
if (rst == 'b0)
out <= 'd0 ;
else
out <= in ;
end
endmodule
在使用vivado RTL 分析对应的电路结构如下:
RTL电路结构
使用vivado综合后结构如下:
综合后的实际电路
由于xilinx的器件结构中的触发器为高复位,所以会引入LUT实现复位信号的功能,引入额外的逻辑资源。
同步高复位的代码如下:
module reset(
input clk,
input rst,
input [1:0] in,
output reg [1:0] out
);
always @ (posedge clk) begin
if (rst == 'b1)
out <= 'd0 ;
else
out <= in ;
end
endmodule
在使用vivado RTL 分析对应的电路结构如下:
RTL电路结构
使用vivado综合后结构如下:
综合后的实际电路
由于xilinx的器件结构中的触发器为高复位,所以在使用同步高复位时,直接会将复位信号连接到复位输入端。
「同步复位的优点:」
❝由于同步复位信号是被时钟启动(Launch)和锁存(Latch),而启动和锁存的时钟彼此同步,所以复位信号的到达时间(Arrival Time)和所需时间(Required Time)就能很轻易地确定并进行正确的时序裕度(slack)分析。
❞
「同步复位的缺点:」
复位丢失示例
上图为快时钟的同步信号传输给慢时钟后造成复位丢失,具体解决方法可参考单信号的快时钟域转慢时钟域的跨时钟处理方法。
在一些情况中,在出于节省功耗的目的而使用门控时钟时,就可能出现问题。在复位信号发出时,时钟可能关闭。在这种情况下只能使用异步复位,并在时钟恢复前移除复位信号。
又如不同的芯片在复位的时候不能把自身的总线接口重置成三态或者输入状态,而是总线上有多个芯片同时通过接口将数据输出到总线,总线上将出现电平冲突,严重时可能导致接口损坏。因此,在这种时候,同步复位就不太适用。
门控时钟导致同步复位丢失
如果 ASIC/FPGA有内部三态总线,需要时钟来产生复位。为了阻止芯片上电时内部三态总线出现竞争,芯片应当有下图所示的异步上电复位。
输出使能的异步复位
当然也可以使用同步复位信号,但是也必须使用复位信号直接撤销三态使能。
用于输出使能的同步复位
这种同步技术的优点是能简化复位–高阻这一路径的时序分析。
异步低复位的代码如下:
module reset_async(
input clk,
input rst_n,
input [1:0] in,
output reg [1:0] out
);
always @ (posedge clk or negedge rst_n) begin
if (rst_n == 'b0)
out <= 'd0 ;
else
out <= in ;
end
endmodule
在使用vivado RTL 分析对应的电路结构如下:
RTL电路结构
使用vivado综合后结构如下:
由于xilinx的器件结构中的触发器为高复位,所以会引入LUT实现复位信号的功能,引入额外的逻辑资源。
异步高复位的代码如下:
module reset_async(
input clk,
input rst,
input [1:0] in,
output reg [1:0] out
);
always @ (posedge clk or posedge rst) begin
if (rst == 'b1)
out <= 'd0 ;
else
out <= in ;
end
endmodule
在使用vivado RTL 分析对应的电路结构如下:
使用vivado综合后结构如下:
这里综合后也没有引入新的组合逻辑资源,在该层次看并没有什么影响,「但是Xilinx FPGA综合规则中:有和没有异步复位的寄存器不能被包装在一个Slice,不同异步复位的寄存器不能被包装在一个Slice,这就导致在Slice中的资源无法充分利用从而造成资源浪费。」
「异步复位电路的优点:」
「异步复位电路的缺点:」
所有异步信号的缺点也同时等效是异步复位信号的问题,复位信号从本质讲就是一个频繁使用的控制信号,因此可以总结其缺点如下。
由于复位信号实现了对D触发器的控制(置位信号同理),所以但是本质上也是实现了控制相关物理电路进行开关实现置位或者复位,由于异步复位与系统时钟毫无关系,不考虑其余因素时,异步复位可以在任意时刻撤除。但复位信号恰好在时钟沿附近时,复位(置位)信号同样也要满足相应的“亚稳态窗口”的不能移除的需求,满足寄存器的“建立时间”与“保持时间”。
❝「恢复时间:」 如果复位信号在时钟有效沿之前撤消,并且离时钟有效沿非常接近,再加上时钟有效沿到达各个触发器有一定时间差(clock skew),那么极有可能一部份触发器仍处于复位状态中而对时钟沿没有响应,而一部份触发器对时钟有响应,那么从这一个时钟开始,电路的状态已经出错了。
「移除时间:」 如果复位信号在时钟有效沿之后撤消,并且离时钟有效沿非常接近,再加上时钟有效沿到达各个触发器有一定时间差(clock skew),那么极有可能一部份触发器从复位状态中恢复并响应了时钟,而一部份触发器没有响应,那么从这一个时钟开始,电路的状态已经出错了。
❞
下图中异步复位信号有足够的恢复时间,异步复位能正常释放。
当异步复位信号在时钟上升沿附近撤除时,导致触发器的输出为亚稳态,亚稳态前文已经讨论过了,亚稳态在电路中的危害是显而易见的。
恢复时间不足造成的亚稳态问题
❝如果你想让某个时钟沿起作用,那么你就应该在 “恢复时间” 之前是异步控制信号变无效;如果你想让某个时钟沿不起作用,那么你就应该在 “去除时间” 过后使控制信号变无效。
❞
我觉得这里其实本质上就是要避开触发器的建立时间和保持时间,避免在亚稳态窗口附近寄存器的双锁存结构和复位结构同时作用,这将会引入亚稳态。
异步确立和同步释放的复位电路通常会提供比完全异步或完全同步复位更可靠的复位。
电路结构如下图所示:
异步复位同步释放电路结构
根据结构可写出代码如下:
module reset_async_and_free_sync(
input clk,
input rst_n,
input [1:0] in,
output reg [1:0] out
);
reg rst_n_dly0,rst_n_dly1;
always @ (posedge clk or negedge rst_n) begin
if (rst_n == 'b0)begin
rst_n_dly0 <= 'd0 ;
rst_n_dly1 <= 'd0 ;
end
else begin
rst_n_dly0 <= 'd1 ;
rst_n_dly1 <= rst_n_dly0;
end
end
wire rstn = rst_n_dly1;
always @ (posedge clk or negedge rstn) begin
if (rstn == 'b0)
out <= 'd0 ;
else
out <= in ;
end
endmodule
在使用vivado对应的电路结构如下:
使用vivado综合后结构如下:
异步复位、同步释放具有异步复位和同步的优点,主要是:
异步复位对毛刺很敏感,这就意味着任何满足触发器最小复位脉冲宽度的输入都能引起触发器复位。如果复位线受到毛刺的影响,这就真的成为问题了。在设计中,可能没有足够高频的采样时钟来检测复位上的小毛刺;下面将会介绍过滤掉毛刺的方法。该方法需要一个数字延时来过滤毛刺。复位输入引脚也必须是施密特触发器引脚才有助于毛刺过滤。下图显示了复位毛刺滤波器的电路和时序图。
复位毛刺过滤
为了加人延时,一些生产商提供了用于延迟且能够手动实例化的宏单元。如果没有这样的宏单元,设计人员就需要在优化后的已综合设计中手动加入延时。第二种方法需要创建一个包含较慢缓冲器的模块,再多次实例化该模块以达到所期望的延迟。基于这种思想,可以产生许多变种的解决办法。
由于该方法使用了延迟链,因此一个缺点是所产生的延迟会随着温度、电压和工艺而变化。必须注意确保延迟在所有PVT环境下都能满足设计要求。
如果针对Xilinx FPGA的设计应用,我觉得不进行 “复位” 是可以的,不必要的数据信号可以不进行“复位”,这样可以节省资源,在xilinx的白皮书中也是这样建议的:
❝当一个Xilinx的FPGA芯片被重新配置时,每一个单元都将被初始化。在某种意义上讲,这是一个上电之后的“终极的”全局复位操作,因为它不仅仅是对所有的触发器进行了复位操作,还初始化了所有的RAM单元。随着Xilinx FPGA芯片内部的嵌入式RAM资源越来越多,这种“终极的”全局复位操作越来越有意义。对所有的RAM单元进行预定义,在软件仿真和实际操作中都是非常有帮助的,因为这样避免了在上电时采用复杂的启动顺序来清除存储单元内容的操作。
❞
通常可以将设计分为两部分,控制路径和数据路径
虽然在这里提到了不进行复位,但是不得不注意的是Xilinx的FPGA在上电后会对芯片内的资源进行复位,所以即使相关寄存器不进行复位,在芯片上电后也是能知道恢复到了芯片设置的默认状态的。在xilinx平台,部分复位设计实际是没有多大意义的。
编写代码使得输入做一级寄存处理,然后再将寄存输出的结果输出给out寄存器,此时对out这个寄存器不做复位处理。编写代码如下:
module noreset(
input clk,
input rst_n,
input [1:0] in,
output reg [1:0] out
);
reg [1:0] in_r;
always @ (posedge clk) begin
if (rst_n == 'b0)begin
in_r <= 'd0 ;
//out <= 'd0 ;
end
else begin
in_r <= in;
out <= in_r;
end
end
endmodule
在使用vivado RTL分析后对应的电路结构如下,从结构图中可以看到,第二级的输出寄存器没有添加相关复位信号控制逻辑资源。
使用vivado综合后结构如下,对输出寄存器没有设置复位,在综合分析时会自动设置复位信号为无效。
在一个设计中,无论是同步复位还是异步复位,其扇出数量往往仅次于时钟网络。复位网络通常会被布线在全局网络上,在布线的时候需要控制各个路径的时钟偏移保持在大致相等的水平上,使复位能“同时”撤离。
下图为一个树状全局复位网络。
树状全局复位网络
当复位信号驱动的模块和信号过多时,会导致扇出过大,从而使得布局布线变得困难。下图为一个全局复位网络的例子,从图中可以看出,复位信号扇出很大,资源分布散乱,从而给布局、布线带来很大的困难,增加了EDA的编译负担。
复位网络扇出过大
考虑下图的复位方案也会存在,由于rst_ol和rst_o2在撤离时可能存在一个时钟周期的偏差,因此,在实际电路系统中,该方式有可能导致复位失败,与前文提到的亚稳态的多个同步器道理相同。
多个复位同步器网络
比较合理的设计如下图:
模块化复位同步网络
图中的复位电路首先用两级寄存器对复位进行同步,得到根复位信号后再对其用复位同步器进行分发。由于同步后的根复位信号不会带来亚稳态的问题,因此,在分发根复位信号时再次使用两级寄存器对根复位信号进行同步和分发是很安全的。
根复位信号经过复位同步器分发后,各个子复位网络是各自独立的,并且扇出的数量比根复位网络要小很多。在布局布线的时候,这些子复位网络需要一一进行约束和时序分析。一般情况下,在设计的顶层代码中划分专门的复位模块,由该模块统一处理电路所需要的所有复位信号,使复位的方案更加清晰安全。在设计中,将复位电路的处理分散到各个底层模块是不安全的,有可能导致不同模块间的复位行为不一致,使电路因复位失败而工作在异常的状态上。
模块化复位网络
上图为使用模块化的复位的布局布线的结果,可以看到,复位信号经过模块化的处理后,降低了扇出,更有利于提高电路的工作性能。
在多时钟域电路中,合理的复位处理方式应如下图所示。各个时钟域的复位信号由各自的时钟进行同步。在每个时钟域内,电路总是能被正确地复位。
本文分析了复位的用途,通过同步复位和异步复位两个示例表示了在Xilinx FPGA中的不同复位的编写方法综合出的实际电路,指导我们在实际应用中去合理的进行复位设计,同时引入了恢复时间和去除时间的概念,进一步解释了在复位时,复位信号和时钟信号应该遵守的相关约定,进而结合异步复位的优点和同步复位的优点,介绍了异步复位同步释放的复位设计方法,在最后介绍了合理的复位网络设计与多时钟域的复位设计。根据本文的分析,可以小结一下关于复位的相关操作的注意事项以及复位设计的小技巧:
全部0条评论
快来发表一下你的评论吧 !