aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAngie2016-08-22 05:21:03 -0700
committerjackkoenig2016-09-06 00:17:18 -0700
commit1825c7fc02277ee995c07e8a3b1dc39bf9a354fe (patch)
treedc4cdb11c4b44d175b5c737b1db19fca88a8a80c /src
parentfb821d5fa9eee6581a6177c492ab8fc2cd2d8f75 (diff)
Pulled out duplicate memory annotations
* Annotate reference * Changed memory port names to RWx, Wx, Rx, etc. and reconnected nodes
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/passes/UpdateDuplicateMemMacros.scala94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/passes/UpdateDuplicateMemMacros.scala b/src/main/scala/firrtl/passes/UpdateDuplicateMemMacros.scala
new file mode 100644
index 00000000..2301ad1b
--- /dev/null
+++ b/src/main/scala/firrtl/passes/UpdateDuplicateMemMacros.scala
@@ -0,0 +1,94 @@
+package firrtl.passes
+
+import scala.collection.mutable.{HashMap,ArrayBuffer}
+import AnalysisUtils._
+import MemTransformUtils._
+import firrtl.ir._
+import firrtl._
+import firrtl.Mappers._
+import firrtl.Utils._
+
+object MemTransformUtils {
+
+ def createRef(n: String) = WRef(n,UnknownType,ExpKind(),UNKNOWNGENDER)
+ def createSubField(exp: Expression, n: String) = WSubField(exp,n,UnknownType,UNKNOWNGENDER)
+ def connectFields(lref: Expression, lname: String, rref: Expression, rname: String) =
+ Connect(NoInfo,createSubField(lref,lname),createSubField(rref,rname))
+
+ def getMemPortMap(m: DefMemory) = {
+ val memPortMap = HashMap[String,Expression]()
+ 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], portType: String) =
+ for (p <- ports.zipWithIndex; f <- fields) {
+ val newPort = createSubField(createRef(m.name),portType+p._2)
+ val field = createSubField(newPort,f)
+ memPortMap(s"${m.name}.${p._1}.${f}") = field
+ }
+ updateMemPortMap(m.readers,rFields,"R")
+ updateMemPortMap(m.writers,wFields,"W")
+ updateMemPortMap(m.readwriters,rwFields,"RW")
+ memPortMap.toMap
+ }
+ def createMemProto(m: DefMemory) = {
+ val rports = (0 until m.readers.length) map (i => s"R$i")
+ val wports = (0 until m.writers.length) map (i => s"W$i")
+ val rwports = (0 until m.readwriters.length) map (i => s"RW$i")
+ m.copy(readers = rports, writers = wports, readwriters = rwports)
+ }
+
+ def updateStmtRefs(s: Statement, repl: Map[String,Expression]): Statement = {
+ def updateRef(e: Expression): Expression = e map updateRef match {
+ case e: WSubField => repl getOrElse (e.serialize,e)
+ case e => e
+ }
+ def updateStmtRefs(s: Statement): Statement = s map updateStmtRefs map updateRef match {
+ case Connect(info, loc, exp) if loc == EmptyExpression => EmptyStmt
+ case s => s
+ }
+ updateStmtRefs(s)
+ }
+
+}
+
+object UpdateDuplicateMemMacros extends Pass {
+
+ def name = "Convert memory port names to be more meaningful and tag duplicate memories"
+
+ def run(c: Circuit) = {
+ val uniqueMems = ArrayBuffer[DefMemory]()
+
+ def updateMemMods(m: Module) = {
+ val memPortMap = HashMap[String,Expression]()
+
+ def updateMemStmts(s: Statement): Statement = s match {
+ case m: DefMemory if containsInfo(m.info,"useMacro") =>
+ val updatedMem = createMemProto(m)
+ memPortMap ++= getMemPortMap(m)
+ val proto = uniqueMems find (x => eqMems(x,updatedMem))
+ if (proto == None) {
+ uniqueMems += updatedMem
+ updatedMem
+ }
+ else updatedMem.copy(info = appendInfo(updatedMem.info,"ref" -> proto.get.name))
+ case b: Block => Block(b.stmts map updateMemStmts)
+ case s => s
+ }
+
+ val updatedMems = updateMemStmts(m.body)
+ val updatedConns = updateStmtRefs(updatedMems,memPortMap.toMap)
+ m.copy(body = updatedConns)
+ }
+
+ val updatedMods = c.modules map {
+ case m: Module => updateMemMods(m)
+ case m: ExtModule => m
+ }
+ c.copy(modules = updatedMods)
+ }
+
+}
+// TODO: Module namespace? \ No newline at end of file