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
68
69
70
71
72
73
74
75
76
77
|
// See LICENSE for license details.
package firrtl.passes
package memlib
import firrtl._
import firrtl.ir._
import firrtl.Utils._
import firrtl.Mappers._
import AnalysisUtils._
import MemPortUtils._
import MemTransformUtils._
/** Changes memory port names to standard port names (i.e. RW0 instead T_408)
*/
object RenameAnnotatedMemoryPorts extends Pass {
def name = "Rename Annotated Memory Ports"
/** Renames memory ports to a standard naming scheme:
* - R0, R1, ... for each read port
* - W0, W1, ... for each write port
* - RW0, RW1, ... for each readwrite port
*/
def createMemProto(m: DefAnnotatedMemory): DefAnnotatedMemory = {
val rports = m.readers.indices map (i => s"R$i")
val wports = m.writers.indices map (i => s"W$i")
val rwports = m.readwriters.indices map (i => s"RW$i")
m copy (readers = rports, writers = wports, readwriters = rwports)
}
/** Maps the serialized form of all memory port field names to the
* corresponding new memory port field Expression.
* E.g.:
* - ("m.read.addr") becomes (m.R0.addr)
*/
def getMemPortMap(m: DefAnnotatedMemory): MemPortMap = {
val memPortMap = new MemPortMap
val defaultFields = Seq("addr", "en", "clk")
val rFields = defaultFields :+ "data"
val wFields = rFields :+ "mask"
val rwFields = defaultFields ++ Seq("wmode", "wdata", "rdata", "wmask")
def updateMemPortMap(ports: Seq[String], fields: Seq[String], newPortKind: String): Unit =
for ((p, i) <- ports.zipWithIndex; f <- fields) {
val newPort = createSubField(createRef(m.name), newPortKind + i)
val field = createSubField(newPort, f)
memPortMap(s"${m.name}.$p.$f") = field
}
updateMemPortMap(m.readers, rFields, "R")
updateMemPortMap(m.writers, wFields, "W")
updateMemPortMap(m.readwriters, rwFields, "RW")
memPortMap
}
/** Replaces candidate memories with memories with standard port names
* Does not update the references (this is done via updateStmtRefs)
*/
def updateMemStmts(memPortMap: MemPortMap)(s: Statement): Statement = s match {
case m: DefAnnotatedMemory =>
val updatedMem = createMemProto(m)
memPortMap ++= getMemPortMap(m)
updatedMem
case s => s map updateMemStmts(memPortMap)
}
/** Replaces candidate memories and their references with standard port names
*/
def updateMemMods(m: DefModule) = {
val memPortMap = new MemPortMap
(m map updateMemStmts(memPortMap)
map updateStmtRefs(memPortMap))
}
def run(c: Circuit) = c copy (modules = c.modules map updateMemMods)
}
|