0

I'm trying to alter the clocks and resets which go to each Rocket tile in my system.

At the moment I'm trying to do it like this. In Platform.scala I have some inputs declared in my PlatformIO (where $HARTS is our number of harts):

val hart_clocks = Vec($HARTS,Bool(INPUT))
val hart_resets = Vec($HARTS,Bool(INPUT))

In System.scala I have:

val hart_clocks = IO(Vec($HARTS,Bool(INPUT)))
val hart_resets = IO(Vec($HARTS,Bool(INPUT)))

and in Platform.scala I have this:

sys.hart_clocks := io.internals.hart_clocks
sys.hart_resets := io.internals.hart_resets

Now the tricky bit is the interaction between the SystemModule ... extends RocketSubsystemModuleImp(_outer) guy and the RocketSubsystemModuleImp class.

In RocketSubsystemModuleImp we originally have this:

class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
    with HasRocketTilesModuleImp {
  tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
    wire.clock := clock
    wire.reset := reset
    wire.hartid := UInt(i)
    wire.reset_vector := global_reset_vector
  }
} 

All good - I chose this point to override the clocks and resets because it is a nice point hierarchically (on the edge of the tile) and in the code, with the clock and reset assignments ready to be altered.

However I've been unable to make anything work so far. Here are the various things I've tried and the errors I got:

Attempt 1

In SystemModule in System.scala I simply try to drive the clock and wires:

  _outer.module.tile_inputs(0).clock := hart_clocks(0)
  _outer.module.tile_inputs(1).clock := hart_clocks(1)
  ...
  _outer.module.tile_inputs(2).clock := hart_clocks($HARTS)

  _outer.module.tile_inputs(0).reset := hart_resets(0)
  _outer.module.tile_inputs(1).reset := hart_resets(1)
  ...
  _outer.module.tile_inputs(1).reset := hart_resets($HARTS)

Ugly and whatnot but it was a first attempt.

I obviously also commented out the wire assignments in the RocketSubsystemModuleImp:

  tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
    //wire.clock := clock
    //wire.reset := reset
    wire.hartid := UInt(i)
    wire.reset_vector := global_reset_vector
  }

This compiled but blows up in elaboration with this error:

[error] Caused by: chisel3.internal.ChiselException: Error: attempted to instantiate a Module without wrapping it in Module().
[error]         at chisel3.internal.throwException$.apply(Error.scala:44)
[error]         at chisel3.core.BaseModule.<init>(Module.scala:126)
[error]         at chisel3.core.UserModule.<init>(UserModule.scala:18)
[error]         at chisel3.core.ImplicitModule.<init>(UserModule.scala:121)
[error]         at freechips.rocketchip.diplomacy.LazyModuleImp.<init>(LazyModule.scala:185)
[error]         at freechips.rocketchip.subsystem.BareSubsystemModuleImp.<init>(BaseSubsystem.scala:20)
[error]         at freechips.rocketchip.subsystem.BaseSubsystemModuleImp.<init>(BaseSubsystem.scala:101)
[error]         at freechips.rocketchip.subsystem.RocketSubsystemModuleImp.<init>(RocketSubsystem.scala:69)

Attempt 2

Declare some intermediate variables in class RocketSubsystemModuleImp:

class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
    with HasRocketTilesModuleImp {
  val hart_clocks_wire = Wire(Vec($HARTS,Bool()))
  val hart_resets_wire = Wire(Vec($HARTS,Bool()))
  tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
    wire.clock := hart_clocks_wire(i).asClock()
    wire.reset := hart_resets_wire(i)
    wire.hartid := UInt(i)
    wire.reset_vector := global_reset_vector
  }
}

and then in SystemModule:

  val hart_clocks = IO(Vec($HARTS,Bool(INPUT)))
  val hart_resets = IO(Vec($HARTS,Bool(INPUT)))

  _outer.module.hart_clocks_wire := hart_clocks
  _outer.module.hart_resets_wire := hart_resets

However this also elicits the same disapproval from the tools:

[error] Caused by: chisel3.internal.ChiselException: Error: attempted to instantiate a Module without wrapping it in Module().
[error]         at chisel3.internal.throwException$.apply(Error.scala:44)
[error]         at chisel3.core.BaseModule.<init>(Module.scala:126)
[error]         at chisel3.core.UserModule.<init>(UserModule.scala:18)
[error]         at chisel3.core.ImplicitModule.<init>(UserModule.scala:121)
[error]         at freechips.rocketchip.diplomacy.LazyModuleImp.<init>(LazyModule.scala:185)
[error]         at freechips.rocketchip.subsystem.BareSubsystemModuleImp.<init>(BaseSubsystem.scala:20)
[error]         at freechips.rocketchip.subsystem.BaseSubsystemModuleImp.<init>(BaseSubsystem.scala:101)
[error]         at freechips.rocketchip.subsystem.RocketSubsystemModuleImp.<init>(RocketSubsystem.scala:69)

Attempt 3

Instead of attempting to override it in the ModuleImp, I then tried driving it like so in System.scala:

  _outer.tiles(0).module.clock := hart_clocks(0).asClock()
  _outer.tiles(0).module.reset := hart_resets(0)

and having commented out the wire.clock and wire.reset assignments in RocketSubsystemModuleImp...

... however firrtl then barfed saying my directions were wrong?

firrtl.passes.CheckGenders$WrongGender:  @[Platform.scala 283:19:Config.fir@540640.4]: [module Platform]  Expression sys.hart_clocks is used as a FEMALE but can only be used as a MALE.
firrtl.passes.CheckGenders$WrongGender:  @[Platform.scala 284:19:Config.fir@540641.4]: [module Platform]  Expression sys.hart_resets is used as a FEMALE but can only be used as a MALE.

Hmmm? I would've thought Input -> Input -> Input would be okay?

And now I'm stuck.

What would be the neatest, cleanest way to do this without having a modification in the rocket-chip Chisel?

Thanks!

jbaxter
  • 182
  • 10

1 Answers1

0

first, it is not recommended to use different clocks for each hart. Since the L2 system is designed to be synchronized.

The reason why you always get the error attempted to instantiate a Module without wrapping it in Module() is you are actually connecting some wires in the LazyModule which is not instantiated at the beginning of elaboration. Instead, you should do all your work in LazyModuleImp.

I think you can do this like this:

In RocketSubsystemModuleImp:

    with HasResetVectorWire
    with HasRocketTilesModuleImp {
  val harts_clock = IO(Vec($HARTS,Clock().asInput))
  val harts_reset = IO(Vec($HARTS, Bool().asInput))
  tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
    wire.clock := harts_clock(i)
    wire.reset := harts_reset(i)
    wire.wic_clock := wic_clock
    wire.hartid := UInt(i)
    wire.reset_vector := global_reset_vector
  }
}

In TestHarness, you can directly connect your harts_clock

dut.harts_clock(0) := clock

shuyun
  • 11
  • 4