From 436a6cb538e0de0556129efdbc8c8505b2bd479b Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Wed, 24 May 2023 19:40:30 -0700 Subject: [PATCH] Add MultiHarnessBinder API --- .../main/scala/harness/HarnessBinders.scala | 4 +- .../harness/HasHarnessInstantiators.scala | 1 + .../scala/harness/MultiHarnesBinders.scala | 78 +++++++++++++++++++ .../src/main/scala/harness/package.scala | 17 ++++ 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 generators/chipyard/src/main/scala/harness/MultiHarnesBinders.scala create mode 100644 generators/chipyard/src/main/scala/harness/package.scala diff --git a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala index 0c2e4c49..db6f0cda 100644 --- a/generators/chipyard/src/main/scala/harness/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/harness/HarnessBinders.scala @@ -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 = { diff --git a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala index b5c7e2ce..4c1186b9 100644 --- a/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala +++ b/generators/chipyard/src/main/scala/harness/HasHarnessInstantiators.scala @@ -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) diff --git a/generators/chipyard/src/main/scala/harness/MultiHarnesBinders.scala b/generators/chipyard/src/main/scala/harness/MultiHarnesBinders.scala new file mode 100644 index 00000000..1c057dff --- /dev/null +++ b/generators/chipyard/src/main/scala/harness/MultiHarnesBinders.scala @@ -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) + } + } +)) diff --git a/generators/chipyard/src/main/scala/harness/package.scala b/generators/chipyard/src/main/scala/harness/package.scala new file mode 100644 index 00000000..789d1595 --- /dev/null +++ b/generators/chipyard/src/main/scala/harness/package.scala @@ -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]) => ()) +}