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