From 23e896ed5dabef578c0c0155641095cfac56cb0a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 8 Sep 2016 11:30:35 -0700 Subject: [PATCH] tilelink2 IntNodes: support interrupt graphs --- .../scala/uncore/tilelink2/IntNodes.scala | 72 +++++++++++++++++++ src/main/scala/uncore/tilelink2/package.scala | 1 + 2 files changed, 73 insertions(+) create mode 100644 src/main/scala/uncore/tilelink2/IntNodes.scala diff --git a/src/main/scala/uncore/tilelink2/IntNodes.scala b/src/main/scala/uncore/tilelink2/IntNodes.scala new file mode 100644 index 00000000..fb35a49f --- /dev/null +++ b/src/main/scala/uncore/tilelink2/IntNodes.scala @@ -0,0 +1,72 @@ +// See LICENSE for license details. + +package uncore.tilelink2 + +import Chisel._ +import scala.collection.mutable.ListBuffer +import scala.math.max +import chisel3.internal.sourceinfo.SourceInfo + +case class IntSourceParameters(device: String, num: Int) + +case class IntSinkPortParameters() +case class IntSourcePortParameters(sources: Seq[IntSourceParameters]) +{ + val num = sources.map(_.num).sum +} +case class IntEdge(source: IntSourcePortParameters, sink: IntSinkPortParameters) + +object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]] +{ + def edgeO(po: IntSourcePortParameters, pi: IntSinkPortParameters): IntEdge = IntEdge(po, pi) + def edgeI(po: IntSourcePortParameters, pi: IntSinkPortParameters): IntEdge = IntEdge(po, pi) + def bundleO(eo: Seq[IntEdge]): Vec[Vec[Bool]] = { + if (eo.isEmpty) Vec(0, Vec(0, Bool())) else + Vec(eo.size, Vec(eo.map(_.source.num).max, Bool())) + } + def bundleI(ei: Seq[IntEdge]): Vec[Vec[Bool]] = { + require (!ei.isEmpty) + Vec(ei.size, Vec(ei.map(_.source.num).max, Bool())).flip + } + + def connect(bo: Vec[Bool], eo: IntEdge, bi: Vec[Bool], ei: IntEdge)(implicit sourceInfo: SourceInfo): Unit = { + require (eo == ei) + // Cannot use bulk connect, because the widths could differ + (bo zip bi) foreach { case (o, i) => i := o } + } +} + +case class IntIdentityNode() extends IdentityNode(IntImp) +case class IntOutputNode() extends OutputNode(IntImp) +case class IntInputNode() extends InputNode(IntImp) + +case class IntSourceNode(device: String, num: Int) extends SourceNode(IntImp)( + IntSourcePortParameters(Seq(IntSourceParameters(device, num))), + (if (num == 0) 0 else 1) to 1) +case class IntSinkNode() extends SinkNode(IntImp)(IntSinkPortParameters()) + +case class IntAdapterNode( + sourceFn: Seq[IntSourcePortParameters] => IntSourcePortParameters, + sinkFn: Seq[IntSinkPortParameters] => IntSinkPortParameters, + numSourcePorts: Range.Inclusive = 1 to 1, + numSinkPorts: Range.Inclusive = 1 to 1) + extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) + +class IntXbar extends LazyModule +{ + val intnode = IntAdapterNode( + numSourcePorts = 1 to 1, // does it make sense to have more than one interrupt sink? + numSinkPorts = 1 to 128, + sourceFn = { seq => IntSourcePortParameters(seq.map(_.sources).flatten) }, + sinkFn = { _ => IntSinkPortParameters() }) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = intnode.bundleIn + val out = intnode.bundleOut + } + + val cat = (intnode.edgesIn zip io.in).map{ case (e, i) => i.take(e.source.num) }.flatten + io.out.foreach { _ := cat } + } +} diff --git a/src/main/scala/uncore/tilelink2/package.scala b/src/main/scala/uncore/tilelink2/package.scala index b1e3dda2..cb78a633 100644 --- a/src/main/scala/uncore/tilelink2/package.scala +++ b/src/main/scala/uncore/tilelink2/package.scala @@ -5,6 +5,7 @@ import Chisel._ package object tilelink2 { type TLBaseNode = BaseNode[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle] + type IntBaseNode = BaseNode[IntSourcePortParameters, IntSinkPortParameters, IntEdge, IntEdge, Vec[Bool]] def OH1ToUInt(x: UInt) = OHToUInt((x << 1 | UInt(1)) ^ x) def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0) def trailingZeros(x: Int) = if (x > 0) Some(log2Ceil(x & -x)) else None