tilelink2 IntNodes: support interrupt graphs
This commit is contained in:
parent
d7df7d3109
commit
23e896ed5d
72
src/main/scala/uncore/tilelink2/IntNodes.scala
Normal file
72
src/main/scala/uncore/tilelink2/IntNodes.scala
Normal file
@ -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 }
|
||||
}
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user