diff --git a/src/main/scala/uncore/tilelink2/Bundles.scala b/src/main/scala/uncore/tilelink2/Bundles.scala index 5b0893c2..c32e3f4c 100644 --- a/src/main/scala/uncore/tilelink2/Bundles.scala +++ b/src/main/scala/uncore/tilelink2/Bundles.scala @@ -190,7 +190,7 @@ object TLBundle def apply(params: TLBundleParameters) = new TLBundle(params) } -class IrrevocableSnoop[+T <: Data](gen: T) extends Bundle +final class IrrevocableSnoop[+T <: Data](gen: T) extends Bundle { val ready = Bool() val valid = Bool() @@ -232,3 +232,23 @@ object TLBundleSnoop out } } + +final class AsyncBundle[T <: Data](depth: Int, gen: T) extends Bundle +{ + require (isPow2(depth)) + val ridx = UInt(width = log2Up(depth)+1).flip + val widx = UInt(width = log2Up(depth)+1) + val mem = Vec(depth, gen) + override def cloneType: this.type = new AsyncBundle(depth, gen).asInstanceOf[this.type] +} + +class TLAsyncBundleBase(params: TLAsyncBundleParameters) extends GenericParameterizedBundle(params) + +class TLAsyncBundle(params: TLAsyncBundleParameters) extends TLAsyncBundleBase(params) +{ + val a = new AsyncBundle(params.depth, new TLBundleA(params.base)) + val b = new AsyncBundle(params.depth, new TLBundleB(params.base)).flip + val c = new AsyncBundle(params.depth, new TLBundleC(params.base)) + val d = new AsyncBundle(params.depth, new TLBundleD(params.base)).flip + val e = new AsyncBundle(params.depth, new TLBundleE(params.base)) +} diff --git a/src/main/scala/uncore/tilelink2/Parameters.scala b/src/main/scala/uncore/tilelink2/Parameters.scala index 71fd667e..514e6acd 100644 --- a/src/main/scala/uncore/tilelink2/Parameters.scala +++ b/src/main/scala/uncore/tilelink2/Parameters.scala @@ -401,6 +401,17 @@ case class TLBundleParameters( max(sizeBits, x.sizeBits)) } +object TLBundleParameters +{ + def apply(client: TLClientPortParameters, manager: TLManagerPortParameters) = + new TLBundleParameters( + addrHiBits = log2Up(manager.maxAddress + 1) - log2Ceil(manager.beatBytes), + dataBits = manager.beatBytes * 8, + sourceBits = log2Up(client.endSourceId), + sinkBits = log2Up(manager.endSinkId), + sizeBits = log2Up(log2Ceil(max(client.maxTransfer, manager.maxTransfer))+1)) +} + case class TLEdgeParameters( client: TLClientPortParameters, manager: TLManagerPortParameters) @@ -411,10 +422,13 @@ case class TLEdgeParameters( // Sanity check the link... require (maxTransfer >= manager.beatBytes) - val bundle = TLBundleParameters( - addrHiBits = log2Up(manager.maxAddress + 1) - log2Ceil(manager.beatBytes), - dataBits = manager.beatBytes * 8, - sourceBits = log2Up(client.endSourceId), - sinkBits = log2Up(manager.endSinkId), - sizeBits = log2Up(maxLgSize+1)) + val bundle = TLBundleParameters(client, manager) +} + +case class TLAsyncManagerPortParameters(depth: Int, base: TLManagerPortParameters) { require (isPow2(depth)) } +case class TLAsyncClientPortParameters(base: TLClientPortParameters) +case class TLAsyncBundleParameters(depth: Int, base: TLBundleParameters) { require (isPow2(depth)) } +case class TLAsyncEdgeParameters(client: TLAsyncClientPortParameters, manager: TLAsyncManagerPortParameters) +{ + val bundle = TLAsyncBundleParameters(manager.depth, TLBundleParameters(client.base, manager.base)) } diff --git a/src/main/scala/uncore/tilelink2/TLNodes.scala b/src/main/scala/uncore/tilelink2/TLNodes.scala index 84c1405e..e52b275d 100644 --- a/src/main/scala/uncore/tilelink2/TLNodes.scala +++ b/src/main/scala/uncore/tilelink2/TLNodes.scala @@ -71,3 +71,42 @@ class TLInputNodeTest extends UnitTest(500000) { io.finished := Module(fuzzer.module).io.finished } + +object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncEdgeParameters, TLAsyncEdgeParameters, TLAsyncBundle] +{ + def edgeO(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu) + def edgeI(pd: TLAsyncClientPortParameters, pu: TLAsyncManagerPortParameters): TLAsyncEdgeParameters = TLAsyncEdgeParameters(pd, pu) + def bundleO(eo: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = { + require (eo.size == 1) + Vec(eo.size, new TLAsyncBundle(eo(0).bundle)) + } + def bundleI(ei: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = { + require (ei.size == 1) + Vec(ei.size, new TLAsyncBundle(ei(0).bundle)).flip + } + + def connect(bo: => TLAsyncBundle, bi: => TLAsyncBundle, ei: => TLAsyncEdgeParameters)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { + (None, () => { bi <> bo }) + } + + override def mixO(pd: TLAsyncClientPortParameters, node: OutwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncClientPortParameters = + pd.copy(base = pd.base.copy(clients = pd.base.clients.map { c => c.copy (nodePath = node +: c.nodePath) })) + override def mixI(pu: TLAsyncManagerPortParameters, node: InwardNode[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle]): TLAsyncManagerPortParameters = + pu.copy(base = pu.base.copy(managers = pu.base.managers.map { m => m.copy (nodePath = node +: m.nodePath) })) +} + +case class TLAsyncIdentityNode() extends IdentityNode(TLAsyncImp) +case class TLAsyncOutputNode() extends OutputNode(TLAsyncImp) +case class TLAsyncInputNode() extends InputNode(TLAsyncImp) + +case class TLAsyncSourceNode() extends MixedNode(TLImp, TLAsyncImp)( + dFn = { case (1, s) => s.map(TLAsyncClientPortParameters(_)) }, + uFn = { case (1, s) => s.map(_.base) }, + numPO = 1 to 1, + numPI = 1 to 1) + +case class TLAsyncSinkNode(depth: Int) extends MixedNode(TLAsyncImp, TLImp)( + dFn = { case (1, s) => s.map(_.base) }, + uFn = { case (1, s) => s.map(TLAsyncManagerPortParameters(depth, _)) }, + numPO = 1 to 1, + numPI = 1 to 1)