异步 negedge 重置的可能解决方法?

Possible workaround for async negedge reset?

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

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

我试过 class AsyncReset()withReset()。但是生成的代码使用了posedge reset,AsyncReset()的变量不接受!.

有什么解决方法吗?

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

  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 优化器修剪。复位同步的逻辑下游可以是同步或异步复位。