1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
// SPDX-License-Identifier: Apache-2.0
package firrtl.passes
package clocklist
import firrtl._
import firrtl.ir._
import wiring.Lineage
import Utils._
import memlib.AnalysisUtils._
object ClockListUtils {
/** Returns a list of clock outputs from instances of external modules
*/
def getSourceList(moduleMap: Map[String, DefModule])(lin: Lineage): Seq[String] = {
val s = lin.foldLeft(Seq[String]()) {
case (sL, (i, l)) =>
val sLx = getSourceList(moduleMap)(l)
val sLxx = sLx.map(i + "$" + _)
sL ++ sLxx
}
val sourceList = moduleMap(lin.name) match {
case ExtModule(i, n, ports, dn, p) =>
val portExps = ports.flatMap { p => create_exps(WRef(p.name, p.tpe, PortKind, to_flow(p.direction))) }
portExps.filter(e => (e.tpe == ClockType) && (flow(e) == SinkFlow)).map(_.serialize)
case _ => Nil
}
val sx = sourceList ++ s
sx
}
/** Returns a map from instance name to its clock origin.
* Child instances are not included if they share the same clock as their parent
*/
def getOrigins(
connects: Connects,
me: String,
moduleMap: Map[String, DefModule]
)(lin: Lineage
): Map[String, String] = {
val sep = if (me == "") "" else "$"
// Get origins from all children
val childrenOrigins = lin.foldLeft(Map[String, String]()) {
case (o, (i, l)) =>
o ++ getOrigins(connects, me + sep + i, moduleMap)(l)
}
// If I have a clock, get it
val clockOpt = moduleMap(lin.name) match {
case Module(i, n, ports, b) => ports.collectFirst { case p if p.name == "clock" => me + sep + "clock" }
case ExtModule(i, n, ports, dn, p) => None
}
// Return new origins with direct children removed, if they match my clock
clockOpt match {
case Some(clock) =>
val myOrigin = getOrigin(connects, clock).serialize
childrenOrigins.foldLeft(Map(me -> myOrigin)) {
case (o, (childInstance, childOrigin)) =>
val childrenInstances = lin.children.map { case (instance, _) => me + sep + instance }
// If direct child shares my origin, omit it
if (childOrigin == myOrigin && childrenInstances.contains(childInstance)) o
else o + (childInstance -> childOrigin)
}
case None => childrenOrigins
}
}
}
|