FPGA复位设计与DFF资源浅析

FPGA复位设计与DFF资源浅析

摘要:很多FPGA工程师习惯于对FPGA设计进行上电复位,总担心如果不复位,触发器就处于未知状态,导致系统跑飞。事实上,每个触发器都有明确的初始值,这个初始值与是否复位无关。即,一旦系统上电,即使没有复位信号,对于FDSE和FDPE,其初始值为1,对于FDRE和FDCE,其初始值为0,Block RAM和DSP48内部触发器初始值为0。本文对于四种DFF触发器与复位设计进行一些浅要的探讨。

Xilinx器件中的四种DFF

我们先看一下xilinx器件中的4中不同的DFF

 

异步复位(FDCE):CLR  clear               DFF 异步清0

异步置位(FDPE):PRE  preset positive     DFF 异步置1

同步复位(FDRE):R    reset               DFF 同步清0

同步置位(FDSE):S   set                 DFF 同步置1

Verilog Code如下:

module clk_rst(
    input  wire         clk_sys,
    input  wire         rst_sys,
    input  wire         din,
    output reg          dout1,
    output reg          dout2,
    output reg          dout3,
    output reg          dout4,
    output reg          dout5
    );
//FDCE 
always@(posedge clk_sys or posedge rst_sys)
 begin
    if (rst_sys == 1'b1)
        dout1 <= 1'b0;
    else
        dout1 <= din;
end

//FDRE 
always@(posedge clk_sys)
begin
if (rst_sys == 1'b1)
    dout2 <= 1'b0;
else
    dout2 <= din;
end
 
//FDPE
always@(posedge clk_sys or posedge rst_sys)
 begin
    if (rst_sys == 1'b1)
        dout3 <= 1'b1;
    else
        dout3 <= din;
end

//FDSE
always@(posedge clk_sys)
begin
if (rst_sys == 1'b1)
    dout4 <= 1'b1;
else
    dout4 <= din;
end

(*keep = "ture"*) reg rst_sys_1d;
(*keep = "ture"*) reg rst_sys_2d;
wire rst_sys_bufg;
always@(posedge clk_sys or posedge rst_sys)
begin
if (rst_sys == 1'b1) begin
    rst_sys_1d  <= 1'b0;
    rst_sys_2d  <= 1'b0;
end
else begin
    rst_sys_1d <= rst_sys;
    rst_sys_2d <= rst_sys_1d;
end
end

always@(posedge clk_sys or posedge rst_sys_2d)
 begin
    if (rst_sys_2d == 1'b1)
        dout5 <= 1'b0;
    else
        dout5 <= din;
end 

/*
wire [5:0] dout_16;
c_shift_ram_0 your_instance_name (
  .A(depth),      // input wire [5 : 0] A
  .D({15{1'b1}}),      // input wire [15 : 0] D
  .CLK(clk_sys),  // input wire CLK
  .CE(dout3[0]),    // input wire CE
  .Q(dout_16)      // output wire [15 : 0] Q
);
*/
endmodule

  

如图所示,D是数据输入端口,CE是使能端口,CLK是时钟输入,SRSet/Reset的意思,可用作置位或者复位,置位和复位又分同步和异步,因此D触发器有如下四种应用类型:

如何进行复位设计

什么情形下用复位信号,why?

很多工程师习惯于对FPGA设计进行上电复位,总担心如果不复位,触发器就处于未知状态,导致系统跑飞。事实上,每个触发器都有明确的初始值,这个初始值与是否复位无关。即,一旦系统上电,即使没有复位,对于FDSEFDPE,其初始值为1,对于FDREFDCE,其初始值为0Block RAMDSP48内部触发器初始值为0

结论1:如果只是上电复位,那么这种复位是不需要的

结论2:控制路径需要复位(如状态机),数据路径不需要复位(如打拍寄存器)

对于控制路径,例如状态机,这种复位通常是必需的,保障状态机。相比之下,数据路径的复位通常是不需要的,数据持续随时钟沿刷新。

结论3:功能仿真时,为获得触发器初始值,可在定义该触发器时直接声明,无需复位

从功能仿真的角度看,如果没有初始值,触发器输出会显示“X”,从而导致仿真无法继续。解决方法是在定义触发器时,给出初始值,且这种方式是可综合的。

Reg [3:0]       a = 4’h0;

So同步复位还是异步复位?

如果必须使用复位,Xilinx建议使用同步复位Xilinx FPGA中的触发器既支持同步复位,也支持异步复位(FDREFDCE),常被误认为异步复位并不会带来不良后果。事实上,相比于同步复位,全局异步复位会增加时序分析的复杂度。另外,Block RAMDSP48自带的触发器只支持同步复位,基于LUTSRL(移位寄存器, SRL16ESRLC32E)不支持复位

同步复位的优点:

抗干扰性高,可以剔除复位信号中周期短于时钟周期的毛刺;电路稳定性强。

同步复位的缺点:

  1. 如果逻辑器件的目标库内的DFF都只有异步复位端口,使用同步复位时,综合器会在寄存器数据输入端插入组合逻辑,占用更多的逻辑资源;
  2. 同步复位依赖于时钟,如果电路中的时钟信号出现问题,无法完成复位。
  3. 对复位信号的脉冲宽度有要求,必须大于指定的时钟周期,由于线路上的延迟,可能需要多个时钟周期的复位脉冲宽度,且很难保证复位信号到达各个寄存器的时序。

异步复位的优点:

无需额外的逻辑资源,实现简单;复位信号不依赖于时钟。

异步复位缺点:

复位信号容易受到外界的干扰,如毛刺等影响;

复位信号释放的随机性,可能导致时序违规,倘若复位释放时恰恰在时钟有效沿附近,就很容易使电路处于亚稳态。

异步复位,同步释放

异步复位:就是复位信号可以直接不受时钟信号影响,在任意时刻只要是低电平就能复位,即复位信号不需要和时钟同步。

同步释放:同步解复位信号,跟随时钟打两到三拍,即刚好跟时钟同沿,实现同步释放。

异步复位,同步释放的优点

避免复位信号释放的时候造成亚稳态问题

只要复位信号一有效,电路就处于复位状态,与时钟沿无关,

有效捕捉复位,即使是短脉冲复位也不会丢失

有明确的复位撤销行为,复位的撤离是同步信号,因此有良好的的撤离时序和足够的恢复时间

用两级触发器打两拍的方法解决亚稳态的问题

全局复位还是局部复位

全局复位信号意味着该复位的扇出会很大,这会造成两个典型的不利结果。设想一下,从一个点出发要到达芯片其他位置的成千上万甚至几十万个地方,会占用很多布线资源,给布线带来压力,同时,也不利于时序收敛。这也就是为什么对于全局复位,要将其采用复位树的方式优化为局部复位。对于SSI器件更是如此,要确保每个SLR有自己的复位信号,避免一个复位信号全片飞。

复位结论:不必要的复位信号可移除,必要的复位信号建议使用同步复位,非要使用异步复位的信号,可以选择异步复位同步释放,全局复位信号优化为局部复位信号

复位设计在FPGA中非常关键,对复位设计经验有限,欢迎大家一起探讨,一起成长

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值