您的位置:首页 > 其它

FPGA中同步复位,异步复位介绍

2018-03-02 14:03 274 查看
在FPGA逻辑编写时,经常会用到复位操作,那究竟是用同步复位了,还是异步复位了?这两者究竟有什么区别了?

同步复位:复位信号和时钟同步,当时钟上升沿检测到复位信号,执行复位操作

异步复位:不受时钟影响,只要复位信号有效,就会进行复位。

同步复位与异步复位的比较如下表所示





1、同步复位:

下面是一个简单的同步复位逻辑

module async

(

clk,

reset,

cnt,

out_cnt

);

input clk;

input reset;

input cnt;

output out_cnt;

always @(posedge clk)begin //,posedge reset

if(reset==1’b1)begin

out_cnt<=1’b0;

end else begin

out_cnt<=cnt;

end

end

endmodule

综合后的RTL视图如下:

复位信号reset是通过组合逻辑的方式去完成out_cnt寄存器的复位操作的。在reset为1 ,复位有效时,组合逻辑生成的选择器会选择1’h0为组合逻辑输出,连接到out_cnt寄存器的D管脚上,进行复位操作。而正常工作,没有复位时,组合逻辑会选择cnt 信号为组合逻辑的输出,连接到out_cnt寄存器的D管脚上。



下图是全编译适配到芯片上的chip planner视图:



看见上图的红圈就是out_cnt寄存器,看其结构发现该寄存器是有异步复位管脚的。但是在这里没有用到,因为我们在前级通过组合逻辑电路去产生的异步复位。可想,要是用异步复位,复位信号直接就接到寄存器的异步复位管脚上去了,是不是就不用额外消耗FPGA的逻辑资源去产生组合逻辑复位电路,下面我们就将上面的代码改成异步复位,看下是不是想的那样。

2、异步复位:

module async

(

clk,

reset,

cnt,

out_cnt

);

input clk;

input reset;

input cnt;

output out_cnt;

always @(posedge clk,posedge reset)begin //,

if(reset==1’b1)begin

out_cnt<=1’b0;

end else begin

out_cnt<=cnt;

end

end

endmodule

RTL视图如下:

跟上面的同步逻辑相比,是不是少了一个组合逻辑模块。这样如果整个工程都使用这种异步复位操作的话,会节省很多的逻辑资源。



下图是全编译适配到芯片上的chip planner视图:

复位信号是直接接到寄存器的异步复位管脚上去的,而不像同步复位那样,还要用额外的组合逻辑去产生复位。



3、在实际应用时,经常都采用的是异步复位的操作,这样可以节省很多的资源,但是这样做容易产生亚稳态,所以就有了异步复位,同步释放的操作,避免了亚稳态的产生。

FPGA中亚稳态怎么产生的?

在FPGA中,如果数据传输时,不满足触发器的Tsu 和Th,或者复位过程中复位信号的释放相对于有效时钟沿的恢复时间(recovery time)不满足,就可能产生亚稳态。

下面对于异步复位,同步释放的分析是引用他人的blog分析

http://blog.csdn.net/frank_wff/article/details/43226507

//异步复位 同步释放rtl视图



异步复位,同步释放:指复位信号是异步有效的,即复位的发生与clk无关。后半句“同步释放”是指复位信号的撤除(释放)则与clk相关,即同步的。

下面说明一下如何实现异步复位和同步释放的。

异步复位:显而易见,asyn_reset异步复位后,syn_reset将拉低,即实现异步复位。

同步释放:这个是关键,看如何实现同步释放,即当复位信号rst_async_n撤除时,由于双缓冲电路的作用,rst_sync_n复位信号不会随着rst_async_n的撤除而撤除。

假设asyn_reset撤除时发生在clk上升沿,如果不加上图的电路则可能发生亚稳态事件(在上升沿附近rst置1,这时候建立时间还不够长,数据可能还未打入寄存器,导致输出不确定)。但是加上此电路以后,假设第一级D触发器clk上升沿时asyn_reset正好撤除,则D触发器1输出高电平“1”,此时第二级触发器也会更新输出,但是输出值为前一级触发器次clk来之前时的Q1输出状态。显然Q1之前为低电平,顾第二级触发器输出保持复位低电平,直到下一个clk来之后,才随着变为高电平。即同步释放。

代码实现:(Altera 官方资料)

module reset_best(clk,asyn_reset,syn_reset);

input clk;

input asyn_reset;

output syn_reset;

reg rst_s1;

reg rst_s2;

always @( posedge clk ,posedge asyn_reset)

begin

if(asyn_reset)

begin

rst_s1<=1’b0;

rst_s2<=1’b0;

end

else

begin

rst_s1<=1’b1;

rst_s2<=rst_s1;

end

end

assign syn_reset=rst_s2;

endmodule
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息