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
|
// See LICENSE for license details.
package firrtl.passes
package memlib
import firrtl._
import firrtl.ir._
import AnalysisUtils.eqMems
import firrtl.Mappers._
import firrtl.annotations._
/** A component, e.g. register etc. Must be declared only once under the TopAnnotation */
case class NoDedupMemAnnotation(target: ComponentName) extends SingleTargetAnnotation[ComponentName] {
def duplicate(n: ComponentName) = NoDedupMemAnnotation(n)
}
/** Resolves annotation ref to memories that exactly match (except name) another memory
*/
class ResolveMemoryReference extends Transform {
def inputForm = MidForm
def outputForm = MidForm
type AnnotatedMemories = collection.mutable.ArrayBuffer[(String, DefAnnotatedMemory)]
/** If a candidate memory is identical except for name to another, add an
* annotation that references the name of the other memory.
*/
def updateMemStmts(mname: String, uniqueMems: AnnotatedMemories, noDeDupeMems: Seq[String])(s: Statement): Statement = s match {
case m: DefAnnotatedMemory =>
uniqueMems find (x => eqMems(x._2, m, noDeDupeMems)) match {
case None =>
uniqueMems += (mname -> m)
m
case Some((module, proto)) => m copy (memRef = Some(module -> proto.name))
}
case s => s map updateMemStmts(mname, uniqueMems, noDeDupeMems)
}
def run(c: Circuit, noDeDupeMems: Seq[String]) = {
val uniqueMems = new AnnotatedMemories
c copy (modules = c.modules map (m => m map updateMemStmts(m.name, uniqueMems, noDeDupeMems)))
}
def execute(state: CircuitState): CircuitState = {
val noDedups = state.annotations.collect {
case NoDedupMemAnnotation(ComponentName(cn, _)) => cn
}
state.copy(circuit=run(state.circuit, noDedups))
}
}
|