From 61ef560c75dd22c6ca0052dd203dacc4fa6b18a9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 14 Nov 2017 17:49:10 -0800 Subject: [PATCH] tilelink: don't pollute TLParamters with AtomicAutomata's implementation (#1111) --- src/main/scala/tilelink/AtomicAutomata.scala | 8 +++++++- src/main/scala/tilelink/Parameters.scala | 11 ++++++++++- src/main/scala/tilelink/ToAHB.scala | 2 +- src/main/scala/tilelink/ToAPB.scala | 2 +- src/main/scala/tilelink/Xbar.scala | 2 -- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/scala/tilelink/AtomicAutomata.scala b/src/main/scala/tilelink/AtomicAutomata.scala index b0200024..2e8a1a5b 100644 --- a/src/main/scala/tilelink/AtomicAutomata.scala +++ b/src/main/scala/tilelink/AtomicAutomata.scala @@ -15,7 +15,6 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc require (concurrency >= 1) val node = TLAdapterNode( - clientFn = { case cp => require (!cp.unsafeAtomics); cp.copy(unsafeAtomics = true) }, managerFn = { case mp => mp.copy(managers = mp.managers.map { m => val ourSupport = TransferSizes(1, mp.beatBytes) def widen(x: TransferSizes) = if (passthrough && x.min <= 2*mp.beatBytes) TransferSizes(1, max(mp.beatBytes, x.max)) else ourSupport @@ -32,6 +31,13 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc val managers = edgeOut.manager.managers val beatBytes = edgeOut.manager.beatBytes + // This is necessary (though not sufficient) for correctness: + edgeOut.manager.findTreeViolation() match { + case None => () + case Some(node) => require(edgeOut.manager.isTree, s"AtomicAutomata can only be placed infront of a tree of diplomatic nodes (${node.name} has parents ${node.inputs.map(_._1.name)})") + } + // You also need to know that the slaves don't have an internal masters that can get between the read and write + // To which managers are we adding atomic support? val ourSupport = TransferSizes(1, edgeOut.manager.beatBytes) val managersNeedingHelp = managers.filter { m => diff --git a/src/main/scala/tilelink/Parameters.scala b/src/main/scala/tilelink/Parameters.scala index ace1a459..3ab22ee1 100644 --- a/src/main/scala/tilelink/Parameters.scala +++ b/src/main/scala/tilelink/Parameters.scala @@ -67,6 +67,13 @@ case class TLManagerParameters( c = regionType >= RegionType.UNCACHED, a = supportsArithmetic && supportsLogical)) } + + def findTreeViolation() = nodePath.find { + case _: MixedAdapterNode[_, _, _, _, _, _, _, _] => false + case _: SinkNode[_, _, _, _, _] => false + case node => node.inputs.size != 1 + } + def isTree = findTreeViolation() == None } case class TLManagerPortParameters( @@ -170,6 +177,9 @@ case class TLManagerPortParameters( def supportsPutFullFast (address: UInt, lgSize: UInt, range: Option[TransferSizes] = None) = supportHelper(false, _.supportsPutFull, address, lgSize, range) def supportsPutPartialFast(address: UInt, lgSize: UInt, range: Option[TransferSizes] = None) = supportHelper(false, _.supportsPutPartial, address, lgSize, range) def supportsHintFast (address: UInt, lgSize: UInt, range: Option[TransferSizes] = None) = supportHelper(false, _.supportsHint, address, lgSize, range) + + def findTreeViolation() = managers.flatMap(_.findTreeViolation()).headOption + def isTree = !managers.exists(!_.isTree) } case class TLClientParameters( @@ -208,7 +218,6 @@ case class TLClientParameters( case class TLClientPortParameters( clients: Seq[TLClientParameters], - unsafeAtomics: Boolean = false, minLatency: Int = 0) // Only applies to B=>C { require (!clients.isEmpty) diff --git a/src/main/scala/tilelink/ToAHB.scala b/src/main/scala/tilelink/ToAHB.scala index b935cbbc..77b129d0 100644 --- a/src/main/scala/tilelink/ToAHB.scala +++ b/src/main/scala/tilelink/ToAHB.scala @@ -11,7 +11,7 @@ import scala.math.{min, max} import AHBParameters._ case class TLToAHBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, AHBImp)( - dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => + dFn = { case TLClientPortParameters(clients, minLatency) => val masters = clients.map { case c => AHBMasterParameters(name = c.name, nodePath = c.nodePath) } AHBMasterPortParameters(masters) }, diff --git a/src/main/scala/tilelink/ToAPB.scala b/src/main/scala/tilelink/ToAPB.scala index 046aa97d..b0146090 100644 --- a/src/main/scala/tilelink/ToAPB.scala +++ b/src/main/scala/tilelink/ToAPB.scala @@ -10,7 +10,7 @@ import scala.math.{min, max} import APBParameters._ case class TLToAPBNode()(implicit valName: ValName) extends MixedAdapterNode(TLImp, APBImp)( - dFn = { case TLClientPortParameters(clients, unsafeAtomics, minLatency) => + dFn = { case TLClientPortParameters(clients, minLatency) => val masters = clients.map { case c => APBMasterParameters(name = c.name, nodePath = c.nodePath) } APBMasterPortParameters(masters) }, diff --git a/src/main/scala/tilelink/Xbar.scala b/src/main/scala/tilelink/Xbar.scala index ca3f9dbf..c9c39d96 100644 --- a/src/main/scala/tilelink/Xbar.scala +++ b/src/main/scala/tilelink/Xbar.scala @@ -34,8 +34,6 @@ class TLXbar(policy: TLArbiter.Policy = TLArbiter.roundRobin)(implicit p: Parame numClientPorts = 1 to 999, numManagerPorts = 1 to 999, clientFn = { seq => - require (!seq.exists(_.unsafeAtomics) || seq.size == 1, - "An unsafe atomic port can not be combined with any other!") seq(0).copy( minLatency = seq.map(_.minLatency).min, clients = (TLXbar.mapInputIds(seq) zip seq) flatMap { case (range, port) =>