异步否定边缘重置的可能解决方法?



我想有一个带有异步复位信号的寄存器,如下所示:

always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
out <= 1'b0
else
out <= in
end

我试过AsyncReset()类和withReset()。但是,生成的代码使用posedge重置,并且AsyncReset()变量不接受!

有什么解决方法吗?

虽然不能直接反转AsyncReset类型(通常将逻辑应用于 AsyncReset 是不好的,因为它可能会出现故障(,但您可以转换为布尔值并返回:

val reset_n = (!reset.asBool).asAsyncReset
val reg = withReset(reset_n)(RegInit(0.U(8.W)))

可运行的示例:https://scastie.scala-lang.org/ERy0qHt2Q3OvWIsp9qiiNg

我认为杰克关于避免故障的快速评论值得更长的解释。

使用异步复位会在设计中创建第二个时序弧,从复位到结束翻牌。 复位信号可以随时置位,但需要与时钟同步解除置位,否则翻牌可能会变得亚稳态。

执行此操作的常用技术是使用复位同步器。
https://scastie.scala-lang.org/hutch31/EPozcu39QBOmaB5So6fyeA/13

上面代码中显示的同步器直接在 Verilog 中编码,因为我不知道通过不断优化来防止 FIRRTL 优化器修剪的方法。 重置同步的下游逻辑可以是同步或异步重置。