Add MultiHarnessBinder API
This commit is contained in:
@@ -30,9 +30,7 @@ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvon
|
||||
|
||||
import scala.reflect.{ClassTag}
|
||||
|
||||
case object HarnessBinders extends Field[Map[String, (Any, HasHarnessInstantiators, Seq[Data]) => Unit]](
|
||||
Map[String, (Any, HasHarnessInstantiators, Seq[Data]) => Unit]().withDefaultValue((t: Any, th: HasHarnessInstantiators, d: Seq[Data]) => ())
|
||||
)
|
||||
case object HarnessBinders extends Field[HarnessBinderMap](HarnessBinderMapDefault)
|
||||
|
||||
object ApplyHarnessBinders {
|
||||
def apply(th: HasHarnessInstantiators, sys: LazyModule, portMap: Map[String, Seq[Data]])(implicit p: Parameters): Unit = {
|
||||
|
||||
@@ -86,6 +86,7 @@ trait HasHarnessInstantiators {
|
||||
case (d: HasIOBinders, i: Int) => ApplyHarnessBinders(this, d.lazySystem, d.portMap)(chipParameters(i))
|
||||
case _ =>
|
||||
}
|
||||
ApplyMultiHarnessBinders(this, lazyDuts)
|
||||
}
|
||||
|
||||
val harnessBinderClk = harnessClockInstantiator.requestClockMHz("harnessbinder_clock", getHarnessBinderClockFreqMHz)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package chipyard.harness
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
import testchipip._
|
||||
|
||||
import chipyard._
|
||||
import chipyard.clocking.{HasChipyardPRCI, ClockWithFreq}
|
||||
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasIOBinders}
|
||||
|
||||
import scala.reflect.{ClassTag}
|
||||
|
||||
case class MultiHarnessBinders(c0: Int, c1: Int) extends Field[MultiHarnessBinderMap](MultiHarnessBinderMapDefault)
|
||||
|
||||
class MultiHarnessBinder[T0, T1, S <: HasHarnessInstantiators, U0 <: Data, U1 <: Data]
|
||||
(chip0: Int, chip1: Int, fn: => (T0, T1, S, Seq[U0], Seq[U1]) => Unit)
|
||||
(implicit tag0: ClassTag[T0], tag1: ClassTag[T1], thtag: ClassTag[S], ptag0: ClassTag[U0], ptag1: ClassTag[U1])
|
||||
extends Config((site, here, up) => {
|
||||
// Override any HarnessBinders for chip0/chip1
|
||||
case MultiChipParameters(`chip0`) => new Config(
|
||||
new OverrideHarnessBinder[T0, S, U0]((system: T0, th: S, ports: Seq[U0]) => Nil) ++
|
||||
up(MultiChipParameters(chip0))
|
||||
)
|
||||
case MultiChipParameters(`chip1`) => new Config(
|
||||
new OverrideHarnessBinder[T1, S, U1]((system: T1, th: S, ports: Seq[U1]) => Nil) ++
|
||||
up(MultiChipParameters(chip1))
|
||||
)
|
||||
// Set the multiharnessbinder key
|
||||
case MultiHarnessBinders(`chip0`, `chip1`) => up(MultiHarnessBinders(chip0, chip1)) +
|
||||
((tag0.runtimeClass.toString, tag1.runtimeClass.toString) ->
|
||||
((c0: Any, c1: Any, th: HasHarnessInstantiators, ports0: Seq[Data], ports1: Seq[Data]) => {
|
||||
val pts0 = ports0.map(_.asInstanceOf[U0])
|
||||
val pts1 = ports1.map(_.asInstanceOf[U1])
|
||||
require(pts0.size == pts1.size)
|
||||
(c0, c1, th) match {
|
||||
case (c0: T0, c1: T1, th: S) => fn(c0, c1, th, pts0, pts1)
|
||||
case _ =>
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
object ApplyMultiHarnessBinders {
|
||||
def apply(th: HasHarnessInstantiators, chips: Seq[LazyModule])(implicit p: Parameters): Unit = {
|
||||
Seq.tabulate(chips.size, chips.size) { case (i, j) => if (i != j) {
|
||||
(chips(i), chips(j)) match {
|
||||
case (l0: HasIOBinders, l1: HasIOBinders) => p(MultiHarnessBinders(i, j)).foreach {
|
||||
case ((s0, s1), f) => {
|
||||
f(l0.lazySystem , l1.lazySystem , th, l0.portMap(s0), l1.portMap(s1))
|
||||
f(l0.lazySystem.module, l1.lazySystem.module, th, l0.portMap(s0), l1.portMap(s1))
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
class WithMultiChipSerialTL(chip0: Int, chip1: Int) extends MultiHarnessBinder(chip0, chip1, (
|
||||
(system0: CanHavePeripheryTLSerial, system1: CanHavePeripheryTLSerial,
|
||||
th: HasHarnessInstantiators,
|
||||
ports0: Seq[ClockedIO[SerialIO]], ports1: Seq[ClockedIO[SerialIO]]
|
||||
) => {
|
||||
require(ports0.size == ports1.size)
|
||||
(ports0 zip ports1).map { case (l, r) =>
|
||||
l.clock <> r.clock
|
||||
require(l.bits.w == r.bits.w)
|
||||
l.bits.flipConnect(r.bits)
|
||||
}
|
||||
}
|
||||
))
|
||||
17
generators/chipyard/src/main/scala/harness/package.scala
Normal file
17
generators/chipyard/src/main/scala/harness/package.scala
Normal file
@@ -0,0 +1,17 @@
|
||||
package chipyard
|
||||
|
||||
import chisel3._
|
||||
import scala.collection.immutable.ListMap
|
||||
|
||||
package object harness
|
||||
{
|
||||
type HarnessBinderFunction = (Any, HasHarnessInstantiators, Seq[Data]) => Unit
|
||||
type HarnessBinderMap = Map[String, HarnessBinderFunction]
|
||||
def HarnessBinderMapDefault: HarnessBinderMap = (new ListMap[String, HarnessBinderFunction])
|
||||
.withDefaultValue((t: Any, th: HasHarnessInstantiators, d: Seq[Data]) => ())
|
||||
|
||||
type MultiHarnessBinderFunction = (Any, Any, HasHarnessInstantiators, Seq[Data], Seq[Data]) => Unit
|
||||
type MultiHarnessBinderMap = Map[(String, String), MultiHarnessBinderFunction]
|
||||
def MultiHarnessBinderMapDefault: MultiHarnessBinderMap = (new ListMap[(String, String), MultiHarnessBinderFunction])
|
||||
.withDefaultValue((_: Any, _: Any, _: HasHarnessInstantiators, _: Seq[Data], _: Seq[Data]) => ())
|
||||
}
|
||||
Reference in New Issue
Block a user