Port to MDF library and start re-developing tests

This commit is contained in:
Edward Wang
2017-07-19 19:18:42 -07:00
committed by edwardcwang
parent 57b0fec78e
commit c79ea47909
12 changed files with 1640 additions and 1469 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "mdf"]
path = mdf
url = https://github.com/edwardcwang/plsi-mdf.git

View File

@@ -15,11 +15,18 @@ val defaultVersions = Map(
"chisel-iotesters" -> "1.2-SNAPSHOT" "chisel-iotesters" -> "1.2-SNAPSHOT"
) )
lazy val mdf = RootProject(file("mdf/scalalib"))
lazy val tapeout = (project in file("tapeout")) lazy val tapeout = (project in file("tapeout"))
.dependsOn(mdf)
.settings(commonSettings) .settings(commonSettings)
.settings( .settings(
libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { libraryDependencies ++= Seq("chisel3","chisel-iotesters").map {
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) 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")) .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls"))

1
mdf Submodule

Submodule mdf added at 89c15682aa

View File

@@ -8,19 +8,20 @@ import firrtl.PrimOps
import firrtl.Utils._ import firrtl.Utils._
import firrtl.annotations._ import firrtl.annotations._
import firrtl.CompilerUtils.getLoweringTransforms import firrtl.CompilerUtils.getLoweringTransforms
import mdf.macrolib.{PolarizedPort, PortPolarity}
import scala.collection.mutable.{ArrayBuffer, HashMap} import scala.collection.mutable.{ArrayBuffer, HashMap}
import java.io.{File, FileWriter} import java.io.{File, FileWriter}
import Utils._ import Utils._
object MacroCompilerAnnotation { 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], Annotation(CircuitName(c), classOf[MacroCompilerTransform],
s"${mem} %s ${synflops}".format(lib map (_.toString) getOrElse "")) s"${mem} %s ${synflops}".format(lib map (_.toString) getOrElse ""))
} }
private val matcher = "([^ ]+) ([^ ]*) (true|false)".r private val matcher = "([^ ]+) ([^ ]*) (true|false)".r
def unapply(a: Annotation) = a match { def unapply(a: Annotation) = a match {
case Annotation(CircuitName(c), t, matcher(mem, lib, synflops)) if t == classOf[MacroCompilerTransform] => 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 case _ => None
} }
} }
@@ -33,11 +34,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Parallel mapping // Parallel mapping
val pairs = ArrayBuffer[(BigInt, BigInt)]() val pairs = ArrayBuffer[(BigInt, BigInt)]()
var last = 0 var last = 0
for (i <- 0 until mem.width.toInt) { for (i <- 0 until mem.src.width) {
if (i <= last + 1) { if (i <= last + 1) {
/* Palmer: Every memory is going to have to fit at least a single bit. */ /* Palmer: Every memory is going to have to fit at least a single bit. */
// continue // 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, /* Palmer: It's possible that we rolled over a memory's width here,
if so generate one. */ if so generate one. */
pairs += ((last, i-1)) pairs += ((last, i-1))
@@ -45,13 +46,13 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
} else { } else {
/* Palmer: FIXME: This is a mess, I must just be super confused. */ /* Palmer: FIXME: This is a mess, I must just be super confused. */
for ((memPort, libPort) <- pairedPorts) { 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 p == 1 => // continue
case (Some(p), _) if i % p == 0 => case (Some(p), _) if i % p == 0 =>
pairs += ((last, i-1)) pairs += ((last, i-1))
last = i last = i
case (_, None) => // continue case (_, None) => // continue
case (_, Some(p)) if p == lib.width => // continue case (_, Some(p)) if p == lib.src.width => // continue
case _ => case _ =>
System.err println "Bit-mask (or unmasked) target memories are supported only" System.err println "Bit-mask (or unmasked) target memories are supported only"
return None 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 // Serial mapping
val stmts = ArrayBuffer[Statement]() val stmts = ArrayBuffer[Statement]()
@@ -67,27 +68,27 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
val outputs = HashMap[String, ArrayBuffer[(Expression, Expression)]]() val outputs = HashMap[String, ArrayBuffer[(Expression, Expression)]]()
/* Palmer: If we've got a parallel memory then we've got to take the /* Palmer: If we've got a parallel memory then we've got to take the
* address bits into account. */ * address bits into account. */
if (mem.depth > lib.depth) { if (mem.src.depth > lib.src.depth) {
mem.ports foreach { port => mem.src.ports foreach { port =>
val high = ceilLog2(mem.depth) val high = ceilLog2(mem.src.depth)
val low = ceilLog2(lib.depth) val low = ceilLog2(lib.src.depth)
val ref = WRef(port.addressName) val ref = WRef(port.address.name)
val name = s"${ref.name}_sel" val name = s"${ref.name}_sel"
selects(ref.name) = WRef(name, UIntType(IntWidth(high-low))) selects(ref.name) = WRef(name, UIntType(IntWidth(high-low)))
stmts += DefNode(NoInfo, name, bits(ref, high-1, 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) { for (j <- pairs.indices) {
val name = s"mem_${i}_${j}" 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 // connect extra ports
stmts ++= lib.extraPorts map { case (portName, portValue) => stmts ++= lib.extraPorts map { case (portName, portValue) =>
Connect(NoInfo, WSubField(WRef(name), portName), portValue) Connect(NoInfo, WSubField(WRef(name), portName), portValue)
} }
} }
for ((memPort, libPort) <- pairedPorts) { for ((memPort, libPort) <- pairedPorts) {
val addrMatch = selects get memPort.addressName match { val addrMatch = selects get memPort.src.address.name match {
case None => one case None => one
case Some(addr) => case Some(addr) =>
val index = UIntLiteral(i, IntWidth(bitWidth(addr.tpe))) val index = UIntLiteral(i, IntWidth(bitWidth(addr.tpe)))
@@ -98,33 +99,37 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
for (((low, high), j) <- pairs.zipWithIndex) { for (((low, high), j) <- pairs.zipWithIndex) {
val inst = WRef(s"mem_${i}_${j}", lib.tpe) val inst = WRef(s"mem_${i}_${j}", lib.tpe)
def connectPorts(mem: Expression, def connectPorts2(mem: Expression,
lib: String, lib: String,
polarity: Option[PortPolarity]): Statement = 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 // Clock port mapping
/* Palmer: FIXME: I don't handle memories with read/write clocks yet. */ /* Palmer: FIXME: I don't handle memories with read/write clocks yet. */
stmts += connectPorts(WRef(memPort.clockName), stmts += connectPorts(WRef(memPort.src.clock.name),
libPort.clockName, libPort.src.clock.name,
libPort.clockPolarity) libPort.src.clock.polarity)
// Adress port mapping // Adress port mapping
/* Palmer: The address port to a memory is just the low-order bits of /* Palmer: The address port to a memory is just the low-order bits of
* the top address. */ * the top address. */
stmts += connectPorts(WRef(memPort.addressName), stmts += connectPorts(WRef(memPort.src.address.name),
libPort.addressName, libPort.src.address.name,
libPort.addressPolarity) libPort.src.address.polarity)
// Output port mapping // Output port mapping
(memPort.outputName, libPort.outputName) match { (memPort.src.output, libPort.src.output) match {
case (Some(mem), Some(lib)) => case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) =>
/* Palmer: In order to produce the output of a memory we need to cat /* Palmer: In order to produce the output of a memory we need to cat
* together a bunch of narrower memories, which can only be * together a bunch of narrower memories, which can only be
* done after generating all the memories. This saves up the * done after generating all the memories. This saves up the
* output statements for later. */ * output statements for later. */
val name = s"${mem}_${i}_${j}" 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) stmts += DefNode(NoInfo, name, exp)
cats += WRef(name) cats += WRef(name)
case (None, Some(lib)) => 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 /* Palmer: If there's no output ports at all (ie, read-only
* port on the memory) then just don't worry about it, * port on the memory) then just don't worry about it,
* there's nothing to do. */ * 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 "WARNING: Unable to match output ports on memory"
System.err println s" outer output port: ${mem}" System.err println s" outer output port: ${mem}"
return None return None
} }
// Input port mapping // Input port mapping
(memPort.inputName, libPort.inputName) match { (memPort.src.input, libPort.src.input) match {
case (Some(mem), Some(lib)) => case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) =>
/* Palmer: The input port to a memory just needs to happen in parallel, /* Palmer: The input port to a memory just needs to happen in parallel,
* this does a part select to narrow the memory down. */ * 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)) => case (None, Some(lib)) =>
/* Palmer: If the inner memory has an input port but the other /* Palmer: If the inner memory has an input port but the other
* one doesn't then it's safe to just leave the inner * 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 /* Palmer: If there's no input ports at all (ie, read-only
* port on the memory) then just don't worry about it, * port on the memory) then just don't worry about it,
* there's nothing to do. */ * 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 "WARNING: Unable to match input ports on memory"
System.err println s" outer input port: ${mem}" System.err println s" outer input port: ${mem}"
return None return None
} }
// Mask port mapping // Mask port mapping
val memMask = memPort.maskName match { val memMask = memPort.src.maskPort match {
case Some(mem) => case Some(PolarizedPort(mem, _)) =>
/* Palmer: The bits from the outer memory's write mask that will be /* Palmer: The bits from the outer memory's write mask that will be
* used as the write mask for this inner memory. */ * used as the write mask for this inner memory. */
if (libPort.effectiveMaskGran == libPort.width) { if (libPort.src.effectiveMaskGran == libPort.src.width) {
bits(WRef(mem), low / memPort.effectiveMaskGran) bits(WRef(mem), low / memPort.src.effectiveMaskGran)
} else { } else {
if (libPort.effectiveMaskGran != 1) { if (libPort.src.effectiveMaskGran != 1) {
// TODO // TODO
System.err println "only single-bit mask supported" System.err println "only single-bit mask supported"
return None 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 => case None =>
/* Palmer: If there is no input port on the source memory port /* Palmer: If there is no input port on the source memory port
* then we don't ever want to turn on this write * then we don't ever want to turn on this write
* enable. Otherwise, we just _always_ turn on the * enable. Otherwise, we just _always_ turn on the
* write enable port on the inner memory. */ * write enable port on the inner memory. */
if (!libPort.maskName.isDefined) one if (libPort.src.maskPort.isEmpty) one
else { else {
val width = libPort.width / libPort.effectiveMaskGran val width = libPort.src.width / libPort.src.effectiveMaskGran
val value = (BigInt(1) << width.toInt) - 1 val value = (BigInt(1) << width.toInt) - 1
UIntLiteral(value, IntWidth(width)) UIntLiteral(value, IntWidth(width))
} }
} }
// Write enable port mapping // Write enable port mapping
val memWriteEnable = memPort.writeEnableName match { val memWriteEnable = memPort.src.writeEnable match {
case Some(mem) => case Some(PolarizedPort(mem, _)) =>
/* Palmer: The outer memory's write enable port, or a constant 1 if /* Palmer: The outer memory's write enable port, or a constant 1 if
* there isn't a write enable port. */ * there isn't a write enable port. */
WRef(mem) WRef(mem)
@@ -202,60 +207,65 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* then we don't ever want to turn on this write * then we don't ever want to turn on this write
* enable. Otherwise, we just _always_ turn on the * enable. Otherwise, we just _always_ turn on the
* write enable port on the inner memory. */ * 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 // Chip enable port mapping
val memChipEnable = memPort.chipEnableName match { val memChipEnable = memPort.src.chipEnable match {
case Some(mem) => WRef(mem) case Some(PolarizedPort(mem, _)) => WRef(mem)
case None => one case None => one
} }
// Read enable port mapping // Read enable port mapping
/* Palmer: It's safe to ignore read enables, but we pass them through /* 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 * to the vendor memory if there's a port on there that
* implements the read enables. */ * implements the read enables. */
(memPort.readEnableName, libPort.readEnableName) match { (memPort.src.readEnable, libPort.src.readEnable) match {
case (_, None) => case (_, None) =>
case (Some(mem), Some(lib)) => case (Some(PolarizedPort(mem, _)), Some(PolarizedPort(lib, lib_polarity))) =>
stmts += connectPorts(andAddrMatch(WRef(mem)), lib, libPort.readEnablePolarity) stmts += connectPorts(andAddrMatch(WRef(mem)), lib, lib_polarity)
case (None, Some(lib)) => case (None, Some(PolarizedPort(lib, lib_polarity))) =>
stmts += connectPorts(andAddrMatch(not(memWriteEnable)), lib, libPort.readEnablePolarity) stmts += connectPorts(andAddrMatch(not(memWriteEnable)), lib, lib_polarity)
} }
/* Palmer: This is actually the memory compiler: it figures out how to /* Palmer: This is actually the memory compiler: it figures out how to
* implement the outer memory's collection of ports using what * implement the outer memory's collection of ports using what
* the inner memory has availiable. */ * the inner memory has availiable. */
((libPort.maskName, libPort.writeEnableName, libPort.chipEnableName): @unchecked) match { ((libPort.src.maskPort, libPort.src.writeEnable, libPort.src.chipEnable): @unchecked) match {
case (Some(mask), Some(we), Some(en)) => 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. */ /* Palmer: This is the simple option: every port exists. */
stmts += connectPorts(memMask, mask, libPort.maskPolarity) stmts += connectPorts(memMask, mask, mask_polarity)
stmts += connectPorts(andAddrMatch(memWriteEnable), we, libPort.writeEnablePolarity) stmts += connectPorts(andAddrMatch(memWriteEnable), we, we_polarity)
stmts += connectPorts(andAddrMatch(memChipEnable), en, libPort.chipEnablePolarity) stmts += connectPorts(andAddrMatch(memChipEnable), en, en_polarity)
case (Some(mask), Some(we), None) => case (Some(PolarizedPort(mask, mask_polarity)), Some(PolarizedPort(we, we_polarity)), None) =>
/* Palmer: If we don't have a chip enable but do have */ /* Palmer: If we don't have a chip enable but do have mask ports. */
stmts += connectPorts(memMask, mask, libPort.maskPolarity) stmts += connectPorts(memMask, mask, mask_polarity)
stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)), stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)),
we, libPort.writeEnablePolarity) we, mask_polarity)
case (None, Some(we), Some(en)) if bitWidth(memMask.tpe) == 1 => case (None, Some(PolarizedPort(we, we_polarity)), chipEnable) if bitWidth(memMask.tpe) == 1 =>
/* Palmer: If we're expected to provide mask ports without a /* Palmer: If we're expected to provide mask ports without a
* memory that actually has them then we can use the * memory that actually has them then we can use the
* write enable port instead of the mask port. */ * write enable port instead of the mask port. */
stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)), stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)),
we, libPort.writeEnablePolarity) we, we_polarity)
stmts += connectPorts(andAddrMatch(memChipEnable), en, libPort.chipEnablePolarity) chipEnable match {
case (None, Some(we), Some(en)) => 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 // 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 return None
case (None, None, None) => case (None, None, None) =>
/* Palmer: There's nothing to do here since there aren't any /* 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 // Cat macro outputs for selection
memPort.outputName match { memPort.src.output match {
case Some(mem) if cats.nonEmpty => case Some(PolarizedPort(mem, _)) if cats.nonEmpty =>
val name = s"${mem}_${i}" val name = s"${mem}_${i}"
stmts += DefNode(NoInfo, name, cat(cats.toSeq.reverse)) stmts += DefNode(NoInfo, name, cat(cats.toSeq.reverse))
(outputs getOrElseUpdate (mem, ArrayBuffer[(Expression, Expression)]())) += (outputs getOrElseUpdate (mem, ArrayBuffer[(Expression, Expression)]())) +=
@@ -265,9 +275,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
} }
} }
// Connect mem outputs // Connect mem outputs
mem.ports foreach { port => mem.src.ports foreach { port =>
port.outputName match { port.output match {
case Some(mem) => outputs get mem match { case Some(PolarizedPort(mem, _)) => outputs get mem match {
case Some(select) => case Some(select) =>
val output = (select foldRight (zero: Expression)) { val output = (select foldRight (zero: Expression)) {
case ((cond, tval), fval) => Mux(cond, tval, fval, fval.tpe) } 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 { val modules = (mems, libs) match {
case (Some(mems), Some(libs)) => (mems foldLeft c.modules){ (modules, mem) => case (Some(mems), Some(libs)) => (mems foldLeft c.modules){ (modules, mem) =>
val (best, cost) = (libs foldLeft (None: Option[(Module, ExtModule)], BigInt(Long.MaxValue))){ 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 /* Palmer: FIXME: This just assumes the Chisel and vendor ports are in the same
* order, but I'm starting with what actually gets generated. */ * 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) (best, area)
case ((best, area), lib) => case ((best, area), lib) =>
/* Palmer: A quick cost function (that must be kept in sync with /* 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) + // val cost = 100 * (mem.depth * mem.width) / (lib.depth * lib.width) +
// (mem.depth * mem.width) // (mem.depth * mem.width)
// Donggyu: I re-define cost // Donggyu: I re-define cost
val cost = (((mem.depth - 1) / lib.depth) + 1) * val cost = (((mem.src.depth - 1) / lib.src.depth) + 1) *
(((mem.width - 1) / lib.width) + 1) * (((mem.src.width - 1) / lib.src.width) + 1) *
(lib.depth * lib.width + 1) // weights on # cells (lib.src.depth * lib.src.width + 1) // weights on # cells
System.err println s"Cost of ${lib.name} for ${mem.name}: ${cost}" System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${cost}")
if (cost > area) (best, area) if (cost > area) (best, area)
else compile(mem, lib) match { else compile(mem, lib) match {
case None => (best, area) case None => (best, area)
@@ -326,8 +336,17 @@ class MacroCompilerTransform extends Transform {
def execute(state: CircuitState) = getMyAnnotations(state) match { def execute(state: CircuitState) = getMyAnnotations(state) match {
case Seq(MacroCompilerAnnotation(state.circuit.main, memFile, libFile, synflops)) => case Seq(MacroCompilerAnnotation(state.circuit.main, memFile, libFile, synflops)) =>
require(memFile.isDefined) require(memFile.isDefined)
val mems: Option[Seq[Macro]] = readJSON(memFile) map (_ map (x => new Macro(x))) // Read, eliminate None, get only SRAM, make firrtl macro
val libs: Option[Seq[Macro]] = readJSON(libFile) map (_ map (x => new Macro(x))) 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( val transforms = Seq(
new MacroCompilerPass(mems, libs), new MacroCompilerPass(mems, libs),
new SynFlopsPass(synflops, libs getOrElse mems.get), new SynFlopsPass(synflops, libs getOrElse mems.get),
@@ -349,24 +368,24 @@ object MacroCompiler extends App {
sealed trait MacroParam sealed trait MacroParam
case object Macros extends MacroParam case object Macros extends MacroParam
case object Library extends MacroParam case object Library extends MacroParam
case object Verilog extends MacroParam case object Verilog extends MacroParam
type MacroParamMap = Map[MacroParam, File] type MacroParamMap = Map[MacroParam, String]
val usage = Seq( val usage = Seq(
"Options:", "Options:",
" -m, --macro-list: The set of macros to compile", " -m, --macro-list: The set of macros to compile",
" -l, --library: The set of macros that have blackbox instances", " -l, --library: The set of macros that have blackbox instances",
" -v, --verilog: Verilog output", " -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) = def parseArgs(map: MacroParamMap, synflops: Boolean, args: List[String]): (MacroParamMap, Boolean) =
args match { args match {
case Nil => (map, synflops) case Nil => (map, synflops)
case ("-m" | "--macro-list") :: value :: tail => 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 => case ("-l" | "--library") :: value :: tail =>
parseArgs(map + (Library -> new File(value)), synflops, tail) parseArgs(map + (Library -> value), synflops, tail)
case ("-v" | "--verilog") :: value :: tail => case ("-v" | "--verilog") :: value :: tail =>
parseArgs(map + (Verilog -> new File(value)), synflops, tail) parseArgs(map + (Verilog -> value), synflops, tail)
case "--syn-flops" :: tail => case "--syn-flops" :: tail =>
parseArgs(map, true, tail) parseArgs(map, true, tail)
case arg :: tail => case arg :: tail =>
@@ -375,18 +394,29 @@ object MacroCompiler extends App {
} }
def run(args: List[String]) { def run(args: List[String]) {
val (params, synflops) = parseArgs(Map[MacroParam, File](), false, args) val (params, synflops) = parseArgs(Map[MacroParam, String](), false, args)
try { try {
val macros = readJSON(params get Macros).get map (x => (new Macro(x)).blackbox) val macros = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
val verilog = new FileWriter(params(Verilog))
// Open the writer for the output Verilog file.
val verilogWriter = new FileWriter(new File(params.get(Verilog).get))
if (macros.nonEmpty) { if (macros.nonEmpty) {
val circuit = Circuit(NoInfo, macros, macros.last.name) val circuit = Circuit(NoInfo, macros, macros.last.name)
val annotations = AnnotationMap(Seq(MacroCompilerAnnotation( 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 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 { } catch {
case e: java.util.NoSuchElementException => case e: java.util.NoSuchElementException =>
throw new Exception(usage) throw new Exception(usage)

View File

@@ -9,9 +9,9 @@ import firrtl.passes.MemPortUtils.{memPortField, memType}
import Utils._ import Utils._
class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass { class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass {
lazy val libMods = (libs map { lib => lib.name -> { lazy val libMods = (libs map { lib => lib.src.name -> {
val dataType = (lib.ports foldLeft (None: Option[BigInt]))((res, port) => val dataType = (lib.src.ports foldLeft (None: Option[BigInt]))((res, port) =>
(res, port.maskName) match { (res, port.maskPort) match {
case (_, None) => case (_, None) =>
res res
case (None, Some(_)) => case (None, Some(_)) =>
@@ -21,15 +21,15 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
res res
} }
) match { ) match {
case None => UIntType(IntWidth(lib.width)) case None => UIntType(IntWidth(lib.src.width))
case Some(gran) => VectorType(UIntType(IntWidth(gran)), (lib.width / gran).toInt) case Some(gran) => VectorType(UIntType(IntWidth(gran)), (lib.src.width / gran).toInt)
} }
val mem = DefMemory( val mem = DefMemory(
NoInfo, NoInfo,
"ram", "ram",
dataType, dataType,
lib.depth.toInt, lib.src.depth,
1, // writeLatency 1, // writeLatency
0, // readLatency 0, // readLatency
(lib.readers ++ lib.readwriters).indices map (i => s"R_$i"), (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 readConnects = (lib.readers ++ lib.readwriters).zipWithIndex flatMap { case (r, i) =>
val clock = invert(WRef(r.clockName), r.clockPolarity) val clock = portToExpression(r.src.clock)
val address = invert(WRef(r.addressName), r.addressPolarity) val address = portToExpression(r.src.address)
val enable = (r.chipEnableName, r.readEnableName) match { val enable = (r.src chipEnable, r.src readEnable) match {
case (Some(en), Some(re)) => case (Some(en_port), Some(re_port)) =>
and(invert(WRef(en), r.chipEnablePolarity), and(portToExpression(en_port),
invert(WRef(re), r.readEnablePolarity)) portToExpression(re_port))
case (Some(en), None) => invert(WRef(en), r.chipEnablePolarity) case (Some(en_port), None) => portToExpression(en_port)
case (None, Some(re)) => invert(WRef(re), r.readEnablePolarity) case (None, Some(re_port)) => portToExpression(re_port)
case (None, None) => one case (None, None) => one
} }
val data = memPortField(mem, s"R_$i", "data") 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", "clk"), clock),
Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), addrReg), Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), addrReg),
Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable), 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)) Connect(NoInfo, addrReg, Mux(enable, address, addrReg, UnknownType))
) )
} }
val writeConnects = (lib.writers ++ lib.readwriters).zipWithIndex flatMap { case (w, i) => val writeConnects = (lib.writers ++ lib.readwriters).zipWithIndex flatMap { case (w, i) =>
val clock = invert(WRef(w.clockName), w.clockPolarity) val clock = portToExpression(w.src.clock)
val address = invert(WRef(w.addressName), w.addressPolarity) val address = portToExpression(w.src.address)
val enable = (w.chipEnableName, w.writeEnableName) match { val enable = (w.src.chipEnable, w.src.writeEnable) match {
case (Some(en), Some(we)) => case (Some(en), Some(we)) =>
and(invert(WRef(en), w.chipEnablePolarity), and(portToExpression(en),
invert(WRef(we), w.writeEnablePolarity)) portToExpression(we))
case (Some(en), None) => invert(WRef(en), w.chipEnablePolarity) case (Some(en), None) => portToExpression(en)
case (None, Some(we)) => invert(WRef(we), w.writeEnablePolarity) case (None, Some(we)) => portToExpression(we)
case (None, None) => zero // is it possible? case (None, None) => zero // is it possible?
} }
val mask = memPortField(mem, s"W_$i", "mask") val mask = memPortField(mem, s"W_$i", "mask")
val data = memPortField(mem, s"W_$i", "data") 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( Seq(
Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock), Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock),
Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address), 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)))) ++ bits(write, (k + 1) * width - 1, k * width)))) ++
((0 until size) map (k => ((0 until size) map (k =>
Connect(NoInfo, WSubIndex(mask, k, BoolType, UNKNOWNGENDER), Connect(NoInfo, WSubIndex(mask, k, BoolType, UNKNOWNGENDER),
bits(WRef(w.maskName.get), k)))) bits(WRef(w.src.maskPort.get.name), k))))
case _: UIntType => case _: UIntType =>
Seq(Connect(NoInfo, data, write), Connect(NoInfo, mask, one)) Seq(Connect(NoInfo, data, write), Connect(NoInfo, mask, one))
}) })

View File

@@ -6,133 +6,70 @@ import firrtl._
import firrtl.ir._ import firrtl.ir._
import firrtl.PrimOps import firrtl.PrimOps
import firrtl.Utils.{ceilLog2, BoolType} 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 java.io.File
import scala.language.implicitConversions import scala.language.implicitConversions
trait PortPolarity class FirrtlMacroPort(port: MacroPort) {
case object ActiveLow extends PortPolarity val src = port
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
}
case class MacroPort( val isReader = !port.readEnable.isEmpty && port.writeEnable.isEmpty
clockName: String, val isWriter = !port.writeEnable.isEmpty && port.readEnable.isEmpty
clockPolarity: Option[PortPolarity], val isReadWriter = !port.writeEnable.isEmpty && !port.readEnable.isEmpty
addressName: String,
addressPolarity: Option[PortPolarity], val AddrType = UIntType(IntWidth(ceilLog2(port.depth) max 1))
inputName: Option[String], val DataType = UIntType(IntWidth(port.width))
inputPolarity: Option[PortPolarity], val MaskType = UIntType(IntWidth(port.width / port.effectiveMaskGran))
outputName: Option[String],
outputPolarity: Option[PortPolarity], // Bundle representing this macro port.
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 tpe = BundleType(Seq( val tpe = BundleType(Seq(
Field(clockName, Flip, ClockType), Field(port.clock.name, Flip, ClockType),
Field(addressName, Flip, addrType)) ++ Field(port.address.name, Flip, AddrType)) ++
(inputName map (Field(_, Flip, dataType))) ++ (port.input map (p => Field(p.name, Flip, DataType))) ++
(outputName map (Field(_, Default, dataType))) ++ (port.output map (p => Field(p.name, Default, DataType))) ++
(chipEnableName map (Field(_, Flip, BoolType))) ++ (port.chipEnable map (p => Field(p.name, Flip, BoolType))) ++
(readEnableName map (Field(_, Flip, BoolType))) ++ (port.readEnable map (p => Field(p.name, Flip, BoolType))) ++
(writeEnableName map (Field(_, Flip, BoolType))) ++ (port.writeEnable map (p => Field(p.name, Flip, BoolType))) ++
(maskName map (Field(_, Flip, maskType))) (port.maskPort map (p => Field(p.name, Flip, MaskType)))
) )
val ports = tpe.fields map (f => Port( val ports = tpe.fields map (f => Port(
NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe)) NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe))
} }
class Macro(lib: Map[String, Any]) { // Reads an SRAMMacro and generates firrtl blackboxes.
val name = lib("name").asInstanceOf[String] class Macro(srcMacro: SRAMMacro) {
val width = BigInt(lib("width").asInstanceOf[Double].toLong) val src = srcMacro
val depth = BigInt(lib("depth").asInstanceOf[Double].toLong)
val ports = lib("ports").asInstanceOf[List[_]] map { x => val firrtlPorts = srcMacro.ports map { new FirrtlMacroPort(_) }
val map = x.asInstanceOf[Map[String, Any]]
MacroPort( val writers = firrtlPorts filter (p => p.isReader)
map("clock port name").asInstanceOf[String], val readers = firrtlPorts filter (p => p.isWriter)
map get "clock port polarity", val readwriters = firrtlPorts filter (p => p.isReadWriter)
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)
val sortedPorts = writers ++ readers ++ readwriters val sortedPorts = writers ++ readers ++ readwriters
val extraPorts = lib get "extra ports" match { val extraPorts = srcMacro.extraPorts map { p =>
case None => Nil assert(p.portType == Constant) // TODO: release it?
case Some(p) => p.asInstanceOf[List[_]] map { x => val name = p.name
val map = x.asInstanceOf[Map[String, Any]] val width = BigInt(p.width.asInstanceOf[Double].toLong)
assert(map("type").asInstanceOf[String] == "constant") // TODO: release it? val value = BigInt(p.value.asInstanceOf[Double].toLong)
val name = map("name").asInstanceOf[String] (name -> UIntLiteral(value, IntWidth(width)))
val width = BigInt(map("width").asInstanceOf[Double].toLong)
val value = BigInt(map("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) }) (extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
val blackbox = ExtModule(NoInfo, name, modPorts, name, Nil) val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil)
def module(body: Statement) = Module(NoInfo, name, modPorts, body) def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body)
} }
object Utils { object Utils {
def readJSON(file: Option[File]): Option[Seq[Map[String, Any]]] = file match { def filterForSRAM(s: Option[Seq[mdf.macrolib.Macro]]): Option[Seq[mdf.macrolib.SRAMMacro]] = {
case None => None s match {
case Some(f) => try { case Some(l:Seq[mdf.macrolib.Macro]) => Some(l filter { _.macroType == mdf.macrolib.SRAM } map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] })
(JSON parseFull io.Source.fromFile(f).mkString) match { case _ => None
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)
} }
} }
@@ -147,7 +84,11 @@ object Utils {
def not(e: Expression) = def not(e: Expression) =
DoPrim(PrimOps.Not, Seq(e), Nil, e.tpe) 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 { polarity match {
case Some(ActiveLow) | Some(NegativeEdge) => not(exp) case Some(ActiveLow) | Some(NegativeEdge) => not(exp)
case _ => exp case _ => exp

View File

@@ -4,6 +4,7 @@
"name": "vendor_sram", "name": "vendor_sram",
"depth": 1024, "depth": 1024,
"width": 8, "width": 8,
"family": "1rw",
"ports": [ "ports": [
{ {
"clock port name": "clock", "clock port name": "clock",

View File

@@ -4,6 +4,7 @@
"name": "name_of_sram_module", "name": "name_of_sram_module",
"depth": 2048, "depth": 2048,
"width": 8, "width": 8,
"family": "1rw",
"ports": [ "ports": [
{ {
"clock port name": "clock", "clock port name": "clock",

View File

@@ -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.ir.{Circuit, NoInfo}
import firrtl.passes.RemoveEmpty import firrtl.passes.RemoveEmpty
import firrtl.Parser.parse import firrtl.Parser.parse
import java.io.{File, StringWriter} 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 { abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalatest.Matchers {
val macroDir = new File("tapeout/src/test/resources/macros") val macroDir: String = "tapeout/src/test/resources/macros"
val testDir = new File("test_run_dir/macros") ; testDir.mkdirs 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) = // Override these to change the prefixing of macroDir and testDir
List("-m", mem.toString, "-v", v.toString) ++ 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) }) ++ (lib match { case None => Nil case Some(l) => List("-l", l.toString) }) ++
(if (synflops) List("--syn-flops") else Nil) (if (synflops) List("--syn-flops") else Nil)
def compile(mem: File, lib: Option[File], v: File, synflops: Boolean) { // Run the full compiler as if from the command line interface.
MacroCompiler.run(args(mem, lib, v, synflops)) // 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) require(memFile.isDefined)
val mems = readJSON(memFile) map (_ map (x => new Macro(x))) val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get map (new Macro(_))
val libs = readJSON(libFile) map (_ map (x => new Macro(x))) val libs: Option[Seq[Macro]] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(lib_full)) match {
val macros = mems.get map (_.blackbox) 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 circuit = Circuit(NoInfo, macros, macros.last.name)
val passes = Seq( val passes = Seq(
new MacroCompilerPass(mems, libs), new MacroCompilerPass(Some(mems), libs),
new SynFlopsPass(synflops, libs getOrElse mems.get), new SynFlopsPass(synflops, libs getOrElse mems),
RemoveEmpty) RemoveEmpty)
val result = (passes foldLeft circuit)((c, pass) => pass run c) val result = (passes foldLeft circuit)((c, pass) => pass run c)
val gold = RemoveEmpty run parse(output) val gold = RemoveEmpty run parse(output)
(result.serialize) should be (gold.serialize) (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 { trait HasSRAMGenerator {
val mem = new File(macroDir, "rocketchip.json") import mdf.macrolib._
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 // Generate a "simple" SRAM (active high/positive edge, 1 read-write port).
inst mem_0_1 of SRAM1RW64x32 def generateSRAM(name: String, prefix: String, width: Int, depth: Int, maskGran: Option[Int] = None): SRAMMacro = {
inst mem_0_2 of SRAM1RW64x32 val realPrefix = prefix + "_"
inst mem_0_3 of SRAM1RW64x32 SRAMMacro(
mem_0_0.CE <= RW0_clk macroType=SRAM,
mem_0_0.A <= RW0_addr name=name,
node RW0_rdata_0_0 = bits(mem_0_0.O, 19, 0) width=width,
mem_0_0.I <= bits(RW0_wdata, 19, 0) depth=depth,
mem_0_0.OEB <= not(and(not(RW0_wmode), UInt<1>("h1"))) family="1rw",
mem_0_0.WEB <= not(and(and(RW0_wmode, bits(RW0_wmask, 0, 0)), UInt<1>("h1"))) ports=Seq(MacroPort(
mem_0_0.CEB <= not(and(RW0_en, UInt<1>("h1"))) address=PolarizedPort(name=realPrefix + "addr", polarity=ActiveHigh),
mem_0_1.CE <= RW0_clk clock=PolarizedPort(name=realPrefix + "clk", polarity=PositiveEdge),
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 : writeEnable=Some(PolarizedPort(name=realPrefix + "write_en", polarity=ActiveHigh)),
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 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 : width=width, depth=depth // These numbers don't matter here.
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)
} }
//~ 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)
//~ }

View File

@@ -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 { class SplitDepth2048x8_mrw extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x8-mrw.json") val mem = "mem-2048x8-mrw.json"
val lib = new File(macroDir, "lib-1024x8-mrw.json") val lib = "lib-1024x8-mrw.json"
val v = new File(testDir, "split_depth_2048x8_mrw.v") val v = "split_depth_2048x8_mrw.v"
val output = val output =
""" """
circuit name_of_sram_module : circuit name_of_sram_module :
@@ -50,226 +210,174 @@ circuit name_of_sram_module :
defname = vendor_sram defname = vendor_sram
""" """
compile(mem, Some(lib), v, false) compile(mem, lib, v, false)
execute(Some(mem), Some(lib), false, output) execute(mem, lib, false, output)
} }
class SplitDepth2000x8_mrw extends MacroCompilerSpec { //~ class SplitDepth2048x8_n28 extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2000x8-mrw.json") //~ val mem = new File(macroDir, "mem-2048x8-mrw.json")
val lib = new File(macroDir, "lib-1024x8-mrw.json") //~ val lib = new File(macroDir, "lib-1024x8-n28.json")
val v = new File(testDir, "split_depth_2000x8_mrw.v") //~ val v = new File(testDir, "split_depth_2048x8_n28.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
node RW0A_sel = bits(RW0A, 10, 10) //~ node RW0A_sel = bits(RW0A, 10, 10)
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.RW0I <= bits(RW0I, 7, 0)
mem_0_0.RW0M <= bits(RW0M, 0, 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.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0")))
mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) //~ mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0")))
node RW0O_0 = RW0O_0_0 //~ node RW0O_0 = RW0O_0_0
inst mem_1_0 of vendor_sram //~ inst mem_1_0 of vendor_sram
mem_1_0.clock <= clock //~ mem_1_0.clock <= clock
mem_1_0.RW0A <= RW0A //~ mem_1_0.RW0A <= RW0A
node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) //~ node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0)
mem_1_0.RW0I <= bits(RW0I, 7, 0) //~ mem_1_0.RW0I <= bits(RW0I, 7, 0)
mem_1_0.RW0M <= bits(RW0M, 0, 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.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1")))
mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) //~ mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1")))
node RW0O_1 = RW0O_1_0 //~ 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"))) //~ 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 : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<10> //~ input RW0A : UInt<10>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<8>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, lib, v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(mem, lib, false, output)
} //~ }
class SplitDepth2048x8_n28 extends MacroCompilerSpec { //~ class SplitDepth2048x8_r_mw extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x8-mrw.json") //~ val mem = new File(macroDir, "mem-2048x8-r-mw.json")
val lib = new File(macroDir, "lib-1024x8-n28.json") //~ val lib = new File(macroDir, "lib-1024x8-r-mw.json")
val v = new File(testDir, "split_depth_2048x8_n28.v") //~ val v = new File(testDir, "split_depth_2048x8_r_mw.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input W0A : UInt<11>
input RW0I : UInt<8> //~ input W0I : UInt<8>
output RW0O : UInt<8> //~ input W0E : UInt<1>
input RW0E : UInt<1> //~ input W0M : UInt<1>
input RW0W : UInt<1> //~ input clock : Clock
input RW0M : UInt<1> //~ input R0A : UInt<11>
//~ output R0O : UInt<8>
node RW0A_sel = bits(RW0A, 10, 10) //~ node W0A_sel = bits(W0A, 10, 10)
inst mem_0_0 of vendor_sram //~ node R0A_sel = bits(R0A, 10, 10)
mem_0_0.clock <= clock //~ inst mem_0_0 of vendor_sram
mem_0_0.RW0A <= RW0A //~ mem_0_0.clock <= clock
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ mem_0_0.W0A <= W0A
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.W0I <= bits(W0I, 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.W0M <= bits(W0M, 0, 0)
mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) //~ mem_0_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h0")))
mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) //~ mem_0_0.W0E <= and(W0E, eq(W0A_sel, UInt<1>("h0")))
node RW0O_0 = RW0O_0_0 //~ mem_0_0.clock <= clock
inst mem_1_0 of vendor_sram //~ mem_0_0.R0A <= R0A
mem_1_0.clock <= clock //~ node R0O_0_0 = bits(mem_0_0.R0O, 7, 0)
mem_1_0.RW0A <= RW0A //~ node R0O_0 = R0O_0_0
node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) //~ inst mem_1_0 of vendor_sram
mem_1_0.RW0I <= bits(RW0I, 7, 0) //~ mem_1_0.clock <= clock
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.W0A <= W0A
mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) //~ mem_1_0.W0I <= bits(W0I, 7, 0)
mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) //~ mem_1_0.W0M <= bits(W0M, 0, 0)
node RW0O_1 = RW0O_1_0 //~ mem_1_0.W0W <= and(UInt<1>("h1"), eq(W0A_sel, UInt<1>("h1")))
RW0O <= mux(eq(RW0A_sel, UInt<1>("h0")), RW0O_0, mux(eq(RW0A_sel, UInt<1>("h1")), RW0O_1, UInt<1>("h0"))) //~ 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 : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<10> //~ input R0A : UInt<10>
input RW0I : UInt<8> //~ output R0O : UInt<8>
output RW0O : UInt<8> //~ input clock : Clock
input RW0E : UInt<1> //~ input W0A : UInt<10>
input RW0W : UInt<1> //~ input W0I : UInt<8>
input RW0M : UInt<8> //~ input W0E : UInt<1>
//~ input W0W : UInt<1>
//~ input W0M : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, lib, v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(mem, 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)
}
class SplitDepth2048x8_mrw_Sleep extends MacroCompilerSpec { //~ class SplitDepth2048x8_mrw_Sleep extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x8-mrw.json") //~ val mem = new File(macroDir, "mem-2048x8-mrw.json")
val lib = new File(macroDir, "lib-1024x8-sleep.json") //~ val lib = new File(macroDir, "lib-1024x8-sleep.json")
val v = new File(testDir, "split_depth_2048x8_sleep.v") //~ val v = new File(testDir, "split_depth_2048x8_sleep.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
node RW0A_sel = bits(RW0A, 10, 10) //~ node RW0A_sel = bits(RW0A, 10, 10)
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
mem_0_0.sleep <= UInt<1>("h0") //~ mem_0_0.sleep <= UInt<1>("h0")
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.RW0I <= bits(RW0I, 7, 0)
mem_0_0.RW0M <= bits(RW0M, 0, 0) //~ mem_0_0.RW0M <= bits(RW0M, 0, 0)
mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0"))) //~ mem_0_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h0")))
mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0"))) //~ mem_0_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h0")))
node RW0O_0 = RW0O_0_0 //~ node RW0O_0 = RW0O_0_0
inst mem_1_0 of vendor_sram //~ inst mem_1_0 of vendor_sram
mem_1_0.sleep <= UInt<1>("h0") //~ mem_1_0.sleep <= UInt<1>("h0")
mem_1_0.clock <= clock //~ mem_1_0.clock <= clock
mem_1_0.RW0A <= RW0A //~ mem_1_0.RW0A <= RW0A
node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0) //~ node RW0O_1_0 = bits(mem_1_0.RW0O, 7, 0)
mem_1_0.RW0I <= bits(RW0I, 7, 0) //~ mem_1_0.RW0I <= bits(RW0I, 7, 0)
mem_1_0.RW0M <= bits(RW0M, 0, 0) //~ mem_1_0.RW0M <= bits(RW0M, 0, 0)
mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1"))) //~ mem_1_0.RW0W <= and(RW0W, eq(RW0A_sel, UInt<1>("h1")))
mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1"))) //~ mem_1_0.RW0E <= and(RW0E, eq(RW0A_sel, UInt<1>("h1")))
node RW0O_1 = RW0O_1_0 //~ 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"))) //~ 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 : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<10> //~ input RW0A : UInt<10>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
input sleep : UInt<1> //~ input sleep : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, lib, v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(mem, lib, false, output)
} //~ }

View File

@@ -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 { //~ class SplitWidth2048x16_mrw extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw.json")
val lib = new File(macroDir, "lib-2048x8-mrw.json") //~ val lib = new File(macroDir, "lib-2048x8-mrw.json")
val v = new File(testDir, "split_width_2048x16_mrw.v") //~ val v = new File(testDir, "split_width_2048x16_mrw.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.RW0I <= bits(RW0I, 7, 0)
mem_0_0.RW0M <= bits(RW0M, 0, 0) //~ mem_0_0.RW0M <= bits(RW0M, 0, 0)
mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0)
mem_0_1.RW0I <= bits(RW0I, 15, 8) //~ mem_0_1.RW0I <= bits(RW0I, 15, 8)
mem_0_1.RW0M <= bits(RW0M, 1, 1) //~ mem_0_1.RW0M <= bits(RW0M, 1, 1)
mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0)
RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth2048x16_mrw_Uneven extends MacroCompilerSpec { //~ class SplitWidth2048x16_mrw_Uneven extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw.json")
val lib = new File(macroDir, "lib-2048x10-rw.json") //~ val lib = new File(macroDir, "lib-2048x10-rw.json")
val v = new File(testDir, "split_width_2048x16_mrw_uneven.v") //~ val v = new File(testDir, "split_width_2048x16_mrw_uneven.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 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.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0)
mem_0_1.RW0I <= bits(RW0I, 15, 8) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0)
RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<10> //~ input RW0I : UInt<10>
output RW0O : UInt<10> //~ output RW0O : UInt<10>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth2048x16_mrw_VeryUneven extends MacroCompilerSpec { //~ class SplitWidth2048x16_mrw_VeryUneven extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw-2.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw-2.json")
val lib = new File(macroDir, "lib-2048x10-rw.json") //~ val lib = new File(macroDir, "lib-2048x10-rw.json")
val v = new File(testDir, "split_width_2048x16_mrw_very_uneven.v") //~ val v = new File(testDir, "split_width_2048x16_mrw_very_uneven.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<8> //~ input RW0M : UInt<8>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
inst mem_0_2 of vendor_sram //~ inst mem_0_2 of vendor_sram
inst mem_0_3 of vendor_sram //~ inst mem_0_3 of vendor_sram
inst mem_0_4 of vendor_sram //~ inst mem_0_4 of vendor_sram
inst mem_0_5 of vendor_sram //~ inst mem_0_5 of vendor_sram
inst mem_0_6 of vendor_sram //~ inst mem_0_6 of vendor_sram
inst mem_0_7 of vendor_sram //~ inst mem_0_7 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 1, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 1, 0)
mem_0_0.RW0I <= bits(RW0I, 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.RW0W <= and(and(RW0W, bits(RW0M, 0, 0)), UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0)
mem_0_1.RW0I <= bits(RW0I, 3, 2) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 1, 1)), UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_2.clock <= clock //~ mem_0_2.clock <= clock
mem_0_2.RW0A <= RW0A //~ mem_0_2.RW0A <= RW0A
node RW0O_0_2 = bits(mem_0_2.RW0O, 1, 0) //~ node RW0O_0_2 = bits(mem_0_2.RW0O, 1, 0)
mem_0_2.RW0I <= bits(RW0I, 5, 4) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 2, 2)), UInt<1>("h1"))
mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_2.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_3.clock <= clock //~ mem_0_3.clock <= clock
mem_0_3.RW0A <= RW0A //~ mem_0_3.RW0A <= RW0A
node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) //~ node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0)
mem_0_3.RW0I <= bits(RW0I, 7, 6) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 3, 3)), UInt<1>("h1"))
mem_0_3.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_3.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_4.clock <= clock //~ mem_0_4.clock <= clock
mem_0_4.RW0A <= RW0A //~ mem_0_4.RW0A <= RW0A
node RW0O_0_4 = bits(mem_0_4.RW0O, 1, 0) //~ node RW0O_0_4 = bits(mem_0_4.RW0O, 1, 0)
mem_0_4.RW0I <= bits(RW0I, 9, 8) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 4, 4)), UInt<1>("h1"))
mem_0_4.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_4.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_5.clock <= clock //~ mem_0_5.clock <= clock
mem_0_5.RW0A <= RW0A //~ mem_0_5.RW0A <= RW0A
node RW0O_0_5 = bits(mem_0_5.RW0O, 1, 0) //~ node RW0O_0_5 = bits(mem_0_5.RW0O, 1, 0)
mem_0_5.RW0I <= bits(RW0I, 11, 10) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 5, 5)), UInt<1>("h1"))
mem_0_5.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_5.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_6.clock <= clock //~ mem_0_6.clock <= clock
mem_0_6.RW0A <= RW0A //~ mem_0_6.RW0A <= RW0A
node RW0O_0_6 = bits(mem_0_6.RW0O, 1, 0) //~ node RW0O_0_6 = bits(mem_0_6.RW0O, 1, 0)
mem_0_6.RW0I <= bits(RW0I, 13, 12) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 6, 6)), UInt<1>("h1"))
mem_0_6.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_6.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_7.clock <= clock //~ mem_0_7.clock <= clock
mem_0_7.RW0A <= RW0A //~ mem_0_7.RW0A <= RW0A
node RW0O_0_7 = bits(mem_0_7.RW0O, 1, 0) //~ node RW0O_0_7 = bits(mem_0_7.RW0O, 1, 0)
mem_0_7.RW0I <= bits(RW0I, 15, 14) //~ 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.RW0W <= and(and(RW0W, bits(RW0M, 7, 7)), UInt<1>("h1"))
mem_0_7.RW0E <= and(RW0E, 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))))))) //~ 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")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<10> //~ input RW0I : UInt<10>
output RW0O : UInt<10> //~ output RW0O : UInt<10>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth2048x16_mrw_ReadEnable extends MacroCompilerSpec { //~ class SplitWidth2048x16_mrw_ReadEnable extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw.json")
val lib = new File(macroDir, "lib-2048x8-mrw-re.json") //~ val lib = new File(macroDir, "lib-2048x8-mrw-re.json")
val v = new File(testDir, "split_width_2048x16_mrw_read_enable.v") //~ val v = new File(testDir, "split_width_2048x16_mrw_read_enable.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.RW0I <= bits(RW0I, 7, 0)
mem_0_0.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) //~ mem_0_0.RW0R <= not(and(not(RW0W), UInt<1>("h1")))
mem_0_0.RW0M <= bits(RW0M, 0, 0) //~ mem_0_0.RW0M <= bits(RW0M, 0, 0)
mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 7, 0)
mem_0_1.RW0I <= bits(RW0I, 15, 8) //~ mem_0_1.RW0I <= bits(RW0I, 15, 8)
mem_0_1.RW0R <= not(and(not(RW0W), UInt<1>("h1"))) //~ mem_0_1.RW0R <= not(and(not(RW0W), UInt<1>("h1")))
mem_0_1.RW0M <= bits(RW0M, 1, 1) //~ mem_0_1.RW0M <= bits(RW0M, 1, 1)
mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0)
RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0R : UInt<1> //~ input RW0R : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth2048x16_n28 extends MacroCompilerSpec { //~ class SplitWidth2048x16_n28 extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw.json")
val lib = new File(macroDir, "lib-2048x16-n28.json") //~ val lib = new File(macroDir, "lib-2048x16-n28.json")
val v = new File(testDir, "split_width_2048x16_n28.v") //~ val v = new File(testDir, "split_width_2048x16_n28.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
inst mem_0_0 of vendor_sram_16 //~ inst mem_0_0 of vendor_sram_16
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 15, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 15, 0)
mem_0_0.RW0I <= bits(RW0I, 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.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.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
node RW0O_0 = RW0O_0_0 //~ node RW0O_0 = RW0O_0_0
RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram_16 : //~ extmodule vendor_sram_16 :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<16> //~ input RW0M : UInt<16>
defname = vendor_sram_16 //~ defname = vendor_sram_16
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth2048x20_mrw_UnevenMask extends MacroCompilerSpec { //~ class SplitWidth2048x20_mrw_UnevenMask extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x20-mrw.json") //~ val mem = new File(macroDir, "mem-2048x20-mrw.json")
val lib = new File(macroDir, "lib-2048x8-mrw.json") //~ val lib = new File(macroDir, "lib-2048x8-mrw.json")
val v = new File(testDir, "split_width_2048x20_mrw_uneven_mask.v") //~ val v = new File(testDir, "split_width_2048x20_mrw_uneven_mask.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<20> //~ input RW0I : UInt<20>
output RW0O : UInt<20> //~ output RW0O : UInt<20>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
inst mem_0_2 of vendor_sram //~ inst mem_0_2 of vendor_sram
inst mem_0_3 of vendor_sram //~ inst mem_0_3 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 7, 0)
mem_0_0.RW0I <= bits(RW0I, 7, 0) //~ mem_0_0.RW0I <= bits(RW0I, 7, 0)
mem_0_0.RW0M <= bits(RW0M, 0, 0) //~ mem_0_0.RW0M <= bits(RW0M, 0, 0)
mem_0_0.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_0.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 1, 0)
mem_0_1.RW0I <= bits(RW0I, 9, 8) //~ mem_0_1.RW0I <= bits(RW0I, 9, 8)
mem_0_1.RW0M <= bits(RW0M, 0, 0) //~ mem_0_1.RW0M <= bits(RW0M, 0, 0)
mem_0_1.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_1.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_2.clock <= clock //~ mem_0_2.clock <= clock
mem_0_2.RW0A <= RW0A //~ mem_0_2.RW0A <= RW0A
node RW0O_0_2 = bits(mem_0_2.RW0O, 7, 0) //~ node RW0O_0_2 = bits(mem_0_2.RW0O, 7, 0)
mem_0_2.RW0I <= bits(RW0I, 17, 10) //~ mem_0_2.RW0I <= bits(RW0I, 17, 10)
mem_0_2.RW0M <= bits(RW0M, 1, 1) //~ mem_0_2.RW0M <= bits(RW0M, 1, 1)
mem_0_2.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_2.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_2.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_2.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_3.clock <= clock //~ mem_0_3.clock <= clock
mem_0_3.RW0A <= RW0A //~ mem_0_3.RW0A <= RW0A
node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0) //~ node RW0O_0_3 = bits(mem_0_3.RW0O, 1, 0)
mem_0_3.RW0I <= bits(RW0I, 19, 18) //~ mem_0_3.RW0I <= bits(RW0I, 19, 18)
mem_0_3.RW0M <= bits(RW0M, 1, 1) //~ mem_0_3.RW0M <= bits(RW0M, 1, 1)
mem_0_3.RW0W <= and(RW0W, UInt<1>("h1")) //~ mem_0_3.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_3.RW0E <= and(RW0E, 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))) //~ 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")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth24x52 extends MacroCompilerSpec { //~ class SplitWidth24x52 extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-24x52-r-w.json") //~ val mem = new File(macroDir, "mem-24x52-r-w.json")
val lib = new File(macroDir, "lib-32x32-2rw.json") //~ val lib = new File(macroDir, "lib-32x32-2rw.json")
val v = new File(testDir, "split_width_24x52.v") //~ val v = new File(testDir, "split_width_24x52.v")
val output = //~ val output =
""" //~ """
circuit entries_info_ext : //~ circuit entries_info_ext :
module entries_info_ext : //~ module entries_info_ext :
input R0_clk : Clock //~ input R0_clk : Clock
input R0_addr : UInt<5> //~ input R0_addr : UInt<5>
output R0_data : UInt<52> //~ output R0_data : UInt<52>
input R0_en : UInt<1> //~ input R0_en : UInt<1>
input W0_clk : Clock //~ input W0_clk : Clock
input W0_addr : UInt<5> //~ input W0_addr : UInt<5>
input W0_data : UInt<52> //~ input W0_data : UInt<52>
input W0_en : UInt<1> //~ input W0_en : UInt<1>
inst mem_0_0 of SRAM2RW32x32 //~ inst mem_0_0 of SRAM2RW32x32
inst mem_0_1 of SRAM2RW32x32 //~ inst mem_0_1 of SRAM2RW32x32
mem_0_0.CE1 <= W0_clk //~ mem_0_0.CE1 <= W0_clk
mem_0_0.A1 <= W0_addr //~ mem_0_0.A1 <= W0_addr
mem_0_0.I1 <= bits(W0_data, 31, 0) //~ 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.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.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_0.CSB1 <= not(and(W0_en, UInt<1>("h1")))
mem_0_1.CE1 <= W0_clk //~ mem_0_1.CE1 <= W0_clk
mem_0_1.A1 <= W0_addr //~ mem_0_1.A1 <= W0_addr
mem_0_1.I1 <= bits(W0_data, 51, 32) //~ 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.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.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_1.CSB1 <= not(and(W0_en, UInt<1>("h1")))
mem_0_0.CE2 <= R0_clk //~ mem_0_0.CE2 <= R0_clk
mem_0_0.A2 <= R0_addr //~ mem_0_0.A2 <= R0_addr
node R0_data_0_0 = bits(mem_0_0.O2, 31, 0) //~ 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.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.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_0.CSB2 <= not(and(R0_en, UInt<1>("h1")))
mem_0_1.CE2 <= R0_clk //~ mem_0_1.CE2 <= R0_clk
mem_0_1.A2 <= R0_addr //~ mem_0_1.A2 <= R0_addr
node R0_data_0_1 = bits(mem_0_1.O2, 19, 0) //~ 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.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.WEB2 <= not(and(and(UInt<1>("h0"), UInt<1>("h1")), UInt<1>("h1")))
mem_0_1.CSB2 <= not(and(R0_en, 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) //~ 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")) //~ R0_data <= mux(UInt<1>("h1"), R0_data_0, UInt<1>("h0"))
extmodule SRAM2RW32x32 : //~ extmodule SRAM2RW32x32 :
input CE1 : Clock //~ input CE1 : Clock
input A1 : UInt<5> //~ input A1 : UInt<5>
input I1 : UInt<32> //~ input I1 : UInt<32>
output O1 : UInt<32> //~ output O1 : UInt<32>
input CSB1 : UInt<1> //~ input CSB1 : UInt<1>
input OEB1 : UInt<1> //~ input OEB1 : UInt<1>
input WEB1 : UInt<1> //~ input WEB1 : UInt<1>
input CE2 : Clock //~ input CE2 : Clock
input A2 : UInt<5> //~ input A2 : UInt<5>
input I2 : UInt<32> //~ input I2 : UInt<32>
output O2 : UInt<32> //~ output O2 : UInt<32>
input CSB2 : UInt<1> //~ input CSB2 : UInt<1>
input OEB2 : UInt<1> //~ input OEB2 : UInt<1>
input WEB2 : UInt<1> //~ input WEB2 : UInt<1>
defname = SRAM2RW32x32 //~ defname = SRAM2RW32x32
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }
class SplitWidth32x160 extends MacroCompilerSpec { //~ class SplitWidth32x160 extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-32x160-mrw.json") //~ val mem = new File(macroDir, "mem-32x160-mrw.json")
val lib = new File(macroDir, "lib-32x80-mrw.json") //~ val lib = new File(macroDir, "lib-32x80-mrw.json")
val v = new File(testDir, "split_width_32x160.v") //~ val v = new File(testDir, "split_width_32x160.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<5> //~ input RW0A : UInt<5>
input RW0I : UInt<160> //~ input RW0I : UInt<160>
output RW0O : UInt<160> //~ output RW0O : UInt<160>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<8> //~ input RW0M : UInt<8>
inst mem_0_0 of vendor_sram //~ inst mem_0_0 of vendor_sram
inst mem_0_1 of vendor_sram //~ inst mem_0_1 of vendor_sram
mem_0_0.clock <= clock //~ mem_0_0.clock <= clock
mem_0_0.RW0A <= RW0A //~ mem_0_0.RW0A <= RW0A
node RW0O_0_0 = bits(mem_0_0.RW0O, 79, 0) //~ node RW0O_0_0 = bits(mem_0_0.RW0O, 79, 0)
mem_0_0.RW0I <= bits(RW0I, 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.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.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_0.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_0.RW0E <= and(RW0E, UInt<1>("h1"))
mem_0_1.clock <= clock //~ mem_0_1.clock <= clock
mem_0_1.RW0A <= RW0A //~ mem_0_1.RW0A <= RW0A
node RW0O_0_1 = bits(mem_0_1.RW0O, 79, 0) //~ node RW0O_0_1 = bits(mem_0_1.RW0O, 79, 0)
mem_0_1.RW0I <= bits(RW0I, 159, 80) //~ 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.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.RW0W <= and(RW0W, UInt<1>("h1"))
mem_0_1.RW0E <= and(RW0E, UInt<1>("h1")) //~ mem_0_1.RW0E <= and(RW0E, UInt<1>("h1"))
node RW0O_0 = cat(RW0O_0_1, RW0O_0_0) //~ node RW0O_0 = cat(RW0O_0_1, RW0O_0_0)
RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0")) //~ RW0O <= mux(UInt<1>("h1"), RW0O_0, UInt<1>("h0"))
extmodule vendor_sram : //~ extmodule vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<5> //~ input RW0A : UInt<5>
input RW0I : UInt<80> //~ input RW0I : UInt<80>
output RW0O : UInt<80> //~ output RW0O : UInt<80>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<80> //~ input RW0M : UInt<80>
defname = vendor_sram //~ defname = vendor_sram
""" //~ """
compile(mem, Some(lib), v, false) //~ compile(mem, Some(lib), v, false)
execute(Some(mem), Some(lib), false, output) //~ execute(Some(mem), Some(lib), false, output)
} //~ }

View File

@@ -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 { //~ class Synflops2048x16_mrw extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x16-mrw.json") //~ val mem = new File(macroDir, "mem-2048x16-mrw.json")
val v = new File(testDir, "syn_flops_2048x16_mrw.v") //~ val v = new File(testDir, "syn_flops_2048x16_mrw.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<2> //~ input RW0M : UInt<2>
mem ram : //~ mem ram :
data-type => UInt<8>[2] //~ data-type => UInt<8>[2]
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= RW0E //~ ram.R_0.en <= RW0E
RW0O <= cat(ram.R_0.data[1], ram.R_0.data[0]) //~ RW0O <= cat(ram.R_0.data[1], ram.R_0.data[0])
R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= RW0A //~ ram.W_0.addr <= RW0A
ram.W_0.en <= and(RW0E, RW0W) //~ ram.W_0.en <= and(RW0E, RW0W)
ram.W_0.data[0] <= bits(RW0I, 7, 0) //~ ram.W_0.data[0] <= bits(RW0I, 7, 0)
ram.W_0.data[1] <= bits(RW0I, 15, 8) //~ ram.W_0.data[1] <= bits(RW0I, 15, 8)
ram.W_0.mask[0] <= bits(RW0M, 0, 0) //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0)
ram.W_0.mask[1] <= bits(RW0M, 1, 1) //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1)
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }
class Synflops2048x8_r_mw extends MacroCompilerSpec { //~ class Synflops2048x8_r_mw extends MacroCompilerSpec {
val mem = new File(macroDir, "mem-2048x8-r-mw.json") //~ val mem = new File(macroDir, "mem-2048x8-r-mw.json")
val v = new File(testDir, "syn_flops_2048x8_r_mw.v") //~ val v = new File(testDir, "syn_flops_2048x8_r_mw.v")
val output = //~ val output =
""" //~ """
circuit name_of_sram_module : //~ circuit name_of_sram_module :
module name_of_sram_module : //~ module name_of_sram_module :
input clock : Clock //~ input clock : Clock
input W0A : UInt<11> //~ input W0A : UInt<11>
input W0I : UInt<8> //~ input W0I : UInt<8>
input W0E : UInt<1> //~ input W0E : UInt<1>
input W0M : UInt<1> //~ input W0M : UInt<1>
input clock : Clock //~ input clock : Clock
input R0A : UInt<11> //~ input R0A : UInt<11>
output R0O : UInt<8> //~ output R0O : UInt<8>
mem ram : //~ mem ram :
data-type => UInt<8>[1] //~ data-type => UInt<8>[1]
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= UInt<1>("h1") //~ ram.R_0.en <= UInt<1>("h1")
R0O <= ram.R_0.data[0] //~ R0O <= ram.R_0.data[0]
R_0_addr_reg <= mux(UInt<1>("h1"), R0A, R_0_addr_reg) //~ R_0_addr_reg <= mux(UInt<1>("h1"), R0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= W0A //~ ram.W_0.addr <= W0A
ram.W_0.en <= W0E //~ ram.W_0.en <= W0E
ram.W_0.data[0] <= bits(W0I, 7, 0) //~ ram.W_0.data[0] <= bits(W0I, 7, 0)
ram.W_0.mask[0] <= bits(W0M, 0, 0) //~ ram.W_0.mask[0] <= bits(W0M, 0, 0)
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }
class Synflops2048x10_rw extends MacroCompilerSpec { //~ class Synflops2048x10_rw extends MacroCompilerSpec {
val mem = new File(macroDir, "lib-2048x10-rw.json") //~ val mem = new File(macroDir, "lib-2048x10-rw.json")
val v = new File(testDir, "syn_flops_2048x10_rw.v") //~ val v = new File(testDir, "syn_flops_2048x10_rw.v")
val output = //~ val output =
""" //~ """
circuit vendor_sram : //~ circuit vendor_sram :
module vendor_sram : //~ module vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<10> //~ input RW0I : UInt<10>
output RW0O : UInt<10> //~ output RW0O : UInt<10>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
mem ram : //~ mem ram :
data-type => UInt<10> //~ data-type => UInt<10>
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= RW0E //~ ram.R_0.en <= RW0E
RW0O <= ram.R_0.data //~ RW0O <= ram.R_0.data
R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg) //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= RW0A //~ ram.W_0.addr <= RW0A
ram.W_0.en <= and(RW0E, RW0W) //~ ram.W_0.en <= and(RW0E, RW0W)
ram.W_0.data <= RW0I //~ ram.W_0.data <= RW0I
ram.W_0.mask <= UInt<1>("h1") //~ ram.W_0.mask <= UInt<1>("h1")
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }
class Synflops2048x8_mrw_re extends MacroCompilerSpec { //~ class Synflops2048x8_mrw_re extends MacroCompilerSpec {
val mem = new File(macroDir, "lib-2048x8-mrw-re.json") //~ val mem = new File(macroDir, "lib-2048x8-mrw-re.json")
val v = new File(testDir, "syn_flops_2048x8_mrw_re.v") //~ val v = new File(testDir, "syn_flops_2048x8_mrw_re.v")
val output = //~ val output =
""" //~ """
circuit vendor_sram : //~ circuit vendor_sram :
module vendor_sram : //~ module vendor_sram :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<8> //~ input RW0I : UInt<8>
output RW0O : UInt<8> //~ output RW0O : UInt<8>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0R : UInt<1> //~ input RW0R : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<1> //~ input RW0M : UInt<1>
mem ram : //~ mem ram :
data-type => UInt<8>[1] //~ data-type => UInt<8>[1]
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= and(RW0E, not(RW0R)) //~ ram.R_0.en <= and(RW0E, not(RW0R))
RW0O <= ram.R_0.data[0] //~ RW0O <= ram.R_0.data[0]
R_0_addr_reg <= mux(and(RW0E, not(RW0R)), RW0A, R_0_addr_reg) //~ R_0_addr_reg <= mux(and(RW0E, not(RW0R)), RW0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= RW0A //~ ram.W_0.addr <= RW0A
ram.W_0.en <= and(RW0E, RW0W) //~ ram.W_0.en <= and(RW0E, RW0W)
ram.W_0.data[0] <= bits(RW0I, 7, 0) //~ ram.W_0.data[0] <= bits(RW0I, 7, 0)
ram.W_0.mask[0] <= bits(RW0M, 0, 0) //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0)
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }
class Synflops2048x16_n28 extends MacroCompilerSpec { //~ class Synflops2048x16_n28 extends MacroCompilerSpec {
val mem = new File(macroDir, "lib-2048x16-n28.json") //~ val mem = new File(macroDir, "lib-2048x16-n28.json")
val v = new File(testDir, "syn_flops_2048x16_n28.v") //~ val v = new File(testDir, "syn_flops_2048x16_n28.v")
val output = //~ val output =
""" //~ """
circuit vendor_sram_4 : //~ circuit vendor_sram_4 :
module vendor_sram_16 : //~ module vendor_sram_16 :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<16> //~ input RW0I : UInt<16>
output RW0O : UInt<16> //~ output RW0O : UInt<16>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<16> //~ input RW0M : UInt<16>
mem ram : //~ mem ram :
data-type => UInt<1>[16] //~ data-type => UInt<1>[16]
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= RW0E //~ 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]))))))))))))))) //~ 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) //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= RW0A //~ ram.W_0.addr <= RW0A
ram.W_0.en <= and(RW0E, RW0W) //~ ram.W_0.en <= and(RW0E, RW0W)
ram.W_0.data[0] <= bits(RW0I, 0, 0) //~ ram.W_0.data[0] <= bits(RW0I, 0, 0)
ram.W_0.data[1] <= bits(RW0I, 1, 1) //~ ram.W_0.data[1] <= bits(RW0I, 1, 1)
ram.W_0.data[2] <= bits(RW0I, 2, 2) //~ ram.W_0.data[2] <= bits(RW0I, 2, 2)
ram.W_0.data[3] <= bits(RW0I, 3, 3) //~ ram.W_0.data[3] <= bits(RW0I, 3, 3)
ram.W_0.data[4] <= bits(RW0I, 4, 4) //~ ram.W_0.data[4] <= bits(RW0I, 4, 4)
ram.W_0.data[5] <= bits(RW0I, 5, 5) //~ ram.W_0.data[5] <= bits(RW0I, 5, 5)
ram.W_0.data[6] <= bits(RW0I, 6, 6) //~ ram.W_0.data[6] <= bits(RW0I, 6, 6)
ram.W_0.data[7] <= bits(RW0I, 7, 7) //~ ram.W_0.data[7] <= bits(RW0I, 7, 7)
ram.W_0.data[8] <= bits(RW0I, 8, 8) //~ ram.W_0.data[8] <= bits(RW0I, 8, 8)
ram.W_0.data[9] <= bits(RW0I, 9, 9) //~ ram.W_0.data[9] <= bits(RW0I, 9, 9)
ram.W_0.data[10] <= bits(RW0I, 10, 10) //~ ram.W_0.data[10] <= bits(RW0I, 10, 10)
ram.W_0.data[11] <= bits(RW0I, 11, 11) //~ ram.W_0.data[11] <= bits(RW0I, 11, 11)
ram.W_0.data[12] <= bits(RW0I, 12, 12) //~ ram.W_0.data[12] <= bits(RW0I, 12, 12)
ram.W_0.data[13] <= bits(RW0I, 13, 13) //~ ram.W_0.data[13] <= bits(RW0I, 13, 13)
ram.W_0.data[14] <= bits(RW0I, 14, 14) //~ ram.W_0.data[14] <= bits(RW0I, 14, 14)
ram.W_0.data[15] <= bits(RW0I, 15, 15) //~ ram.W_0.data[15] <= bits(RW0I, 15, 15)
ram.W_0.mask[0] <= bits(RW0M, 0, 0) //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0)
ram.W_0.mask[1] <= bits(RW0M, 1, 1) //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1)
ram.W_0.mask[2] <= bits(RW0M, 2, 2) //~ ram.W_0.mask[2] <= bits(RW0M, 2, 2)
ram.W_0.mask[3] <= bits(RW0M, 3, 3) //~ ram.W_0.mask[3] <= bits(RW0M, 3, 3)
ram.W_0.mask[4] <= bits(RW0M, 4, 4) //~ ram.W_0.mask[4] <= bits(RW0M, 4, 4)
ram.W_0.mask[5] <= bits(RW0M, 5, 5) //~ ram.W_0.mask[5] <= bits(RW0M, 5, 5)
ram.W_0.mask[6] <= bits(RW0M, 6, 6) //~ ram.W_0.mask[6] <= bits(RW0M, 6, 6)
ram.W_0.mask[7] <= bits(RW0M, 7, 7) //~ ram.W_0.mask[7] <= bits(RW0M, 7, 7)
ram.W_0.mask[8] <= bits(RW0M, 8, 8) //~ ram.W_0.mask[8] <= bits(RW0M, 8, 8)
ram.W_0.mask[9] <= bits(RW0M, 9, 9) //~ ram.W_0.mask[9] <= bits(RW0M, 9, 9)
ram.W_0.mask[10] <= bits(RW0M, 10, 10) //~ ram.W_0.mask[10] <= bits(RW0M, 10, 10)
ram.W_0.mask[11] <= bits(RW0M, 11, 11) //~ ram.W_0.mask[11] <= bits(RW0M, 11, 11)
ram.W_0.mask[12] <= bits(RW0M, 12, 12) //~ ram.W_0.mask[12] <= bits(RW0M, 12, 12)
ram.W_0.mask[13] <= bits(RW0M, 13, 13) //~ ram.W_0.mask[13] <= bits(RW0M, 13, 13)
ram.W_0.mask[14] <= bits(RW0M, 14, 14) //~ ram.W_0.mask[14] <= bits(RW0M, 14, 14)
ram.W_0.mask[15] <= bits(RW0M, 15, 15) //~ ram.W_0.mask[15] <= bits(RW0M, 15, 15)
module vendor_sram_4 : //~ module vendor_sram_4 :
input clock : Clock //~ input clock : Clock
input RW0A : UInt<11> //~ input RW0A : UInt<11>
input RW0I : UInt<4> //~ input RW0I : UInt<4>
output RW0O : UInt<4> //~ output RW0O : UInt<4>
input RW0E : UInt<1> //~ input RW0E : UInt<1>
input RW0W : UInt<1> //~ input RW0W : UInt<1>
input RW0M : UInt<4> //~ input RW0M : UInt<4>
mem ram : //~ mem ram :
data-type => UInt<1>[4] //~ data-type => UInt<1>[4]
depth => 2048 //~ depth => 2048
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
writer => W_0 //~ writer => W_0
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<11>, clock with : //~ reg R_0_addr_reg : UInt<11>, clock with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= clock //~ ram.R_0.clk <= clock
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= RW0E //~ 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]))) //~ 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) //~ R_0_addr_reg <= mux(RW0E, RW0A, R_0_addr_reg)
ram.W_0.clk <= clock //~ ram.W_0.clk <= clock
ram.W_0.addr <= RW0A //~ ram.W_0.addr <= RW0A
ram.W_0.en <= and(RW0E, RW0W) //~ ram.W_0.en <= and(RW0E, RW0W)
ram.W_0.data[0] <= bits(RW0I, 0, 0) //~ ram.W_0.data[0] <= bits(RW0I, 0, 0)
ram.W_0.data[1] <= bits(RW0I, 1, 1) //~ ram.W_0.data[1] <= bits(RW0I, 1, 1)
ram.W_0.data[2] <= bits(RW0I, 2, 2) //~ ram.W_0.data[2] <= bits(RW0I, 2, 2)
ram.W_0.data[3] <= bits(RW0I, 3, 3) //~ ram.W_0.data[3] <= bits(RW0I, 3, 3)
ram.W_0.mask[0] <= bits(RW0M, 0, 0) //~ ram.W_0.mask[0] <= bits(RW0M, 0, 0)
ram.W_0.mask[1] <= bits(RW0M, 1, 1) //~ ram.W_0.mask[1] <= bits(RW0M, 1, 1)
ram.W_0.mask[2] <= bits(RW0M, 2, 2) //~ ram.W_0.mask[2] <= bits(RW0M, 2, 2)
ram.W_0.mask[3] <= bits(RW0M, 3, 3) //~ ram.W_0.mask[3] <= bits(RW0M, 3, 3)
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }
class Synflops32x32_2rw extends MacroCompilerSpec { //~ class Synflops32x32_2rw extends MacroCompilerSpec {
val mem = new File(macroDir, "lib-32x32-2rw.json") //~ val mem = new File(macroDir, "lib-32x32-2rw.json")
val v = new File(testDir, "syn_flops_32x32_2rw.v") //~ val v = new File(testDir, "syn_flops_32x32_2rw.v")
val output = //~ val output =
""" //~ """
circuit SRAM2RW32x32 : //~ circuit SRAM2RW32x32 :
module SRAM2RW32x32 : //~ module SRAM2RW32x32 :
input CE1 : Clock //~ input CE1 : Clock
input A1 : UInt<5> //~ input A1 : UInt<5>
input I1 : UInt<32> //~ input I1 : UInt<32>
output O1 : UInt<32> //~ output O1 : UInt<32>
input CSB1 : UInt<1> //~ input CSB1 : UInt<1>
input OEB1 : UInt<1> //~ input OEB1 : UInt<1>
input WEB1 : UInt<1> //~ input WEB1 : UInt<1>
input CE2 : Clock //~ input CE2 : Clock
input A2 : UInt<5> //~ input A2 : UInt<5>
input I2 : UInt<32> //~ input I2 : UInt<32>
output O2 : UInt<32> //~ output O2 : UInt<32>
input CSB2 : UInt<1> //~ input CSB2 : UInt<1>
input OEB2 : UInt<1> //~ input OEB2 : UInt<1>
input WEB2 : UInt<1> //~ input WEB2 : UInt<1>
mem ram : //~ mem ram :
data-type => UInt<32> //~ data-type => UInt<32>
depth => 32 //~ depth => 32
read-latency => 0 //~ read-latency => 0
write-latency => 1 //~ write-latency => 1
reader => R_0 //~ reader => R_0
reader => R_1 //~ reader => R_1
writer => W_0 //~ writer => W_0
writer => W_1 //~ writer => W_1
read-under-write => undefined //~ read-under-write => undefined
reg R_0_addr_reg : UInt<5>, CE1 with : //~ reg R_0_addr_reg : UInt<5>, CE1 with :
reset => (UInt<1>("h0"), R_0_addr_reg) //~ reset => (UInt<1>("h0"), R_0_addr_reg)
ram.R_0.clk <= CE1 //~ ram.R_0.clk <= CE1
ram.R_0.addr <= R_0_addr_reg //~ ram.R_0.addr <= R_0_addr_reg
ram.R_0.en <= and(not(CSB1), not(OEB1)) //~ ram.R_0.en <= and(not(CSB1), not(OEB1))
O1 <= ram.R_0.data //~ O1 <= ram.R_0.data
R_0_addr_reg <= mux(and(not(CSB1), not(OEB1)), A1, R_0_addr_reg) //~ R_0_addr_reg <= mux(and(not(CSB1), not(OEB1)), A1, R_0_addr_reg)
reg R_1_addr_reg : UInt<5>, CE2 with : //~ reg R_1_addr_reg : UInt<5>, CE2 with :
reset => (UInt<1>("h0"), R_1_addr_reg) //~ reset => (UInt<1>("h0"), R_1_addr_reg)
ram.R_1.clk <= CE2 //~ ram.R_1.clk <= CE2
ram.R_1.addr <= R_1_addr_reg //~ ram.R_1.addr <= R_1_addr_reg
ram.R_1.en <= and(not(CSB2), not(OEB2)) //~ ram.R_1.en <= and(not(CSB2), not(OEB2))
O2 <= ram.R_1.data //~ O2 <= ram.R_1.data
R_1_addr_reg <= mux(and(not(CSB2), not(OEB2)), A2, R_1_addr_reg) //~ R_1_addr_reg <= mux(and(not(CSB2), not(OEB2)), A2, R_1_addr_reg)
ram.W_0.clk <= CE1 //~ ram.W_0.clk <= CE1
ram.W_0.addr <= A1 //~ ram.W_0.addr <= A1
ram.W_0.en <= and(not(CSB1), not(WEB1)) //~ ram.W_0.en <= and(not(CSB1), not(WEB1))
ram.W_0.data <= I1 //~ ram.W_0.data <= I1
ram.W_0.mask <= UInt<1>("h1") //~ ram.W_0.mask <= UInt<1>("h1")
ram.W_1.clk <= CE2 //~ ram.W_1.clk <= CE2
ram.W_1.addr <= A2 //~ ram.W_1.addr <= A2
ram.W_1.en <= and(not(CSB2), not(WEB2)) //~ ram.W_1.en <= and(not(CSB2), not(WEB2))
ram.W_1.data <= I2 //~ ram.W_1.data <= I2
ram.W_1.mask <= UInt<1>("h1") //~ ram.W_1.mask <= UInt<1>("h1")
""" //~ """
compile(mem, None, v, true) //~ compile(mem, None, v, true)
execute(Some(mem), None, true, output) //~ execute(Some(mem), None, true, output)
} //~ }