From 1825c7fc02277ee995c07e8a3b1dc39bf9a354fe Mon Sep 17 00:00:00 2001 From: Angie Date: Mon, 22 Aug 2016 05:21:03 -0700 Subject: Pulled out duplicate memory annotations * Annotate reference * Changed memory port names to RWx, Wx, Rx, etc. and reconnected nodes --- .../firrtl/passes/UpdateDuplicateMemMacros.scala | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/scala/firrtl/passes/UpdateDuplicateMemMacros.scala (limited to 'src') 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 -- cgit v1.2.3