【问题标题】:How to generate an asynchronous reset verilog always blocks with chisel如何生成异步重置verilog总是用凿子阻塞
【发布时间】:2015-04-21 08:40:45
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: verilog fpga chisel


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

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

      为了更全面地展示这一点,请考虑以下MultiIOModule,它具有三个重置:

      • 隐式reset 输入具有抽象重置类型(这是“抽象重置”)
      • 具有Bool 类型的显式syncReset 输入(这是“同步重置”)
      • 具有AsyncReset 类型的显式asyncReset 输入(这是“异步重置”)

      使用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

      【讨论】:

      • 嗨,with RequireAsyncReset 会递归影响子模块吗?
      • 混合起来可能会产生这种效果。顶部的抽象重置被强制为AsyncReset。连接到此重置线的子模块将被转换为AsyncReset(如果您将AsyncReset 连接到Bool,则会导致失败)。
      • 似乎只有默认的reset 受该特征影响。在顶级模块中显式声明为 Reset() 的重置不受 RequireAsyncReset 特征的影响,并触发 firrtl 错误 Abstract Reset not allowed as top-level input: io.rst。有什么解决方法吗?
      • 要么使这些顶级重置为它们应该是的重置类型(BoolAsynReset),或者,如果您确实希望在顶层进行抽象重置并尝试生成不同的版本,然后使用带有具体重置类型的RawModule 包装器并连接到您的抽象重置。这对你的情况有用吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2013-05-07
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多