我看网上已经有很多有关FPGA设计中的复位问题的解读了,我大致看了几个,写的还是很不错的,大致都是异步复位,同步复位,以及异步复位、同步释放这些,这里呢,我为了备忘,也参考大神的博客,写上一篇,根据自己的困惑来说,志在解决自己的困惑,如果能解决你的困惑,那就更好了。
复位的目的:
复位的基本目的是使器件进入到可以稳定工作的确定状态,这避免了器件在上电后进入到随机状态导致跑飞了。在实际设计过程中,设计者必须选择最适合于设计本身的复位方式。
耳熟能详的是同步复位和异步复位,分别介绍如下:
同步复位:
同步复位就是指复位信号只有在时钟上升沿到来时,才能有效。同步复位的Verilog HDL描述为:
module syn_reset(
input rst_n,
input clk,
input data_in,
output out
);
reg out;
always@(posedge clk)
begin
if(!rst_n)
out <= 1'b0;
else
out <= data_in;
end
endmodule
综合后的RTL图为:
(这个图值得斟酌,为什么我的ISE综合出来的总是异步的?)
异步复位:
异步复位是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。异步复位的Verilog HDL描述为:
module test
(
input clk,
input rst_n,
input data_in,
output out
);
reg out;
always @ (posedge clk or negedge rst_n)
if(!rst_n) out <= 1'b0;
else out <= data_in;
endmodule
综合后的RTL图为:
优缺点比较:
同步复位的优点:
- 一般能够确保电路是百分之百同步的。
- 确保复位只发生在有效时钟沿,可以作为过滤掉毛刺的手段。
同步复位的缺点:
- 复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位。同时还要考虑如:时钟偏移、组合逻辑路径延时、复位延时等因素。
- 由于大多数的厂商目标库内的触发器都只有异步复位端口,采用同步复位的话,就会耗费较多的逻辑资源。
异步复位优点:
- 异步复位信号识别方便,而且可以很方便的使用全局复位。
- 由于大多数的厂商目标库内的触发器都有异步复位端口,可以节约逻辑资源。
异步复位缺点:
- 复位信号容易受到毛刺的影响。
-
复位结束时刻恰在亚稳态窗口内时,无法决定现在的复位状态是1还是0,会导致亚稳态。
异步复位、同步释放机制,既解决了同步复位浪费资源问题,又解决了异步复位带来的亚稳态。
复位信号同步化,系统时钟不变化,还是采用异步复位的方法,但是当复位信号操作时会进入一个同步寄存器,使得复位信号同步化,这样既避免了异步复位的冒险与竞争,又避免了同步复位耗费太多资源。只需要将复位信号同步化编写成独立模块,然后顶层例化就好了。系统时钟信号不变化。
下例是以及寄存器异步复位,同步释放的Verilog HDL描述和RTL图:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 22:22:24 12/02/2018
// Design Name:
// Module Name: syn_reset
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module syn_reset(
input rst_n,
input clk,
input data_in,
output data_out
);
reg rst_nr;
reg data_out;
always @ (posedge clk)
rst_nr <= rst_n;
always@(posedge clk or negedge rst_nr)
begin
if(!rst_nr)
data_out <= 1'b0;
else
data_out <= data_in;
end
endmodule
下面是量级寄存器异步复位,同步释放的Verilog HDL描述和RTL视图:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 22:22:24 12/02/2018
// Design Name:
// Module Name: syn_reset
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module syn_reset(
input rst_n,
input clk,
input data_in,
output data_out
);
reg data_mid;
reg rst_nr;
reg data_out;
always @ (posedge clk)
rst_nr <= rst_n;
always@(posedge clk or negedge rst_nr)
begin
if(!rst_nr)
data_mid <= 1'b0;
else
data_mid <= data_in;
end
always @ (posedge clk or negedge rst_nr)
if(!rst_nr)
data_out <= 1'b0;
else
data_out <= data_mid;
endmodule
暂时理解到这里,还不是太深刻,明天继续看看吧
参考文献:
https://zhuanlan.zhihu.com/p/32071206
https://www.cnblogs.com/yfwblog/p/4793118.html
http://www.cnblogs.com/qiweiwang/archive/2010/11/25/1887888.html