写在前面
本文记录总结之前在FPGA分享会中学到的关于赛灵思系列的复位功能操作的设计以及建议,进行分析总结。
学习FPGA入门,有一说一我的领路人大部分都是用的intel的芯片下板验证,当时也不理解为啥子要这样复位,写抄就完了甚至感觉还挺有道理哈哈哈哈。
但是现在随着学习的深入我渐渐得发现复位还真是门学问。话不多说正文见。
总述
- 对于Altera的FPGA而言,因为里面的flip-flop只支持低有效的异步复位,所以推荐使用低有效的异步复位。
- 对于xilinx 7系列的FPGA而言,flip-flop支持高有效的异步复/置位和同步复位/置位。对普通逻辑设计,同步复位和异步复位没有区别,当然由于器件内部信号均为高有效,因此推荐使用高有效的控制信号,最好使用高有效的同步复位。输入复位信号的低有效在顶层放置反相器可以被吸收到IOB中。
为什么复位?
使用全局复位有利于我们仿真,所有的寄存器都是有初始值的,也可以在任意时刻让你的寄存器恢复初值,所以验证工程师很喜欢这样的设计,但是Xilinx建议的是尽量避免使用全局复位。
复位的基本目的是使器件强制进入到可以稳定工作的确定状态。
这避免了器件在上电后进入到随机状态导致进入到无法判断的状态(也就是死机了)。在实际设计过程中,设计者必须选择最适合于设计本身的复位方式。
xilinx为什么不推荐异步复位?
- 异步重置将不会被添加到数据路径。所以数据路径对于时序分析来说是干净的。
- 电路可以复位与或没有时钟的情况下复位电路。
- 不需要综合指令
导致亚稳态
异步复位比预期的要复杂得多,异步复位与寄存器工作时钟域没有一定的相位关系,很难确保所有寄存器同时从状态中释放出来。
因为内部复位信号的偏差,寄存器A将在当前时钟周期内从复位中释放,C将在下一个时钟周期释放,B难以定义,甚至可能导致亚稳态。
简而言之,***亚稳态亚稳态亚稳态!!!***
浪费布线资源
异步复位信号会占用大量的布线资源是高速设计的必要条件,但我们不能看到它在源代码
-占用太多布线资源将减少其他连接的自由。
-可能降低系统性能潜在地需要一个更高的设备速度等级。
-增加布线时间。
浪费Slice资源
-有和没有异步复位的寄存器不能被包装在一个Slice
-不同异步复位的寄存器不能被包装在一个Slice
降低DSP和BRAM性能
如图,在XILINX内部 的dsp和bram中,只有同步复位,异步复位是不会包含复位到BRAM/DSP的
解决方案
- 不复位
- 同步复位
同步复位的好处
同步复位为工具提供了更多的灵活性
异步复位确实会出现高扇出的情况。Fan-out即扇出,模块直接调用的下级模块的个数,如果这个数值过大的话,在FPGA直接表现为net delay较大,不利于时序收敛。因此,在写代码时应尽量避免高扇出的情况。
- 合成可以选择将控制信号的低扇出同步复位移到数据通路,以释放更多的寄存器。
- 这可以允许将这个寄存器打包到以前不可能的一个slice中
- 可以改善时序以及寄存器密度
同步复位让我们的设计稳定
从上图我们可以看出,在我们的复位发送故障时,我们的同步复位只能在时钟的边沿触发,这样进而保证了我们系统的稳定性,在复位故障时尽量相对保证系统稳定。
复位建议
- 避免复位
- 高复位
- 同步复位
- 不要混合复位
- 可以在寄存器初始化时候直接赋值
reg [7:0] code = 8'hff;
内部寄存器其实很多情况不需要过分复位,大不了之前的垃圾数据我们不用就行了。重置重置是设计中需要考虑和限制的更常见和重要的控制信号之一。重置可以显著影响设计的性能、面积和功率。
模块化复位
模块复位可以降低扇出,保证电路的稳定进行。
使用指令确保模块复位信号不被综合掉
example:
(* keep="true" *) reg my_modular_reset1;
(* keep="true" *) reg my_modular_reset2;
(* keep=“true” *) reg my_modular_reset3;
always @(posedge clkA) begin
my_modular_reset1 <= synchronized_reset;
my_modular_reset2 <= synchronized_reset;
my_modular_reset3 <= synchronized_reset;
end
DSP片采用同步复位
DSP芯片比大多数实现的芯片更通用
-它可以用于乘数,增加/sub, MACC,计数器(与可编程终端计数),比较器,移位,多路复用器,模式匹配,和许多其他逻辑功能。
每个DSP片有效地具有> 310寄存器
-没有异步复位
使用同步全局重置可以使合成工具更容易地使用DSP切片
-异步复位方法将防止工具使用的存储资源在DSP片。
块RAM使用同步重置
RAM只有同步复位,块ram通过使用输出寄存器获得最小时钟输出时间。
非复位不可吗?
流水线的操作在几个周期内就会把垃圾数据给移走,所以在这里的设计进行复位是多余的。
但是有一些情况下,复位的释放后是很重要的。
比如独热码状态机。如果表示独热码状态的第一个触发器比第二个触发器早释放了一个时钟周期,那状态机的状态机会跳转到一个无效的状态。如果所有的表示独热码的寄存器无法在同一个周期内被释放,那状态机肯定会跳转到一个无效的状态。
其实当Xilinx FPGA配置或重新配置时,所有的单元都会被初始化。称为master reset,因为这可比你复位一些D触发器要强得多,它甚至初始化了片内RAM。
Xilinx的器件也有嵌入处理的系列,软核或硬核。在程序执行第一条指令前,程序和数据区域已经定义好了。有了上电复位,还用专门消耗逻辑资源去复位触发器是没有意义的。
通常可以将设计分为两部分,控制路径和数据路径
-至于数据路径,初始值并不重要。重置是不必要的。
-只在设计中需要获得有效帧信号或设计回到已知良好状态的部分使用外部复位
不复位是最好的!
总之就是能不用复位就尽量不用。
demo分享
demo1
优化前资源使用:
优化后:
资源节约的不是一点点阿…
全局复位和模块复位对比
高扇出
优化后你就说带不带劲哈哈哈哈。
复位总结
- 复位前考虑是否需要复位
- 尽量不用复位
- 使用初始化代码寄存器进行复位
- 使用异步复位时候要注意
使用异步复位,同步释放的方法。用内部定义复位信号的方法来复位触发器,而不是全都直接使用全局复位信号。当进行复位操作时,所有的触发器被预设为1。如上图,移位寄存器的最后一个触发器去操作模块内部定义的复位网络。当复位信号释放时,移位寄存器经过移位,当最后一个触发器由高电平变为低电平时,对本地的复位网络进行复位操作。也就是异步复位,同步释放。
异步复位,就是复位信号可以直接不受时钟信号影响,在任意时刻只要是低电平就能复位(假如约定低电平复位),也就是说,复位信号不需要和时钟同步。而同步释放就很有意思了,它的意思是让复位信号取消的时候,必须跟时钟信号同步,也就是说正好跟时钟同沿。
module Reset_test(
input clk,
input rst_nin,
output reg rst_nout
);
reg rst_mid;
always@(posedge clk or negedge rst_nin)
begin
if(!rst_nin)
begin
rst_mid <= 0;
rst_nout <= 0;
end
else
begin
rst_mid <= 1;
rst_nout <= rst_mid;
end
end
endmodule
Reference
- xilinx FPGA复位浅析
- 你真的会Xilinx FPGA的复位吗?