如何生成异步复位 verilog 总是用凿子阻塞

How to generate an asynchronous reset verilog always blocks with chisel

Chisel 总是生成敏感列表中只有时钟的块:

always @posedge(clk) begin
  [...]
end

是否可以将模块配置为使用异步重置并生成这样的 always 块?

always @(posedge clk or posedge reset) begin
   [...]
end

3.2.0 之前的 Chisel 版本不支持异步重置。

看起来在 Chisel 中执行此操作的方法是使用同步重置:

always @posedge(clk) begin
  if (reset) begin
  [...]
  end 
  else 
  [...]
  end
end

有关该主题的更多讨论: https://groups.google.com/forum/#!topic/chisel-users/4cc4SyB5mk8

从 Chisel 3.2.0 开始,支持同步、异步和抽象重置类型。根据明确指定或推断的复位类型,您将获得规范的同步或异步 Verilog 输出。

为了更全面地展示这一点,请考虑以下 MultiIOModule,其中包含三个重置:

  • 具有抽象重置类型的隐式 reset 输入(这是 "abstract reset")
  • 具有 Bool 类型的显式 syncReset 输入(这是 "synchronous reset")
  • 具有 AsyncReset 类型的显式 asyncReset 输入(这是 "asynchronous reset")

使用withReset,特定的复位连接可以用于设计中的不同寄存器:

import chisel3._
import chisel3.stage.ChiselStage

class Foo extends MultiIOModule {
  val syncReset  = IO(Input(Bool()      ))
  val asyncReset = IO(Input(AsyncReset()))

  val in          = IO(Input( Bool()))
  val outAbstract = IO(Output(Bool()))
  val outSync     = IO(Output(Bool()))
  val outAsync    = IO(Output(Bool()))

  val regAbstract =                         RegNext(in, init=0.U)
  val regSync     = withReset(syncReset)  { RegNext(in, init=0.U) }
  val regAsync    = withReset(asyncReset) { RegNext(in, init=0.U) }

  outAbstract := regAbstract
  outSync     := regSync
  outAsync    := regAsync
}

编译时生成以下 Verilog:(new ChiselStage).emitVerilog(new Foo):

module Foo(
  input   clock,
  input   reset,
  input   syncReset,
  input   asyncReset,
  input   in,
  output  outAbstract,
  output  outSync,
  output  outAsync
);
  reg  regAbstract;
  reg  regSync;
  reg  regAsync;
  assign outAbstract = regAbstract;
  assign outSync = regSync;
  assign outAsync = regAsync;
  always @(posedge clock) begin
    if (reset) begin
      regAbstract <= 1'h0;
    end else begin
      regAbstract <= in;
    end
    if (syncReset) begin
      regSync <= 1'h0;
    end else begin
      regSync <= in;
    end
  end
  always @(posedge clock or posedge asyncReset) begin
    if (asyncReset) begin
      regAsync <= 1'h0;
    end else begin
      regAsync <= in;
    end
  end
endmodule

注意:在 Chisel 3.2 中,顶层抽象重置将始终设置为同步重置。在 Chisel 3.3.0 中,添加了两个特征:RequireSyncResetRequireAsyncReset。这些可用于将连接到 regAbstract 的寄存器的复位类型从同步更改为异步。使用 (new ChiselStage).emitVerilog(new Foo with RequireAsyncReset) 重新编译设计,将 regAbstract 逻辑更改为

always @(posedge clock or posedge reset) begin
  if (reset) begin
    regAbstract <= 1'h0;
  end else begin
    regAbstract <= in;
  end
end

有关详细信息,Chisel website has more information on resets