Reformat all scala files in macros

- Mostly this reformat comments and large argument lists to classes and methods
This commit is contained in:
chick
2021-02-03 17:50:36 -08:00
parent 93f86a5bc6
commit 68c3425493
15 changed files with 1743 additions and 1204 deletions

View File

@@ -2,15 +2,14 @@
package barstools.macros
/**
* Trait which can calculate the cost of compiling a memory against a certain
/** Trait which can calculate the cost of compiling a memory against a certain
* library memory macro using a cost function.
*/
// TODO: eventually explore compiling a single target memory using multiple
// different kinds of target memory.
trait CostMetric extends Serializable {
/**
* Cost function that returns the cost of compiling a memory using a certain
/** Cost function that returns the cost of compiling a memory using a certain
* macro.
*
* @param mem Memory macro to compile (target memory)
@@ -20,8 +19,7 @@ trait CostMetric extends Serializable {
*/
def cost(mem: Macro, lib: Macro): Option[Double]
/**
* Helper function to return the map of arguments (or an empty map if there are none).
/** Helper function to return the map of arguments (or an empty map if there are none).
*/
def commandLineParams(): Map[String, String]
@@ -41,7 +39,8 @@ trait CostMetricCompanion {
/** Palmer's old metric.
* TODO: figure out what is the difference between this metric and the current
* default metric and either revive or delete this metric. */
* default metric and either revive or delete this metric.
*/
object OldMetric extends CostMetric with CostMetricCompanion {
override def cost(mem: Macro, lib: Macro): Option[Double] = {
/* Palmer: A quick cost function (that must be kept in sync with
@@ -58,8 +57,7 @@ object OldMetric extends CostMetric with CostMetricCompanion {
override def construct(m: Map[String, String]) = OldMetric
}
/**
* An external cost function.
/** An external cost function.
* Calls the specified path with paths to the JSON MDF representation of the mem
* and lib macros. The external executable should print a Double.
* None will be returned if the external executable does not print a valid
@@ -115,11 +113,14 @@ object ExternalMetric extends CostMetricCompanion {
// TODO: write tests for this function to make sure it selects the right things
object DefaultMetric extends CostMetric with CostMetricCompanion {
override def cost(mem: Macro, lib: Macro): Option[Double] = {
val memMask = mem.src.ports map (_.maskGran) find (_.isDefined) map (_.get)
val libMask = lib.src.ports map (_.maskGran) find (_.isDefined) map (_.get)
val memMask = mem.src.ports.map(_.maskGran).find(_.isDefined).map(_.get)
val libMask = lib.src.ports.map(_.maskGran).find(_.isDefined).map(_.get)
val memWidth = (memMask, libMask) match {
case (None, _) => mem.src.width
case (Some(p), None) => (mem.src.width/p)*math.ceil(p.toDouble/lib.src.width)*lib.src.width //We map the mask to distinct memories
case (Some(p), None) =>
(mem.src.width / p) * math.ceil(
p.toDouble / lib.src.width
) * lib.src.width //We map the mask to distinct memories
case (Some(p), Some(m)) => {
if (m <= p) (mem.src.width / p) * math.ceil(p.toDouble / m) * m //Using multiple m's to create a p (integeraly)
else (mem.src.width / p) * m //Waste the extra maskbits
@@ -148,7 +149,8 @@ object MacroCompilerUtil {
// Adapted from https://stackoverflow.com/a/134918
/** Serialize an arbitrary object to String.
* Used to pass structured values through as an annotation. */
* Used to pass structured values through as an annotation.
*/
def objToString(o: Serializable): String = {
val baos: ByteArrayOutputStream = new ByteArrayOutputStream
val oos: ObjectOutputStream = new ObjectOutputStream(baos)
@@ -168,6 +170,7 @@ object MacroCompilerUtil {
}
object CostMetric {
/** Define some default metric. */
val default: CostMetric = DefaultMetric
@@ -178,8 +181,7 @@ object CostMetric {
registerCostMetric(ExternalMetric)
registerCostMetric(DefaultMetric)
/**
* Register a cost metric.
/** Register a cost metric.
* @param createFuncHelper Companion object to fetch the name and construct
* the metric.
*/

View File

@@ -1,7 +1,6 @@
// See LICENSE for license details.
/**
* Terminology note:
/** Terminology note:
* mem - target memory to compile, in design (e.g. Mem() in rocket)
* lib - technology SRAM(s) to use to compile mem
*/
@@ -29,33 +28,35 @@ case class MacroCompilerAnnotation(content: String) extends NoTargetAnnotation {
def params: Params = MacroCompilerUtil.objFromString(content).asInstanceOf[Params]
}
/**
* The MacroCompilerAnnotation to trigger the macro compiler.
/** The MacroCompilerAnnotation to trigger the macro compiler.
* Note that this annotation does NOT actually target any modules for
* compilation. It simply holds all the settings for the memory compiler. The
* actual selection of which memories to compile is set in the Params.
*
* To use, simply annotate the entire circuit itself with this annotation and
* include [[MacroCompilerTransform]].
*
*/
object MacroCompilerAnnotation {
/** Macro compiler mode. */
sealed trait CompilerMode
/** Strict mode - must compile all memories or error out. */
case object Strict extends CompilerMode
/** Synflops mode - compile all memories with synflops (do not map to lib at all). */
case object Synflops extends CompilerMode
/** CompileAndSynflops mode - compile all memories and create mock versions of the target libs with synflops. */
case object CompileAndSynflops extends CompilerMode
/** FallbackSynflops - compile all memories to SRAM when possible and fall back to synflops if a memory fails. * */
case object FallbackSynflops extends CompilerMode
/** CompileAvailable - compile what is possible and do nothing with uncompiled memories. * */
case object CompileAvailable extends CompilerMode
/**
* The default mode for the macro compiler.
/** The default mode for the macro compiler.
* TODO: Maybe set the default to FallbackSynflops (typical for
* vlsi_mem_gen-like scripts) once it's implemented?
*/
@@ -65,20 +66,37 @@ object MacroCompilerAnnotation {
val options: Seq[(CompilerMode, String, String)] = Seq(
(Default, "default", "Select the default option from below."),
(Strict, "strict", "Compile all memories to library or return an error."),
(Synflops, "synflops", "Produces synthesizable flop-based memories for all memories (do not map to lib at all); likely useful for simulation purposes."),
(CompileAndSynflops, "compileandsynflops", "Compile all memories and create mock versions of the target libs with synflops; likely also useful for simulation purposes."),
(FallbackSynflops, "fallbacksynflops", "Compile all memories to library when possible and fall back to synthesizable flop-based memories when library synth is not possible."),
(CompileAvailable, "compileavailable", "Compile all memories to library when possible and do nothing in case of errors. (default)")
(
Synflops,
"synflops",
"Produces synthesizable flop-based memories for all memories (do not map to lib at all); likely useful for simulation purposes."
),
(
CompileAndSynflops,
"compileandsynflops",
"Compile all memories and create mock versions of the target libs with synflops; likely also useful for simulation purposes."
),
(
FallbackSynflops,
"fallbacksynflops",
"Compile all memories to library when possible and fall back to synthesizable flop-based memories when library synth is not possible."
),
(
CompileAvailable,
"compileavailable",
"Compile all memories to library when possible and do nothing in case of errors. (default)"
)
)
/** Helper function to select a compiler mode. */
def stringToCompilerMode(str: String): CompilerMode = options.collectFirst { case (mode, cmd, _) if cmd == str => mode } match {
def stringToCompilerMode(str: String): CompilerMode = options.collectFirst {
case (mode, cmd, _) if cmd == str => mode
} match {
case Some(x) => x
case None => throw new IllegalArgumentException("No such compiler mode " + str)
}
/**
* Parameters associated to this MacroCompilerAnnotation.
/** Parameters associated to this MacroCompilerAnnotation.
*
* @param mem Path to memory lib
* @param memFormat Type of memory lib (Some("conf"), Some("mdf"), or None (defaults to mdf))
@@ -89,12 +107,18 @@ object MacroCompilerAnnotation {
* @param forceCompile Set of memories to force compiling to lib regardless of the mode
* @param forceSynflops Set of memories to force compiling as flops regardless of the mode
*/
case class Params(mem: String, memFormat: Option[String], lib: Option[String], hammerIR: Option[String],
costMetric: CostMetric, mode: CompilerMode, useCompiler: Boolean,
forceCompile: Set[String], forceSynflops: Set[String])
case class Params(
mem: String,
memFormat: Option[String],
lib: Option[String],
hammerIR: Option[String],
costMetric: CostMetric,
mode: CompilerMode,
useCompiler: Boolean,
forceCompile: Set[String],
forceSynflops: Set[String])
/**
* Create a MacroCompilerAnnotation.
/** Create a MacroCompilerAnnotation.
* @param c Top-level circuit name (see class description)
* @param p Parameters (see above).
*/
@@ -103,12 +127,14 @@ object MacroCompilerAnnotation {
}
class MacroCompilerPass(mems: Option[Seq[Macro]],
class MacroCompilerPass(
mems: Option[Seq[Macro]],
libs: Option[Seq[Macro]],
compilers: Option[SRAMCompiler],
hammerIR: Option[String],
costMetric: CostMetric = CostMetric.default,
mode: MacroCompilerAnnotation.CompilerMode = MacroCompilerAnnotation.Default) extends firrtl.passes.Pass {
mode: MacroCompilerAnnotation.CompilerMode = MacroCompilerAnnotation.Default)
extends firrtl.passes.Pass {
// Helper function to check the legality of bitPairs.
// e.g. ((0,21), (22,43)) is legal
// ((0,21), (22,21)) is illegal and will throw an assert
@@ -120,8 +146,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
})
}
/**
* Calculate bit pairs.
/** Calculate bit pairs.
* This is a list of submemories by width.
* The tuples are (lsb, msb) inclusive.
* Example: (0, 7) and (8, 15) might be a split for a width=16 memory into two width=8 target memories.
@@ -132,7 +157,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* @return Bit pairs or empty list if there was an error.
*/
private def calculateBitPairs(mem: Macro, lib: Macro): Seq[(BigInt, BigInt)] = {
val pairedPorts = mem.sortedPorts zip lib.sortedPorts
val pairedPorts = mem.sortedPorts.zip(lib.sortedPorts)
val bitPairs = ArrayBuffer[(BigInt, BigInt)]()
var currentLSB: BigInt = 0
@@ -203,7 +228,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
splitMemory(memMask.get)
} else {
// e.g. mem mask = 13, lib width = 8
System.err.println(s"Unmasked target memory: unaligned mem maskGran $p with lib (${lib.src.name}) width ${libPort.src.width.get} not supported")
System.err.println(
s"Unmasked target memory: unaligned mem maskGran $p with lib (${lib.src.name}) width ${libPort.src.width.get} not supported"
)
return Seq()
}
}
@@ -266,9 +293,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
}
def compile(mem: Macro, lib: Macro): Option[(Module, Macro)] = {
assert(mem.sortedPorts.lengthCompare(lib.sortedPorts.length) == 0,
"mem and lib should have an equal number of ports")
val pairedPorts = mem.sortedPorts zip lib.sortedPorts
assert(
mem.sortedPorts.lengthCompare(lib.sortedPorts.length) == 0,
"mem and lib should have an equal number of ports"
)
val pairedPorts = mem.sortedPorts.zip(lib.sortedPorts)
// Width mapping. See calculateBitPairs.
val bitPairs: Seq[(BigInt, BigInt)] = calculateBitPairs(mem, lib)
@@ -287,7 +316,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
/* Palmer: If we've got a parallel memory then we've got to take the
* address bits into account. */
if (mem.src.depth > lib.src.depth) {
mem.src.ports foreach { port =>
mem.src.ports.foreach { port =>
val high = MacroCompilerMath.ceilLog2(mem.src.depth)
val low = MacroCompilerMath.ceilLog2(lib.src.depth)
val ref = WRef(port.address.name)
@@ -317,18 +346,18 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Create the instance.
stmts += WDefInstance(NoInfo, name, lib.src.name, lib.tpe)
// Connect extra ports of the lib.
stmts ++= lib.extraPorts map { case (portName, portValue) =>
stmts ++= lib.extraPorts.map { case (portName, portValue) =>
Connect(NoInfo, WSubField(WRef(name), portName), portValue)
}
}
for ((memPort, libPort) <- pairedPorts) {
val addrMatch = selects get memPort.src.address.name match {
val addrMatch = selects.get(memPort.src.address.name) match {
case None => one
case Some(addr) =>
val index = UIntLiteral(i, IntWidth(bitWidth(addr.tpe)))
DoPrim(PrimOps.Eq, Seq(addr, index), Nil, index.tpe)
}
val addrMatchReg = selectRegs get memPort.src.address.name match {
val addrMatchReg = selectRegs.get(memPort.src.address.name) match {
case None => one
case Some(reg) =>
val index = UIntLiteral(i, IntWidth(bitWidth(reg.tpe)))
@@ -341,29 +370,22 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
for (((low, high), j) <- bitPairs.zipWithIndex) {
val inst = WRef(s"mem_${i}_${j}", lib.tpe)
def connectPorts2(mem: Expression,
lib: String,
polarity: Option[PortPolarity]): Statement =
def connectPorts2(mem: Expression, lib: String, polarity: Option[PortPolarity]): Statement =
Connect(NoInfo, WSubField(inst, lib), portToExpression(mem, polarity))
def connectPorts(mem: Expression,
lib: String,
polarity: PortPolarity): Statement =
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. */
/* Colin not all libPorts have clocks but all memPorts do*/
libPort.src.clock.foreach { cPort =>
stmts += connectPorts(WRef(memPort.src.clock.get.name),
cPort.name,
cPort.polarity) }
stmts += connectPorts(WRef(memPort.src.clock.get.name), cPort.name, cPort.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.src.address.name),
libPort.src.address.name,
libPort.src.address.polarity)
stmts += connectPorts(WRef(memPort.src.address.name), libPort.src.address.name, libPort.src.address.polarity)
// Output port mapping
(memPort.src.output, libPort.src.output) match {
@@ -385,8 +407,8 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* port on the memory) then just don't worry about it,
* there's nothing to do. */
case (Some(PolarizedPort(mem, _)), None) =>
System.err println "WARNING: Unable to match output ports on memory"
System.err println s" outer output port: ${mem}"
System.err.println("WARNING: Unable to match output ports on memory")
System.err.println(s" outer output port: ${mem}")
return None
}
@@ -409,8 +431,8 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* port on the memory) then just don't worry about it,
* there's nothing to do. */
case (Some(PolarizedPort(mem, _)), None) =>
System.err println "WARNING: Unable to match input ports on memory"
System.err println s" outer input port: ${mem}"
System.err.println("WARNING: Unable to match input ports on memory")
System.err.println(s" outer input port: ${mem}")
return None
}
@@ -429,12 +451,16 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Example: if we have a lib whose maskGran is 8 but our mem's maskGran is 4.
// The other case is if we're using a larger lib than mem.
val usingLessThanLibMaskGran = (memPort.src.maskGran.get < libPort.src.effectiveMaskGran)
val effectiveLibWidth = if (usingLessThanLibMaskGran)
val effectiveLibWidth =
if (usingLessThanLibMaskGran)
memPort.src.maskGran.get
else
libPort.src.width.get
cat(((0 until libPort.src.width.get by libPort.src.effectiveMaskGran) map (i => {
cat(
(
(0 until libPort.src.width.get by libPort.src.effectiveMaskGran)
.map(i => {
if (usingLessThanLibMaskGran && i >= effectiveLibWidth) {
// If the memMaskGran is smaller than the lib's gran, then
// zero out the upper bits.
@@ -448,7 +474,10 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
bits(WRef(mem), (low + i) / memPort.src.effectiveMaskGran)
}
}
})).reverse)
})
)
.reverse
)
}
case None =>
/* If there is a lib mask port but no mem mask port, just turn on
@@ -501,7 +530,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* implement the outer memory's collection of ports using what
* 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))) =>
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, mask_polarity)
stmts += connectPorts(andAddrMatch(memWriteEnable), we, we_polarity)
@@ -509,8 +542,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
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, we_polarity)
stmts += connectPorts(andAddrMatch(and(memWriteEnable, memChipEnable)), we, we_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
@@ -518,13 +550,15 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
* write enable port instead of the mask port. */
chipEnable match {
case Some(PolarizedPort(en, en_polarity)) => {
stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)),
we, we_polarity)
stmts += connectPorts(andAddrMatch(and(memWriteEnable, memMask)), we, we_polarity)
stmts += connectPorts(andAddrMatch(memChipEnable), en, en_polarity)
}
case _ => {
stmts += connectPorts(andAddrMatch(and(and(memWriteEnable, memChipEnable), memMask)),
we, we_polarity)
stmts += connectPorts(
andAddrMatch(and(and(memWriteEnable, memChipEnable), memMask)),
we,
we_polarity
)
}
}
} else {
@@ -541,7 +575,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
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)]())) +=
(outputs.getOrElseUpdate(mem, ArrayBuffer[(Expression, Expression)]())) +=
(addrMatchReg -> WRef(name))
case _ =>
}
@@ -549,12 +583,14 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
}
// Connect mem outputs
val zeroOutputValue: Expression = UIntLiteral(0, IntWidth(mem.src.width))
mem.src.ports foreach { port =>
mem.src.ports.foreach { port =>
port.output match {
case Some(PolarizedPort(mem, _)) => outputs get mem match {
case Some(PolarizedPort(mem, _)) =>
outputs.get(mem) match {
case Some(select) =>
val output = (select foldRight (zeroOutputValue)) {
case ((cond, tval), fval) => Mux(cond, tval, fval, fval.tpe) }
val output = (select.foldRight(zeroOutputValue)) { case ((cond, tval), fval) =>
Mux(cond, tval, fval, fval.tpe)
}
stmts += Connect(NoInfo, WRef(mem), output)
case None =>
}
@@ -572,12 +608,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Try to compile each of the memories in mems.
// The 'state' is c.modules, which is a list of all the firrtl modules
// in the 'circuit'.
(mems foldLeft c.modules){ (modules, mem) =>
(mems.foldLeft(c.modules)) { (modules, mem) =>
val sram = mem.src
def groupMatchesMask(group: SRAMGroup, mem: SRAMMacro): Boolean = {
val memMask = mem.ports map (_.maskGran) find (_.isDefined) map (_.get)
val libMask = group.ports map (_.maskGran) find (_.isDefined) map (_.get)
val memMask = mem.ports.map(_.maskGran).find(_.isDefined).map(_.get)
val libMask = group.ports.map(_.maskGran).find(_.isDefined).map(_.get)
(memMask, libMask) match {
case (None, _) => true
case (Some(_), None) => false
@@ -587,9 +622,13 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Add compiler memories that might map well to libs
val compLibs = compilers match {
case Some(SRAMCompiler(_, groups)) => {
groups.filter(g => g.family == sram.family && groupMatchesMask(g, sram)).map( g => {
for(w <- g.width; d <- g.depth if((sram.width % w == 0) && (sram.depth % d == 0)))
yield Seq(new Macro(buildSRAMMacro(g, d, w, g.vt.head)))
groups
.filter(g => g.family == sram.family && groupMatchesMask(g, sram))
.map(g => {
for {
w <- g.width
d <- g.depth if ((sram.width % w == 0) && (sram.depth % d == 0))
} yield Seq(new Macro(buildSRAMMacro(g, d, w, g.vt.head)))
})
}
case None => Seq()
@@ -598,11 +637,11 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
// Try to compile mem against each lib in libs, keeping track of the
// best compiled version, external lib used, and cost.
val (best, cost) = (fullLibs foldLeft (None: Option[(Module, Macro)], Double.MaxValue)){
val (best, cost) = (fullLibs.foldLeft(None: Option[(Module, Macro)], Double.MaxValue)) {
case ((best, cost), 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.src.name} using ${lib.src.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, cost)
case ((best, cost), lib) =>
// Run the cost function to evaluate this potential compile.
@@ -626,7 +665,9 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
best match {
case None => {
if (mode == MacroCompilerAnnotation.Strict)
throw new MacroCompilerException(s"Target memory ${mem.src.name} could not be compiled and strict mode is activated - aborting.")
throw new MacroCompilerException(
s"Target memory ${mem.src.name} could not be compiled and strict mode is activated - aborting."
)
else
modules
}
@@ -642,7 +683,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
}
case None =>
}
(modules filterNot (m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox)
(modules.filterNot(m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox)
}
}
case _ => c.modules
@@ -657,13 +698,23 @@ class MacroCompilerTransform extends Transform {
def execute(state: CircuitState) = state.annotations.collect { case a: MacroCompilerAnnotation => a } match {
case Seq(anno: MacroCompilerAnnotation) =>
val MacroCompilerAnnotation.Params(memFile, memFileFormat, libFile, hammerIR, costMetric, mode, useCompiler, forceCompile, forceSynflops) = anno.params
val MacroCompilerAnnotation.Params(
memFile,
memFileFormat,
libFile,
hammerIR,
costMetric,
mode,
useCompiler,
forceCompile,
forceSynflops
) = anno.params
if (mode == MacroCompilerAnnotation.FallbackSynflops) {
throw new UnsupportedOperationException("Not implemented yet")
}
// Check that we don't have any modules both forced to compile and synflops.
assert((forceCompile intersect forceSynflops).isEmpty, "Cannot have modules both forced to compile and synflops")
assert((forceCompile.intersect(forceSynflops)).isEmpty, "Cannot have modules both forced to compile and synflops")
// Read, eliminate None, get only SRAM, make firrtl macro
val mems: Option[Seq[Macro]] = (memFileFormat match {
@@ -671,24 +722,22 @@ class MacroCompilerTransform extends Transform {
case _ => mdf.macrolib.Utils.readMDFFromPath(Some(memFile))
}) match {
case Some(x: Seq[mdf.macrolib.Macro]) =>
Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new 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(_)})
Some(Utils.filterForSRAM(Some(x)).getOrElse(List()).map { new Macro(_) })
case _ => None
}
val compilers: Option[mdf.macrolib.SRAMCompiler] = mdf.macrolib.Utils.readMDFFromPath(libFile) match {
case Some(x: Seq[mdf.macrolib.Macro]) =>
if (useCompiler) {
findSRAMCompiler(Some(x))
}
else None
} else None
case _ => None
}
// Helper function to turn a set of mem names into a Seq[Macro].
def setToSeqMacro(names: Set[String]): Seq[Macro] = {
names.toSeq.map(memName => mems.get.collectFirst { case m if m.src.name == memName => m }.get)
@@ -706,12 +755,16 @@ class MacroCompilerTransform extends Transform {
val transforms = Seq(
new MacroCompilerPass(memCompile, libs, compilers, hammerIR, costMetric, mode),
new SynFlopsPass(true, memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) {
new SynFlopsPass(
true,
memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) {
libs.get
} else {
Seq.empty
})))
(transforms foldLeft state) ((s, xform) => xform runTransform s).copy(form = outputForm)
})
)
)
(transforms.foldLeft(state))((s, xform) => xform.runTransform(s)).copy(form = outputForm)
case _ => state
}
}
@@ -729,7 +782,8 @@ class MacroCompilerOptimizations extends SeqTransform {
new firrtl.transforms.ConstantPropagation,
passes.Legalize,
passes.SplitExpressions,
passes.CommonSubexpressionElimination)
passes.CommonSubexpressionElimination
)
}
class MacroCompiler extends Compiler {
@@ -756,8 +810,9 @@ object MacroCompiler extends App {
type MacroParamMap = Map[MacroParam, String]
type CostParamMap = Map[String, String]
type ForcedMemories = (Set[String], Set[String])
val modeOptions: Seq[String] = MacroCompilerAnnotation.options
.map { case (_, cmd, description) => s" $cmd: $description" }
val modeOptions: Seq[String] = MacroCompilerAnnotation.options.map { case (_, cmd, description) =>
s" $cmd: $description"
}
val usage: String = (Seq(
"Options:",
" -n, --macro-conf: The set of macros to compile in firrtl-generated conf format (exclusive with -m)",
@@ -772,10 +827,14 @@ object MacroCompiler extends App {
" --force-compile [mem]: Force the given memory to be compiled to target libs regardless of the mode",
" --force-synflops [mem]: Force the given memory to be compiled via synflops regardless of the mode",
" --mode:"
) ++ modeOptions) mkString "\n"
) ++ modeOptions).mkString("\n")
def parseArgs(map: MacroParamMap, costMap: CostParamMap, forcedMemories: ForcedMemories,
args: List[String]): (MacroParamMap, CostParamMap, ForcedMemories) =
def parseArgs(
map: MacroParamMap,
costMap: CostParamMap,
forcedMemories: ForcedMemories,
args: List[String]
): (MacroParamMap, CostParamMap, ForcedMemories) =
args match {
case Nil => (map, costMap, forcedMemories)
case ("-n" | "--macro-conf") :: value :: tail =>
@@ -809,11 +868,17 @@ object MacroCompiler extends App {
}
def run(args: List[String]) {
val (params, costParams, forcedMemories) = parseArgs(Map[MacroParam, String](), Map[String, String](), (Set.empty, Set.empty), args)
val (params, costParams, forcedMemories) =
parseArgs(Map[MacroParam, String](), Map[String, String](), (Set.empty, Set.empty), args)
try {
val macros = params.get(MacrosFormat) match {
case Some("conf") => Utils.filterForSRAM(Utils.readConfFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
case _ => Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
case Some("conf") =>
Utils.filterForSRAM(Utils.readConfFromPath(params.get(Macros))).get.map(x => (new Macro(x)).blackbox)
case _ =>
Utils
.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros)))
.get
.map(x => (new Macro(x)).blackbox)
}
if (macros.nonEmpty) {
@@ -821,24 +886,28 @@ object MacroCompiler extends App {
// determined as the firrtl "top-level module".
val circuit = Circuit(NoInfo, macros, macros.last.name)
val annotations = AnnotationSeq(
Seq(MacroCompilerAnnotation(
Seq(
MacroCompilerAnnotation(
circuit.main,
MacroCompilerAnnotation.Params(
params.get(Macros).get, params.get(MacrosFormat), params.get(Library),
params.get(Macros).get,
params.get(MacrosFormat),
params.get(Library),
params.get(HammerIR),
CostMetric.getCostMetric(params.getOrElse(CostFunc, "default"), costParams),
MacroCompilerAnnotation.stringToCompilerMode(params.getOrElse(Mode, "default")),
params.contains(UseCompiler),
forceCompile = forcedMemories._1, forceSynflops = forcedMemories._2
forceCompile = forcedMemories._1,
forceSynflops = forcedMemories._2
)
)
)
))
)
// The actual MacroCompilerTransform basically just generates an input circuit
val macroCompilerInput = CircuitState(circuit, MidForm, annotations)
val macroCompiled = (new MacroCompilerTransform).execute(macroCompilerInput)
// Since the MacroCompiler defines its own CLI, reconcile this with FIRRTL options
val firOptions = new ExecutionOptionsManager("macrocompiler") with HasFirrtlOptions {
firrtlOptions = FirrtlExecutionOptions(
@@ -864,7 +933,7 @@ object MacroCompiler extends App {
}
} else {
// Warn user
System.err println "WARNING: Empty *.mems.conf file. No memories generated."
System.err.println("WARNING: Empty *.mems.conf file. No memories generated.")
// Emit empty verilog file if no macros found
params.get(Verilog) match {

View File

@@ -10,8 +10,9 @@ import firrtl.passes.MemPortUtils.memPortField
class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pass {
val extraMods = scala.collection.mutable.ArrayBuffer.empty[Module]
lazy val libMods = (libs map { lib => lib.src.name -> {
val (dataType, dataWidth) = (lib.src.ports foldLeft (None: Option[BigInt]))((res, port) =>
lazy val libMods = (libs.map { lib =>
lib.src.name -> {
val (dataType, dataWidth) = (lib.src.ports.foldLeft(None: Option[BigInt]))((res, port) =>
(res, port.maskPort) match {
case (_, None) =>
res
@@ -31,10 +32,20 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
// Change macro to be mapped onto to look like the below mem
// by changing its depth, and width
val lib_macro = new Macro(lib.src.copy(name="split_"+lib.src.name,
depth = maxDepth, width = dataWidth, ports = lib.src.ports.map(p =>
p.copy(width = p.width.map(_ => dataWidth), depth = p.depth.map(_ => maxDepth),
maskGran = p.maskGran.map(_ => dataWidth)))))
val lib_macro = new Macro(
lib.src.copy(
name = "split_" + lib.src.name,
depth = maxDepth,
width = dataWidth,
ports = lib.src.ports.map(p =>
p.copy(
width = p.width.map(_ => dataWidth),
depth = p.depth.map(_ => maxDepth),
maskGran = p.maskGran.map(_ => dataWidth)
)
)
)
)
val mod_macro = (new MacroCompilerPass(None, None, None, None)).compile(lib, lib_macro)
val (real_mod, real_macro) = mod_macro.get
@@ -45,18 +56,17 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
maxDepth,
1, // writeLatency
1, // readLatency. This is possible because of VerilogMemDelays
real_macro.readers.indices map (i => s"R_$i"),
real_macro.writers.indices map (i => s"W_$i"),
real_macro.readwriters.indices map (i => s"RW_$i")
real_macro.readers.indices.map(i => s"R_$i"),
real_macro.writers.indices.map(i => s"W_$i"),
real_macro.readwriters.indices.map(i => s"RW_$i")
)
val readConnects = real_macro.readers.zipWithIndex flatMap { case (r, i) =>
val readConnects = real_macro.readers.zipWithIndex.flatMap { case (r, i) =>
val clock = portToExpression(r.src.clock.get)
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))
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
@@ -71,13 +81,12 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
)
}
val writeConnects = real_macro.writers.zipWithIndex flatMap { case (w, i) =>
val writeConnects = real_macro.writers.zipWithIndex.flatMap { case (w, i) =>
val clock = portToExpression(w.src.clock.get)
val address = portToExpression(w.src.address)
val enable = (w.src.chipEnable, w.src.writeEnable) match {
case (Some(en), Some(we)) =>
and(portToExpression(en),
portToExpression(we))
and(portToExpression(en), portToExpression(we))
case (Some(en), None) => portToExpression(en)
case (None, Some(we)) => portToExpression(we)
case (None, None) => zero // is it possible?
@@ -97,7 +106,7 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
)
}
val readwriteConnects = real_macro.readwriters.zipWithIndex flatMap { case (rw, i) =>
val readwriteConnects = real_macro.readwriters.zipWithIndex.flatMap { case (rw, i) =>
val clock = portToExpression(rw.src.clock.get)
val address = portToExpression(rw.src.address)
val wmode = rw.src.writeEnable match {
@@ -132,10 +141,11 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa
extraMods.append(real_macro.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects))))
real_mod
}}).toMap
}
}).toMap
def run(c: Circuit): Circuit = {
if (!synflops) c
else c.copy(modules = (c.modules map (m => libMods.getOrElse(m.name, m))) ++ extraMods)
else c.copy(modules = (c.modules.map(m => libMods.getOrElse(m.name, m))) ++ extraMods)
}
}

View File

@@ -21,37 +21,46 @@ class FirrtlMacroPort(port: MacroPort) {
val isWriter = port.input.nonEmpty && port.output.isEmpty
val isReadWriter = port.input.nonEmpty && port.output.nonEmpty
val addrType = UIntType(IntWidth(MacroCompilerMath.ceilLog2(port.depth.get) max 1))
val addrType = UIntType(IntWidth(MacroCompilerMath.ceilLog2(port.depth.get).max(1)))
val dataType = UIntType(IntWidth(port.width.get))
val maskType = UIntType(IntWidth(port.width.get / port.effectiveMaskGran))
// Bundle representing this macro port.
val tpe = BundleType(Seq(
Field(port.address.name, Flip, addrType)) ++
(port.clock map (p => Field(p.name, Flip, ClockType))) ++
(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 tpe = BundleType(
Seq(Field(port.address.name, Flip, addrType)) ++
(port.clock.map(p => Field(p.name, Flip, ClockType))) ++
(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
)
)
val ports = tpe.fields map (f => Port(
NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe))
}
// Reads an SRAMMacro and generates firrtl blackboxes.
class Macro(srcMacro: SRAMMacro) {
val src = srcMacro
val firrtlPorts = srcMacro.ports map { new FirrtlMacroPort(_) }
val firrtlPorts = srcMacro.ports.map { new FirrtlMacroPort(_) }
val writers = firrtlPorts filter (p => p.isWriter)
val readers = firrtlPorts filter (p => p.isReader)
val readwriters = firrtlPorts filter (p => p.isReadWriter)
val writers = firrtlPorts.filter(p => p.isWriter)
val readers = firrtlPorts.filter(p => p.isReader)
val readwriters = firrtlPorts.filter(p => p.isReadWriter)
val sortedPorts = writers ++ readers ++ readwriters
val extraPorts = srcMacro.extraPorts map { p =>
val extraPorts = srcMacro.extraPorts.map { p =>
assert(p.portType == Constant) // TODO: release it?
val name = p.name
val width = BigInt(p.width.toLong)
@@ -60,10 +69,10 @@ class Macro(srcMacro: SRAMMacro) {
}
// Bundle representing this memory blackbox
val tpe = BundleType(firrtlPorts flatMap (_.tpe.fields))
val tpe = BundleType(firrtlPorts.flatMap(_.tpe.fields))
private val modPorts = (firrtlPorts flatMap (_.ports)) ++
(extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
private val modPorts = (firrtlPorts.flatMap(_.ports)) ++
(extraPorts.map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil)
def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body)
}
@@ -71,7 +80,8 @@ class Macro(srcMacro: SRAMMacro) {
object Utils {
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 { _.isInstanceOf[mdf.macrolib.SRAMMacro] } map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] })
case Some(l: Seq[mdf.macrolib.Macro]) =>
Some(l.filter { _.isInstanceOf[mdf.macrolib.SRAMMacro] }.map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] })
case _ => None
}
}
@@ -81,8 +91,14 @@ object Utils {
}
def readConfFromString(str: String): Seq[mdf.macrolib.Macro] = {
MemConf.fromString(str).map { m: MemConf =>
val ports = m.ports.map { case (port, num) => Seq.fill(num)(port) } reduce (_ ++ _)
SRAMMacro(m.name, m.width, m.depth, Utils.portSpecToFamily(ports), Utils.portSpecToMacroPort(m.width, m.depth, m.maskGranularity, ports))
val ports = m.ports.map { case (port, num) => Seq.fill(num)(port) }.reduce(_ ++ _)
SRAMMacro(
m.name,
m.width,
m.depth,
Utils.portSpecToFamily(ports),
Utils.portSpecToMacroPort(m.width, m.depth, m.maskGranularity, ports)
)
}
}
def portSpecToFamily(ports: Seq[MemPort]): String = {
@@ -99,56 +115,66 @@ object Utils {
var numR = 0
var numW = 0
var numRW = 0
ports.map { _ match {
ports.map {
_ match {
case ReadPort => {
val portName = s"R${numR}"
numR += 1
MacroPort(
width=Some(width), depth=Some(depth),
width = Some(width),
depth = Some(depth),
address = PolarizedPort(s"${portName}_addr", ActiveHigh),
clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)),
readEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
output = Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
)
}
case WritePort => {
val portName = s"W${numW}"
numW += 1
MacroPort(
width=Some(width), depth=Some(depth),
width = Some(width),
depth = Some(depth),
address = PolarizedPort(s"${portName}_addr", ActiveHigh),
clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)),
writeEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
input = Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
)
}
case MaskedWritePort => {
val portName = s"W${numW}"
numW += 1
MacroPort(
width=Some(width), depth=Some(depth),
width = Some(width),
depth = Some(depth),
address = PolarizedPort(s"${portName}_addr", ActiveHigh),
clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)),
writeEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
maskPort = Some(PolarizedPort(s"${portName}_mask", ActiveHigh)),
maskGran = maskGran,
input = Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
)
}
case ReadWritePort => {
val portName = s"RW${numRW}"
numRW += 1
MacroPort(
width=Some(width), depth=Some(depth),
width = Some(width),
depth = Some(depth),
address = PolarizedPort(s"${portName}_addr", ActiveHigh),
clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)),
chipEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
writeEnable = Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)),
input = Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)),
output = Some(PolarizedPort(s"${portName}_rdata", ActiveHigh))
) }
)
}
case MaskedReadWritePort => {
val portName = s"RW${numRW}"
numRW += 1
MacroPort(
width=Some(width), depth=Some(depth),
width = Some(width),
depth = Some(depth),
address = PolarizedPort(s"${portName}_addr", ActiveHigh),
clock = Some(PolarizedPort(s"${portName}_clk", PositiveEdge)),
chipEnable = Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
@@ -157,24 +183,48 @@ object Utils {
maskGran = maskGran,
input = Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)),
output = Some(PolarizedPort(s"${portName}_rdata", ActiveHigh))
) }
}}
)
}
}
}
}
def findSRAMCompiler(s: Option[Seq[mdf.macrolib.Macro]]): Option[mdf.macrolib.SRAMCompiler] = {
s match {
case Some(l: Seq[mdf.macrolib.Macro]) =>
l collectFirst {
case x: mdf.macrolib.SRAMCompiler => x
l.collectFirst { case x: mdf.macrolib.SRAMCompiler =>
x
}
case _ => None
}
}
def buildSRAMMacros(s: mdf.macrolib.SRAMCompiler): Seq[mdf.macrolib.SRAMMacro] = {
for (g <- s.groups; d <- g.depth; w <- g.width; vt <- g.vt)
yield mdf.macrolib.SRAMMacro(makeName(g, d, w, vt), w, d, g.family, g.ports.map(_.copy(width=Some(w), depth=Some(d))), vt, g.mux, g.extraPorts)
for {
g <- s.groups
d <- g.depth
w <- g.width
vt <- g.vt
} yield mdf.macrolib.SRAMMacro(
makeName(g, d, w, vt),
w,
d,
g.family,
g.ports.map(_.copy(width = Some(w), depth = Some(d))),
vt,
g.mux,
g.extraPorts
)
}
def buildSRAMMacro(g: mdf.macrolib.SRAMGroup, d: Int, w: Int, vt: String): mdf.macrolib.SRAMMacro = {
return mdf.macrolib.SRAMMacro(makeName(g, d, w, vt), w, d, g.family, g.ports.map(_.copy(width=Some(w), depth=Some(d))), vt, g.mux, g.extraPorts)
return mdf.macrolib.SRAMMacro(
makeName(g, d, w, vt),
w,
d,
g.family,
g.ports.map(_.copy(width = Some(w), depth = Some(d))),
vt,
g.mux,
g.extraPorts
)
}
def makeName(g: mdf.macrolib.SRAMGroup, depth: Int, width: Int, vt: String): String = {
g.name.foldLeft("") { (builder, next) =>

View File

@@ -6,7 +6,8 @@
"depth": "512",
"mux": 4,
"family": "1rw",
"ports" : [ {
"ports": [
{
"address port name": "addr",
"address port polarity": "active high",
"clock port name": "clk",
@@ -22,6 +23,7 @@
"mask port name": "mport",
"mask port polarity": "active low",
"mask granularity": 1
} ]
}
]
}
]

View File

@@ -6,7 +6,8 @@
"depth": "4096",
"mux": 4,
"family": "1rw",
"ports" : [ {
"ports": [
{
"address port name": "addr",
"address port polarity": "active high",
"clock port name": "clk",
@@ -19,6 +20,7 @@
"output port polarity": "active high",
"input port name": "datain",
"input port polarity": "active high"
} ]
}
]
}
]

View File

@@ -4,8 +4,7 @@ import mdf.macrolib._
/** Tests to check that the cost function mechanism is working properly. */
/**
* A test metric that simply favours memories with smaller widths, to test that
/** A test metric that simply favours memories with smaller widths, to test that
* the metric is chosen properly.
*/
object TestMinWidthMetric extends CostMetric with CostMetricCompanion {

View File

@@ -39,7 +39,10 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate
private def args(mem: String, lib: Option[String], v: String, synflops: Boolean, useCompiler: Boolean) =
List("-m", mem.toString, "-v", v) ++
(lib match { case None => Nil case Some(l) => List("-l", l.toString) }) ++
(lib match {
case None => Nil
case Some(l) => List("-l", l.toString)
}) ++
costMetricCmdLine ++
(if (synflops) List("--mode", "synflops") else Nil) ++
(if (useCompiler) List("--use-compiler") else Nil)
@@ -68,7 +71,14 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate
}
// Convenience function for running both compile, execute, and test at once.
def compileExecuteAndTest(mem: String, lib: Option[String], v: String, output: String, synflops: Boolean = false, useCompiler: Boolean = false): Unit = {
def compileExecuteAndTest(
mem: String,
lib: Option[String],
v: String,
output: String,
synflops: Boolean = false,
useCompiler: Boolean = false
): Unit = {
compile(mem, lib, v, synflops, useCompiler)
val result = execute(mem, lib, synflops, useCompiler)
test(result, output)
@@ -76,38 +86,48 @@ abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalate
// Compare FIRRTL outputs after reparsing output with ScalaTest ("should be").
def test(result: Circuit, output: String): Unit = {
val gold = RemoveEmpty run parse(output)
val gold = RemoveEmpty.run(parse(output))
(result.serialize) should be(gold.serialize)
}
// Execute the macro compiler and returns a Circuit containing the output of
// the memory compiler.
def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean): Circuit = execute(memFile, libFile, synflops, false)
def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean): Circuit =
execute(memFile, libFile, synflops, false)
def execute(memFile: Option[String], libFile: Option[String], synflops: Boolean, useCompiler: Boolean): Circuit = {
var mem_full = concat(memPrefix, memFile)
var lib_full = concat(libPrefix, libFile)
require(memFile.isDefined)
val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get map (new Macro(_))
val mems: Seq[Macro] = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(mem_full)).get.map(new Macro(_))
val libs: Option[Seq[Macro]] = if (useCompiler) {
Utils.findSRAMCompiler(mdf.macrolib.Utils.readMDFFromPath(lib_full)).map{x => Utils.buildSRAMMacros(x).map(new Macro(_)) }
Utils.findSRAMCompiler(mdf.macrolib.Utils.readMDFFromPath(lib_full)).map { x =>
Utils.buildSRAMMacros(x).map(new Macro(_))
}
} else {
Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(lib_full)) match {
case Some(x) => Some(x map (new Macro(_)))
case Some(x) => Some(x.map(new Macro(_)))
case None => None
}
}
val macros = mems map (_.blackbox)
val macros = mems.map(_.blackbox)
val circuit = Circuit(NoInfo, macros, macros.last.name)
val passes = Seq(
new MacroCompilerPass(Some(mems), libs, None, None, getCostMetric, if (synflops) MacroCompilerAnnotation.Synflops else MacroCompilerAnnotation.Default),
new SynFlopsPass(synflops, libs getOrElse mems),
RemoveEmpty)
val result: Circuit = (passes foldLeft circuit)((c, pass) => pass run c)
new MacroCompilerPass(
Some(mems),
libs,
None,
None,
getCostMetric,
if (synflops) MacroCompilerAnnotation.Synflops else MacroCompilerAnnotation.Default
),
new SynFlopsPass(synflops, libs.getOrElse(mems)),
RemoveEmpty
)
val result: Circuit = (passes.foldLeft(circuit))((c, pass) => pass.run(c))
result
}
// 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] = {
@@ -126,7 +146,6 @@ trait HasSRAMGenerator {
implicit def Int2SomeInt(i: Int): Option[Int] = Some(i)
implicit def BigInt2SomeBigInt(i: BigInt): Option[BigInt] = Some(i)
// Generate a standard (read/write/combo) port for testing.
// Helper methods for optional width argument
def generateTestPort(
@@ -144,44 +163,70 @@ trait HasSRAMGenerator {
MacroPort(
address = PolarizedPort(name = realPrefix + "addr", polarity = ActiveHigh),
clock = Some(PolarizedPort(name = realPrefix + "clk", polarity = PositiveEdge)),
readEnable = if (readEnable) Some(PolarizedPort(name = realPrefix + "read_en", polarity = ActiveHigh)) else None,
writeEnable = if (writeEnable) Some(PolarizedPort(name = realPrefix + "write_en", polarity = ActiveHigh)) else None,
writeEnable =
if (writeEnable) Some(PolarizedPort(name = realPrefix + "write_en", polarity = ActiveHigh)) else None,
output = if (read) Some(PolarizedPort(name = realPrefix + "dout", polarity = ActiveHigh)) else None,
input = if (write) Some(PolarizedPort(name = realPrefix + "din", polarity = ActiveHigh)) else None,
maskPort = maskGran match {
case Some(x: Int) => Some(PolarizedPort(name = realPrefix + "mask", polarity = ActiveHigh))
case _ => None
},
maskGran = maskGran,
width = width, depth = depth // These numbers don't matter here.
width = width,
depth = depth // These numbers don't matter here.
)
}
// Generate a read port for testing.
def generateReadPort(prefix: String, width: Option[Int], depth: Option[BigInt], readEnable: Boolean = false): MacroPort = {
def generateReadPort(
prefix: String,
width: Option[Int],
depth: Option[BigInt],
readEnable: Boolean = false
): MacroPort = {
generateTestPort(prefix, width, depth, write = false, read = true, readEnable = readEnable)
}
// Generate a write port for testing.
def generateWritePort(prefix: String, width: Option[Int], depth: Option[BigInt], maskGran: Option[Int] = None, writeEnable: Boolean = true): MacroPort = {
def generateWritePort(
prefix: String,
width: Option[Int],
depth: Option[BigInt],
maskGran: Option[Int] = None,
writeEnable: Boolean = true
): MacroPort = {
generateTestPort(prefix, width, depth, maskGran = maskGran, write = true, read = false, writeEnable = writeEnable)
}
// Generate a simple read-write port for testing.
def generateReadWritePort(prefix: String, width: Option[Int], depth: Option[BigInt], maskGran: Option[Int] = None): MacroPort = {
def generateReadWritePort(
prefix: String,
width: Option[Int],
depth: Option[BigInt],
maskGran: Option[Int] = None
): MacroPort = {
generateTestPort(
prefix, width, depth, maskGran = maskGran,
write = true, writeEnable = true,
read = true, readEnable = false
prefix,
width,
depth,
maskGran = maskGran,
write = true,
writeEnable = true,
read = true,
readEnable = false
)
}
// Generate a "simple" SRAM (active high/positive edge, 1 read-write port).
def generateSRAM(name: String, prefix: String, width: Int, depth: BigInt, maskGran: Option[Int] = None, extraPorts: Seq[MacroExtraPort] = List()): SRAMMacro = {
def generateSRAM(
name: String,
prefix: String,
width: Int,
depth: BigInt,
maskGran: Option[Int] = None,
extraPorts: Seq[MacroExtraPort] = List()
): SRAMMacro = {
SRAMMacro(
name = name,
width = width,
@@ -193,17 +238,35 @@ trait HasSRAMGenerator {
}
// Generate a "simple" SRAM group (active high/positive edge, 1 read-write port).
def generateSimpleSRAMGroup(prefix: String, mux: Int, depth: Range, width: Range, maskGran: Option[Int] = None, extraPorts: Seq[MacroExtraPort] = List()): SRAMGroup = {
SRAMGroup(Seq("mygroup_", "width", "x", "depth", "_", "VT"), "1rw", Seq("svt", "lvt", "ulvt"), mux, depth, width, Seq(generateReadWritePort(prefix, None, None, maskGran)))
def generateSimpleSRAMGroup(
prefix: String,
mux: Int,
depth: Range,
width: Range,
maskGran: Option[Int] = None,
extraPorts: Seq[MacroExtraPort] = List()
): SRAMGroup = {
SRAMGroup(
Seq("mygroup_", "width", "x", "depth", "_", "VT"),
"1rw",
Seq("svt", "lvt", "ulvt"),
mux,
depth,
width,
Seq(generateReadWritePort(prefix, None, None, maskGran))
)
}
// 'vt': ('svt','lvt','ulvt'), 'mux': 2, 'depth': range(16,513,8), 'width': range(8,289,2), 'ports': 1
// 'vt': ('svt','lvt','ulvt'), 'mux': 4, 'depth': range(32,1025,16), 'width': range(4,145), 'ports': 1}
def generateSRAMCompiler(name: String, prefix: String): mdf.macrolib.SRAMCompiler = {
SRAMCompiler(name, Seq(
SRAMCompiler(
name,
Seq(
generateSimpleSRAMGroup(prefix, 2, Range(16, 512, 8), Range(8, 288, 2)),
generateSimpleSRAMGroup(prefix, 4, Range(32, 1024, 16), Range(4, 144, 1))
))
)
)
}
}
@@ -288,8 +351,7 @@ trait HasSimpleTestGenerator {
lazy val lastWidthBits = if (memWidth % usableLibWidth == 0) usableLibWidth else (memWidth % usableLibWidth)
lazy val selectBits = mem_addr_width - lib_addr_width
/**
* Convenience function to generate a mask statement.
/** Convenience function to generate a mask statement.
* @param widthInst Width instance (mem_0_x)
* @param depthInst Depth instance (mem_x_0)
*/
@@ -312,7 +374,7 @@ trait HasSimpleTestGenerator {
// calculateMaskBit({0, 1}) = 0 and calculateMaskBit({1, 2}) = 1
def calculateMaskBit(bit: Int): Int = bit / memMaskGran.getOrElse(memWidth)
val bitsArr = ((libMaskBits - 1 to 0 by -1) map (x => {
val bitsArr = ((libMaskBits - 1 to 0 by -1).map(x => {
if (x * libMaskGran.get > myMemWidth) {
// If we have extra mask bits leftover after the effective width,
// disable those bits.
@@ -340,7 +402,17 @@ trait HasSimpleTestGenerator {
* @param mask Mask granularity (# bits) of the port or None.
* @param extraPorts Extra ports (name, # bits)
*/
def generatePort(prefix: String, addrWidth: Int, width: Int, write: Boolean, writeEnable: Boolean, read: Boolean, readEnable: Boolean, mask: Option[Int], extraPorts: Seq[(String, Int)] = Seq()): String = {
def generatePort(
prefix: String,
addrWidth: Int,
width: Int,
write: Boolean,
writeEnable: Boolean,
read: Boolean,
readEnable: Boolean,
mask: Option[Int],
extraPorts: Seq[(String, Int)] = Seq()
): String = {
val realPrefix = if (prefix == "") "" else prefix + "_"
val readStr = if (read) s"output ${realPrefix}dout : UInt<$width>" else ""
@@ -364,32 +436,58 @@ $extraPortsStr
"""
}
/**
* Helper function to generate a RW footer port.
/** Helper function to generate a RW footer port.
*
* @param prefix Memory port prefix (e.g. "x" for ports like "x_clk")
* @param readEnable Has a read enable port?
* @param mask Mask granularity (# bits) of the port or None.
* @param extraPorts Extra ports (name, # bits)
*/
def generateReadWriteFooterPort(prefix: String, readEnable: Boolean, mask: Option[Int], extraPorts: Seq[(String, Int)] = Seq()): String = {
generatePort(prefix, lib_addr_width, libWidth,
write = true, writeEnable = true, read = true, readEnable = readEnable, mask = mask, extraPorts = extraPorts)
def generateReadWriteFooterPort(
prefix: String,
readEnable: Boolean,
mask: Option[Int],
extraPorts: Seq[(String, Int)] = Seq()
): String = {
generatePort(
prefix,
lib_addr_width,
libWidth,
write = true,
writeEnable = true,
read = true,
readEnable = readEnable,
mask = mask,
extraPorts = extraPorts
)
}
/** Helper function to generate a RW header port.
* @param prefix Memory port prefix (e.g. "x" for ports like "x_clk")
* @param readEnable Has a read enable port?
* @param mask Mask granularity (# bits) of the port or None. */
* @param mask Mask granularity (# bits) of the port or None.
*/
def generateReadWriteHeaderPort(prefix: String, readEnable: Boolean, mask: Option[Int]): String = {
generatePort(prefix, mem_addr_width, memWidth,
write=true, writeEnable=true, read=true, readEnable=readEnable, mask)
generatePort(
prefix,
mem_addr_width,
memWidth,
write = true,
writeEnable = true,
read = true,
readEnable = readEnable,
mask
)
}
// Generate the header memory ports.
def generateHeaderPorts(): String = {
require(memSRAM.ports.size == 1, "Header generator only supports single RW port mem")
generateReadWriteHeaderPort(memPortPrefix, memSRAM.ports(0).readEnable.isDefined, if (memHasMask) Some(memMaskBits) else None)
generateReadWriteHeaderPort(
memPortPrefix,
memSRAM.ports(0).readEnable.isDefined,
if (memHasMask) Some(memMaskBits) else None
)
}
// Generate the header (contains the circuit statement and the target memory
@@ -405,8 +503,12 @@ ${generateHeaderPorts}
// Generate the target memory ports.
def generateFooterPorts(): String = {
require(libSRAM.ports.size == 1, "Footer generator only supports single RW port mem")
generateReadWriteFooterPort(libPortPrefix, libSRAM.ports(0).readEnable.isDefined,
if (libHasMask) Some(libMaskBits) else None, extraPorts.map(p => (p.name, p.width)))
generateReadWriteFooterPort(
libPortPrefix,
libSRAM.ports(0).readEnable.isDefined,
if (libHasMask) Some(libMaskBits) else None,
extraPorts.map(p => (p.name, p.width))
)
}
// Generate the footer (contains the target memory extmodule declaration by default).
@@ -450,4 +552,3 @@ trait HasNoLibTestGenerator extends HasSimpleTestGenerator {
// If there is no lib, don't generate a body.
override def generateBody = ""
}

View File

@@ -9,9 +9,7 @@ trait MasksTestSettings {
}
// Try all four different kinds of mask config:
/**
*
* Non-masked mem Masked mem
/** Non-masked mem Masked mem
* ---------------------------------
* Non-masked lib | | |
* ---------------------------------
@@ -19,7 +17,10 @@ trait MasksTestSettings {
* ---------------------------------
*/
class Masks_FourTypes_NonMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_NonMaskedMem_NonMaskedLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = None
@@ -29,7 +30,10 @@ class Masks_FourTypes_NonMaskedMem_NonMaskedLib extends MacroCompilerSpec with H
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_NonMaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_NonMaskedMem_MaskedLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = None
@@ -39,7 +43,10 @@ class Masks_FourTypes_NonMaskedMem_MaskedLib extends MacroCompilerSpec with HasS
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_MaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_MaskedMem_NonMaskedLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = Some(8)
@@ -49,7 +56,10 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib extends MacroCompilerSpec with HasS
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = Some(4)
@@ -59,7 +69,10 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran extends MacroCompil
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_MaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_MaskedMem_MaskedLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = Some(8)
@@ -69,7 +82,10 @@ class Masks_FourTypes_MaskedMem_MaskedLib extends MacroCompilerSpec with HasSRAM
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 32
override lazy val memMaskGran = Some(8)
@@ -79,7 +95,10 @@ class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran extends MacroCompilerSpec
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 64
override lazy val memMaskGran = Some(4)
@@ -103,7 +122,11 @@ class Masks_BitMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGene
// FPGA-style byte-masked memories.
class Masks_FPGAStyle_32_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_FPGAStyle_32_8
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 32
override lazy val memMaskGran = Some(32)
override lazy val libMaskGran = Some(8)
@@ -113,7 +136,11 @@ class Masks_FPGAStyle_32_8 extends MacroCompilerSpec with HasSRAMGenerator with
// Simple powers of two with bit-masked lib.
class Masks_PowersOfTwo_8_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_8_1
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 64
override lazy val memMaskGran = Some(8)
override lazy val libMaskGran = Some(1)
@@ -121,7 +148,11 @@ class Masks_PowersOfTwo_8_1 extends MacroCompilerSpec with HasSRAMGenerator with
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_PowersOfTwo_16_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_16_1
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 64
override lazy val memMaskGran = Some(16)
override lazy val libMaskGran = Some(1)
@@ -129,7 +160,11 @@ class Masks_PowersOfTwo_16_1 extends MacroCompilerSpec with HasSRAMGenerator wit
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_PowersOfTwo_32_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_32_1
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 64
override lazy val memMaskGran = Some(32)
override lazy val libMaskGran = Some(1)
@@ -137,7 +172,11 @@ class Masks_PowersOfTwo_32_1 extends MacroCompilerSpec with HasSRAMGenerator wit
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_PowersOfTwo_64_1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_64_1
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 64
override lazy val memMaskGran = Some(64)
override lazy val libMaskGran = Some(1)
@@ -147,7 +186,11 @@ class Masks_PowersOfTwo_64_1 extends MacroCompilerSpec with HasSRAMGenerator wit
// Simple powers of two with non bit-masked lib.
class Masks_PowersOfTwo_32_4 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_32_4
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 128
override lazy val memMaskGran = Some(32)
override lazy val libMaskGran = Some(4)
@@ -155,7 +198,11 @@ class Masks_PowersOfTwo_32_4 extends MacroCompilerSpec with HasSRAMGenerator wit
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_PowersOfTwo_32_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_32_8
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 128
override lazy val memMaskGran = Some(32)
override lazy val libMaskGran = Some(8)
@@ -163,7 +210,11 @@ class Masks_PowersOfTwo_32_8 extends MacroCompilerSpec with HasSRAMGenerator wit
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_PowersOfTwo_8_8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_PowersOfTwo_8_8
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 128
override lazy val memMaskGran = Some(8)
override lazy val libMaskGran = Some(8)
@@ -173,7 +224,11 @@ class Masks_PowersOfTwo_8_8 extends MacroCompilerSpec with HasSRAMGenerator with
// Width as a multiple of the mask, bit-masked lib
class Masks_IntegerMaskMultiple_20_10 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_20_10
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 20
override lazy val memMaskGran = Some(10)
override lazy val libMaskGran = Some(1)
@@ -181,16 +236,24 @@ class Masks_IntegerMaskMultiple_20_10 extends MacroCompilerSpec with HasSRAMGene
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_21_7 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_21_7
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 21
override lazy val memMaskGran = Some(21)
override lazy val libMaskGran = Some(7)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//~ compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_21_21 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_21_21
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 21
override lazy val memMaskGran = Some(21)
override lazy val libMaskGran = Some(1)
@@ -198,7 +261,11 @@ class Masks_IntegerMaskMultiple_21_21 extends MacroCompilerSpec with HasSRAMGene
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_84_21 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_84_21
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 84
override lazy val memMaskGran = Some(21)
override lazy val libMaskGran = Some(1)
@@ -206,7 +273,11 @@ class Masks_IntegerMaskMultiple_84_21 extends MacroCompilerSpec with HasSRAMGene
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_92_23 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_92_23
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 92
override lazy val memMaskGran = Some(23)
override lazy val libMaskGran = Some(1)
@@ -214,7 +285,11 @@ class Masks_IntegerMaskMultiple_92_23 extends MacroCompilerSpec with HasSRAMGene
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_117_13 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_117_13
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 117
override lazy val memMaskGran = Some(13)
override lazy val libMaskGran = Some(1)
@@ -222,7 +297,11 @@ class Masks_IntegerMaskMultiple_117_13 extends MacroCompilerSpec with HasSRAMGen
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_160_20 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_160_20
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 160
override lazy val memMaskGran = Some(20)
override lazy val libMaskGran = Some(1)
@@ -230,7 +309,11 @@ class Masks_IntegerMaskMultiple_160_20 extends MacroCompilerSpec with HasSRAMGen
compileExecuteAndTest(mem, lib, v, output)
}
class Masks_IntegerMaskMultiple_184_23 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_IntegerMaskMultiple_184_23
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 184
override lazy val memMaskGran = Some(23)
override lazy val libMaskGran = Some(1)
@@ -240,11 +323,15 @@ class Masks_IntegerMaskMultiple_184_23 extends MacroCompilerSpec with HasSRAMGen
// Width as an non-integer multiple of the mask, bit-masked lib
class Masks_NonIntegerMaskMultiple_32_3 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with MasksTestSettings {
class Masks_NonIntegerMaskMultiple_32_3
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with MasksTestSettings {
override lazy val width = 32
override lazy val memMaskGran = Some(3)
override lazy val libMaskGran = Some(1)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//~ compileExecuteAndTest(mem, lib, v, output)
}

View File

@@ -17,15 +17,28 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim
width = memWidth,
depth = memDepth,
family = "2rw",
ports=Seq(generateTestPort(
"portA", memWidth, Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
), generateTestPort(
"portB", memWidth, Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"portA",
memWidth,
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
),
generateTestPort(
"portB",
memWidth,
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
@@ -35,20 +48,35 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim
width = libWidth,
depth = libDepth,
family = "2rw",
ports=Seq(generateTestPort(
"portA", libWidth, libDepth,
write=true, writeEnable=true,
read=true, readEnable=true
), generateTestPort(
"portB", libWidth, libDepth,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"portA",
libWidth,
libDepth,
write = true,
writeEnable = true,
read = true,
readEnable = true
),
generateTestPort(
"portB",
libWidth,
libDepth,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
override def generateHeaderPorts() = {
generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort("portB", true, Some(memMaskBits))
generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort(
"portB",
true,
Some(memMaskBits)
)
}
override def generateFooterPorts() = {
@@ -132,15 +160,28 @@ class SplitWidth_1r_1w extends MacroCompilerSpec with HasSRAMGenerator with HasS
width = memWidth,
depth = memDepth,
family = "1r1w",
ports=Seq(generateTestPort(
"portA", memWidth, Some(memDepth), maskGran=memMaskGran,
write=false, writeEnable=false,
read=true, readEnable=true
), generateTestPort(
"portB", memWidth, Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=false, readEnable=false
))
ports = Seq(
generateTestPort(
"portA",
memWidth,
Some(memDepth),
maskGran = memMaskGran,
write = false,
writeEnable = false,
read = true,
readEnable = true
),
generateTestPort(
"portB",
memWidth,
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = false,
readEnable = false
)
)
)
}
@@ -150,30 +191,73 @@ class SplitWidth_1r_1w extends MacroCompilerSpec with HasSRAMGenerator with HasS
width = libWidth,
depth = libDepth,
family = "1r1w",
ports=Seq(generateTestPort(
"portA", libWidth, libDepth,
write=false, writeEnable=false,
read=true, readEnable=true
), generateTestPort(
"portB", libWidth, libDepth,
write=true, writeEnable=true,
read=false, readEnable=false
))
ports = Seq(
generateTestPort(
"portA",
libWidth,
libDepth,
write = false,
writeEnable = false,
read = true,
readEnable = true
),
generateTestPort(
"portB",
libWidth,
libDepth,
write = true,
writeEnable = true,
read = false,
readEnable = false
)
)
)
}
override def generateHeaderPorts() = {
generatePort("portA", mem_addr_width, memWidth,
write=false, writeEnable=false, read=true, readEnable=true, Some(memMaskBits)) + "\n" +
generatePort("portB", mem_addr_width, memWidth,
write=true, writeEnable=true, read=false, readEnable=false, Some(memMaskBits))
generatePort(
"portA",
mem_addr_width,
memWidth,
write = false,
writeEnable = false,
read = true,
readEnable = true,
Some(memMaskBits)
) + "\n" +
generatePort(
"portB",
mem_addr_width,
memWidth,
write = true,
writeEnable = true,
read = false,
readEnable = false,
Some(memMaskBits)
)
}
override def generateFooterPorts() = {
generatePort("portA", lib_addr_width, libWidth,
write=false, writeEnable=false, read=true, readEnable=true, None) + "\n" +
generatePort("portB", lib_addr_width, libWidth,
write=true, writeEnable=true, read=false, readEnable=false, None)
generatePort(
"portA",
lib_addr_width,
libWidth,
write = false,
writeEnable = false,
read = true,
readEnable = true,
None
) + "\n" +
generatePort(
"portB",
lib_addr_width,
libWidth,
write = true,
writeEnable = true,
read = false,
readEnable = false,
None
)
}
override def generateBody() =
@@ -238,15 +322,28 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera
width = memWidth,
depth = memDepth,
family = "2rw",
ports=Seq(generateTestPort(
"portA", memWidth, Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
), generateTestPort(
"portB", memWidth, Some(memDepth), maskGran=Some(memMaskGranB),
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"portA",
memWidth,
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
),
generateTestPort(
"portB",
memWidth,
Some(memDepth),
maskGran = Some(memMaskGranB),
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
@@ -256,20 +353,35 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera
width = libWidth,
depth = libDepth,
family = "2rw",
ports=Seq(generateTestPort(
"portA", libWidth, libDepth,
write=true, writeEnable=true,
read=true, readEnable=true
), generateTestPort(
"portB", libWidth, libDepth,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"portA",
libWidth,
libDepth,
write = true,
writeEnable = true,
read = true,
readEnable = true
),
generateTestPort(
"portB",
libWidth,
libDepth,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
override def generateHeaderPorts() = {
generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort("portB", true, Some(memWidth / memMaskGranB))
generateReadWriteHeaderPort("portA", true, Some(memMaskBits)) + "\n" + generateReadWriteHeaderPort(
"portB",
true,
Some(memWidth / memMaskGranB)
)
}
override def generateFooterPorts() = {

View File

@@ -13,7 +13,6 @@ class SRAMCompiler extends MacroCompilerSpec with HasSRAMGenerator with HasSimpl
writeToLib(lib, Seq(compiler))
writeToMem(mem, Seq(generateSRAM("mymem", "X", 8, 16)))
compileExecuteAndTest(mem, Some(lib), verilog, output = output, false, true)

View File

@@ -28,9 +28,12 @@ s"""
for (i <- 0 to depthInstances - 1) {
val maskStatement = generateMaskStatement(0, i)
val enableIdentifier = if (selectBits > 0) s"""eq(${memPortPrefix}_addr_sel, UInt<${selectBits}>("h${i.toHexString}"))""" else "UInt<1>(\"h1\")"
val enableIdentifier =
if (selectBits > 0) s"""eq(${memPortPrefix}_addr_sel, UInt<${selectBits}>("h${i.toHexString}"))"""
else "UInt<1>(\"h1\")"
val chipEnable = s"""UInt<1>("h1")"""
val writeEnable = if (memMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en"
val writeEnable =
if (memMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en"
output.append(
s"""
inst mem_${i}_0 of ${lib_name}
@@ -49,15 +52,18 @@ s"""
s"""UInt<${libWidth}>("h0")"""
} else {
s"""mux(eq(${memPortPrefix}_addr_sel_reg, UInt<%d>("h%s")), ${memPortPrefix}_dout_%d, %s)""".format(
selectBits, i.toHexString, i, generate_outer_dout_tree(i + 1, depthInstances)
selectBits,
i.toHexString,
i,
generate_outer_dout_tree(i + 1, depthInstances)
)
}
}
output append s" ${memPortPrefix}_dout <= "
output.append(s" ${memPortPrefix}_dout <= ")
if (selectBits > 0) {
output append generate_outer_dout_tree(0, depthInstances)
output.append(generate_outer_dout_tree(0, depthInstances))
} else {
output append s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))"""
output.append(s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))""")
}
output.toString
@@ -154,7 +160,10 @@ class SplitDepth2048x8_mrw_lib8 extends MacroCompilerSpec with HasSRAMGenerator
}
// Non-bit level mask
class SplitDepth2048x64_mrw_mem32_lib8 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator {
class SplitDepth2048x64_mrw_mem32_lib8
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator {
override lazy val width = 64
override lazy val memDepth = BigInt(2048)
override lazy val libDepth = BigInt(1024)
@@ -165,7 +174,10 @@ class SplitDepth2048x64_mrw_mem32_lib8 extends MacroCompilerSpec with HasSRAMGen
}
// Bit level mask
class SplitDepth2048x32_mrw_mem16_lib1 extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator {
class SplitDepth2048x32_mrw_mem16_lib1
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator {
override lazy val width = 32
override lazy val memDepth = BigInt(2048)
override lazy val libDepth = BigInt(1024)
@@ -213,7 +225,7 @@ class SplitDepth2048x32_mrw_mem3_lib1 extends MacroCompilerSpec with HasSRAMGene
override lazy val memMaskGran = Some(3)
override lazy val libMaskGran = Some(1)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//compileExecuteAndTest(mem, lib, v, output)
}
@@ -224,7 +236,7 @@ class SplitDepth2048x32_mrw_mem7_lib1 extends MacroCompilerSpec with HasSRAMGene
override lazy val memMaskGran = Some(7)
override lazy val libMaskGran = Some(1)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//compileExecuteAndTest(mem, lib, v, output)
}
@@ -235,7 +247,7 @@ class SplitDepth2048x32_mrw_mem9_lib1 extends MacroCompilerSpec with HasSRAMGene
override lazy val memMaskGran = Some(9)
override lazy val libMaskGran = Some(1)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//compileExecuteAndTest(mem, lib, v, output)
}

View File

@@ -15,14 +15,15 @@ trait HasSimpleWidthTestGenerator extends HasSimpleTestGenerator {
// Generate mem_0_<i> lines for number of width instances.
output.append(
((0 to widthInstances - 1) map {i:Int => s"""
((0 to widthInstances - 1).map { i: Int =>
s"""
inst mem_0_${i} of ${lib_name}
"""
}).reduceLeft(_ + _)
)
// Generate submemory connection blocks.
output append (for (i <- 0 to widthInstances - 1) yield {
output.append((for (i <- 0 to widthInstances - 1) yield {
// Width of this submemory.
val myMemWidth = if (i == widthInstances - 1) lastWidthBits else usableLibWidth
// Base bit of this submemory.
@@ -39,7 +40,8 @@ trait HasSimpleWidthTestGenerator extends HasSimpleTestGenerator {
s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})"
} else """UInt<1>("h1")"""
val chipEnable = s"""UInt<1>("h1")"""
val writeEnableExpr = if (libMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en"
val writeEnableExpr =
if (libMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en"
s"""
mem_0_${i}.${libPortPrefix}_clk <= ${memPortPrefix}_clk
@@ -49,22 +51,21 @@ s"""
${maskStatement}
mem_0_${i}.${libPortPrefix}_write_en <= and(and(${writeEnableExpr}, ${writeEnableBit}), UInt<1>("h1"))
"""
}).reduceLeft(_ + _)
}).reduceLeft(_ + _))
// Generate final output that concats together the sub-memories.
// e.g. cat(outer_dout_0_2, cat(outer_dout_0_1, outer_dout_0_0))
output append {
val doutStatements = ((widthInstances - 1 to 0 by -1) map (i => s"${memPortPrefix}_dout_0_${i}"))
output.append {
val doutStatements = ((widthInstances - 1 to 0 by -1).map(i => s"${memPortPrefix}_dout_0_${i}"))
val catStmt = doutStatements.init.foldRight(doutStatements.last)((l: String, r: String) => s"cat($l, $r)")
s"""
node ${memPortPrefix}_dout_0 = ${catStmt}
"""
}
output append
s"""
output.append(s"""
${memPortPrefix}_dout <= mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${memWidth}>("h0"))
"""
""")
output.toString
}
}
@@ -268,7 +269,10 @@ class SplitWidth1024x16_mem11_rw extends MacroCompilerSpec with HasSRAMGenerator
// Masked RAM
class SplitWidth1024x8_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x8_memGran_8_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 8
override lazy val libWidth = 8
@@ -278,7 +282,10 @@ class SplitWidth1024x8_memGran_8_libGran_1_rw extends MacroCompilerSpec with Has
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x16_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_8_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -288,7 +295,10 @@ class SplitWidth1024x16_memGran_8_libGran_1_rw extends MacroCompilerSpec with Ha
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x16_memGran_8_libGran_8_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_8_libGran_8_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -298,7 +308,10 @@ class SplitWidth1024x16_memGran_8_libGran_8_rw extends MacroCompilerSpec with Ha
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x128_memGran_8_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x128_memGran_8_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 128
override lazy val libWidth = 32
@@ -308,7 +321,10 @@ class SplitWidth1024x128_memGran_8_libGran_1_rw extends MacroCompilerSpec with H
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x16_memGran_4_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_4_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -318,7 +334,10 @@ class SplitWidth1024x16_memGran_4_libGran_1_rw extends MacroCompilerSpec with Ha
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x16_memGran_2_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_2_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -328,7 +347,10 @@ class SplitWidth1024x16_memGran_2_libGran_1_rw extends MacroCompilerSpec with Ha
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x16_memGran_16_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_16_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -360,7 +382,10 @@ class SplitWidth1024x16_libGran_1_rw extends MacroCompilerSpec with HasSRAMGener
// Non-memMask and non-1 libMask
class SplitWidth1024x16_memGran_8_libGran_2_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_8_libGran_2_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
@@ -372,21 +397,27 @@ class SplitWidth1024x16_memGran_8_libGran_2_rw extends MacroCompilerSpec with Ha
// Non-power of two memGran
class SplitWidth1024x16_memGran_9_libGran_1_rw extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x16_memGran_9_libGran_1_rw
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
override lazy val depth = BigInt(1024)
override lazy val memWidth = 16
override lazy val libWidth = 8
override lazy val memMaskGran = Some(9)
override lazy val libMaskGran = Some(1)
it should "be enabled when non-power of two masks are supported" is (pending)
(it should "be enabled when non-power of two masks are supported").is(pending)
//~ compile(mem, lib, v, false)
//~ execute(mem, lib, false, output)
}
// Read enable
class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x32_readEnable_Lib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
import mdf.macrolib._
override lazy val depth = BigInt(1024)
@@ -399,11 +430,18 @@ class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGen
width = libWidth,
depth = libDepth,
family = "1rw",
ports=Seq(generateTestPort(
"lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"lib",
Some(libWidth),
Some(libDepth),
maskGran = libMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
@@ -444,7 +482,10 @@ class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGen
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x32_readEnable_Mem
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
import mdf.macrolib._
override lazy val depth = BigInt(1024)
@@ -457,11 +498,18 @@ class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGen
width = memWidth,
depth = memDepth,
family = "1rw",
ports=Seq(generateTestPort(
"outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"outer",
Some(memWidth),
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
@@ -470,7 +518,10 @@ class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGen
compileExecuteAndTest(mem, lib, v, output)
}
class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
class SplitWidth1024x32_readEnable_LibMem
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator {
import mdf.macrolib._
override lazy val depth = BigInt(1024)
@@ -483,11 +534,18 @@ class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAM
width = libWidth,
depth = libDepth,
family = "1rw",
ports=Seq(generateTestPort(
"lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"lib",
Some(libWidth),
Some(libDepth),
maskGran = libMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}
@@ -497,11 +555,18 @@ class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAM
width = memWidth,
depth = memDepth,
family = "1rw",
ports=Seq(generateTestPort(
"outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran,
write=true, writeEnable=true,
read=true, readEnable=true
))
ports = Seq(
generateTestPort(
"outer",
Some(memWidth),
Some(memDepth),
maskGran = memMaskGran,
write = true,
writeEnable = true,
read = true,
readEnable = true
)
)
)
}

View File

@@ -29,8 +29,8 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator {
override val libPrefix = "macros/src/test/resources"
val memSRAMs = mdf.macrolib.Utils.readMDFFromString(
"""
val memSRAMs = mdf.macrolib.Utils
.readMDFFromString("""
[ {
"type" : "sram",
"name" : "cc_banks_0_ext",
@@ -99,8 +99,8 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator {
override val libPrefix = "macros/src/test/resources"
val memSRAMs = mdf.macrolib.Utils.readMDFFromString(
"""
val memSRAMs = mdf.macrolib.Utils
.readMDFFromString("""
[ {
"type" : "sram",
"name" : "cc_dir_ext",
@@ -183,8 +183,8 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator {
override val libPrefix = "macros/src/test/resources"
val memSRAMs = mdf.macrolib.Utils.readMDFFromString(
"""
val memSRAMs = mdf.macrolib.Utils
.readMDFFromString("""
[ {
"type" : "sram",
"name" : "_T_182_ext",
@@ -1453,8 +1453,8 @@ class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator {
)
)
val memSRAMs = mdf.macrolib.Utils.readMDFFromString(
"""
val memSRAMs = mdf.macrolib.Utils
.readMDFFromString("""
[
{
"type": "sram",

View File

@@ -47,7 +47,8 @@ s"""
// If there is no lib, don't generate a footer, since the flops definition
// will be in the body.
override def generateFooter = {
if (this.isInstanceOf[HasNoLibTestGenerator]) "" else
if (this.isInstanceOf[HasNoLibTestGenerator]) ""
else
s"""
module ${lib_name} :
${generateFooterPorts}
@@ -58,28 +59,44 @@ ${generateFlops}
}
class Synflops2048x8_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator {
class Synflops2048x8_noLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasNoLibTestGenerator
with HasSynFlopsTestGenerator {
override lazy val memDepth = BigInt(2048)
override lazy val memWidth = 8
compileExecuteAndTest(mem, None, v, output, true)
}
class Synflops2048x16_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator {
class Synflops2048x16_noLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasNoLibTestGenerator
with HasSynFlopsTestGenerator {
override lazy val memDepth = BigInt(2048)
override lazy val memWidth = 16
compileExecuteAndTest(mem, None, v, output, true)
}
class Synflops8192x16_noLib extends MacroCompilerSpec with HasSRAMGenerator with HasNoLibTestGenerator with HasSynFlopsTestGenerator {
class Synflops8192x16_noLib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasNoLibTestGenerator
with HasSynFlopsTestGenerator {
override lazy val memDepth = BigInt(8192)
override lazy val memWidth = 16
compileExecuteAndTest(mem, None, v, output, true)
}
class Synflops2048x16_depth_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator {
class Synflops2048x16_depth_Lib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with HasSynFlopsTestGenerator {
override lazy val memDepth = BigInt(2048)
override lazy val libDepth = BigInt(1024)
override lazy val width = 16
@@ -87,7 +104,11 @@ class Synflops2048x16_depth_Lib extends MacroCompilerSpec with HasSRAMGenerator
compileExecuteAndTest(mem, lib, v, output, true)
}
class Synflops2048x64_width_Lib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator with HasSynFlopsTestGenerator {
class Synflops2048x64_width_Lib
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleWidthTestGenerator
with HasSynFlopsTestGenerator {
override lazy val memWidth = 64
override lazy val libWidth = 8
override lazy val depth = BigInt(1024)
@@ -95,7 +116,11 @@ class Synflops2048x64_width_Lib extends MacroCompilerSpec with HasSRAMGenerator
compileExecuteAndTest(mem, lib, v, output, true)
}
class Synflops_SplitPorts_Read_Write extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator {
class Synflops_SplitPorts_Read_Write
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with HasSynFlopsTestGenerator {
import mdf.macrolib._
override lazy val memDepth = BigInt(2048)
@@ -222,7 +247,11 @@ circuit target_memory :
}
}
class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator with HasSynFlopsTestGenerator {
class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite
extends MacroCompilerSpec
with HasSRAMGenerator
with HasSimpleDepthTestGenerator
with HasSynFlopsTestGenerator {
import mdf.macrolib._
override lazy val memDepth = BigInt(2048)