Search code examples
chisel

How do you test RawModules?


I'm using a chisel RawModule for an AXI interface to a module I'm building (so that I can use axi aclk and aresetn.) However, I'm unable to do the normal tactic of using a peekpoke tester. What's the recommended strategy for testing rawmodules that have clocks?


Solution

  • PeekPokeTester is currently limited to working on MultiIOModule or its subtypes. You can get around this by wrapping your RawModule in a MultiIOModule and bridging the IO (including the implicit clock/reset) from the wrapping MultiIOModule to your RawModule.

    The new testing and verification library for Chisel (which replaces chisel-testers/chisel3.iotesters) is expected to support this natively and has an associated tracking issue: ucb-bar/chisel-testers2#14.

    Edit: Example of wrapping a RawModule in a MultiIOModule:

    import chisel3._
    import chisel3.stage.ChiselStage
    
    sealed trait CommonIO { this: RawModule =>
      val a = IO(Input(Bool()))
      val b = IO(Output(Bool()))
    }
    
    class Foo extends RawModule with CommonIO {
      val clk = IO(Input(Clock()))
      val rst = IO(Input(Reset()))
      b := withClockAndReset(clk, rst){ RegNext(a, true.B) }
    }
    
    class Wrapper extends MultiIOModule with CommonIO {
      val foo = Module(new Foo)
      foo.a := a
      b := foo.b
      foo.clk := clock
      foo.rst := reset
    }
    
    (new ChiselStage)
      .execute(Array("-X", "verilog"),
               Seq(chisel3.stage.ChiselGeneratorAnnotation(() => new Wrapper)))
    

    This produces the following FIRRTL:

    circuit Wrapper :
      module Foo :
        input a : UInt<1>
        output b : UInt<1>
        input clk : Clock
        input rst : Reset
    
        reg _T : UInt<1>, clk with : (reset => (rst, UInt<1>("h01")))
        _T <= a
        b <= _T
    
      module Wrapper :
        input clock : Clock
        input reset : UInt<1>
        input a : UInt<1>
        output b : UInt<1>
    
        inst foo of Foo
        foo.a <= a
        b <= foo.b
        foo.clk <= clock
        foo.rst <= reset
    

    Note:

    1. The use of withClockAndReset to use clk and rst for the clock and reset connections of the RegNext
    2. The connections from the implicit Wrapper.clock and Wrapper.reset have to be made explicitly. withClockAndReset will not work here.