-
Notifications
You must be signed in to change notification settings - Fork 629
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sriram Sridhar
authored and
Sriram Sridhar
committed
Apr 26, 2023
1 parent
6d8680b
commit ea2f093
Showing
7 changed files
with
415 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// See LICENSE for license details | ||
package chipyard.upf | ||
|
||
import chipyard.TestHarness | ||
import freechips.rocketchip.diplomacy.LazyModule | ||
|
||
import scala.collection.mutable.ListBuffer | ||
|
||
import scalax.collection.mutable.Graph | ||
import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._ | ||
|
||
object ChipTopUPF { | ||
|
||
def default: UPFFunc.UPFFunction = { | ||
case top: LazyModule => { | ||
val modulesList = getLazyModules(top) | ||
val pdList = createPowerDomains(modulesList) | ||
val g = connectPDHierarchy(pdList) | ||
traverseGraph(g, UPFGenerator.generateUPF) | ||
} | ||
} | ||
|
||
def getLazyModules(top: LazyModule): ListBuffer[LazyModule] = { | ||
var i = 0 | ||
var result = new ListBuffer[LazyModule]() | ||
result.append(top) | ||
while (i < result.length) { | ||
val lazyMod = result(i) | ||
for (child <- lazyMod.getChildren) { | ||
result.append(child) | ||
} | ||
i += 1 | ||
} | ||
return result | ||
} | ||
|
||
def createPowerDomains(modulesList: ListBuffer[LazyModule]): ListBuffer[PowerDomain] = { | ||
var pdList = ListBuffer[PowerDomain]() | ||
for (pdInput <- UPFInputs.upfInfo) { | ||
val pd = new PowerDomain(name=pdInput.name, modules=getPDModules(pdInput, modulesList), | ||
isTop=pdInput.isTop, isGated=pdInput.isGated, | ||
highVoltage=pdInput.highVoltage, lowVoltage=pdInput.lowVoltage) | ||
pdList.append(pd) | ||
} | ||
return pdList | ||
} | ||
|
||
def getPDModules(pdInput: PowerDomainInput, modulesList: ListBuffer[LazyModule]): ListBuffer[LazyModule] = { | ||
var pdModules = ListBuffer[LazyModule]() | ||
for (moduleName <- pdInput.moduleList) { | ||
var module = modulesList.filter(_.module.name == moduleName) | ||
if (module.length == 1) { // filter returns a collection | ||
pdModules.append(module(0)) | ||
} else { | ||
module = modulesList.filter(_.module.instanceName == moduleName) | ||
if (module.length == 1) { | ||
pdModules.append(module(0)) | ||
} else { | ||
module = modulesList.filter(_.module.pathName == moduleName) | ||
if (module.length == 1) { | ||
pdModules.append(module(0)) | ||
} else { | ||
throw new Exception(s"PowerDomainInput module list doesn't exist in design.") | ||
} | ||
} | ||
} | ||
} | ||
return pdModules | ||
} | ||
|
||
def connectPDHierarchy(pdList: ListBuffer[PowerDomain]): Graph[PowerDomain, DiEdge] = { | ||
var g = Graph[PowerDomain, DiEdge]() | ||
for (pd <- pdList) { | ||
val pdInput = UPFInputs.upfInfo.filter(_.name == pd.name)(0) | ||
val childPDs = pdList.filter(x => pdInput.childrenPDs.contains(x.name)) | ||
for (childPD <- childPDs) { | ||
g += (pd ~> childPD) // directed edge from pd to childPD | ||
} | ||
} | ||
return g | ||
} | ||
|
||
def traverseGraph(g: Graph[PowerDomain, DiEdge], action: (PowerDomain, Graph[PowerDomain, DiEdge]) => Unit): Unit = { | ||
for (node <- g.nodes.filter(_.diPredecessors.isEmpty)) { // all nodes without parents | ||
g.outerNodeTraverser(node).foreach(pd => action(pd, g)) | ||
} | ||
} | ||
|
||
} | ||
|
||
case object ChipTopUPFAspect extends UPFAspect[chipyard.TestHarness](ChipTopUPF.default) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// See LICENSE for license details | ||
package chipyard.upf | ||
|
||
import chisel3.aop.Aspect | ||
import firrtl.{AnnotationSeq} | ||
import chipyard.TestHarness | ||
import freechips.rocketchip.stage.phases.TargetDirKey | ||
|
||
import freechips.rocketchip.diplomacy.LazyModule | ||
|
||
abstract class UPFAspect[T <: TestHarness](upf: UPFFunc.UPFFunction) extends Aspect[T] { | ||
|
||
final override def toAnnotation(top: T): AnnotationSeq = { | ||
UPFFunc.UPFPath = top.p(TargetDirKey) + "/upf" | ||
upf(top.lazyDut) | ||
AnnotationSeq(Seq()) // noop | ||
} | ||
|
||
} | ||
|
||
object UPFFunc { | ||
type UPFFunction = PartialFunction[LazyModule, Unit] | ||
var UPFPath = "" // output dir path | ||
} |
Oops, something went wrong.