1
0
rocket-chip/src/main/scala/uncore/tilelink2/IntNodes.scala

73 lines
2.6 KiB
Scala
Raw Normal View History

// 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 }
}
}