// SPDX-License-Identifier: Apache-2.0 package firrtl.passes package memlib import firrtl._ import firrtl.ir._ import firrtl.Mappers._ import MemPortUtils._ import MemTransformUtils._ /** Changes memory port names to standard port names (i.e. RW0 instead T_408) */ object RenameAnnotatedMemoryPorts extends Pass { /** 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: MemPortMap): Unit = { 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 = WSubField(WRef(m.name), newPortKind + i) val field = WSubField(newPort, f) memPortMap(s"${m.name}.$p.$f") = field } updateMemPortMap(m.readers, rFields, "R") updateMemPortMap(m.writers, wFields, "W") updateMemPortMap(m.readwriters, rwFields, "RW") } /** 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) getMemPortMap(m, memPortMap) 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)) }