当前位置:网站首页>Chisel tutorial - 05 Sequential logic in chisel (including explicit multi clock, explicit synchronous reset and explicit asynchronous reset)

Chisel tutorial - 05 Sequential logic in chisel (including explicit multi clock, explicit synchronous reset and explicit asynchronous reset)

2022-07-07 23:41:00 github-3rr0r

Sequential logic

motivation

It is impossible for us to write a meaningful digital logic circuit without States !

It is impossible for us to write a meaningful digital logic circuit without States !

It is impossible for us to write a meaningful digital logic circuit without States !

Say the important thing three times !

Because nothing can be done without storing intermediate results .

This section describes how to use Chisel Express general temporal logic , At the end of this section , You should have a spare Chisel Implement and test the ability of a shift register .

It should be emphasized that this section may not be too shocking , because Chisel The power of is not reflected in the temporal logic pattern , But in the parameterization of design . This ability has been demonstrated before , Now we have to learn about the temporal patterns . therefore , This section will show Chisel Than Verilog Well done place , Just learn some grammar .

register (Register)

Chisel The basic stateful element in is a register , The symbol is Reg.Reg It will keep its output value until the rising edge of its clock , At the rising edge, new data is accepted as input . By default , Every Chisel Each module has an implicit clock , Used by each register in the design . This saves the time of specifying the same clock signal in the code every time .

Use of registers

The following code implements a module , It takes an input , Then add 1 And connected to the input of a register .

Be careful : Implicit clock can be covered by multi clock design , See the examples in the appendix below .

// MyModule.scala
import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in = Input(UInt(12.W))
    val out = Output(UInt(12.W))
  })

  val register = Reg(UInt(12.W))
  register := io.in + 1.U
  io.out := register
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

// MyModuleTest.scala
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    test(new MyModule) {
     c =>
      for (i <- 0 until 100) {
    
        c.io.in.poke(i.U)
        c.clock.step(1)
        c.io.out.expect((i + 1).U)
      }
    }
    println("SUCCESS!!")
  }
}

Register by calling Reg(tpe), here tpe It refers to variables that encode register types , Here is a 12bit Of UInt.

Then look at what's done in the tester . Calling poke and expect Between , There is one step(1) Call to . This tells the tester to push (tick) Primary clock , This will cause the register to pass its input to the output . call step(n) will tick The clock n Time .

If you are scheming 0, Then you can notice that there is no call in the tester of combinatorial logic step() Of . This is because calling on an input poke() The value will be immediately passed and updated through combinatorial logic . Only in temporal logic ,step() Is necessary .

Generated Verilog The code is as follows ( It can be seen that it is very complicated !):

module MyModule(
  input         clock,
  input         reset,
  input  [11:0] io_in,
  output [11:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [11:0] register; // @[MyModule.scala 10:21]
  assign io_out = register; // @[MyModule.scala 12:10]
  always @(posedge clock) begin
    register <= io_in + 12'h1; // @[MyModule.scala 11:21]
  end
// Register and memory initialization
...	//  Omit 
endmodule

Observe this generated Verilog Code , It can be noted that :

  1. This module has a clock input and a reset input , This is not explicitly added by myself ;
  2. Variable register As expected, it became reg [11:0];
  3. There is a long code block , With ``ifdef RANDOMIZE` start , Used to initialize the register value to a random number before the simulation starts ;
  4. register On the rising edge of the clock (@(posedge clock)) to update .

Another thing to note is ,Chisel In type ( Such as UInt) And hardware nodes ( Such as literal value 2.U or myReg Output ) There is a distinction between :

val myReg = Reg(UInt(2.W))

It's legal. , because Reg Need a data type as a model ;

val myReg = Reg(2.U)

This will lead to errors , because 2.U It's a node , It cannot be used as a model .

RegNext Use

Chisel There is a useful register object , Register for simple input connection . The previous module can be shortened to the following code :

import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in = Input(UInt(12.W))
    val out = Output(UInt(12.W))
  })
  
  io.out := RegNext(io.in + 1.U)
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

Here are two points to note :

  1. RegNext The value will be updated to the output on the rising edge of the next clock ;
  2. The width of the register is not specified here , But it can be achieved by Output The connection of infers , Here is the io.out Width ;

Generated Verilog The code is as follows :

module MyModule(
  input         clock,
  input         reset,
  input  [11:0] io_in,
  output [11:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [11:0] io_out_REG; // @[MyModule.scala 10:20]
  assign io_out = io_out_REG; // @[MyModule.scala 10:10]
  always @(posedge clock) begin
    io_out_REG <= io_in + 12'h1; // @[MyModule.scala 10:27]
  end
// Register and memory initialization
...	//  Omit 
endmodule

It is very similar to the previous code , Only the name of the register is automatically generated (io_out_REG) Not explicitly defined .

The test passed .

RegInit Use

In the module above , Registers are initialized to a random value during simulation . Unless specified , The register has no reset value .

Can pass RegInit To create registers and specify reset values .

such as , Will a 12bit The register of is initialized to 0 It can be written like this :

val myReg = RegInit(UInt(12.W), 0.U)

perhaps :

val myReg = RegInit(0.U(12.W))

The first method has two parameters , The first parameter is the type node , Specify the width and type of register , The second parameter is a hardware node , Specify the reset value of the register , Here is the 0.

The second method has only one parameter , The parameter is a hardware node , It's usually 0.U,0.U(12.W) Is the use of mandatory width .

Now add initialization to the previous code :

import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in = Input(UInt(12.W))
    val out = Output(UInt(12.W))
  })

  val register = RegInit(0.U(12.W))
  register := io.in + 1.U
  io.out := register
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

Output is as follows :

module MyModule(
  input         clock,
  input         reset,
  input  [11:0] io_in,
  output [11:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [11:0] register; // @[MyModule.scala 10:25]
  wire [11:0] _register_T_1 = io_in + 12'h1; // @[MyModule.scala 11:21]
  assign io_out = register; // @[MyModule.scala 12:10]
  always @(posedge clock) begin
    if (reset) begin // @[MyModule.scala 10:25]
      register <= 12'h0; // @[MyModule.scala 10:25]
    end else begin
      register <= _register_T_1; // @[MyModule.scala 11:12]
    end
  end
// Register and memory initialization
...	//  Omit 
endmodule

It can be observed that Verilog There are already pairs in the code reset Check the signal , Used to reset the register to 0. And this reset operation is in always @(posedge clock) In the code block .

Chisel The implicit reset of is active at high level (active high) And synchronized (synchronous) Of .

Before the reset , The register will still be initialized to a random number .

PeekPokeTesters Always call reset before running the test , But you can also use reset(n) Manually call the reset function , The reset signal will remain n High level of clock cycles .

Combine the control flow of the register

And use wire The control flow of is similar , Both have final connection semantics and support when,elsewhen and otherwise structure .

The following code uses the control flow to find the maximum value in a sequence :

// MyModule.scala
import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in = Input(UInt(10.W))
    val max = Output(UInt(10.W))
  })

  val max = RegInit(0.U(10.W))
  when(io.in > max) {
    
    max := io.in
  }
  io.max := max
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

// MyModuleTest.scala
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    test(new MyModule) {
     c =>
      c.io.max.expect(0.U)
      c.io.in.poke(1.U)
      c.clock.step(1)
      c.io.max.expect(1.U)
      c.io.in.poke(3.U)
      c.clock.step(1)
      c.io.max.expect(3.U)
      c.io.in.poke(2.U)
      c.clock.step(1)
      c.io.max.expect(3.U)
      c.io.in.poke(24.U)
      c.clock.step(1)
      c.io.max.expect(24.U)
    }
    println("SUCCESS!!")
  }
}

Output Verilog The code is as follows :

module MyModule(
  input        clock,
  input        reset,
  input  [9:0] io_in,
  output [9:0] io_max
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [9:0] max; // @[MyModule.scala 10:20]
  assign io_max = max; // @[MyModule.scala 14:10]
  always @(posedge clock) begin
    if (reset) begin // @[MyModule.scala 10:20]
      max <= 10'h0; // @[MyModule.scala 10:20]
    end else if (io_in > max) begin // @[MyModule.scala 11:21]
      max <= io_in; // @[MyModule.scala 12:9]
    end
  end
// Register and memory initialization
...	//  Omit 
endmodule

Another example of register

The operation on the register is on the register Output Performed on , And the type of operation is based on the type of register , This means that it can be written like this :

val reg: UInt = Reg(UInt(4.W))

This means reg It's a UInt Type value , So it can be executed UInt The operating , Such as addition and subtraction .

whatever chisel.Data You can do this for all data types in , Include SInt etc. .

Here is a comb filter (Comb Filter, This means that the output of each clock cycle is equal to the input of this round minus the input of the previous round ) The implementation of the :

import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in  = Input(SInt(12.W))
    val out = Output(SInt(12.W))
  })

  val delay: SInt = Reg(SInt(12.W))
  delay := io.in
  io.out := io.in - delay
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

The meaning is as follows :

  1. val delay: SInt = Reg(SInt(12.W)) Express delay It's a register ,delay The following designation of types can be omitted ;
  2. delay := io.in Indicates that the input of the register is connected to io.in, The register will be updated on the rising edge of the next clock ;
  3. io.out := io.in - delay It means that you will io.in And the value of the current register ( Input of last cycle ) The difference is connected to io.out On .

Generated Verilog The code is as follows :

module MyModule(
  input         clock,
  input         reset,
  input  [11:0] io_in,
  output [11:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [11:0] delay; // @[MyModule.scala 10:18]
  assign io_out = $signed(io_in) - $signed(delay); // @[MyModule.scala 12:19]
  always @(posedge clock) begin
    delay <= io_in; // @[MyModule.scala 11:9]
  end
// Register and memory initialization
...	//  Omit 
endmodule

practice

Implementation of shift register

For now LFSR( Linear feedback shift register ) Implement a shift register , requirement :

  1. Every element is 1bit wide ;
  2. Yes 4bit The signal output of ;
  3. Accept one 1bit Input , This input is the next value to enter the shift register ;
  4. Parallel output of output shift register , May need to use Cat;
  5. The output is initialized to b0001;
  6. Every clock cycle shifts ( No enable signal );
  7. Be careful : stay Chisel in , The assignment of subwords is illegal , such as out(0) := in No way. .

 Insert picture description here

A brief analysis of , You need a register to store the current value , Connect to output , The current value is shifted one bit to the left, and the input 1bit, Use or to calculate , Then as the state of the next clock cycle . therefore , The code implementation is as follows :

// MyModule.scala
import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in  = Input(Bool())
    val out = Output(UInt(4.W))
  })

  val state = RegInit(UInt(4.W), 1.U)

  val nextState = state << 1 | io.in
  state := nextState
  io.out := state
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule))
}

// MyModuleTest.scala
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    test(new MyModule) {
     c =>
      var state = 1
      for (i <- 0 until 10) {
    
        // poke in LSB of i (i % 2)
        c.io.in.poke(((i % 2) != 0).B)
        // update expected state
        state = ((state * 2) + (i % 2)) & 0xf
        c.clock.step(1)
        c.io.out.expect(state.U)
      }
    }
    println("SUCCESS!!")
  }
}

Generated Verilog The code is as follows :

module MyModule(
  input        clock,
  input        reset,
  input        io_in,
  output [3:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [3:0] state; // @[MyModule.scala 10:22]
  wire [4:0] _nextState_T = {state, 1'h0}; // @[MyModule.scala 12:25]
  wire [4:0] _GEN_0 = {
   {4'd0}, io_in}; // @[MyModule.scala 12:30]
  wire [4:0] nextState = _nextState_T | _GEN_0; // @[MyModule.scala 12:30]
  wire [4:0] _GEN_1 = reset ? 5'h1 : nextState; // @[MyModule.scala 10:{22,22} 13:9]
  assign io_out = state; // @[MyModule.scala 14:10]
  always @(posedge clock) begin
    state <= _GEN_1[3:0]; // @[MyModule.scala 10:{22,22} 13:9]
  end
// Register and memory initialization
...	//  Omit 
endmodule

The test passed .

Parameterized shift register

Now write another parameterized shift register , Through it delay(n) And the initial value (init) To parameterize , There is also an enable signal input .(delay It means that the input will delay several clock cycles before output , That is, the width of the shift register )

The code is as follows :

// MyModule.scala
import chisel3._
import chisel3.util._

class MyModule(val n: Int, val init: BigInt = 1) extends Module {
    
  val io = IO(new Bundle {
    
    val en  = Input(Bool())
    val in  = Input(Bool())
    val out = Output(UInt(n.W))
  })

  val state = RegInit(UInt(n.W), init.U)
  val nextState = state << 1 | io.in
  when (io.en) {
    
    state := nextState
  }
  io.out := state
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule(10, 2)))
}

// MyModuleTest.scala
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    for (i <- Seq(3, 4, 8, 24, 65)) {
    
      println(s"Testing n=$i")
      test(new MyModule(n = i)) {
     c =>
        val inSeq = Seq(0, 1, 1, 1, 0, 1, 1, 0, 0, 1)
        var state = c.init
        var i = 0
        c.io.en.poke(true.B)
        while (i < 10 * c.n) {
    
          // poke in repeated inSeq
          val toPoke = inSeq(i % inSeq.length)
          c.io.in.poke((toPoke != 0).B)
          // update expected state
          state = ((state * 2) + toPoke) & BigInt("1"*c.n, 2)
          c.clock.step(1)
          c.io.out.expect(state.U)
          i += 1
        }
      }
    }
    println("SUCCESS!!")
  }
}

Verilog Output is as follows :

module MyModule(
  input        clock,
  input        reset,
  input        io_en,
  input        io_in,
  output [9:0] io_out
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
`endif // RANDOMIZE_REG_INIT
  reg [9:0] state; // @[MyModule.scala 11:22]
  wire [10:0] _nextState_T = {state, 1'h0}; // @[MyModule.scala 12:25]
  wire [10:0] _GEN_1 = {
   {10'd0}, io_in}; // @[MyModule.scala 12:30]
  wire [10:0] nextState = _nextState_T | _GEN_1; // @[MyModule.scala 12:30]
  wire [10:0] _GEN_0 = io_en ? nextState : {
   {1'd0}, state}; // @[MyModule.scala 13:16 14:11 11:22]
  wire [10:0] _GEN_2 = reset ? 11'h2 : _GEN_0; // @[MyModule.scala 11:{22,22}]
  assign io_out = state; // @[MyModule.scala 16:10]
  always @(posedge clock) begin
    state <= _GEN_2[9:0]; // @[MyModule.scala 11:{22,22}]
  end
// Register and memory initialization
...	//  Omit 
endmodule

The test passed .

Explicit clock and reset

Chisel The module has a default clock and reset signal , Each register created in the module implicitly uses them .

If you want to override this default behavior , Maybe there is a black box that can generate a clock or reset signal , Maybe there is a multi clock design .

Synchronous multi clock and synchronous reset

Chisel Provides a structure to handle this situation , The clock and reset signal pass withClock() {},withReset() {} and withClockAndReset() {} Cover separately or together . The following code gives examples of using these functions , It is a module with multiple clock signals and reset signals :

// MyModule.scala
import chisel3._
import chisel3.util._
//  In the old version, this is an experimental feature , And the tester does not support ( The tester does not support it now )
// import chisel3.experimental.{withClock, withReset, withClockAndReset}

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in  = Input(UInt(10.W))
    val alternateReset    = Input(Bool())
    val alternateClock    = Input(Clock())
    val outImplicit       = Output(UInt())
    val outAlternateReset = Output(UInt())
    val outAlternateClock = Output(UInt())
    val outAlternateBoth  = Output(UInt())
  })

  val imp = RegInit(0.U(10.W))
  imp := io.in
  io.outImplicit := imp

  withReset(io.alternateReset) {
    
    val altRst = RegInit(0.U(10.W))
    altRst := io.in
    io.outAlternateReset := altRst
  }

  withClock(io.alternateClock) {
    
    val altClk = RegInit(0.U(10.W))
    altClk := io.in
    io.outAlternateClock := altClk
  }

  withClockAndReset(io.alternateClock, io.alternateReset) {
    
    val alt = RegInit(0.U(10.W))
    alt := io.in
    io.outAlternateBoth := alt
  }
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule()))
}

// MyModuleTest.scala
//  current version Chisel(3.5) The multi clock feature on the tester is not supported 

Note that there reset The signal is synchronous and of type Bool,Reset Type cannot be used in top-level input .

Chisel 3.2 Start to support asynchronous reset 了 , The type is AsyncReset().

The clock is Chisel Has its own type (Clock) And it must be stated .

Bool Can pass asClock() Convert to Clock, But don't do stupid things when you use it .

Output Verilog The code is as follows :

module MyModule(
  input        clock,
  input        reset,
  input  [9:0] io_in,
  input        io_alternateReset,
  input        io_alternateClock,
  output [9:0] io_outImplicit,
  output [9:0] io_outAlternateReset,
  output [9:0] io_outAlternateClock,
  output [9:0] io_outAlternateBoth
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
  reg [31:0] _RAND_1;
  reg [31:0] _RAND_2;
  reg [31:0] _RAND_3;
`endif // RANDOMIZE_REG_INIT
  reg [9:0] imp; // @[MyModule.scala 17:20]
  reg [9:0] altRst; // @[MyModule.scala 22:25]
  reg [9:0] altClk; // @[MyModule.scala 28:25]
  reg [9:0] alt; // @[MyModule.scala 34:22]
  assign io_outImplicit = imp; // @[MyModule.scala 19:18]
  assign io_outAlternateReset = altRst; // @[MyModule.scala 24:26]
  assign io_outAlternateClock = altClk; // @[MyModule.scala 30:26]
  assign io_outAlternateBoth = alt; // @[MyModule.scala 36:25]
  always @(posedge clock) begin
    if (reset) begin // @[MyModule.scala 17:20]
      imp <= 10'h0; // @[MyModule.scala 17:20]
    end else begin
      imp <= io_in; // @[MyModule.scala 18:7]
    end
    if (io_alternateReset) begin // @[MyModule.scala 22:25]
      altRst <= 10'h0; // @[MyModule.scala 22:25]
    end else begin
      altRst <= io_in; // @[MyModule.scala 23:12]
    end
  end
  always @(posedge io_alternateClock) begin
    if (reset) begin // @[MyModule.scala 28:25]
      altClk <= 10'h0; // @[MyModule.scala 28:25]
    end else begin
      altClk <= io_in; // @[MyModule.scala 29:12]
    end
    if (io_alternateReset) begin // @[MyModule.scala 34:22]
      alt <= 10'h0; // @[MyModule.scala 34:22]
    end else begin
      alt <= io_in; // @[MyModule.scala 35:9]
    end
  end
// Register and memory initialization
...	//  Omit 
endmodule

It does not support multiple clocks, so it is impossible to test , I won't test it .

But the reset signal can still be tested :

import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    test(new MyModule) {
     c =>
      c.io.in.poke(111.U)
      c.io.alternateReset.poke(false.B)
      c.clock.step(1)
      c.io.outImplicit.expect(111.U)
      c.io.outAlternateReset.expect(111.U)

      c.reset.poke(true.B)
      c.clock.step(1)
      c.io.outImplicit.expect(0.U)
      c.io.outAlternateReset.expect(111.U)

      c.io.alternateReset.poke(true.B)
      c.clock.step(1)
      c.io.outAlternateReset.expect(0.U)
    }
    println("SUCCESS!!")
  }
}

The test passed .

Asynchronous reset

Then there is the asynchronous reset signal , The code is as follows :

// MyModule.scala
import chisel3._
import chisel3.util._

class MyModule extends Module {
    
  val io = IO(new Bundle {
    
    val in  = Input(UInt(10.W))
    val alternateAsyncReset    = Input(Bool())	//  Synchronous reset signal 
    val outImplicit       = Output(UInt())
    val outAlternateAsyncReset = Output(UInt())
  })

  val imp = RegInit(0.U(10.W))
  imp := io.in
  io.outImplicit := imp

  withReset(io.alternateAsyncReset.asAsyncReset()) {
    	//  Convert to asynchronous reset signal using 
    val altRst = RegInit(0.U(10.W))
    altRst := io.in
    io.outAlternateAsyncReset := altRst
  }
}

object MyModule extends App {
    
  println(getVerilogString(new MyModule()))
}

// MyModuleTest.scala
import chisel3._
import chiseltest._
import org.scalatest.flatspec.AnyFlatSpec

class MyModuleTest extends AnyFlatSpec with ChiselScalatestTester {
    
  behavior of "MyModule"
  it should "get right results" in {
    
    test(new MyModule) {
     c =>
      c.io.in.poke(111.U)
      c.io.alternateAsyncReset.poke(false.B)
      c.clock.step(1)
      c.io.outImplicit.expect(111.U)
      c.io.outAlternateAsyncReset.expect(111.U)

      c.reset.poke(true.B)
      c.clock.step(1)
      c.io.outImplicit.expect(0.U)
      c.io.outAlternateAsyncReset.expect(111.U)

      c.io.alternateAsyncReset.poke(true.B)
      // c.clock.step(1) //  Here, direct asynchronous reset , Instead of waiting for the next clock cycle 
      c.io.outAlternateAsyncReset.expect(0.U)
    }
    println("SUCCESS!!")
  }
}

Output Verilog The code is as follows :

module MyModule(
  input        clock,
  input        reset,
  input  [9:0] io_in,
  input        io_alternateAsyncReset,
  output [9:0] io_outImplicit,
  output [9:0] io_outAlternateAsyncReset
);
`ifdef RANDOMIZE_REG_INIT
  reg [31:0] _RAND_0;
  reg [31:0] _RAND_1;
`endif // RANDOMIZE_REG_INIT
  reg [9:0] imp; // @[MyModule.scala 14:20]
  reg [9:0] altRst; // @[MyModule.scala 19:25]
  assign io_outImplicit = imp; // @[MyModule.scala 16:18]
  assign io_outAlternateAsyncReset = altRst; // @[MyModule.scala 21:31]
  always @(posedge clock) begin
    if (reset) begin // @[MyModule.scala 14:20]
      imp <= 10'h0; // @[MyModule.scala 14:20]
    end else begin
      imp <= io_in; // @[MyModule.scala 15:7]
    end
  end
  always @(posedge clock or posedge io_alternateAsyncReset) begin
    if (io_alternateAsyncReset) begin // @[MyModule.scala 19:25]
      altRst <= 10'h0; // @[MyModule.scala 19:25]
    end else begin
      altRst <= io_in; // @[MyModule.scala 20:12]
    end
  end
// Register and memory initialization
...	//  Omit 
endmodule

The test passed .

原网站

版权声明
本文为[github-3rr0r]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130555354137.html