赞
踩
FPGA入门——同步复位/异步复位
提示:以下是本篇文章正文内容,下面案例可供参考
同步复位只有在时钟沿到来时复位信号才起作用,则复位信号持续的时间应该超过一个时钟周期才能保持复位。
代码如下(示例):
module Synchronous_Reset (rst_n, clk, a, b);
input rst_n, clk;
input a;
output reg b;
always @ (posedge clk)
begin
if (!rst_n)
b <= 1'b0;
else
b <= a;
end
endmodule
一般能够保证电路100%同步(Synchronous)。确保复位只发生在有效沿,可以作为过虑掉毛刺的手段。
复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位。同时还要考虑如:
(1)时钟偏移、组合逻辑路径(路由)延时、复位延时等因素。
(2)由于大多数的厂商目标库内的触发器都只有异步复位端口,采用同步复位的话,就会耗费较多的逻辑资源。
只要有复位信号系统马上复位,因此异步复位抗干扰能力差,有些噪声也能使系统复位,因此有时候显得不够稳定,要想设计一个好的复位最好使用异步复位同步释放。
代码如下(sys_Verilog):
module asynchronous_reset(clk, rst_n, a, b);
input clk, rst_n;
input a;
output reg b;
always @ (posedge clk, negedge rst_n)
begin
if (!rst_n)
b <= 1'b0;
else
b <= a;
end
endmodule
正常情况下,在clk的上升沿将c的值更新为b,b的值更新为a。一旦进入复位,b和c都清零,但是并不能确定复位信号rst_n会在什么时候结束,涉及建立时间和保持时间。
如果结束与b_reg和c_reg的{latch edge-setup, latch edge+hold time}时间之外,那么一切都会正常。如果出现在之内(“不好判断了”)复位信号的撤销(由低n到高p)出现在clk锁存数据的建立时间或者保持时间之内,此时clk检测到rst_n的状态就会使一个亚稳态(不确定是0还是1),就会导致输出结果的错误。也有可能一个reg处于复位,另一个reg跳出了复位,均会影响系统的正常工作,如果更大的项目隐患就更大了。
代码如下(sys_Verilog):
module asynchronous_reset_wrong(clk, rst_n, a, b, c); input clk, rst_n; input a; output reg b, c; always @ (posedge clk, negedge rst_n) begin if (!rst_n) b <= 1'b0; else b <= a; end always @ (posedge clk, negedge rst_n) begin if (!rst_n) c <= 1'b0; else c <= b; end endmodule
(1)异步复位信号识别方便,而且可以很方便的使用全局复位。
(2)由于大多数的厂商目标库内的触发器都有异步复位端口(CLR)可以节约逻辑资源。在这个端口(CLR端)一般接低电平有效的复位信号rst_n,即使设计中时高电平复位,实际综合后也会把异步复位信号反向后(!rst_n)接到CLR端
复位信号容易收到毛刺的影响。复位结束时刻恰在亚稳态窗口内时,无法决定现在的复位状态是1还是0,会导致亚稳态。
sync_reset_async_release
代码如下(sys_Verilog):
module sync_reset_async_release(clk, rst_n, a, b); input clk, rst_n; input a; output reg b; reg rst_n_r, rst_n_rr; always @ (posedge clk, negedge rst_n) begin if (!rst_n) {rst_n_rr, rst_n_r} <= 2'b00; else {rst_n_rr, rst_n_r} <= {rst_n_r, rst_n}; end always @ (posedge clk, negedge rst_n_rr) begin if (!rst_n_rr) b <= 1'b0; else b <= a; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。