Изменение тактирования в RocketSubsystemModuleImp из System.scala
Я пытаюсь изменить часы и сбросы, которые идут на каждую плитку Rocket в моей системе.
На данный момент я пытаюсь сделать это так. В Platform.scala у меня есть некоторые входные данные, объявленные в моем PlatformIO (где $HARTS - это наше число хартов):
val hart_clocks = Vec($HARTS,Bool(INPUT))
val hart_resets = Vec($HARTS,Bool(INPUT))
В System.scala у меня есть:
val hart_clocks = IO(Vec($HARTS,Bool(INPUT)))
val hart_resets = IO(Vec($HARTS,Bool(INPUT)))
и в Platform.scala у меня есть это:
sys.hart_clocks := io.internals.hart_clocks
sys.hart_resets := io.internals.hart_resets
Теперь сложным моментом является взаимодействие между SystemModule ... extends RocketSubsystemModuleImp(_outer)
парень и RocketSubsystemModuleImp
учебный класс.
В RocketSubsystemModuleImp
у нас изначально есть это:
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
}
}
Все хорошо - я выбрал эту точку, чтобы переопределить часы и сбрасывать, потому что это хорошая точка иерархически (на краю плитки) и в коде, с назначениями часов и сброса, готовыми для изменения.
Однако до сих пор я не мог заставить что-либо работать. Вот различные вещи, которые я пробовал, и ошибки, которые я получил:
Попытка 1
В SystemModule
в System.scala
Я просто пытаюсь водить часы и провода:
_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)
Уродливый и еще много чего, но это была первая попытка.
Я, очевидно, также закомментировал проводные назначения в 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
}
Это скомпилировано, но взрывается в разработке с этой ошибкой:
[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)
Попытка 2
Объявите некоторые промежуточные переменные в 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
}
}
а затем в 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
Однако это также вызывает то же самое неодобрение со стороны инструментов:
[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)
Попытка 3
Вместо того, чтобы пытаться переопределить его в ModuleImp, я попытался сделать это так System.scala
:
_outer.tiles(0).module.clock := hart_clocks(0).asClock()
_outer.tiles(0).module.reset := hart_resets(0)
и закомментировав wire.clock
а также wire.reset
назначения в RocketSubsystemModuleImp
...
... как же тогда я сказал, что мои указания были неверны?
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.
Ммм? Я бы подумал, что Input -> Input -> Input будет хорошо?
И теперь я застрял.
Что было бы самым аккуратным, самым чистым способом сделать это, не имея модификации в Долоте ракетного чипа?
Спасибо!
0 ответов
Во-первых, не рекомендуется использовать разные часы для каждого харта. Поскольку система L2 предназначена для синхронизации.
Причина, по которой вы всегда получаете ошибку attempted to instantiate a Module without wrapping it in Module()
вы действительно подключаете какие-то провода в LazyModule
который не создается в начале разработки. Вместо этого вам следует выполнять всю свою работу вLazyModuleImp
.
Думаю, можно сделать вот так:
В 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
}
}
В TestHarness
, вы можете напрямую подключить свой harts_clock
dut.harts_clock(0) := clock