1、同步复位同步释放:(常用)
需要保持rst和a在同一时钟域下,且clk需要是持续稳定的。
always @(posedge clk ) begin
if(rst)
q <= 0 ;
else
q <= a ;
end
2、异步复位异步释放:(存在 Recovering time)
没有时钟的情况下也能复位。但rst和a不在同一时钟域下,rst复位释放后,触发器会需要一点恢复时间才能采样数据a,称为Recovering time 。如果Recovering time后,a满足不了保持建立时间,则会出现亚稳态或者采样丢失。
always @(posedge clk or posedge rst) begin
if (rst)
q <= 0 ;
else
q <= a;
end
3、同步复位异步释放:(不推荐)
实际上是异步复位的同步化。虽然这样在Recovering time后能稳定采样a信号,但相比同步复位同步释放没啥优势且仍然需要稳定的clk。
always @(posedge clk) begin
reset_sync <= reset;
end
always @(posedge clk or posedge reset_sync) begin
if (reset_sync)
q <= 0;
else
q <= a;
end
4、异步复位同步释放:(推荐)
既能在没有时钟的情况下复位,又可以在复位释放后所有触发器同步开始采样。
也可以使用计数器产生rst_sync
//把两个寄存器约束到一个slice里面,给亚稳态留足时间
(* ASYNC_REG = “TRUE” *) reg rst_s1 ,rst_s2 ;
//低电平有效
always @ (posedge clk or negedge sys_rst_n)begin
if (!sys_rst_n) begin
rst_s1 <= 1'b0;
rst_s2 <= 1'b0;
end
else begin
rst_s1 <= sys_rst_n;
rst_s2 <= rst_s1;
end
end
assign rst_sync_n = rst_s2;
//使用同步后的复位信号对数据进行复位
always @ (posedge clk or negedge rst_sync_n)begin
if (!rst_sync_n)
q <= 0 ;
else
q <= a ;
end
//高电平有效
reg [2:0] rst_sync ;
always @(posedge clk ) begin
rst_sync <= {rst_sync[1:0],rst};
end
always @(posedge clk or posedge rst) begin
if (rst)
q <=0 ;
else if (rst_sync[2])
q <=0;
else
q = a;
end