FabienM
FabienM

Reputation: 3751

How to generate an asynchronous reset verilog always blocks with chisel

Chisel generate always blocks with only clock in sensivity list :

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

Is it possible to configure Module to use an asynchronous reset and generate an always block like this ?

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

Upvotes: 2

Views: 2401

Answers (2)

Russell
Russell

Reputation: 3457

Chisel versions prior to 3.2.0 do not have support for asynchronous resets.

It looks like the way to do this in Chisel is to use synchronous resets:

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

For more discussion on the topic: https://groups.google.com/forum/#!topic/chisel-users/4cc4SyB5mk8

Upvotes: 4

seldridge
seldridge

Reputation: 2874

Since Chisel 3.2.0, there is support for synchronous, asynchronous, and abstract reset types. Based on the type of reset explicitly specified or inferred, you will get canonical synchronous or asynchronous Verilog output.

To try to show this more fully, consider the following MultiIOModule which has three resets:

  • The implicit reset input which has an abstract reset type (this is "abstract reset")
  • The explicit syncReset input which has a Bool type (this is "synchronous reset")
  • The explicit asyncReset input which has an AsyncReset type (this is "asynchronous reset")

Using withReset, specific reset connections can then be used for different registers in the design:

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
}

This then produces the following Verilog when compiled with: (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

Note: that in Chisel 3.2 the top-level abstract reset would always be set to synchronous reset. In Chisel 3.3.0, two traits were added: RequireSyncReset and RequireAsyncReset. These can be used to change the reset type of the register connected to regAbstract from synchronous to asynchronous. Recompiling the design with (new ChiselStage).emitVerilog(new Foo with RequireAsyncReset), changes the regAbstract logic to

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

For more information, the Chisel website has more information on resets.

Upvotes: 2

Related Questions