有亚稳态产生,我们就要对亚稳态进行消除,常用对亚稳态消除有三种方式:
(1) 对异步信号进行同步处理;
(2) 采用FIFO对跨时钟域数据通信进行缓冲设计;
(3) 对复位电路采用异步复位、同步释放方式处理。
具体操作:
A, 异步信号进行同步提取边沿处理
进行异步信号跨频提取边沿时候,一般采用多进行一级寄存器消除亚稳态,可能在系统稳定性要求高的情况下,采用更多级寄存器来消除亚稳态
input sig_nsyn;
wire sig_nsyn_p;
reg[3:0] sig_nsyn_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) sig_nsyn_r <= 2’d0;
else sig_nsyn_r <= { sig_nsyn_r [2::0], sig_nsyn };
end
assign sig_nsyn_p = sig_nsyn_r[2] & ~sig_nsyn_r[3];
B. 采用FIFO对跨时钟域数据通信进行缓冲设计
当数据流从一个时钟域到另一个时钟域的时候,绝大多数情况下都采用FIFO来作为中间缓冲,采用双时钟对数据缓冲,就可以避免亚稳态的发生
C.对复位电路采用异步复位、同步释放方式处理。
(1)异步复位
always@(posedeg clk or negedge rst_n)
(2)同步复位
module system_ctr (
input clk ,
input reset_l ,
output reg reset_out
);
reg reset_d ;
always @ (posedge clk )
begin
reset_d <= reset_l ;
reset_out<= reset_d ;
end
endmodule
reset_out 信号是已经同步过的复位信号,可以直接在其它模块使用。需要注意的是,这个复位信号会延迟几个时钟周期。并且,复位信号必须要大于时钟周期,才能被系统检测到。
(3)异步复位同步释放
reset_out信号是已经同步过的复位信号,可以直接在其它模块使用。需要注意的是,这个复位信号会延迟几个时钟周期。并且,复位信号必须要大于时钟周期,才能被系统检测到。
module test(
input clk ,
input reset_l ,
output reg reset_out
);
reg reset_d ;
always @ (posedge clk or negedge reset_l)
begin
if(!reset_l)begin
reset_out <= 1’b0 ;
reset_d <= 1’b0 ;
end
else begin
reset_d <= 1’b1 ;
reset_out <= reset_d ;
end
end
endmodule
这个电路图就是理解异步复位、同步释放的关键了。这里的复位信号直接接到D触发器的异步清零端,也就不存在同步复位中复位信号必须要大于时钟周期才能被检测到的局限。这就是异步复位的意思。同时,reset_out变为高电平是受时钟控制的,也就是所说的同步释放。同步释放避免了异步复位可能产生的不满足复位恢复时间的情况。综上所述,异步复位同步释放机制解决了异步复位和同步复位固有的缺陷,因此将这种方法作为系统复位是极好的选择。
)