1
0

diplomacy: change API to auto-create node bundles => cross-module refs

This commit is contained in:
Wesley W. Terpstra
2017-09-13 18:06:03 -07:00
parent 53f6999ea8
commit 9217baf9d4
86 changed files with 575 additions and 933 deletions

View File

@ -6,6 +6,7 @@ import Chisel._
import chisel3.experimental.{BaseModule, RawModule, MultiIOModule, withClockAndReset}
import chisel3.internal.sourceinfo.{SourceInfo, SourceLine, UnlocatableSourceInfo}
import freechips.rocketchip.config.Parameters
import scala.collection.immutable.ListMap
abstract class LazyModule()(implicit val p: Parameters)
{
@ -54,15 +55,6 @@ abstract class LazyModule()(implicit val p: Parameters)
def module: LazyModuleImpLike
protected[diplomacy] def instantiate() = {
children.reverse.foreach { c =>
// !!! fix chisel3 so we can pass the desired sourceInfo
// implicit val sourceInfo = c.module.outer.info
Module(c.module)
}
bindings.reverse.foreach { f => f () }
}
def omitGraphML: Boolean = !nodes.exists(!_.omitGraphML) && !children.exists(!_.omitGraphML)
lazy val graphML: String = parent.map(_.graphML).getOrElse {
val buf = new StringBuilder
@ -144,6 +136,8 @@ object LazyModule
sealed trait LazyModuleImpLike extends BaseModule
{
val wrapper: LazyModule
val auto: AutoBundle
protected[diplomacy] val dangles: Seq[Dangle]
// .module had better not be accessed while LazyModules are still being built!
require (LazyModule.stack.isEmpty, s"${wrapper.name}.module was constructed before LazyModule() was run on ${LazyModule.stack.head.name}")
@ -152,18 +146,47 @@ sealed trait LazyModuleImpLike extends BaseModule
suggestName(wrapper.instanceName)
implicit val p = wrapper.p
protected[diplomacy] def instantiate() = {
val childDangles = wrapper.children.reverse.flatMap { c =>
implicit val sourceInfo = c.info
Module(c.module).dangles
}
val nodeDangles = wrapper.nodes.reverse.flatMap(_.instantiate())
val (toConnect, toForward) = (nodeDangles ++ childDangles).groupBy(_.source).partition(_._2.size == 2)
val forward = toForward.map(_._2(0)).toList
toConnect.foreach { case (_, Seq(a, b)) =>
require (a.flipped != b.flipped)
if (a.flipped) { a.data <> b.data } else { b.data <> a.data }
}
val auto = IO(new AutoBundle(forward.map { d => (d.name, d.data, d.flipped) }:_*))
val dangles = (forward zip auto.elements) map { case (d, (_, io)) =>
if (d.flipped) { d.data <> io } else { io <> d.data }
d.copy(data = io, name = wrapper.valName.getOrElse("anon") + "_" + d.name)
}
wrapper.bindings.reverse.foreach { f => f () }
(auto, dangles)
}
}
abstract class LazyModuleImp(val wrapper: LazyModule) extends Module with LazyModuleImpLike {
wrapper.instantiate()
}
abstract class LazyMultiIOModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
wrapper.instantiate()
abstract class LazyModuleImp(val wrapper: LazyModule) extends MultiIOModule with LazyModuleImpLike {
val (auto, dangles) = instantiate()
}
abstract class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModuleImpLike {
withClockAndReset(Bool(false).asClock, Bool(true)) {
wrapper.instantiate()
val (auto, dangles) = withClockAndReset(Bool(false).asClock, Bool(true)) {
instantiate()
}
}
case class HalfEdge(serial: Int, index: Int)
case class Dangle(source: HalfEdge, sink: HalfEdge, flipped: Boolean, name: String, data: Data)
final class AutoBundle(elts: (String, Data, Boolean)*) extends Record {
// !!! need to fix-up name collision better than appending _#
val elements = ListMap(elts.zipWithIndex map { case ((field, elt, flip), i) =>
(field + "_" + i) -> (if (flip) elt.cloneType.flip else elt.cloneType)
}:_*)
override def cloneType = (new AutoBundle(elts:_*)).asInstanceOf[this.type]
}