diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..13bb74a0 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mdf"] + path = mdf + url = https://github.com/edwardcwang/plsi-mdf.git diff --git a/build.sbt b/build.sbt index 6f61668a..cf97adba 100644 --- a/build.sbt +++ b/build.sbt @@ -15,11 +15,18 @@ val defaultVersions = Map( "chisel-iotesters" -> "1.2-SNAPSHOT" ) +lazy val mdf = RootProject(file("mdf/scalalib")) + lazy val tapeout = (project in file("tapeout")) + .dependsOn(mdf) .settings(commonSettings) .settings( libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) - } + }, + resolvers ++= Seq( + Resolver.sonatypeRepo("snapshots"), + Resolver.sonatypeRepo("releases") + ) ) - .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) \ No newline at end of file + .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) diff --git a/mdf b/mdf new file mode 160000 index 00000000..89c15682 --- /dev/null +++ b/mdf @@ -0,0 +1 @@ +Subproject commit 89c15682aa85d0c9175c23706939533d7611e25d diff --git a/tapeout/src/main/scala/transforms/macros/MacroCompiler.scala b/tapeout/src/main/scala/transforms/macros/MacroCompiler.scala index e43418cd..9112351e 100644 --- a/tapeout/src/main/scala/transforms/macros/MacroCompiler.scala +++ b/tapeout/src/main/scala/transforms/macros/MacroCompiler.scala @@ -8,19 +8,20 @@ import firrtl.PrimOps import firrtl.Utils._ import firrtl.annotations._ import firrtl.CompilerUtils.getLoweringTransforms +import mdf.macrolib.{PolarizedPort, PortPolarity} import scala.collection.mutable.{ArrayBuffer, HashMap} import java.io.{File, FileWriter} import Utils._ object MacroCompilerAnnotation { - def apply(c: String, mem: File, lib: Option[File], synflops: Boolean) = { + def apply(c: String, mem: String, lib: Option[String], synflops: Boolean) = { Annotation(CircuitName(c), classOf[MacroCompilerTransform], s"${mem} %s ${synflops}".format(lib map (_.toString) getOrElse "")) } private val matcher = "([^ ]+) ([^ ]*) (true|false)".r def unapply(a: Annotation) = a match { case Annotation(CircuitName(c), t, matcher(mem, lib, synflops)) if t == classOf[MacroCompilerTransform] => - Some((c, Some(new File(mem)), if (lib.isEmpty) None else Some(new File(lib)), synflops.toBoolean)) + Some((c, Some(mem), if (lib.isEmpty) None else Some(lib), synflops.toBoolean)) case _ => None } } @@ -33,11 +34,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // Parallel mapping val pairs = ArrayBuffer[(BigInt, BigInt)]() var last = 0 - for (i <- 0 until mem.width.toInt) { + for (i <- 0 until mem.src.width) { if (i <= last + 1) { /* Palmer: Every memory is going to have to fit at least a single bit. */ // continue - } else if ((i - last) % lib.width.toInt == 0) { + } else if ((i - last) % lib.src.width.toInt == 0) { /* Palmer: It's possible that we rolled over a memory's width here, if so generate one. */ pairs += ((last, i-1)) @@ -45,13 +46,13 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], } else { /* Palmer: FIXME: This is a mess, I must just be super confused. */ for ((memPort, libPort) <- pairedPorts) { - (memPort.maskGran, libPort.maskGran) match { + (memPort.src.maskGran, libPort.src.maskGran) match { case (_, Some(p)) if p == 1 => // continue case (Some(p), _) if i % p == 0 => pairs += ((last, i-1)) last = i case (_, None) => // continue - case (_, Some(p)) if p == lib.width => // continue + case (_, Some(p)) if p == lib.src.width => // continue case _ => System.err println "Bit-mask (or unmasked) target memories are supported only" return None @@ -59,7 +60,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], } } } - pairs += ((last, mem.width.toInt - 1)) + pairs += ((last, mem.src.width.toInt - 1)) // Serial mapping val stmts = ArrayBuffer[Statement]() @@ -67,27 +68,27 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], val outputs = HashMap[String, ArrayBuffer[(Expression, Expression)]]() /* Palmer: If we've got a parallel memory then we've got to take the * address bits into account. */ - if (mem.depth > lib.depth) { - mem.ports foreach { port => - val high = ceilLog2(mem.depth) - val low = ceilLog2(lib.depth) - val ref = WRef(port.addressName) + if (mem.src.depth > lib.src.depth) { + mem.src.ports foreach { port => + val high = ceilLog2(mem.src.depth) + val low = ceilLog2(lib.src.depth) + val ref = WRef(port.address.name) val name = s"${ref.name}_sel" selects(ref.name) = WRef(name, UIntType(IntWidth(high-low))) stmts += DefNode(NoInfo, name, bits(ref, high-1, low)) } } - for ((off, i) <- (0 until mem.depth.toInt by lib.depth.toInt).zipWithIndex) { + for ((off, i) <- (0 until mem.src.depth by lib.src.depth).zipWithIndex) { for (j <- pairs.indices) { val name = s"mem_${i}_${j}" - stmts += WDefInstance(NoInfo, name, lib.name, lib.tpe) + stmts += WDefInstance(NoInfo, name, lib.src.name, lib.tpe) // connect extra ports stmts ++= lib.extraPorts map { case (portName, portValue) => Connect(NoInfo, WSubField(WRef(name), portName), portValue) } } for ((memPort, libPort) <- pairedPorts) { - val addrMatch = selects get memPort.addressName match { + val addrMatch = selects get memPort.src.address.name match { case None => one case Some(addr) => val index = UIntLiteral(i, IntWidth(bitWidth(addr.tpe))) @@ -98,33 +99,37 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], for (((low, high), j) <- pairs.zipWithIndex) { val inst = WRef(s"mem_${i}_${j}", lib.tpe) - def connectPorts(mem: Expression, + def connectPorts2(mem: Expression, lib: String, polarity: Option[PortPolarity]): Statement = - Connect(NoInfo, WSubField(inst, lib), invert(mem, polarity)) + Connect(NoInfo, WSubField(inst, lib), portToExpression(mem, polarity)) + def connectPorts(mem: Expression, + lib: String, + polarity: PortPolarity): Statement = + connectPorts2(mem, lib, Some(polarity)) // Clock port mapping /* Palmer: FIXME: I don't handle memories with read/write clocks yet. */ - stmts += connectPorts(WRef(memPort.clockName), - libPort.clockName, - libPort.clockPolarity) + stmts += connectPorts(WRef(memPort.src.clock.name), + libPort.src.clock.name, + libPort.src.clock.polarity) // Adress port mapping /* Palmer: The address port to a memory is just the low-order bits of * the top address. */ - stmts += connectPorts(WRef(memPort.addressName), - libPort.addressName, - libPort.addressPolarity) + stmts += connectPorts(WRef(memPort.src.address.name), + libPort.src.address.name, + libPort.src.address.polarity) // Output port mapping - (memPort.outputName, libPort.outputName) match { - case (Some(mem), Some(lib)) => + (memPort.src.output, libPort.src.output) match { + case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) => /* Palmer: In order to produce the output of a memory we need to cat * together a bunch of narrower memories, which can only be * done after generating all the memories. This saves up the * output statements for later. */ val name = s"${mem}_${i}_${j}" - val exp = invert(bits(WSubField(inst, lib), high-low, 0), libPort.outputPolarity) + val exp = portToExpression(bits(WSubField(inst, lib), high-low, 0), Some(lib_polarity)) stmts += DefNode(NoInfo, name, exp) cats += WRef(name) case (None, Some(lib)) => @@ -135,18 +140,18 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], /* Palmer: If there's no output ports at all (ie, read-only * port on the memory) then just don't worry about it, * there's nothing to do. */ - case (Some(mem), None) => + case (Some(PolarizedPort(mem, _)), None) => System.err println "WARNING: Unable to match output ports on memory" System.err println s" outer output port: ${mem}" return None } // Input port mapping - (memPort.inputName, libPort.inputName) match { - case (Some(mem), Some(lib)) => + (memPort.src.input, libPort.src.input) match { + case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) => /* Palmer: The input port to a memory just needs to happen in parallel, * this does a part select to narrow the memory down. */ - stmts += connectPorts(bits(WRef(mem), high, low), lib, libPort.inputPolarity) + stmts += connectPorts(bits(WRef(mem), high, low), lib, lib_polarity) case (None, Some(lib)) => /* Palmer: If the inner memory has an input port but the other * one doesn't then it's safe to just leave the inner @@ -157,43 +162,43 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], /* Palmer: If there's no input ports at all (ie, read-only * port on the memory) then just don't worry about it, * there's nothing to do. */ - case (Some(mem), None) => + case (Some(PolarizedPort(mem, _)), None) => System.err println "WARNING: Unable to match input ports on memory" System.err println s" outer input port: ${mem}" return None } // Mask port mapping - val memMask = memPort.maskName match { - case Some(mem) => + val memMask = memPort.src.maskPort match { + case Some(PolarizedPort(mem, _)) => /* Palmer: The bits from the outer memory's write mask that will be * used as the write mask for this inner memory. */ - if (libPort.effectiveMaskGran == libPort.width) { - bits(WRef(mem), low / memPort.effectiveMaskGran) + if (libPort.src.effectiveMaskGran == libPort.src.width) { + bits(WRef(mem), low / memPort.src.effectiveMaskGran) } else { - if (libPort.effectiveMaskGran != 1) { + if (libPort.src.effectiveMaskGran != 1) { // TODO System.err println "only single-bit mask supported" return None } - cat(((low to high) map (i => bits(WRef(mem), i / memPort.effectiveMaskGran))).reverse) + cat(((low to high) map (i => bits(WRef(mem), i / memPort.src.effectiveMaskGran))).reverse) } case None => /* Palmer: If there is no input port on the source memory port * then we don't ever want to turn on this write * enable. Otherwise, we just _always_ turn on the * write enable port on the inner memory. */ - if (!libPort.maskName.isDefined) one + if (libPort.src.maskPort.isEmpty) one else { - val width = libPort.width / libPort.effectiveMaskGran + val width = libPort.src.width / libPort.src.effectiveMaskGran val value = (BigInt(1) << width.toInt) - 1 UIntLiteral(value, IntWidth(width)) } } // Write enable port mapping - val memWriteEnable = memPort.writeEnableName match { - case Some(mem) => + val memWriteEnable = memPort.src.writeEnable match { + case Some(PolarizedPort(mem, _)) => /* Palmer: The outer memory's write enable port, or a constant 1 if * there isn't a write enable port. */ WRef(mem) @@ -202,60 +207,65 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], * then we don't ever want to turn on this write * enable. Otherwise, we just _always_ turn on the * write enable port on the inner memory. */ - if (!memPort.inputName.isDefined) zero else one + if (memPort.src.input.isEmpty) zero else one } // Chip enable port mapping - val memChipEnable = memPort.chipEnableName match { - case Some(mem) => WRef(mem) + val memChipEnable = memPort.src.chipEnable match { + case Some(PolarizedPort(mem, _)) => WRef(mem) case None => one } - // Read enable port mapping + // Read enable port mapping /* Palmer: It's safe to ignore read enables, but we pass them through * to the vendor memory if there's a port on there that * implements the read enables. */ - (memPort.readEnableName, libPort.readEnableName) match { + (memPort.src.readEnable, libPort.src.readEnable) match { case (_, None) => - case (Some(mem), Some(lib)) => - stmts += connectPorts(andAddrMatch(WRef(mem)), lib, libPort.readEnablePolarity) - case (None, Some(lib)) => - stmts += connectPorts(andAddrMatch(not(memWriteEnable)), lib, libPort.readEnablePolarity) + case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) => + stmts += connectPorts(andAddrMatch(WRef(mem)), lib, lib_polarity) + case (None, Some(PolarizedPort(lib, lib_polarity))) => + stmts += connectPorts(andAddrMatch(not(memWriteEnable)), lib, lib_polarity) } /* Palmer: This is actually the memory compiler: it figures out how to * implement the outer memory's collection of ports using what - * the inner memory has availiable. */ - ((libPort.maskName, libPort.writeEnableName, libPort.chipEnableName): @unchecked) match { - case (Some(mask), Some(we), Some(en)) => + * the inner memory has availiable. */ + ((libPort.src.maskPort, libPort.src.writeEnable, libPort.src.chipEnable): @unchecked) match { + case (Some(PolarizedPort(mask, mask_polarity)), Some(PolarizedPort(we, we_polarity)), Some(PolarizedPort(en, en_polarity))) => /* Palmer: This is the simple option: every port exists. */ - stmts += connectPorts(memMask, mask, libPort.maskPolarity) - stmts += connectPorts(andAddrMatch(memWriteEnable), we, libPort.writeEnablePolarity) - stmts += connectPorts(andAddrMatch(memChipEnable), en, libPort.chipEnablePolarity) - case (Some(mask), Some(we), None) => - /* Palmer: If we don't have a chip enable but do have */ - stmts += connectPorts(memMask, mask, libPort.maskPolarity) + stmts += connectPorts(memMask, mask, mask_polarity) + stmts += connectPorts(andAddrMatch(memWriteEnable), we, we_polarity) + stmts += connectPorts(andAddrMatch(memChipEnable), en, en_polarity) + case (Some(PolarizedPort(mask, mask_polarity)), Some(PolarizedPort(we, we_polarity)), None) => + /* Palmer: If we don't have a chip enable but do have mask ports. */ + stmts += connectPorts(memMask, mask, mask_polarity) stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)), - we, libPort.writeEnablePolarity) - case (None, Some(we), Some(en)) if bitWidth(memMask.tpe) == 1 => + we, mask_polarity) + case (None, Some(PolarizedPort(we, we_polarity)), chipEnable) if bitWidth(memMask.tpe) == 1 => /* Palmer: If we're expected to provide mask ports without a * memory that actually has them then we can use the * write enable port instead of the mask port. */ stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)), - we, libPort.writeEnablePolarity) - stmts += connectPorts(andAddrMatch(memChipEnable), en, libPort.chipEnablePolarity) - case (None, Some(we), Some(en)) => + we, we_polarity) + chipEnable match { + case Some(PolarizedPort(en, en_polarity)) => { + stmts += connectPorts(andAddrMatch(memChipEnable), en, en_polarity) + } + case _ => // TODO: do we care about the case where mem has chipEnable but lib doesn't? + } + case (None, Some(PolarizedPort(we, we_polarity)), Some(PolarizedPort(en, en_polarity))) => // TODO - System.err println "cannot emulate multi-bit mask ports with write enable" + System.err.println("cannot emulate multi-bit mask ports with write enable") return None case (None, None, None) => /* Palmer: There's nothing to do here since there aren't any - * ports to match up. */ + * ports to match up. */ } } // Cat macro outputs for selection - memPort.outputName match { - case Some(mem) if cats.nonEmpty => + memPort.src.output match { + case Some(PolarizedPort(mem, _)) if cats.nonEmpty => val name = s"${mem}_${i}" stmts += DefNode(NoInfo, name, cat(cats.toSeq.reverse)) (outputs getOrElseUpdate (mem, ArrayBuffer[(Expression, Expression)]())) += @@ -265,9 +275,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], } } // Connect mem outputs - mem.ports foreach { port => - port.outputName match { - case Some(mem) => outputs get mem match { + mem.src.ports foreach { port => + port.output match { + case Some(PolarizedPort(mem, _)) => outputs get mem match { case Some(select) => val output = (select foldRight (zero: Expression)) { case ((cond, tval), fval) => Mux(cond, tval, fval, fval.tpe) } @@ -285,10 +295,10 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], val modules = (mems, libs) match { case (Some(mems), Some(libs)) => (mems foldLeft c.modules){ (modules, mem) => val (best, cost) = (libs foldLeft (None: Option[(Module, ExtModule)], BigInt(Long.MaxValue))){ - case ((best, area), lib) if mem.ports.size != lib.ports.size => + case ((best, area), lib) if mem.src.ports.size != lib.src.ports.size => /* Palmer: FIXME: This just assumes the Chisel and vendor ports are in the same * order, but I'm starting with what actually gets generated. */ - System.err println s"INFO: unable to compile ${mem.name} using ${lib.name} port count must match" + System.err println s"INFO: unable to compile ${mem.src.name} using ${lib.src.name} port count must match" (best, area) case ((best, area), lib) => /* Palmer: A quick cost function (that must be kept in sync with @@ -298,10 +308,10 @@ class MacroCompilerPass(mems: Option[Seq[Macro]], // val cost = 100 * (mem.depth * mem.width) / (lib.depth * lib.width) + // (mem.depth * mem.width) // Donggyu: I re-define cost - val cost = (((mem.depth - 1) / lib.depth) + 1) * - (((mem.width - 1) / lib.width) + 1) * - (lib.depth * lib.width + 1) // weights on # cells - System.err println s"Cost of ${lib.name} for ${mem.name}: ${cost}" + val cost = (((mem.src.depth - 1) / lib.src.depth) + 1) * + (((mem.src.width - 1) / lib.src.width) + 1) * + (lib.src.depth * lib.src.width + 1) // weights on # cells + System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${cost}") if (cost > area) (best, area) else compile(mem, lib) match { case None => (best, area) @@ -326,8 +336,17 @@ class MacroCompilerTransform extends Transform { def execute(state: CircuitState) = getMyAnnotations(state) match { case Seq(MacroCompilerAnnotation(state.circuit.main, memFile, libFile, synflops)) => require(memFile.isDefined) - val mems: Option[Seq[Macro]] = readJSON(memFile) map (_ map (x => new Macro(x))) - val libs: Option[Seq[Macro]] = readJSON(libFile) map (_ map (x => new Macro(x))) + // Read, eliminate None, get only SRAM, make firrtl macro + val mems: Option[Seq[Macro]] = mdf.macrolib.Utils.readMDFFromPath(memFile) match { + case Some(x:Seq[mdf.macrolib.Macro]) => + Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)}) + case _ => None + } + val libs: Option[Seq[Macro]] = mdf.macrolib.Utils.readMDFFromPath(libFile) match { + case Some(x:Seq[mdf.macrolib.Macro]) => + Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)}) + case _ => None + } val transforms = Seq( new MacroCompilerPass(mems, libs), new SynFlopsPass(synflops, libs getOrElse mems.get), @@ -349,24 +368,24 @@ object MacroCompiler extends App { sealed trait MacroParam case object Macros extends MacroParam case object Library extends MacroParam - case object Verilog extends MacroParam - type MacroParamMap = Map[MacroParam, File] + case object Verilog extends MacroParam + type MacroParamMap = Map[MacroParam, String] val usage = Seq( "Options:", " -m, --macro-list: The set of macros to compile", " -l, --library: The set of macros that have blackbox instances", " -v, --verilog: Verilog output", - " --syn-flop: Produces synthesizable flop-based memories") mkString "\n" + " --syn-flop: Produces synthesizable flop-based memories (for all memories and library memory macros); likely useful for simulation purposes") mkString "\n" def parseArgs(map: MacroParamMap, synflops: Boolean, args: List[String]): (MacroParamMap, Boolean) = args match { case Nil => (map, synflops) case ("-m" | "--macro-list") :: value :: tail => - parseArgs(map + (Macros -> new File(value)), synflops, tail) + parseArgs(map + (Macros -> value), synflops, tail) case ("-l" | "--library") :: value :: tail => - parseArgs(map + (Library -> new File(value)), synflops, tail) + parseArgs(map + (Library -> value), synflops, tail) case ("-v" | "--verilog") :: value :: tail => - parseArgs(map + (Verilog -> new File(value)), synflops, tail) + parseArgs(map + (Verilog -> value), synflops, tail) case "--syn-flops" :: tail => parseArgs(map, true, tail) case arg :: tail => @@ -375,18 +394,29 @@ object MacroCompiler extends App { } def run(args: List[String]) { - val (params, synflops) = parseArgs(Map[MacroParam, File](), false, args) + val (params, synflops) = parseArgs(Map[MacroParam, String](), false, args) try { - val macros = readJSON(params get Macros).get map (x => (new Macro(x)).blackbox) - val verilog = new FileWriter(params(Verilog)) + val macros = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox) + + // Open the writer for the output Verilog file. + val verilogWriter = new FileWriter(new File(params.get(Verilog).get)) + if (macros.nonEmpty) { val circuit = Circuit(NoInfo, macros, macros.last.name) val annotations = AnnotationMap(Seq(MacroCompilerAnnotation( - circuit.main, params(Macros), params get Library, synflops))) + circuit.main, params.get(Macros).get, params.get(Library), synflops))) val state = CircuitState(circuit, HighForm, Some(annotations)) - val result = new MacroCompiler compile (state, verilog) + + // Run the compiler. + val result = new MacroCompiler().compileAndEmit(state) + + // Extract Verilog circuit and write it. + verilogWriter.write(result.getEmittedCircuit.value) } - verilog.close + + // Close the writer. + verilogWriter.close() + } catch { case e: java.util.NoSuchElementException => throw new Exception(usage) diff --git a/tapeout/src/main/scala/transforms/macros/SynFlops.scala b/tapeout/src/main/scala/transforms/macros/SynFlops.scala index 40718318..c4a84872 100644 --- a/tapeout/src/main/scala/transforms/macros/SynFlops.scala +++ b/tapeout/src/main/scala/transforms/macros/SynFlops.scala @@ -9,9 +9,9 @@ import firrtl.passes.MemPortUtils.{memPortField, memType} import Utils._ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass { - lazy val libMods = (libs map { lib => lib.name -> { - val dataType = (lib.ports foldLeft (None: Option[BigInt]))((res, port) => - (res, port.maskName) match { + lazy val libMods = (libs map { lib => lib.src.name -> { + val dataType = (lib.src.ports foldLeft (None: Option[BigInt]))((res, port) => + (res, port.maskPort) match { case (_, None) => res case (None, Some(_)) => @@ -21,15 +21,15 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa res } ) match { - case None => UIntType(IntWidth(lib.width)) - case Some(gran) => VectorType(UIntType(IntWidth(gran)), (lib.width / gran).toInt) + case None => UIntType(IntWidth(lib.src.width)) + case Some(gran) => VectorType(UIntType(IntWidth(gran)), (lib.src.width / gran).toInt) } val mem = DefMemory( NoInfo, "ram", dataType, - lib.depth.toInt, + lib.src.depth, 1, // writeLatency 0, // readLatency (lib.readers ++ lib.readwriters).indices map (i => s"R_$i"), @@ -38,14 +38,14 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa ) val readConnects = (lib.readers ++ lib.readwriters).zipWithIndex flatMap { case (r, i) => - val clock = invert(WRef(r.clockName), r.clockPolarity) - val address = invert(WRef(r.addressName), r.addressPolarity) - val enable = (r.chipEnableName, r.readEnableName) match { - case (Some(en), Some(re)) => - and(invert(WRef(en), r.chipEnablePolarity), - invert(WRef(re), r.readEnablePolarity)) - case (Some(en), None) => invert(WRef(en), r.chipEnablePolarity) - case (None, Some(re)) => invert(WRef(re), r.readEnablePolarity) + val clock = portToExpression(r.src.clock) + val address = portToExpression(r.src.address) + val enable = (r.src chipEnable, r.src readEnable) match { + case (Some(en_port), Some(re_port)) => + and(portToExpression(en_port), + portToExpression(re_port)) + case (Some(en_port), None) => portToExpression(en_port) + case (None, Some(re_port)) => portToExpression(re_port) case (None, None) => one } val data = memPortField(mem, s"R_$i", "data") @@ -60,25 +60,25 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock), Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), addrReg), Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable), - Connect(NoInfo, WRef(r.outputName.get), read), + Connect(NoInfo, WRef(r.src.output.get.name), read), Connect(NoInfo, addrReg, Mux(enable, address, addrReg, UnknownType)) ) } val writeConnects = (lib.writers ++ lib.readwriters).zipWithIndex flatMap { case (w, i) => - val clock = invert(WRef(w.clockName), w.clockPolarity) - val address = invert(WRef(w.addressName), w.addressPolarity) - val enable = (w.chipEnableName, w.writeEnableName) match { + val clock = portToExpression(w.src.clock) + val address = portToExpression(w.src.address) + val enable = (w.src.chipEnable, w.src.writeEnable) match { case (Some(en), Some(we)) => - and(invert(WRef(en), w.chipEnablePolarity), - invert(WRef(we), w.writeEnablePolarity)) - case (Some(en), None) => invert(WRef(en), w.chipEnablePolarity) - case (None, Some(we)) => invert(WRef(we), w.writeEnablePolarity) + and(portToExpression(en), + portToExpression(we)) + case (Some(en), None) => portToExpression(en) + case (None, Some(we)) => portToExpression(we) case (None, None) => zero // is it possible? } val mask = memPortField(mem, s"W_$i", "mask") val data = memPortField(mem, s"W_$i", "data") - val write = invert(WRef(w.inputName.get), w.inputPolarity) + val write = portToExpression(w.src.input.get) Seq( Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock), Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address), @@ -91,7 +91,7 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa bits(write, (k + 1) * width - 1, k * width)))) ++ ((0 until size) map (k => Connect(NoInfo, WSubIndex(mask, k, BoolType, UNKNOWNGENDER), - bits(WRef(w.maskName.get), k)))) + bits(WRef(w.src.maskPort.get.name), k)))) case _: UIntType => Seq(Connect(NoInfo, data, write), Connect(NoInfo, mask, one)) }) diff --git a/tapeout/src/main/scala/transforms/macros/Utils.scala b/tapeout/src/main/scala/transforms/macros/Utils.scala index 9f9d215e..2355c9f3 100644 --- a/tapeout/src/main/scala/transforms/macros/Utils.scala +++ b/tapeout/src/main/scala/transforms/macros/Utils.scala @@ -6,133 +6,70 @@ import firrtl._ import firrtl.ir._ import firrtl.PrimOps import firrtl.Utils.{ceilLog2, BoolType} -import scala.util.parsing.json.JSON // Todo: this will be gone +import mdf.macrolib.{Constant, MacroPort, SRAMMacro} +import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge} import java.io.File import scala.language.implicitConversions -trait PortPolarity -case object ActiveLow extends PortPolarity -case object ActiveHigh extends PortPolarity -case object NegativeEdge extends PortPolarity -case object PositiveEdge extends PortPolarity -object PortPolarity { - implicit def toPortPolarity(s: Any): PortPolarity = - s match { - case "active low" => ActiveLow - case "active high" => ActiveHigh - case "negative edge" => NegativeEdge - case "positive edge" => PositiveEdge - case _ => throw new firrtl.passes.PassException(s"Wrong port polarity: ${s.toString}") - } - implicit def toPortPolarity(s: Option[Any]): Option[PortPolarity] = - s map toPortPolarity -} +class FirrtlMacroPort(port: MacroPort) { + val src = port -case class MacroPort( - clockName: String, - clockPolarity: Option[PortPolarity], - addressName: String, - addressPolarity: Option[PortPolarity], - inputName: Option[String], - inputPolarity: Option[PortPolarity], - outputName: Option[String], - outputPolarity: Option[PortPolarity], - chipEnableName: Option[String], - chipEnablePolarity: Option[PortPolarity], - readEnableName: Option[String], - readEnablePolarity: Option[PortPolarity], - writeEnableName: Option[String], - writeEnablePolarity: Option[PortPolarity], - maskName: Option[String], - maskPolarity: Option[PortPolarity], - maskGran: Option[BigInt], - width: BigInt, - depth: BigInt) { - val effectiveMaskGran = maskGran.getOrElse(width) - val addrType = UIntType(IntWidth(ceilLog2(depth) max 1)) - val dataType = UIntType(IntWidth(width)) - val maskType = UIntType(IntWidth(width / effectiveMaskGran)) + val isReader = !port.readEnable.isEmpty && port.writeEnable.isEmpty + val isWriter = !port.writeEnable.isEmpty && port.readEnable.isEmpty + val isReadWriter = !port.writeEnable.isEmpty && !port.readEnable.isEmpty + + val AddrType = UIntType(IntWidth(ceilLog2(port.depth) max 1)) + val DataType = UIntType(IntWidth(port.width)) + val MaskType = UIntType(IntWidth(port.width / port.effectiveMaskGran)) + + // Bundle representing this macro port. val tpe = BundleType(Seq( - Field(clockName, Flip, ClockType), - Field(addressName, Flip, addrType)) ++ - (inputName map (Field(_, Flip, dataType))) ++ - (outputName map (Field(_, Default, dataType))) ++ - (chipEnableName map (Field(_, Flip, BoolType))) ++ - (readEnableName map (Field(_, Flip, BoolType))) ++ - (writeEnableName map (Field(_, Flip, BoolType))) ++ - (maskName map (Field(_, Flip, maskType))) + Field(port.clock.name, Flip, ClockType), + Field(port.address.name, Flip, AddrType)) ++ + (port.input map (p => Field(p.name, Flip, DataType))) ++ + (port.output map (p => Field(p.name, Default, DataType))) ++ + (port.chipEnable map (p => Field(p.name, Flip, BoolType))) ++ + (port.readEnable map (p => Field(p.name, Flip, BoolType))) ++ + (port.writeEnable map (p => Field(p.name, Flip, BoolType))) ++ + (port.maskPort map (p => Field(p.name, Flip, MaskType))) ) val ports = tpe.fields map (f => Port( NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe)) } -class Macro(lib: Map[String, Any]) { - val name = lib("name").asInstanceOf[String] - val width = BigInt(lib("width").asInstanceOf[Double].toLong) - val depth = BigInt(lib("depth").asInstanceOf[Double].toLong) - val ports = lib("ports").asInstanceOf[List[_]] map { x => - val map = x.asInstanceOf[Map[String, Any]] - MacroPort( - map("clock port name").asInstanceOf[String], - map get "clock port polarity", - map("address port name").asInstanceOf[String], - map get "address port polarity", - map get "input port name" map (_.asInstanceOf[String]), - map get "input port polarity", - map get "output port name" map (_.asInstanceOf[String]), - map get "output port polarity", - map get "chip enable port name" map (_.asInstanceOf[String]), - map get "chip enable port polarity", - map get "read enable port name" map (_.asInstanceOf[String]), - map get "read enable port polarity", - map get "write enable port name" map (_.asInstanceOf[String]), - map get "write enable port polarity", - map get "mask port name" map (_.asInstanceOf[String]), - map get "mask port polarity", - map get "mask granularity" map (x => BigInt(x.asInstanceOf[Double].toLong)), - width, - depth - ) - } - val writers = ports filter (p => p.inputName.isDefined && !p.outputName.isDefined) - val readers = ports filter (p => !p.inputName.isDefined && p.outputName.isDefined) - val readwriters = ports filter (p => p.inputName.isDefined && p.outputName.isDefined) +// Reads an SRAMMacro and generates firrtl blackboxes. +class Macro(srcMacro: SRAMMacro) { + val src = srcMacro + + val firrtlPorts = srcMacro.ports map { new FirrtlMacroPort(_) } + + val writers = firrtlPorts filter (p => p.isReader) + val readers = firrtlPorts filter (p => p.isWriter) + val readwriters = firrtlPorts filter (p => p.isReadWriter) + val sortedPorts = writers ++ readers ++ readwriters - val extraPorts = lib get "extra ports" match { - case None => Nil - case Some(p) => p.asInstanceOf[List[_]] map { x => - val map = x.asInstanceOf[Map[String, Any]] - assert(map("type").asInstanceOf[String] == "constant") // TODO: release it? - val name = map("name").asInstanceOf[String] - val width = BigInt(map("width").asInstanceOf[Double].toLong) - val value = BigInt(map("value").asInstanceOf[Double].toLong) - (name -> UIntLiteral(value, IntWidth(width))) - } + val extraPorts = srcMacro.extraPorts map { p => + assert(p.portType == Constant) // TODO: release it? + val name = p.name + val width = BigInt(p.width.asInstanceOf[Double].toLong) + val value = BigInt(p.value.asInstanceOf[Double].toLong) + (name -> UIntLiteral(value, IntWidth(width))) } - val tpe = BundleType(ports flatMap (_.tpe.fields)) - private val modPorts = (ports flatMap (_.ports)) ++ + + // Bundle representing this memory blackbox + val tpe = BundleType(firrtlPorts flatMap (_.tpe.fields)) + + private val modPorts = (firrtlPorts flatMap (_.ports)) ++ (extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) }) - val blackbox = ExtModule(NoInfo, name, modPorts, name, Nil) - def module(body: Statement) = Module(NoInfo, name, modPorts, body) + val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil) + def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body) } object Utils { - def readJSON(file: Option[File]): Option[Seq[Map[String, Any]]] = file match { - case None => None - case Some(f) => try { - (JSON parseFull io.Source.fromFile(f).mkString) match { - case Some(p: List[Any]) => Some( - (p foldLeft Seq[Map[String, Any]]()){ - case (res, x: Map[_, _]) => - val map = x.asInstanceOf[Map[String, Any]] - if (map("type").asInstanceOf[String] == "sram") res :+ map else res - case (res, _) => res - } - ) - case _ => Some(Nil) - } - } catch { - case _: Throwable => Some(Nil) + def filterForSRAM(s: Option[Seq[mdf.macrolib.Macro]]): Option[Seq[mdf.macrolib.SRAMMacro]] = { + s match { + case Some(l:Seq[mdf.macrolib.Macro]) => Some(l filter { _.macroType == mdf.macrolib.SRAM } map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] }) + case _ => None } } @@ -147,7 +84,11 @@ object Utils { def not(e: Expression) = DoPrim(PrimOps.Not, Seq(e), Nil, e.tpe) - def invert(exp: Expression, polarity: Option[PortPolarity]) = + // Convert a port to a FIRRTL expression, handling polarity along the way. + def portToExpression(pp: PolarizedPort): Expression = + portToExpression(WRef(pp.name), Some(pp.polarity)) + + def portToExpression(exp: Expression, polarity: Option[PortPolarity]): Expression = polarity match { case Some(ActiveLow) | Some(NegativeEdge) => not(exp) case _ => exp diff --git a/tapeout/src/test/resources/macros/lib-1024x8-mrw.json b/tapeout/src/test/resources/macros/lib-1024x8-mrw.json index b85f45dc..e5cfa0c2 100644 --- a/tapeout/src/test/resources/macros/lib-1024x8-mrw.json +++ b/tapeout/src/test/resources/macros/lib-1024x8-mrw.json @@ -4,6 +4,7 @@ "name": "vendor_sram", "depth": 1024, "width": 8, + "family": "1rw", "ports": [ { "clock port name": "clock", diff --git a/tapeout/src/test/resources/macros/mem-2048x8-mrw.json b/tapeout/src/test/resources/macros/mem-2048x8-mrw.json index 0873fbdb..64f6bfd7 100644 --- a/tapeout/src/test/resources/macros/mem-2048x8-mrw.json +++ b/tapeout/src/test/resources/macros/mem-2048x8-mrw.json @@ -4,6 +4,7 @@ "name": "name_of_sram_module", "depth": 2048, "width": 8, + "family": "1rw", "ports": [ { "clock port name": "clock", diff --git a/tapeout/src/test/scala/transforms/macros/MacroCompilerSpec.scala b/tapeout/src/test/scala/transforms/macros/MacroCompilerSpec.scala index f102f250..a9939715 100644 --- a/tapeout/src/test/scala/transforms/macros/MacroCompilerSpec.scala +++ b/tapeout/src/test/scala/transforms/macros/MacroCompilerSpec.scala @@ -1,302 +1,381 @@ -package barstools.tapeout.transforms.macros +package barstools.tapeout.transforms.macros.test -import firrtl._ +import barstools.tapeout.transforms.macros._ import firrtl.ir.{Circuit, NoInfo} import firrtl.passes.RemoveEmpty import firrtl.Parser.parse import java.io.{File, StringWriter} -import Utils.readJSON + +// TODO: we should think of a less brittle way to run these tests. abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalatest.Matchers { - val macroDir = new File("tapeout/src/test/resources/macros") - val testDir = new File("test_run_dir/macros") ; testDir.mkdirs + val macroDir: String = "tapeout/src/test/resources/macros" + val testDir: String = "test_run_dir/macros" + new File(testDir).mkdirs // Make sure the testDir exists - def args(mem: File, lib: Option[File], v: File, synflops: Boolean) = - List("-m", mem.toString, "-v", v.toString) ++ + // Override these to change the prefixing of macroDir and testDir + val memPrefix: String = macroDir + val libPrefix: String = macroDir + val vPrefix: String = testDir + + private def args(mem: String, lib: Option[String], v: String, synflops: Boolean) = + List("-m", mem.toString, "-v", v) ++ (lib match { case None => Nil case Some(l) => List("-l", l.toString) }) ++ (if (synflops) List("--syn-flops") else Nil) - def compile(mem: File, lib: Option[File], v: File, synflops: Boolean) { - MacroCompiler.run(args(mem, lib, v, synflops)) + // Run the full compiler as if from the command line interface. + // Generates the Verilog; useful in testing since an error will throw an + // exception. + def compile(mem: String, lib: String, v: String, synflops: Boolean) { + compile(mem, Some(lib), v, synflops) + } + def compile(mem: String, lib: Option[String], v: String, synflops: Boolean) { + var mem_full = concat(memPrefix, mem) + var lib_full = concat(libPrefix, lib) + var v_full = concat(vPrefix, v) + + MacroCompiler.run(args(mem_full, lib_full, v_full, synflops)) } - def execute(memFile: Option[File], libFile: Option[File], synflops: Boolean, output: String) { + // Helper functions to write macro libraries to the given files. + def writeToLib(lib: String, libs: Seq[mdf.macrolib.Macro]) = { + mdf.macrolib.Utils.writeMDFToPath(Some(concat(libPrefix, lib)), libs) + } + + def writeToMem(mem: String, mems: Seq[mdf.macrolib.Macro]) = { + mdf.macrolib.Utils.writeMDFToPath(Some(concat(memPrefix, mem)), mems) + } + + // Execute the macro compiler and compare FIRRTL outputs. + // TODO: think of a less brittle way to test this? + def execute(memFile: String, libFile: String, synflops: Boolean, output: String): Unit = { + execute(Some(memFile), Some(libFile), synflops, output) + } + def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean, output: String): Unit = { + var mem_full = concat(memPrefix, memFile) + var lib_full = concat(libPrefix, libFile) + require(memFile.isDefined) - val mems = readJSON(memFile) map (_ map (x => new Macro(x))) - val libs = readJSON(libFile) map (_ map (x => new Macro(x))) - val macros = mems.get map (_.blackbox) + val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get map (new Macro(_)) + val libs: Option[Seq[Macro]] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(lib_full)) match { + case Some(x) => Some(x map (new Macro(_))) + case None => None + } + val macros = mems map (_.blackbox) val circuit = Circuit(NoInfo, macros, macros.last.name) val passes = Seq( - new MacroCompilerPass(mems, libs), - new SynFlopsPass(synflops, libs getOrElse mems.get), + new MacroCompilerPass(Some(mems), libs), + new SynFlopsPass(synflops, libs getOrElse mems), RemoveEmpty) val result = (passes foldLeft circuit)((c, pass) => pass run c) val gold = RemoveEmpty run parse(output) (result.serialize) should be (gold.serialize) } + + // Helper method to deal with String + Option[String] + private def concat(a: String, b: String): String = {a + "/" + b} + private def concat(a: String, b: Option[String]): Option[String] = { + b match { + case Some(b2:String) => Some(a + "/" + b2) + case _ => None + } + } } -class RocketChipTest extends MacroCompilerSpec { - val mem = new File(macroDir, "rocketchip.json") - val lib = new File(macroDir, "mylib.json") - val v = new File(testDir, "rocketchip.macro.v") - val output = // TODO: check correctness... -""" -circuit T_2172_ext : - module tag_array_ext : - input RW0_clk : Clock - input RW0_addr : UInt<6> - input RW0_wdata : UInt<80> - output RW0_rdata : UInt<80> - input RW0_en : UInt<1> - input RW0_wmode : UInt<1> - input RW0_wmask : UInt<4> +trait HasSRAMGenerator { + import mdf.macrolib._ - inst mem_0_0 of SRAM1RW64x32 - inst mem_0_1 of SRAM1RW64x32 - inst mem_0_2 of SRAM1RW64x32 - inst mem_0_3 of SRAM1RW64x32 - mem_0_0.CE <= RW0_clk - mem_0_0.A <= RW0_addr - node RW0_rdata_0_0 = bits(mem_0_0.O, 19, 0) - mem_0_0.I <= bits(RW0_wdata, 19, 0) - mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_0.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 0, 0)), UInt<1>("h1"))) - mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_1.CE <= RW0_clk - mem_0_1.A <= RW0_addr - node RW0_rdata_0_1 = bits(mem_0_1.O, 19, 0) - mem_0_1.I <= bits(RW0_wdata, 39, 20) - mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_1.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 1, 1)), UInt<1>("h1"))) - mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_2.CE <= RW0_clk - mem_0_2.A <= RW0_addr - node RW0_rdata_0_2 = bits(mem_0_2.O, 19, 0) - mem_0_2.I <= bits(RW0_wdata, 59, 40) - mem_0_2.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_2.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 2, 2)), UInt<1>("h1"))) - mem_0_2.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_3.CE <= RW0_clk - mem_0_3.A <= RW0_addr - node RW0_rdata_0_3 = bits(mem_0_3.O, 19, 0) - mem_0_3.I <= bits(RW0_wdata, 79, 60) - mem_0_3.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_3.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 3, 3)), UInt<1>("h1"))) - mem_0_3.CEB <= not(and(RW0_en, UInt<1>("h1"))) - node RW0_rdata_0 = cat(RW0_rdata_0_3, cat(RW0_rdata_0_2, cat(RW0_rdata_0_1, RW0_rdata_0_0))) - RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) + // Generate a "simple" SRAM (active high/positive edge, 1 read-write port). + def generateSRAM(name: String, prefix: String, width: Int, depth: Int, maskGran: Option[Int] = None): SRAMMacro = { + val realPrefix = prefix + "_" + SRAMMacro( + macroType=SRAM, + name=name, + width=width, + depth=depth, + family="1rw", + ports=Seq(MacroPort( + address=PolarizedPort(name=realPrefix + "addr", polarity=ActiveHigh), + clock=PolarizedPort(name=realPrefix + "clk", polarity=PositiveEdge), - extmodule SRAM1RW64x32 : - input CE : Clock - input A : UInt<6> - input I : UInt<32> - output O : UInt<32> - input CEB : UInt<1> - input OEB : UInt<1> - input WEB : UInt<1> + writeEnable=Some(PolarizedPort(name=realPrefix + "write_en", polarity=ActiveHigh)), - defname = SRAM1RW64x32 + output=Some(PolarizedPort(name=realPrefix + "dout", polarity=ActiveHigh)), + input=Some(PolarizedPort(name=realPrefix + "din", polarity=ActiveHigh)), + maskPort=maskGran match { + case Some(x:Int) => Some(PolarizedPort(name=realPrefix + "mask", polarity=ActiveHigh)) + case _ => None + }, + maskGran=maskGran, - module T_1090_ext : - input RW0_clk : Clock - input RW0_addr : UInt<9> - input RW0_wdata : UInt<64> - output RW0_rdata : UInt<64> - input RW0_en : UInt<1> - input RW0_wmode : UInt<1> - - inst mem_0_0 of SRAM1RW512x32 - inst mem_0_1 of SRAM1RW512x32 - mem_0_0.CE <= RW0_clk - mem_0_0.A <= RW0_addr - node RW0_rdata_0_0 = bits(mem_0_0.O, 31, 0) - mem_0_0.I <= bits(RW0_wdata, 31, 0) - mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_0.WEB <= not(and(and(RW0_wmode, UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_1.CE <= RW0_clk - mem_0_1.A <= RW0_addr - node RW0_rdata_0_1 = bits(mem_0_1.O, 31, 0) - mem_0_1.I <= bits(RW0_wdata, 63, 32) - mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_1.WEB <= not(and(and(RW0_wmode, UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) - node RW0_rdata_0 = cat(RW0_rdata_0_1, RW0_rdata_0_0) - RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) - - module T_406_ext : - input RW0_clk : Clock - input RW0_addr : UInt<9> - input RW0_wdata : UInt<64> - output RW0_rdata : UInt<64> - input RW0_en : UInt<1> - input RW0_wmode : UInt<1> - input RW0_wmask : UInt<8> - - inst mem_0_0 of SRAM1RW512x32 - inst mem_0_1 of SRAM1RW512x32 - inst mem_0_2 of SRAM1RW512x32 - inst mem_0_3 of SRAM1RW512x32 - inst mem_0_4 of SRAM1RW512x32 - inst mem_0_5 of SRAM1RW512x32 - inst mem_0_6 of SRAM1RW512x32 - inst mem_0_7 of SRAM1RW512x32 - mem_0_0.CE <= RW0_clk - mem_0_0.A <= RW0_addr - node RW0_rdata_0_0 = bits(mem_0_0.O, 7, 0) - mem_0_0.I <= bits(RW0_wdata, 7, 0) - mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_0.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 0, 0)), UInt<1>("h1"))) - mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_1.CE <= RW0_clk - mem_0_1.A <= RW0_addr - node RW0_rdata_0_1 = bits(mem_0_1.O, 7, 0) - mem_0_1.I <= bits(RW0_wdata, 15, 8) - mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_1.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 1, 1)), UInt<1>("h1"))) - mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_2.CE <= RW0_clk - mem_0_2.A <= RW0_addr - node RW0_rdata_0_2 = bits(mem_0_2.O, 7, 0) - mem_0_2.I <= bits(RW0_wdata, 23, 16) - mem_0_2.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_2.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 2, 2)), UInt<1>("h1"))) - mem_0_2.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_3.CE <= RW0_clk - mem_0_3.A <= RW0_addr - node RW0_rdata_0_3 = bits(mem_0_3.O, 7, 0) - mem_0_3.I <= bits(RW0_wdata, 31, 24) - mem_0_3.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_3.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 3, 3)), UInt<1>("h1"))) - mem_0_3.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_4.CE <= RW0_clk - mem_0_4.A <= RW0_addr - node RW0_rdata_0_4 = bits(mem_0_4.O, 7, 0) - mem_0_4.I <= bits(RW0_wdata, 39, 32) - mem_0_4.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_4.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 4, 4)), UInt<1>("h1"))) - mem_0_4.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_5.CE <= RW0_clk - mem_0_5.A <= RW0_addr - node RW0_rdata_0_5 = bits(mem_0_5.O, 7, 0) - mem_0_5.I <= bits(RW0_wdata, 47, 40) - mem_0_5.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_5.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 5, 5)), UInt<1>("h1"))) - mem_0_5.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_6.CE <= RW0_clk - mem_0_6.A <= RW0_addr - node RW0_rdata_0_6 = bits(mem_0_6.O, 7, 0) - mem_0_6.I <= bits(RW0_wdata, 55, 48) - mem_0_6.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_6.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 6, 6)), UInt<1>("h1"))) - mem_0_6.CEB <= not(and(RW0_en, UInt<1>("h1"))) - mem_0_7.CE <= RW0_clk - mem_0_7.A <= RW0_addr - node RW0_rdata_0_7 = bits(mem_0_7.O, 7, 0) - mem_0_7.I <= bits(RW0_wdata, 63, 56) - mem_0_7.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) - mem_0_7.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 7, 7)), UInt<1>("h1"))) - mem_0_7.CEB <= not(and(RW0_en, UInt<1>("h1"))) - node RW0_rdata_0 = cat(RW0_rdata_0_7, cat(RW0_rdata_0_6, cat(RW0_rdata_0_5, cat(RW0_rdata_0_4, cat(RW0_rdata_0_3, cat(RW0_rdata_0_2, cat(RW0_rdata_0_1, RW0_rdata_0_0))))))) - RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) - - extmodule SRAM1RW512x32 : - input CE : Clock - input A : UInt<9> - input I : UInt<32> - output O : UInt<32> - input CEB : UInt<1> - input OEB : UInt<1> - input WEB : UInt<1> - - defname = SRAM1RW512x32 - - - module T_2172_ext : - input W0_clk : Clock - input W0_addr : UInt<6> - input W0_data : UInt<88> - input W0_en : UInt<1> - input W0_mask : UInt<4> - input R0_clk : Clock - input R0_addr : UInt<6> - output R0_data : UInt<88> - input R0_en : UInt<1> - - inst mem_0_0 of SRAM2RW64x32 - inst mem_0_1 of SRAM2RW64x32 - inst mem_0_2 of SRAM2RW64x32 - inst mem_0_3 of SRAM2RW64x32 - mem_0_0.CE1 <= W0_clk - mem_0_0.A1 <= W0_addr - mem_0_0.I1 <= bits(W0_data, 21, 0) - mem_0_0.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 0, 0)), UInt<1>("h1"))) - mem_0_0.CEB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_1.CE1 <= W0_clk - mem_0_1.A1 <= W0_addr - mem_0_1.I1 <= bits(W0_data, 43, 22) - mem_0_1.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 1, 1)), UInt<1>("h1"))) - mem_0_1.CEB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_2.CE1 <= W0_clk - mem_0_2.A1 <= W0_addr - mem_0_2.I1 <= bits(W0_data, 65, 44) - mem_0_2.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_2.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 2, 2)), UInt<1>("h1"))) - mem_0_2.CEB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_3.CE1 <= W0_clk - mem_0_3.A1 <= W0_addr - mem_0_3.I1 <= bits(W0_data, 87, 66) - mem_0_3.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_3.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 3, 3)), UInt<1>("h1"))) - mem_0_3.CEB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_0.CE2 <= R0_clk - mem_0_0.A2 <= R0_addr - node R0_data_0_0 = bits(mem_0_0.O2, 21, 0) - mem_0_0.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_0.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.CEB2 <= not(and(R0_en, UInt<1>("h1"))) - mem_0_1.CE2 <= R0_clk - mem_0_1.A2 <= R0_addr - node R0_data_0_1 = bits(mem_0_1.O2, 21, 0) - mem_0_1.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_1.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.CEB2 <= not(and(R0_en, UInt<1>("h1"))) - mem_0_2.CE2 <= R0_clk - mem_0_2.A2 <= R0_addr - node R0_data_0_2 = bits(mem_0_2.O2, 21, 0) - mem_0_2.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_2.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_2.CEB2 <= not(and(R0_en, UInt<1>("h1"))) - mem_0_3.CE2 <= R0_clk - mem_0_3.A2 <= R0_addr - node R0_data_0_3 = bits(mem_0_3.O2, 21, 0) - mem_0_3.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_3.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_3.CEB2 <= not(and(R0_en, UInt<1>("h1"))) - node R0_data_0 = cat(R0_data_0_3, cat(R0_data_0_2, cat(R0_data_0_1, R0_data_0_0))) - R0_data <= mux(UInt<1>("h1"), R0_data_0, UInt<1>("h0")) - - extmodule SRAM2RW64x32 : - input CE1 : Clock - input A1 : UInt<6> - input I1 : UInt<32> - output O1 : UInt<32> - input CEB1 : UInt<1> - input OEB1 : UInt<1> - input WEB1 : UInt<1> - input CE2 : Clock - input A2 : UInt<6> - input I2 : UInt<32> - output O2 : UInt<32> - input CEB2 : UInt<1> - input OEB2 : UInt<1> - input WEB2 : UInt<1> - - defname = SRAM2RW64x32 -""" - compile(mem, Some(lib), v, false) + width=width, depth=depth // These numbers don't matter here. + )) + ) + } } + +//~ class RocketChipTest extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "rocketchip.json") + //~ val lib = new File(macroDir, "mylib.json") + //~ val v = new File(testDir, "rocketchip.macro.v") + //~ val output = // TODO: check correctness... +//~ """ +//~ circuit T_2172_ext : + //~ module tag_array_ext : + //~ input RW0_clk : Clock + //~ input RW0_addr : UInt<6> + //~ input RW0_wdata : UInt<80> + //~ output RW0_rdata : UInt<80> + //~ input RW0_en : UInt<1> + //~ input RW0_wmode : UInt<1> + //~ input RW0_wmask : UInt<4> + + //~ inst mem_0_0 of SRAM1RW64x32 + //~ inst mem_0_1 of SRAM1RW64x32 + //~ inst mem_0_2 of SRAM1RW64x32 + //~ inst mem_0_3 of SRAM1RW64x32 + //~ mem_0_0.CE <= RW0_clk + //~ mem_0_0.A <= RW0_addr + //~ node RW0_rdata_0_0 = bits(mem_0_0.O, 19, 0) + //~ mem_0_0.I <= bits(RW0_wdata, 19, 0) + //~ mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_0.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 0, 0)), UInt<1>("h1"))) + //~ mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_1.CE <= RW0_clk + //~ mem_0_1.A <= RW0_addr + //~ node RW0_rdata_0_1 = bits(mem_0_1.O, 19, 0) + //~ mem_0_1.I <= bits(RW0_wdata, 39, 20) + //~ mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_1.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 1, 1)), UInt<1>("h1"))) + //~ mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_2.CE <= RW0_clk + //~ mem_0_2.A <= RW0_addr + //~ node RW0_rdata_0_2 = bits(mem_0_2.O, 19, 0) + //~ mem_0_2.I <= bits(RW0_wdata, 59, 40) + //~ mem_0_2.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_2.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 2, 2)), UInt<1>("h1"))) + //~ mem_0_2.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_3.CE <= RW0_clk + //~ mem_0_3.A <= RW0_addr + //~ node RW0_rdata_0_3 = bits(mem_0_3.O, 19, 0) + //~ mem_0_3.I <= bits(RW0_wdata, 79, 60) + //~ mem_0_3.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_3.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 3, 3)), UInt<1>("h1"))) + //~ mem_0_3.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ node RW0_rdata_0 = cat(RW0_rdata_0_3, cat(RW0_rdata_0_2, cat(RW0_rdata_0_1, RW0_rdata_0_0))) + //~ RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) + + //~ extmodule SRAM1RW64x32 : + //~ input CE : Clock + //~ input A : UInt<6> + //~ input I : UInt<32> + //~ output O : UInt<32> + //~ input CEB : UInt<1> + //~ input OEB : UInt<1> + //~ input WEB : UInt<1> + + //~ defname = SRAM1RW64x32 + + + //~ module T_1090_ext : + //~ input RW0_clk : Clock + //~ input RW0_addr : UInt<9> + //~ input RW0_wdata : UInt<64> + //~ output RW0_rdata : UInt<64> + //~ input RW0_en : UInt<1> + //~ input RW0_wmode : UInt<1> + + //~ inst mem_0_0 of SRAM1RW512x32 + //~ inst mem_0_1 of SRAM1RW512x32 + //~ mem_0_0.CE <= RW0_clk + //~ mem_0_0.A <= RW0_addr + //~ node RW0_rdata_0_0 = bits(mem_0_0.O, 31, 0) + //~ mem_0_0.I <= bits(RW0_wdata, 31, 0) + //~ mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_0.WEB <= not(and(and(RW0_wmode, UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_1.CE <= RW0_clk + //~ mem_0_1.A <= RW0_addr + //~ node RW0_rdata_0_1 = bits(mem_0_1.O, 31, 0) + //~ mem_0_1.I <= bits(RW0_wdata, 63, 32) + //~ mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_1.WEB <= not(and(and(RW0_wmode, UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ node RW0_rdata_0 = cat(RW0_rdata_0_1, RW0_rdata_0_0) + //~ RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) + + //~ module T_406_ext : + //~ input RW0_clk : Clock + //~ input RW0_addr : UInt<9> + //~ input RW0_wdata : UInt<64> + //~ output RW0_rdata : UInt<64> + //~ input RW0_en : UInt<1> + //~ input RW0_wmode : UInt<1> + //~ input RW0_wmask : UInt<8> + + //~ inst mem_0_0 of SRAM1RW512x32 + //~ inst mem_0_1 of SRAM1RW512x32 + //~ inst mem_0_2 of SRAM1RW512x32 + //~ inst mem_0_3 of SRAM1RW512x32 + //~ inst mem_0_4 of SRAM1RW512x32 + //~ inst mem_0_5 of SRAM1RW512x32 + //~ inst mem_0_6 of SRAM1RW512x32 + //~ inst mem_0_7 of SRAM1RW512x32 + //~ mem_0_0.CE <= RW0_clk + //~ mem_0_0.A <= RW0_addr + //~ node RW0_rdata_0_0 = bits(mem_0_0.O, 7, 0) + //~ mem_0_0.I <= bits(RW0_wdata, 7, 0) + //~ mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_0.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 0, 0)), UInt<1>("h1"))) + //~ mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_1.CE <= RW0_clk + //~ mem_0_1.A <= RW0_addr + //~ node RW0_rdata_0_1 = bits(mem_0_1.O, 7, 0) + //~ mem_0_1.I <= bits(RW0_wdata, 15, 8) + //~ mem_0_1.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_1.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 1, 1)), UInt<1>("h1"))) + //~ mem_0_1.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_2.CE <= RW0_clk + //~ mem_0_2.A <= RW0_addr + //~ node RW0_rdata_0_2 = bits(mem_0_2.O, 7, 0) + //~ mem_0_2.I <= bits(RW0_wdata, 23, 16) + //~ mem_0_2.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_2.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 2, 2)), UInt<1>("h1"))) + //~ mem_0_2.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_3.CE <= RW0_clk + //~ mem_0_3.A <= RW0_addr + //~ node RW0_rdata_0_3 = bits(mem_0_3.O, 7, 0) + //~ mem_0_3.I <= bits(RW0_wdata, 31, 24) + //~ mem_0_3.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_3.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 3, 3)), UInt<1>("h1"))) + //~ mem_0_3.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_4.CE <= RW0_clk + //~ mem_0_4.A <= RW0_addr + //~ node RW0_rdata_0_4 = bits(mem_0_4.O, 7, 0) + //~ mem_0_4.I <= bits(RW0_wdata, 39, 32) + //~ mem_0_4.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_4.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 4, 4)), UInt<1>("h1"))) + //~ mem_0_4.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_5.CE <= RW0_clk + //~ mem_0_5.A <= RW0_addr + //~ node RW0_rdata_0_5 = bits(mem_0_5.O, 7, 0) + //~ mem_0_5.I <= bits(RW0_wdata, 47, 40) + //~ mem_0_5.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_5.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 5, 5)), UInt<1>("h1"))) + //~ mem_0_5.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_6.CE <= RW0_clk + //~ mem_0_6.A <= RW0_addr + //~ node RW0_rdata_0_6 = bits(mem_0_6.O, 7, 0) + //~ mem_0_6.I <= bits(RW0_wdata, 55, 48) + //~ mem_0_6.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_6.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 6, 6)), UInt<1>("h1"))) + //~ mem_0_6.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ mem_0_7.CE <= RW0_clk + //~ mem_0_7.A <= RW0_addr + //~ node RW0_rdata_0_7 = bits(mem_0_7.O, 7, 0) + //~ mem_0_7.I <= bits(RW0_wdata, 63, 56) + //~ mem_0_7.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) + //~ mem_0_7.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 7, 7)), UInt<1>("h1"))) + //~ mem_0_7.CEB <= not(and(RW0_en, UInt<1>("h1"))) + //~ node RW0_rdata_0 = cat(RW0_rdata_0_7, cat(RW0_rdata_0_6, cat(RW0_rdata_0_5, cat(RW0_rdata_0_4, cat(RW0_rdata_0_3, cat(RW0_rdata_0_2, cat(RW0_rdata_0_1, RW0_rdata_0_0))))))) + //~ RW0_rdata <= mux(UInt<1>("h1"), RW0_rdata_0, UInt<1>("h0")) + + //~ extmodule SRAM1RW512x32 : + //~ input CE : Clock + //~ input A : UInt<9> + //~ input I : UInt<32> + //~ output O : UInt<32> + //~ input CEB : UInt<1> + //~ input OEB : UInt<1> + //~ input WEB : UInt<1> + + //~ defname = SRAM1RW512x32 + + + //~ module T_2172_ext : + //~ input W0_clk : Clock + //~ input W0_addr : UInt<6> + //~ input W0_data : UInt<88> + //~ input W0_en : UInt<1> + //~ input W0_mask : UInt<4> + //~ input R0_clk : Clock + //~ input R0_addr : UInt<6> + //~ output R0_data : UInt<88> + //~ input R0_en : UInt<1> + + //~ inst mem_0_0 of SRAM2RW64x32 + //~ inst mem_0_1 of SRAM2RW64x32 + //~ inst mem_0_2 of SRAM2RW64x32 + //~ inst mem_0_3 of SRAM2RW64x32 + //~ mem_0_0.CE1 <= W0_clk + //~ mem_0_0.A1 <= W0_addr + //~ mem_0_0.I1 <= bits(W0_data, 21, 0) + //~ mem_0_0.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 0, 0)), UInt<1>("h1"))) + //~ mem_0_0.CEB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_1.CE1 <= W0_clk + //~ mem_0_1.A1 <= W0_addr + //~ mem_0_1.I1 <= bits(W0_data, 43, 22) + //~ mem_0_1.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 1, 1)), UInt<1>("h1"))) + //~ mem_0_1.CEB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_2.CE1 <= W0_clk + //~ mem_0_2.A1 <= W0_addr + //~ mem_0_2.I1 <= bits(W0_data, 65, 44) + //~ mem_0_2.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_2.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 2, 2)), UInt<1>("h1"))) + //~ mem_0_2.CEB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_3.CE1 <= W0_clk + //~ mem_0_3.A1 <= W0_addr + //~ mem_0_3.I1 <= bits(W0_data, 87, 66) + //~ mem_0_3.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_3.WEB1 <= not(and(and(UInt<1>("h1"), bits(W0_mask, 3, 3)), UInt<1>("h1"))) + //~ mem_0_3.CEB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_0.CE2 <= R0_clk + //~ mem_0_0.A2 <= R0_addr + //~ node R0_data_0_0 = bits(mem_0_0.O2, 21, 0) + //~ mem_0_0.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_0.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.CEB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ mem_0_1.CE2 <= R0_clk + //~ mem_0_1.A2 <= R0_addr + //~ node R0_data_0_1 = bits(mem_0_1.O2, 21, 0) + //~ mem_0_1.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_1.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.CEB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ mem_0_2.CE2 <= R0_clk + //~ mem_0_2.A2 <= R0_addr + //~ node R0_data_0_2 = bits(mem_0_2.O2, 21, 0) + //~ mem_0_2.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_2.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_2.CEB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ mem_0_3.CE2 <= R0_clk + //~ mem_0_3.A2 <= R0_addr + //~ node R0_data_0_3 = bits(mem_0_3.O2, 21, 0) + //~ mem_0_3.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_3.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_3.CEB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ node R0_data_0 = cat(R0_data_0_3, cat(R0_data_0_2, cat(R0_data_0_1, R0_data_0_0))) + //~ R0_data <= mux(UInt<1>("h1"), R0_data_0, UInt<1>("h0")) + + //~ extmodule SRAM2RW64x32 : + //~ input CE1 : Clock + //~ input A1 : UInt<6> + //~ input I1 : UInt<32> + //~ output O1 : UInt<32> + //~ input CEB1 : UInt<1> + //~ input OEB1 : UInt<1> + //~ input WEB1 : UInt<1> + //~ input CE2 : Clock + //~ input A2 : UInt<6> + //~ input I2 : UInt<32> + //~ output O2 : UInt<32> + //~ input CEB2 : UInt<1> + //~ input OEB2 : UInt<1> + //~ input WEB2 : UInt<1> + + //~ defname = SRAM2RW64x32 +//~ """ + //~ compile(mem, Some(lib), v, false) +//~ } diff --git a/tapeout/src/test/scala/transforms/macros/SplitDepth.scala b/tapeout/src/test/scala/transforms/macros/SplitDepth.scala index 7a9f5b9d..d7ffebb0 100644 --- a/tapeout/src/test/scala/transforms/macros/SplitDepth.scala +++ b/tapeout/src/test/scala/transforms/macros/SplitDepth.scala @@ -1,11 +1,171 @@ -package barstools.tapeout.transforms.macros +package barstools.tapeout.transforms.macros.test -import java.io.File +import firrtl.Utils.ceilLog2 +import mdf.macrolib._ + +// Test the depth splitting aspect of the memory compiler. +// For example, implementing a 4096x32 memory using four 1024x32 memories. + +trait HasSimpleDepthTestGenerator { + this: MacroCompilerSpec with HasSRAMGenerator => + // Override these with "override lazy val". + // Why lazy? These are used in the constructor here so overriding non-lazily + // would be too late. + def width: Int + def mem_depth: Int + def lib_depth: Int + + require (mem_depth >= lib_depth) + + override val memPrefix = testDir + override val libPrefix = testDir + + val mem = s"mem-${mem_depth}x${width}-rw.json" + val lib = s"lib-${lib_depth}x${width}-rw.json" + val v = s"split_depth_${mem_depth}x${width}_rw.v" + + val mem_name = "target_memory" + val mem_addr_width = ceilLog2(mem_depth) + + val lib_name = "awesome_lib_mem" + val lib_addr_width = ceilLog2(lib_depth) + + writeToLib(lib, Seq(generateSRAM(lib_name, "lib", width, lib_depth))) + writeToMem(mem, Seq(generateSRAM(mem_name, "outer", width, mem_depth))) + + val expectedInstances = mem_depth / lib_depth + val selectBits = mem_addr_width - lib_addr_width + var output = +s""" +circuit $mem_name : + module $mem_name : + input outer_clk : Clock + input outer_addr : UInt<$mem_addr_width> + input outer_din : UInt<$width> + output outer_dout : UInt<$width> + input outer_write_en : UInt<1> +""" + + if (selectBits > 0) { + output += +s""" + node outer_addr_sel = bits(outer_addr, ${mem_addr_width - 1}, $lib_addr_width) +""" + } + + for (i <- 0 to expectedInstances - 1) { + val enableIdentifier = if (selectBits > 0) s"""eq(outer_addr_sel, UInt<${selectBits}>("h${i.toHexString}"))""" else "UInt<1>(\"h1\")" + output += +s""" + inst mem_${i}_0 of awesome_lib_mem + mem_${i}_0.lib_clk <= outer_clk + mem_${i}_0.lib_addr <= outer_addr + node outer_dout_${i}_0 = bits(mem_${i}_0.lib_dout, ${width - 1}, 0) + mem_${i}_0.lib_din <= bits(outer_din, ${width - 1}, 0) + mem_${i}_0.lib_write_en <= and(and(outer_write_en, UInt<1>("h1")), ${enableIdentifier}) + node outer_dout_${i} = outer_dout_${i}_0 +""" + } + def generate_outer_dout_tree(i:Int, expectedInstances: Int): String = { + if (i > expectedInstances - 1) { + "UInt<1>(\"h0\")" + } else { + "mux(eq(outer_addr_sel, UInt<%d>(\"h%s\")), outer_dout_%d, %s)".format( + selectBits, i.toHexString, i, generate_outer_dout_tree(i + 1, expectedInstances) + ) + } + } + output += " outer_dout <= " + if (selectBits > 0) { + output += generate_outer_dout_tree(0, expectedInstances) + } else { + output += """mux(UInt<1>("h1"), outer_dout_0, UInt<1>("h0"))""" + } + + output += +s""" + extmodule $lib_name : + input lib_clk : Clock + input lib_addr : UInt<$lib_addr_width> + input lib_din : UInt<$width> + output lib_dout : UInt<$width> + input lib_write_en : UInt<1> + + defname = $lib_name +""" +} + +// Try different widths +class SplitDepth4096x32_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 32 + override lazy val mem_depth = 4096 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +class SplitDepth4096x16_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 16 + override lazy val mem_depth = 4096 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +class SplitDepth32768x8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 8 + override lazy val mem_depth = 32768 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +class SplitDepth4096x8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 8 + override lazy val mem_depth = 4096 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +class SplitDepth2048x8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 8 + override lazy val mem_depth = 2048 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +class SplitDepth1024x8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 8 + override lazy val mem_depth = 1024 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +// Non power of two +class SplitDepth1024x8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator { + override lazy val width = 8 + override lazy val mem_depth = 1024 + override lazy val lib_depth = 1024 + + compile(mem, lib, v, false) + execute(mem, lib, false, output) +} + +// Masked RAMs class SplitDepth2048x8_mrw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x8-mrw.json") - val lib = new File(macroDir, "lib-1024x8-mrw.json") - val v = new File(testDir, "split_depth_2048x8_mrw.v") + val mem = "mem-2048x8-mrw.json" + val lib = "lib-1024x8-mrw.json" + val v = "split_depth_2048x8_mrw.v" val output = """ circuit name_of_sram_module : @@ -50,226 +210,174 @@ circuit name_of_sram_module : defname = vendor_sram """ - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) + compile(mem, lib, v, false) + execute(mem, lib, false, output) } -class SplitDepth2000x8_mrw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2000x8-mrw.json") - val lib = new File(macroDir, "lib-1024x8-mrw.json") - val v = new File(testDir, "split_depth_2000x8_mrw.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> +//~ class SplitDepth2048x8_n28 extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x8-mrw.json") + //~ val lib = new File(macroDir, "lib-1024x8-n28.json") + //~ val v = new File(testDir, "split_depth_2048x8_n28.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - node RW0A_sel = bits(RW0A, 10, 10) - inst mem_0_0 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0M <= bits(RW0M, 0, 0) - mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) - mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) - node RW0O_0 = RW0O_0_0 - inst mem_1_0 of vendor_sram - mem_1_0.clock <= clock - mem_1_0.RW0A <= RW0A - node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) - mem_1_0.RW0I <= bits(RW0I, 7, 0) - mem_1_0.RW0M <= bits(RW0M, 0, 0) - mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) - mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) - node RW0O_1 = RW0O_1_0 - RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) + //~ node RW0A_sel = bits(RW0A, 10, 10) + //~ inst mem_0_0 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0M <= cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))) + //~ mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) + //~ mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) + //~ node RW0O_0 = RW0O_0_0 + //~ inst mem_1_0 of vendor_sram + //~ mem_1_0.clock <= clock + //~ mem_1_0.RW0A <= RW0A + //~ node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) + //~ mem_1_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_1_0.RW0M <= cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))) + //~ mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) + //~ mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) + //~ node RW0O_1 = RW0O_1_0 + //~ RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<10> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<10> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<8> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, lib, v, false) + //~ execute(mem, lib, false, output) +//~ } -class SplitDepth2048x8_n28 extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x8-mrw.json") - val lib = new File(macroDir, "lib-1024x8-n28.json") - val v = new File(testDir, "split_depth_2048x8_n28.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> +//~ class SplitDepth2048x8_r_mw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x8-r-mw.json") + //~ val lib = new File(macroDir, "lib-1024x8-r-mw.json") + //~ val v = new File(testDir, "split_depth_2048x8_r_mw.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input W0A : UInt<11> + //~ input W0I : UInt<8> + //~ input W0E : UInt<1> + //~ input W0M : UInt<1> + //~ input clock : Clock + //~ input R0A : UInt<11> + //~ output R0O : UInt<8> - node RW0A_sel = bits(RW0A, 10, 10) - inst mem_0_0 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0M <= cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))) - mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) - mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) - node RW0O_0 = RW0O_0_0 - inst mem_1_0 of vendor_sram - mem_1_0.clock <= clock - mem_1_0.RW0A <= RW0A - node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) - mem_1_0.RW0I <= bits(RW0I, 7, 0) - mem_1_0.RW0M <= cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))) - mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) - mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) - node RW0O_1 = RW0O_1_0 - RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) + //~ node W0A_sel = bits(W0A, 10, 10) + //~ node R0A_sel = bits(R0A, 10, 10) + //~ inst mem_0_0 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.W0A <= W0A + //~ mem_0_0.W0I <= bits(W0I, 7, 0) + //~ mem_0_0.W0M <= bits(W0M, 0, 0) + //~ mem_0_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h0"))) + //~ mem_0_0.W0E <= and(W0E, eq(W0A_sel, UInt<1>("h0"))) + //~ mem_0_0.clock <= clock + //~ mem_0_0.R0A <= R0A + //~ node R0O_0_0 = bits(mem_0_0.R0O, 7, 0) + //~ node R0O_0 = R0O_0_0 + //~ inst mem_1_0 of vendor_sram + //~ mem_1_0.clock <= clock + //~ mem_1_0.W0A <= W0A + //~ mem_1_0.W0I <= bits(W0I, 7, 0) + //~ mem_1_0.W0M <= bits(W0M, 0, 0) + //~ mem_1_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h1"))) + //~ mem_1_0.W0E <= and(W0E, eq(W0A_sel, UInt<1>("h1"))) + //~ mem_1_0.clock <= clock + //~ mem_1_0.R0A <= R0A + //~ node R0O_1_0 = bits(mem_1_0.R0O, 7, 0) + //~ node R0O_1 = R0O_1_0 + //~ R0O <= mux(eq(R0A_sel, UInt<1>("h0")), R0O_0, mux(eq(R0A_sel, UInt<1>("h1")), R0O_1, UInt<1>("h0"))) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<10> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<8> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input R0A : UInt<10> + //~ output R0O : UInt<8> + //~ input clock : Clock + //~ input W0A : UInt<10> + //~ input W0I : UInt<8> + //~ input W0E : UInt<1> + //~ input W0W : UInt<1> + //~ input W0M : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} - -class SplitDepth2048x8_r_mw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x8-r-mw.json") - val lib = new File(macroDir, "lib-1024x8-r-mw.json") - val v = new File(testDir, "split_depth_2048x8_r_mw.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input W0A : UInt<11> - input W0I : UInt<8> - input W0E : UInt<1> - input W0M : UInt<1> - input clock : Clock - input R0A : UInt<11> - output R0O : UInt<8> - - node W0A_sel = bits(W0A, 10, 10) - node R0A_sel = bits(R0A, 10, 10) - inst mem_0_0 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.W0A <= W0A - mem_0_0.W0I <= bits(W0I, 7, 0) - mem_0_0.W0M <= bits(W0M, 0, 0) - mem_0_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h0"))) - mem_0_0.W0E <= and(W0E, eq(W0A_sel, UInt<1>("h0"))) - mem_0_0.clock <= clock - mem_0_0.R0A <= R0A - node R0O_0_0 = bits(mem_0_0.R0O, 7, 0) - node R0O_0 = R0O_0_0 - inst mem_1_0 of vendor_sram - mem_1_0.clock <= clock - mem_1_0.W0A <= W0A - mem_1_0.W0I <= bits(W0I, 7, 0) - mem_1_0.W0M <= bits(W0M, 0, 0) - mem_1_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h1"))) - mem_1_0.W0E <= and(W0E, eq(W0A_sel, UInt<1>("h1"))) - mem_1_0.clock <= clock - mem_1_0.R0A <= R0A - node R0O_1_0 = bits(mem_1_0.R0O, 7, 0) - node R0O_1 = R0O_1_0 - R0O <= mux(eq(R0A_sel, UInt<1>("h0")), R0O_0, mux(eq(R0A_sel, UInt<1>("h1")), R0O_1, UInt<1>("h0"))) - - extmodule vendor_sram : - input clock : Clock - input R0A : UInt<10> - output R0O : UInt<8> - input clock : Clock - input W0A : UInt<10> - input W0I : UInt<8> - input W0E : UInt<1> - input W0W : UInt<1> - input W0M : UInt<1> - - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, lib, v, false) + //~ execute(mem, lib, false, output) +//~ } -class SplitDepth2048x8_mrw_Sleep extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x8-mrw.json") - val lib = new File(macroDir, "lib-1024x8-sleep.json") - val v = new File(testDir, "split_depth_2048x8_sleep.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> +//~ class SplitDepth2048x8_mrw_Sleep extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x8-mrw.json") + //~ val lib = new File(macroDir, "lib-1024x8-sleep.json") + //~ val v = new File(testDir, "split_depth_2048x8_sleep.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - node RW0A_sel = bits(RW0A, 10, 10) - inst mem_0_0 of vendor_sram - mem_0_0.sleep <= UInt<1>("h0") - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0M <= bits(RW0M, 0, 0) - mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) - mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) - node RW0O_0 = RW0O_0_0 - inst mem_1_0 of vendor_sram - mem_1_0.sleep <= UInt<1>("h0") - mem_1_0.clock <= clock - mem_1_0.RW0A <= RW0A - node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) - mem_1_0.RW0I <= bits(RW0I, 7, 0) - mem_1_0.RW0M <= bits(RW0M, 0, 0) - mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) - mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) - node RW0O_1 = RW0O_1_0 - RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) + //~ node RW0A_sel = bits(RW0A, 10, 10) + //~ inst mem_0_0 of vendor_sram + //~ mem_0_0.sleep <= UInt<1>("h0") + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0M <= bits(RW0M, 0, 0) + //~ mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) + //~ mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) + //~ node RW0O_0 = RW0O_0_0 + //~ inst mem_1_0 of vendor_sram + //~ mem_1_0.sleep <= UInt<1>("h0") + //~ mem_1_0.clock <= clock + //~ mem_1_0.RW0A <= RW0A + //~ node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) + //~ mem_1_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_1_0.RW0M <= bits(RW0M, 0, 0) + //~ mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) + //~ mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) + //~ node RW0O_1 = RW0O_1_0 + //~ RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<10> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> - input sleep : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<10> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> + //~ input sleep : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, lib, v, false) + //~ execute(mem, lib, false, output) +//~ } diff --git a/tapeout/src/test/scala/transforms/macros/SplitWidth.scala b/tapeout/src/test/scala/transforms/macros/SplitWidth.scala index 0e4d638e..1e172d64 100644 --- a/tapeout/src/test/scala/transforms/macros/SplitWidth.scala +++ b/tapeout/src/test/scala/transforms/macros/SplitWidth.scala @@ -1,468 +1,468 @@ -package barstools.tapeout.transforms.macros +//~ package barstools.tapeout.transforms.macros.test -import java.io.File +//~ import java.io.File -class SplitWidth2048x16_mrw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw.json") - val lib = new File(macroDir, "lib-2048x8-mrw.json") - val v = new File(testDir, "split_width_2048x16_mrw.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class SplitWidth2048x16_mrw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw.json") + //~ val lib = new File(macroDir, "lib-2048x8-mrw.json") + //~ val v = new File(testDir, "split_width_2048x16_mrw.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0M <= bits(RW0M, 0, 0) - mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) - mem_0_1.RW0I <= bits(RW0I, 15, 8) - mem_0_1.RW0M <= bits(RW0M, 1, 1) - mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0M <= bits(RW0M, 0, 0) + //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 15, 8) + //~ mem_0_1.RW0M <= bits(RW0M, 1, 1) + //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth2048x16_mrw_Uneven extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw.json") - val lib = new File(macroDir, "lib-2048x10-rw.json") - val v = new File(testDir, "split_width_2048x16_mrw_uneven.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class SplitWidth2048x16_mrw_Uneven extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw.json") + //~ val lib = new File(macroDir, "lib-2048x10-rw.json") + //~ val v = new File(testDir, "split_width_2048x16_mrw_uneven.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) - mem_0_1.RW0I <= bits(RW0I, 15, 8) - mem_0_1.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 15, 8) + //~ mem_0_1.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<10> - output RW0O : UInt<10> - input RW0E : UInt<1> - input RW0W : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<10> + //~ output RW0O : UInt<10> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth2048x16_mrw_VeryUneven extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw-2.json") - val lib = new File(macroDir, "lib-2048x10-rw.json") - val v = new File(testDir, "split_width_2048x16_mrw_very_uneven.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<8> +//~ class SplitWidth2048x16_mrw_VeryUneven extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw-2.json") + //~ val lib = new File(macroDir, "lib-2048x10-rw.json") + //~ val v = new File(testDir, "split_width_2048x16_mrw_very_uneven.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<8> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - inst mem_0_2 of vendor_sram - inst mem_0_3 of vendor_sram - inst mem_0_4 of vendor_sram - inst mem_0_5 of vendor_sram - inst mem_0_6 of vendor_sram - inst mem_0_7 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 1, 0) - mem_0_0.RW0I <= bits(RW0I, 1, 0) - mem_0_0.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) - mem_0_1.RW0I <= bits(RW0I, 3, 2) - mem_0_1.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_2.clock <= clock - mem_0_2.RW0A <= RW0A - node RW0O_0_2 = bits(mem_0_2.RW0O, 1, 0) - mem_0_2.RW0I <= bits(RW0I, 5, 4) - mem_0_2.RW0W <= and(and(RW0W, bits(RW0M, 2, 2)), UInt<1>("h1")) - mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_3.clock <= clock - mem_0_3.RW0A <= RW0A - node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) - mem_0_3.RW0I <= bits(RW0I, 7, 6) - mem_0_3.RW0W <= and(and(RW0W, bits(RW0M, 3, 3)), UInt<1>("h1")) - mem_0_3.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_4.clock <= clock - mem_0_4.RW0A <= RW0A - node RW0O_0_4 = bits(mem_0_4.RW0O, 1, 0) - mem_0_4.RW0I <= bits(RW0I, 9, 8) - mem_0_4.RW0W <= and(and(RW0W, bits(RW0M, 4, 4)), UInt<1>("h1")) - mem_0_4.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_5.clock <= clock - mem_0_5.RW0A <= RW0A - node RW0O_0_5 = bits(mem_0_5.RW0O, 1, 0) - mem_0_5.RW0I <= bits(RW0I, 11, 10) - mem_0_5.RW0W <= and(and(RW0W, bits(RW0M, 5, 5)), UInt<1>("h1")) - mem_0_5.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_6.clock <= clock - mem_0_6.RW0A <= RW0A - node RW0O_0_6 = bits(mem_0_6.RW0O, 1, 0) - mem_0_6.RW0I <= bits(RW0I, 13, 12) - mem_0_6.RW0W <= and(and(RW0W, bits(RW0M, 6, 6)), UInt<1>("h1")) - mem_0_6.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_7.clock <= clock - mem_0_7.RW0A <= RW0A - node RW0O_0_7 = bits(mem_0_7.RW0O, 1, 0) - mem_0_7.RW0I <= bits(RW0I, 15, 14) - mem_0_7.RW0W <= and(and(RW0W, bits(RW0M, 7, 7)), UInt<1>("h1")) - mem_0_7.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_7, cat(RW0O_0_6, cat(RW0O_0_5, cat(RW0O_0_4, cat(RW0O_0_3, cat(RW0O_0_2, cat(RW0O_0_1, RW0O_0_0))))))) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ inst mem_0_2 of vendor_sram + //~ inst mem_0_3 of vendor_sram + //~ inst mem_0_4 of vendor_sram + //~ inst mem_0_5 of vendor_sram + //~ inst mem_0_6 of vendor_sram + //~ inst mem_0_7 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 1, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 1, 0) + //~ mem_0_0.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 3, 2) + //~ mem_0_1.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_2.clock <= clock + //~ mem_0_2.RW0A <= RW0A + //~ node RW0O_0_2 = bits(mem_0_2.RW0O, 1, 0) + //~ mem_0_2.RW0I <= bits(RW0I, 5, 4) + //~ mem_0_2.RW0W <= and(and(RW0W, bits(RW0M, 2, 2)), UInt<1>("h1")) + //~ mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_3.clock <= clock + //~ mem_0_3.RW0A <= RW0A + //~ node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) + //~ mem_0_3.RW0I <= bits(RW0I, 7, 6) + //~ mem_0_3.RW0W <= and(and(RW0W, bits(RW0M, 3, 3)), UInt<1>("h1")) + //~ mem_0_3.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_4.clock <= clock + //~ mem_0_4.RW0A <= RW0A + //~ node RW0O_0_4 = bits(mem_0_4.RW0O, 1, 0) + //~ mem_0_4.RW0I <= bits(RW0I, 9, 8) + //~ mem_0_4.RW0W <= and(and(RW0W, bits(RW0M, 4, 4)), UInt<1>("h1")) + //~ mem_0_4.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_5.clock <= clock + //~ mem_0_5.RW0A <= RW0A + //~ node RW0O_0_5 = bits(mem_0_5.RW0O, 1, 0) + //~ mem_0_5.RW0I <= bits(RW0I, 11, 10) + //~ mem_0_5.RW0W <= and(and(RW0W, bits(RW0M, 5, 5)), UInt<1>("h1")) + //~ mem_0_5.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_6.clock <= clock + //~ mem_0_6.RW0A <= RW0A + //~ node RW0O_0_6 = bits(mem_0_6.RW0O, 1, 0) + //~ mem_0_6.RW0I <= bits(RW0I, 13, 12) + //~ mem_0_6.RW0W <= and(and(RW0W, bits(RW0M, 6, 6)), UInt<1>("h1")) + //~ mem_0_6.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_7.clock <= clock + //~ mem_0_7.RW0A <= RW0A + //~ node RW0O_0_7 = bits(mem_0_7.RW0O, 1, 0) + //~ mem_0_7.RW0I <= bits(RW0I, 15, 14) + //~ mem_0_7.RW0W <= and(and(RW0W, bits(RW0M, 7, 7)), UInt<1>("h1")) + //~ mem_0_7.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_7, cat(RW0O_0_6, cat(RW0O_0_5, cat(RW0O_0_4, cat(RW0O_0_3, cat(RW0O_0_2, cat(RW0O_0_1, RW0O_0_0))))))) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<10> - output RW0O : UInt<10> - input RW0E : UInt<1> - input RW0W : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<10> + //~ output RW0O : UInt<10> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth2048x16_mrw_ReadEnable extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw.json") - val lib = new File(macroDir, "lib-2048x8-mrw-re.json") - val v = new File(testDir, "split_width_2048x16_mrw_read_enable.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class SplitWidth2048x16_mrw_ReadEnable extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw.json") + //~ val lib = new File(macroDir, "lib-2048x8-mrw-re.json") + //~ val v = new File(testDir, "split_width_2048x16_mrw_read_enable.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) - mem_0_0.RW0M <= bits(RW0M, 0, 0) - mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) - mem_0_1.RW0I <= bits(RW0I, 15, 8) - mem_0_1.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) - mem_0_1.RW0M <= bits(RW0M, 1, 1) - mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) + //~ mem_0_0.RW0M <= bits(RW0M, 0, 0) + //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 15, 8) + //~ mem_0_1.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) + //~ mem_0_1.RW0M <= bits(RW0M, 1, 1) + //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0R : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0R : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth2048x16_n28 extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw.json") - val lib = new File(macroDir, "lib-2048x16-n28.json") - val v = new File(testDir, "split_width_2048x16_n28.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class SplitWidth2048x16_n28 extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw.json") + //~ val lib = new File(macroDir, "lib-2048x16-n28.json") + //~ val v = new File(testDir, "split_width_2048x16_n28.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - inst mem_0_0 of vendor_sram_16 - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 15, 0) - mem_0_0.RW0I <= bits(RW0I, 15, 0) - mem_0_0.RW0M <= cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))))))))))) - mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = RW0O_0_0 - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram_16 + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 15, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 15, 0) + //~ mem_0_0.RW0M <= cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))))))))))) + //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = RW0O_0_0 + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram_16 : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<16> + //~ extmodule vendor_sram_16 : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<16> - defname = vendor_sram_16 -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram_16 +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth2048x20_mrw_UnevenMask extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x20-mrw.json") - val lib = new File(macroDir, "lib-2048x8-mrw.json") - val v = new File(testDir, "split_width_2048x20_mrw_uneven_mask.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<20> - output RW0O : UInt<20> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class SplitWidth2048x20_mrw_UnevenMask extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x20-mrw.json") + //~ val lib = new File(macroDir, "lib-2048x8-mrw.json") + //~ val v = new File(testDir, "split_width_2048x20_mrw_uneven_mask.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<20> + //~ output RW0O : UInt<20> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - inst mem_0_2 of vendor_sram - inst mem_0_3 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) - mem_0_0.RW0I <= bits(RW0I, 7, 0) - mem_0_0.RW0M <= bits(RW0M, 0, 0) - mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) - mem_0_1.RW0I <= bits(RW0I, 9, 8) - mem_0_1.RW0M <= bits(RW0M, 0, 0) - mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_2.clock <= clock - mem_0_2.RW0A <= RW0A - node RW0O_0_2 = bits(mem_0_2.RW0O, 7, 0) - mem_0_2.RW0I <= bits(RW0I, 17, 10) - mem_0_2.RW0M <= bits(RW0M, 1, 1) - mem_0_2.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_3.clock <= clock - mem_0_3.RW0A <= RW0A - node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) - mem_0_3.RW0I <= bits(RW0I, 19, 18) - mem_0_3.RW0M <= bits(RW0M, 1, 1) - mem_0_3.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_3.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_3, cat(RW0O_0_2, cat(RW0O_0_1, RW0O_0_0))) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ inst mem_0_2 of vendor_sram + //~ inst mem_0_3 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 7, 0) + //~ mem_0_0.RW0M <= bits(RW0M, 0, 0) + //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 9, 8) + //~ mem_0_1.RW0M <= bits(RW0M, 0, 0) + //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_2.clock <= clock + //~ mem_0_2.RW0A <= RW0A + //~ node RW0O_0_2 = bits(mem_0_2.RW0O, 7, 0) + //~ mem_0_2.RW0I <= bits(RW0I, 17, 10) + //~ mem_0_2.RW0M <= bits(RW0M, 1, 1) + //~ mem_0_2.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_3.clock <= clock + //~ mem_0_3.RW0A <= RW0A + //~ node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) + //~ mem_0_3.RW0I <= bits(RW0I, 19, 18) + //~ mem_0_3.RW0M <= bits(RW0M, 1, 1) + //~ mem_0_3.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_3.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_3, cat(RW0O_0_2, cat(RW0O_0_1, RW0O_0_0))) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth24x52 extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-24x52-r-w.json") - val lib = new File(macroDir, "lib-32x32-2rw.json") - val v = new File(testDir, "split_width_24x52.v") - val output = -""" -circuit entries_info_ext : - module entries_info_ext : - input R0_clk : Clock - input R0_addr : UInt<5> - output R0_data : UInt<52> - input R0_en : UInt<1> - input W0_clk : Clock - input W0_addr : UInt<5> - input W0_data : UInt<52> - input W0_en : UInt<1> +//~ class SplitWidth24x52 extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-24x52-r-w.json") + //~ val lib = new File(macroDir, "lib-32x32-2rw.json") + //~ val v = new File(testDir, "split_width_24x52.v") + //~ val output = +//~ """ +//~ circuit entries_info_ext : + //~ module entries_info_ext : + //~ input R0_clk : Clock + //~ input R0_addr : UInt<5> + //~ output R0_data : UInt<52> + //~ input R0_en : UInt<1> + //~ input W0_clk : Clock + //~ input W0_addr : UInt<5> + //~ input W0_data : UInt<52> + //~ input W0_en : UInt<1> - inst mem_0_0 of SRAM2RW32x32 - inst mem_0_1 of SRAM2RW32x32 - mem_0_0.CE1 <= W0_clk - mem_0_0.A1 <= W0_addr - mem_0_0.I1 <= bits(W0_data, 31, 0) - mem_0_0.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.WEB1 <= not(and(and(UInt<1>("h1"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.CSB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_1.CE1 <= W0_clk - mem_0_1.A1 <= W0_addr - mem_0_1.I1 <= bits(W0_data, 51, 32) - mem_0_1.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.WEB1 <= not(and(and(UInt<1>("h1"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.CSB1 <= not(and(W0_en, UInt<1>("h1"))) - mem_0_0.CE2 <= R0_clk - mem_0_0.A2 <= R0_addr - node R0_data_0_0 = bits(mem_0_0.O2, 31, 0) - mem_0_0.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_0.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_0.CSB2 <= not(and(R0_en, UInt<1>("h1"))) - mem_0_1.CE2 <= R0_clk - mem_0_1.A2 <= R0_addr - node R0_data_0_1 = bits(mem_0_1.O2, 19, 0) - mem_0_1.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) - mem_0_1.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) - mem_0_1.CSB2 <= not(and(R0_en, UInt<1>("h1"))) - node R0_data_0 = cat(R0_data_0_1, R0_data_0_0) - R0_data <= mux(UInt<1>("h1"), R0_data_0, UInt<1>("h0")) + //~ inst mem_0_0 of SRAM2RW32x32 + //~ inst mem_0_1 of SRAM2RW32x32 + //~ mem_0_0.CE1 <= W0_clk + //~ mem_0_0.A1 <= W0_addr + //~ mem_0_0.I1 <= bits(W0_data, 31, 0) + //~ mem_0_0.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.WEB1 <= not(and(and(UInt<1>("h1"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.CSB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_1.CE1 <= W0_clk + //~ mem_0_1.A1 <= W0_addr + //~ mem_0_1.I1 <= bits(W0_data, 51, 32) + //~ mem_0_1.OEB1 <= not(and(not(UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.WEB1 <= not(and(and(UInt<1>("h1"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.CSB1 <= not(and(W0_en, UInt<1>("h1"))) + //~ mem_0_0.CE2 <= R0_clk + //~ mem_0_0.A2 <= R0_addr + //~ node R0_data_0_0 = bits(mem_0_0.O2, 31, 0) + //~ mem_0_0.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_0.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_0.CSB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ mem_0_1.CE2 <= R0_clk + //~ mem_0_1.A2 <= R0_addr + //~ node R0_data_0_1 = bits(mem_0_1.O2, 19, 0) + //~ mem_0_1.OEB2 <= not(and(not(UInt<1>("h0")), UInt<1>("h1"))) + //~ mem_0_1.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1"))) + //~ mem_0_1.CSB2 <= not(and(R0_en, UInt<1>("h1"))) + //~ node R0_data_0 = cat(R0_data_0_1, R0_data_0_0) + //~ R0_data <= mux(UInt<1>("h1"), R0_data_0, UInt<1>("h0")) - extmodule SRAM2RW32x32 : - input CE1 : Clock - input A1 : UInt<5> - input I1 : UInt<32> - output O1 : UInt<32> - input CSB1 : UInt<1> - input OEB1 : UInt<1> - input WEB1 : UInt<1> - input CE2 : Clock - input A2 : UInt<5> - input I2 : UInt<32> - output O2 : UInt<32> - input CSB2 : UInt<1> - input OEB2 : UInt<1> - input WEB2 : UInt<1> + //~ extmodule SRAM2RW32x32 : + //~ input CE1 : Clock + //~ input A1 : UInt<5> + //~ input I1 : UInt<32> + //~ output O1 : UInt<32> + //~ input CSB1 : UInt<1> + //~ input OEB1 : UInt<1> + //~ input WEB1 : UInt<1> + //~ input CE2 : Clock + //~ input A2 : UInt<5> + //~ input I2 : UInt<32> + //~ output O2 : UInt<32> + //~ input CSB2 : UInt<1> + //~ input OEB2 : UInt<1> + //~ input WEB2 : UInt<1> - defname = SRAM2RW32x32 -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = SRAM2RW32x32 +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } -class SplitWidth32x160 extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-32x160-mrw.json") - val lib = new File(macroDir, "lib-32x80-mrw.json") - val v = new File(testDir, "split_width_32x160.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<5> - input RW0I : UInt<160> - output RW0O : UInt<160> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<8> +//~ class SplitWidth32x160 extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-32x160-mrw.json") + //~ val lib = new File(macroDir, "lib-32x80-mrw.json") + //~ val v = new File(testDir, "split_width_32x160.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<5> + //~ input RW0I : UInt<160> + //~ output RW0O : UInt<160> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<8> - inst mem_0_0 of vendor_sram - inst mem_0_1 of vendor_sram - mem_0_0.clock <= clock - mem_0_0.RW0A <= RW0A - node RW0O_0_0 = bits(mem_0_0.RW0O, 79, 0) - mem_0_0.RW0I <= bits(RW0I, 79, 0) - mem_0_0.RW0M <= cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) - mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) - mem_0_1.clock <= clock - mem_0_1.RW0A <= RW0A - node RW0O_0_1 = bits(mem_0_1.RW0O, 79, 0) - mem_0_1.RW0I <= bits(RW0I, 159, 80) - mem_0_1.RW0M <= cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), bits(RW0M, 4, 4)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) - mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) - mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) - node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) - RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) + //~ inst mem_0_0 of vendor_sram + //~ inst mem_0_1 of vendor_sram + //~ mem_0_0.clock <= clock + //~ mem_0_0.RW0A <= RW0A + //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 79, 0) + //~ mem_0_0.RW0I <= bits(RW0I, 79, 0) + //~ mem_0_0.RW0M <= cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 3, 3), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 2, 2), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 1, 1), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), cat(bits(RW0M, 0, 0), bits(RW0M, 0, 0)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) + //~ mem_0_1.clock <= clock + //~ mem_0_1.RW0A <= RW0A + //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 79, 0) + //~ mem_0_1.RW0I <= bits(RW0I, 159, 80) + //~ mem_0_1.RW0M <= cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 7, 7), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 6, 6), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 5, 5), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), cat(bits(RW0M, 4, 4), bits(RW0M, 4, 4)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) + //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) + //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) + //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) + //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) - extmodule vendor_sram : - input clock : Clock - input RW0A : UInt<5> - input RW0I : UInt<80> - output RW0O : UInt<80> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<80> + //~ extmodule vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<5> + //~ input RW0I : UInt<80> + //~ output RW0O : UInt<80> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<80> - defname = vendor_sram -""" - compile(mem, Some(lib), v, false) - execute(Some(mem), Some(lib), false, output) -} + //~ defname = vendor_sram +//~ """ + //~ compile(mem, Some(lib), v, false) + //~ execute(Some(mem), Some(lib), false, output) +//~ } diff --git a/tapeout/src/test/scala/transforms/macros/SynFlops.scala b/tapeout/src/test/scala/transforms/macros/SynFlops.scala index 981e5e8d..2b3ff531 100644 --- a/tapeout/src/test/scala/transforms/macros/SynFlops.scala +++ b/tapeout/src/test/scala/transforms/macros/SynFlops.scala @@ -1,333 +1,333 @@ -package barstools.tapeout.transforms.macros +//~ package barstools.tapeout.transforms.macros -import java.io.File +//~ import java.io.File -class Synflops2048x16_mrw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x16-mrw.json") - val v = new File(testDir, "syn_flops_2048x16_mrw.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<2> +//~ class Synflops2048x16_mrw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x16-mrw.json") + //~ val v = new File(testDir, "syn_flops_2048x16_mrw.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<2> - mem ram : - data-type => UInt<8>[2] - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= RW0E - RW0O <= cat(ram.R_0.data[1], ram.R_0.data[0]) - R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= RW0A - ram.W_0.en <= and(RW0E, RW0W) - ram.W_0.data[0] <= bits(RW0I, 7, 0) - ram.W_0.data[1] <= bits(RW0I, 15, 8) - ram.W_0.mask[0] <= bits(RW0M, 0, 0) - ram.W_0.mask[1] <= bits(RW0M, 1, 1) -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<8>[2] + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= RW0E + //~ RW0O <= cat(ram.R_0.data[1], ram.R_0.data[0]) + //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= RW0A + //~ ram.W_0.en <= and(RW0E, RW0W) + //~ ram.W_0.data[0] <= bits(RW0I, 7, 0) + //~ ram.W_0.data[1] <= bits(RW0I, 15, 8) + //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0) + //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1) +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ } -class Synflops2048x8_r_mw extends MacroCompilerSpec { - val mem = new File(macroDir, "mem-2048x8-r-mw.json") - val v = new File(testDir, "syn_flops_2048x8_r_mw.v") - val output = -""" -circuit name_of_sram_module : - module name_of_sram_module : - input clock : Clock - input W0A : UInt<11> - input W0I : UInt<8> - input W0E : UInt<1> - input W0M : UInt<1> - input clock : Clock - input R0A : UInt<11> - output R0O : UInt<8> +//~ class Synflops2048x8_r_mw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "mem-2048x8-r-mw.json") + //~ val v = new File(testDir, "syn_flops_2048x8_r_mw.v") + //~ val output = +//~ """ +//~ circuit name_of_sram_module : + //~ module name_of_sram_module : + //~ input clock : Clock + //~ input W0A : UInt<11> + //~ input W0I : UInt<8> + //~ input W0E : UInt<1> + //~ input W0M : UInt<1> + //~ input clock : Clock + //~ input R0A : UInt<11> + //~ output R0O : UInt<8> - mem ram : - data-type => UInt<8>[1] - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= UInt<1>("h1") - R0O <= ram.R_0.data[0] - R_0_addr_reg <= mux(UInt<1>("h1"), R0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= W0A - ram.W_0.en <= W0E - ram.W_0.data[0] <= bits(W0I, 7, 0) - ram.W_0.mask[0] <= bits(W0M, 0, 0) -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<8>[1] + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= UInt<1>("h1") + //~ R0O <= ram.R_0.data[0] + //~ R_0_addr_reg <= mux(UInt<1>("h1"), R0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= W0A + //~ ram.W_0.en <= W0E + //~ ram.W_0.data[0] <= bits(W0I, 7, 0) + //~ ram.W_0.mask[0] <= bits(W0M, 0, 0) +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ } -class Synflops2048x10_rw extends MacroCompilerSpec { - val mem = new File(macroDir, "lib-2048x10-rw.json") - val v = new File(testDir, "syn_flops_2048x10_rw.v") - val output = -""" -circuit vendor_sram : - module vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<10> - output RW0O : UInt<10> - input RW0E : UInt<1> - input RW0W : UInt<1> +//~ class Synflops2048x10_rw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "lib-2048x10-rw.json") + //~ val v = new File(testDir, "syn_flops_2048x10_rw.v") + //~ val output = +//~ """ +//~ circuit vendor_sram : + //~ module vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<10> + //~ output RW0O : UInt<10> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> - mem ram : - data-type => UInt<10> - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= RW0E - RW0O <= ram.R_0.data - R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= RW0A - ram.W_0.en <= and(RW0E, RW0W) - ram.W_0.data <= RW0I - ram.W_0.mask <= UInt<1>("h1") -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<10> + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= RW0E + //~ RW0O <= ram.R_0.data + //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= RW0A + //~ ram.W_0.en <= and(RW0E, RW0W) + //~ ram.W_0.data <= RW0I + //~ ram.W_0.mask <= UInt<1>("h1") +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ } -class Synflops2048x8_mrw_re extends MacroCompilerSpec { - val mem = new File(macroDir, "lib-2048x8-mrw-re.json") - val v = new File(testDir, "syn_flops_2048x8_mrw_re.v") - val output = -""" -circuit vendor_sram : - module vendor_sram : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<8> - output RW0O : UInt<8> - input RW0E : UInt<1> - input RW0R : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<1> +//~ class Synflops2048x8_mrw_re extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "lib-2048x8-mrw-re.json") + //~ val v = new File(testDir, "syn_flops_2048x8_mrw_re.v") + //~ val output = +//~ """ +//~ circuit vendor_sram : + //~ module vendor_sram : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<8> + //~ output RW0O : UInt<8> + //~ input RW0E : UInt<1> + //~ input RW0R : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<1> - mem ram : - data-type => UInt<8>[1] - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= and(RW0E, not(RW0R)) - RW0O <= ram.R_0.data[0] - R_0_addr_reg <= mux(and(RW0E, not(RW0R)), RW0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= RW0A - ram.W_0.en <= and(RW0E, RW0W) - ram.W_0.data[0] <= bits(RW0I, 7, 0) - ram.W_0.mask[0] <= bits(RW0M, 0, 0) -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<8>[1] + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= and(RW0E, not(RW0R)) + //~ RW0O <= ram.R_0.data[0] + //~ R_0_addr_reg <= mux(and(RW0E, not(RW0R)), RW0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= RW0A + //~ ram.W_0.en <= and(RW0E, RW0W) + //~ ram.W_0.data[0] <= bits(RW0I, 7, 0) + //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0) +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ } -class Synflops2048x16_n28 extends MacroCompilerSpec { - val mem = new File(macroDir, "lib-2048x16-n28.json") - val v = new File(testDir, "syn_flops_2048x16_n28.v") - val output = -""" -circuit vendor_sram_4 : - module vendor_sram_16 : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<16> - output RW0O : UInt<16> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<16> +//~ class Synflops2048x16_n28 extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "lib-2048x16-n28.json") + //~ val v = new File(testDir, "syn_flops_2048x16_n28.v") + //~ val output = +//~ """ +//~ circuit vendor_sram_4 : + //~ module vendor_sram_16 : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<16> + //~ output RW0O : UInt<16> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<16> - mem ram : - data-type => UInt<1>[16] - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= RW0E - RW0O <= cat(ram.R_0.data[15], cat(ram.R_0.data[14], cat(ram.R_0.data[13], cat(ram.R_0.data[12], cat(ram.R_0.data[11], cat(ram.R_0.data[10], cat(ram.R_0.data[9], cat(ram.R_0.data[8], cat(ram.R_0.data[7], cat(ram.R_0.data[6], cat(ram.R_0.data[5], cat(ram.R_0.data[4], cat(ram.R_0.data[3], cat(ram.R_0.data[2], cat(ram.R_0.data[1], ram.R_0.data[0]))))))))))))))) - R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= RW0A - ram.W_0.en <= and(RW0E, RW0W) - ram.W_0.data[0] <= bits(RW0I, 0, 0) - ram.W_0.data[1] <= bits(RW0I, 1, 1) - ram.W_0.data[2] <= bits(RW0I, 2, 2) - ram.W_0.data[3] <= bits(RW0I, 3, 3) - ram.W_0.data[4] <= bits(RW0I, 4, 4) - ram.W_0.data[5] <= bits(RW0I, 5, 5) - ram.W_0.data[6] <= bits(RW0I, 6, 6) - ram.W_0.data[7] <= bits(RW0I, 7, 7) - ram.W_0.data[8] <= bits(RW0I, 8, 8) - ram.W_0.data[9] <= bits(RW0I, 9, 9) - ram.W_0.data[10] <= bits(RW0I, 10, 10) - ram.W_0.data[11] <= bits(RW0I, 11, 11) - ram.W_0.data[12] <= bits(RW0I, 12, 12) - ram.W_0.data[13] <= bits(RW0I, 13, 13) - ram.W_0.data[14] <= bits(RW0I, 14, 14) - ram.W_0.data[15] <= bits(RW0I, 15, 15) - ram.W_0.mask[0] <= bits(RW0M, 0, 0) - ram.W_0.mask[1] <= bits(RW0M, 1, 1) - ram.W_0.mask[2] <= bits(RW0M, 2, 2) - ram.W_0.mask[3] <= bits(RW0M, 3, 3) - ram.W_0.mask[4] <= bits(RW0M, 4, 4) - ram.W_0.mask[5] <= bits(RW0M, 5, 5) - ram.W_0.mask[6] <= bits(RW0M, 6, 6) - ram.W_0.mask[7] <= bits(RW0M, 7, 7) - ram.W_0.mask[8] <= bits(RW0M, 8, 8) - ram.W_0.mask[9] <= bits(RW0M, 9, 9) - ram.W_0.mask[10] <= bits(RW0M, 10, 10) - ram.W_0.mask[11] <= bits(RW0M, 11, 11) - ram.W_0.mask[12] <= bits(RW0M, 12, 12) - ram.W_0.mask[13] <= bits(RW0M, 13, 13) - ram.W_0.mask[14] <= bits(RW0M, 14, 14) - ram.W_0.mask[15] <= bits(RW0M, 15, 15) + //~ mem ram : + //~ data-type => UInt<1>[16] + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= RW0E + //~ RW0O <= cat(ram.R_0.data[15], cat(ram.R_0.data[14], cat(ram.R_0.data[13], cat(ram.R_0.data[12], cat(ram.R_0.data[11], cat(ram.R_0.data[10], cat(ram.R_0.data[9], cat(ram.R_0.data[8], cat(ram.R_0.data[7], cat(ram.R_0.data[6], cat(ram.R_0.data[5], cat(ram.R_0.data[4], cat(ram.R_0.data[3], cat(ram.R_0.data[2], cat(ram.R_0.data[1], ram.R_0.data[0]))))))))))))))) + //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= RW0A + //~ ram.W_0.en <= and(RW0E, RW0W) + //~ ram.W_0.data[0] <= bits(RW0I, 0, 0) + //~ ram.W_0.data[1] <= bits(RW0I, 1, 1) + //~ ram.W_0.data[2] <= bits(RW0I, 2, 2) + //~ ram.W_0.data[3] <= bits(RW0I, 3, 3) + //~ ram.W_0.data[4] <= bits(RW0I, 4, 4) + //~ ram.W_0.data[5] <= bits(RW0I, 5, 5) + //~ ram.W_0.data[6] <= bits(RW0I, 6, 6) + //~ ram.W_0.data[7] <= bits(RW0I, 7, 7) + //~ ram.W_0.data[8] <= bits(RW0I, 8, 8) + //~ ram.W_0.data[9] <= bits(RW0I, 9, 9) + //~ ram.W_0.data[10] <= bits(RW0I, 10, 10) + //~ ram.W_0.data[11] <= bits(RW0I, 11, 11) + //~ ram.W_0.data[12] <= bits(RW0I, 12, 12) + //~ ram.W_0.data[13] <= bits(RW0I, 13, 13) + //~ ram.W_0.data[14] <= bits(RW0I, 14, 14) + //~ ram.W_0.data[15] <= bits(RW0I, 15, 15) + //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0) + //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1) + //~ ram.W_0.mask[2] <= bits(RW0M, 2, 2) + //~ ram.W_0.mask[3] <= bits(RW0M, 3, 3) + //~ ram.W_0.mask[4] <= bits(RW0M, 4, 4) + //~ ram.W_0.mask[5] <= bits(RW0M, 5, 5) + //~ ram.W_0.mask[6] <= bits(RW0M, 6, 6) + //~ ram.W_0.mask[7] <= bits(RW0M, 7, 7) + //~ ram.W_0.mask[8] <= bits(RW0M, 8, 8) + //~ ram.W_0.mask[9] <= bits(RW0M, 9, 9) + //~ ram.W_0.mask[10] <= bits(RW0M, 10, 10) + //~ ram.W_0.mask[11] <= bits(RW0M, 11, 11) + //~ ram.W_0.mask[12] <= bits(RW0M, 12, 12) + //~ ram.W_0.mask[13] <= bits(RW0M, 13, 13) + //~ ram.W_0.mask[14] <= bits(RW0M, 14, 14) + //~ ram.W_0.mask[15] <= bits(RW0M, 15, 15) - module vendor_sram_4 : - input clock : Clock - input RW0A : UInt<11> - input RW0I : UInt<4> - output RW0O : UInt<4> - input RW0E : UInt<1> - input RW0W : UInt<1> - input RW0M : UInt<4> + //~ module vendor_sram_4 : + //~ input clock : Clock + //~ input RW0A : UInt<11> + //~ input RW0I : UInt<4> + //~ output RW0O : UInt<4> + //~ input RW0E : UInt<1> + //~ input RW0W : UInt<1> + //~ input RW0M : UInt<4> - mem ram : - data-type => UInt<1>[4] - depth => 2048 - read-latency => 0 - write-latency => 1 - reader => R_0 - writer => W_0 - read-under-write => undefined - reg R_0_addr_reg : UInt<11>, clock with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= clock - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= RW0E - RW0O <= cat(ram.R_0.data[3], cat(ram.R_0.data[2], cat(ram.R_0.data[1], ram.R_0.data[0]))) - R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) - ram.W_0.clk <= clock - ram.W_0.addr <= RW0A - ram.W_0.en <= and(RW0E, RW0W) - ram.W_0.data[0] <= bits(RW0I, 0, 0) - ram.W_0.data[1] <= bits(RW0I, 1, 1) - ram.W_0.data[2] <= bits(RW0I, 2, 2) - ram.W_0.data[3] <= bits(RW0I, 3, 3) - ram.W_0.mask[0] <= bits(RW0M, 0, 0) - ram.W_0.mask[1] <= bits(RW0M, 1, 1) - ram.W_0.mask[2] <= bits(RW0M, 2, 2) - ram.W_0.mask[3] <= bits(RW0M, 3, 3) -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<1>[4] + //~ depth => 2048 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ writer => W_0 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<11>, clock with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= clock + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= RW0E + //~ RW0O <= cat(ram.R_0.data[3], cat(ram.R_0.data[2], cat(ram.R_0.data[1], ram.R_0.data[0]))) + //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) + //~ ram.W_0.clk <= clock + //~ ram.W_0.addr <= RW0A + //~ ram.W_0.en <= and(RW0E, RW0W) + //~ ram.W_0.data[0] <= bits(RW0I, 0, 0) + //~ ram.W_0.data[1] <= bits(RW0I, 1, 1) + //~ ram.W_0.data[2] <= bits(RW0I, 2, 2) + //~ ram.W_0.data[3] <= bits(RW0I, 3, 3) + //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0) + //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1) + //~ ram.W_0.mask[2] <= bits(RW0M, 2, 2) + //~ ram.W_0.mask[3] <= bits(RW0M, 3, 3) +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ } -class Synflops32x32_2rw extends MacroCompilerSpec { - val mem = new File(macroDir, "lib-32x32-2rw.json") - val v = new File(testDir, "syn_flops_32x32_2rw.v") - val output = -""" -circuit SRAM2RW32x32 : - module SRAM2RW32x32 : - input CE1 : Clock - input A1 : UInt<5> - input I1 : UInt<32> - output O1 : UInt<32> - input CSB1 : UInt<1> - input OEB1 : UInt<1> - input WEB1 : UInt<1> - input CE2 : Clock - input A2 : UInt<5> - input I2 : UInt<32> - output O2 : UInt<32> - input CSB2 : UInt<1> - input OEB2 : UInt<1> - input WEB2 : UInt<1> +//~ class Synflops32x32_2rw extends MacroCompilerSpec { + //~ val mem = new File(macroDir, "lib-32x32-2rw.json") + //~ val v = new File(testDir, "syn_flops_32x32_2rw.v") + //~ val output = +//~ """ +//~ circuit SRAM2RW32x32 : + //~ module SRAM2RW32x32 : + //~ input CE1 : Clock + //~ input A1 : UInt<5> + //~ input I1 : UInt<32> + //~ output O1 : UInt<32> + //~ input CSB1 : UInt<1> + //~ input OEB1 : UInt<1> + //~ input WEB1 : UInt<1> + //~ input CE2 : Clock + //~ input A2 : UInt<5> + //~ input I2 : UInt<32> + //~ output O2 : UInt<32> + //~ input CSB2 : UInt<1> + //~ input OEB2 : UInt<1> + //~ input WEB2 : UInt<1> - mem ram : - data-type => UInt<32> - depth => 32 - read-latency => 0 - write-latency => 1 - reader => R_0 - reader => R_1 - writer => W_0 - writer => W_1 - read-under-write => undefined - reg R_0_addr_reg : UInt<5>, CE1 with : - reset => (UInt<1>("h0"), R_0_addr_reg) - ram.R_0.clk <= CE1 - ram.R_0.addr <= R_0_addr_reg - ram.R_0.en <= and(not(CSB1), not(OEB1)) - O1 <= ram.R_0.data - R_0_addr_reg <= mux(and(not(CSB1), not(OEB1)), A1, R_0_addr_reg) - reg R_1_addr_reg : UInt<5>, CE2 with : - reset => (UInt<1>("h0"), R_1_addr_reg) - ram.R_1.clk <= CE2 - ram.R_1.addr <= R_1_addr_reg - ram.R_1.en <= and(not(CSB2), not(OEB2)) - O2 <= ram.R_1.data - R_1_addr_reg <= mux(and(not(CSB2), not(OEB2)), A2, R_1_addr_reg) - ram.W_0.clk <= CE1 - ram.W_0.addr <= A1 - ram.W_0.en <= and(not(CSB1), not(WEB1)) - ram.W_0.data <= I1 - ram.W_0.mask <= UInt<1>("h1") - ram.W_1.clk <= CE2 - ram.W_1.addr <= A2 - ram.W_1.en <= and(not(CSB2), not(WEB2)) - ram.W_1.data <= I2 - ram.W_1.mask <= UInt<1>("h1") -""" - compile(mem, None, v, true) - execute(Some(mem), None, true, output) -} + //~ mem ram : + //~ data-type => UInt<32> + //~ depth => 32 + //~ read-latency => 0 + //~ write-latency => 1 + //~ reader => R_0 + //~ reader => R_1 + //~ writer => W_0 + //~ writer => W_1 + //~ read-under-write => undefined + //~ reg R_0_addr_reg : UInt<5>, CE1 with : + //~ reset => (UInt<1>("h0"), R_0_addr_reg) + //~ ram.R_0.clk <= CE1 + //~ ram.R_0.addr <= R_0_addr_reg + //~ ram.R_0.en <= and(not(CSB1), not(OEB1)) + //~ O1 <= ram.R_0.data + //~ R_0_addr_reg <= mux(and(not(CSB1), not(OEB1)), A1, R_0_addr_reg) + //~ reg R_1_addr_reg : UInt<5>, CE2 with : + //~ reset => (UInt<1>("h0"), R_1_addr_reg) + //~ ram.R_1.clk <= CE2 + //~ ram.R_1.addr <= R_1_addr_reg + //~ ram.R_1.en <= and(not(CSB2), not(OEB2)) + //~ O2 <= ram.R_1.data + //~ R_1_addr_reg <= mux(and(not(CSB2), not(OEB2)), A2, R_1_addr_reg) + //~ ram.W_0.clk <= CE1 + //~ ram.W_0.addr <= A1 + //~ ram.W_0.en <= and(not(CSB1), not(WEB1)) + //~ ram.W_0.data <= I1 + //~ ram.W_0.mask <= UInt<1>("h1") + //~ ram.W_1.clk <= CE2 + //~ ram.W_1.addr <= A2 + //~ ram.W_1.en <= and(not(CSB2), not(WEB2)) + //~ ram.W_1.data <= I2 + //~ ram.W_1.mask <= UInt<1>("h1") +//~ """ + //~ compile(mem, None, v, true) + //~ execute(Some(mem), None, true, output) +//~ }