Repository: ucb-bar/barstools (language: python)

Issue:
Reformat code using scalafmt
Ran `scalafmt` over `iocells`, `macros`, and `tapeout`
This brings code into accordance with chisel standards
Easier to do now, before I do 3.4/3.5 refactor
This should be done after #95



Discussion / hints:

Fix patch:
diff --git a/build.sbt b/build.sbt
index fd9638b1..d8840865 100644
--- a/build.sbt
+++ b/build.sbt
@@ -7,15 +7,14 @@ val defaultVersions = Map(
 
 lazy val commonSettings = Seq(
   organization := "edu.berkeley.cs",
-  version := "0.1-SNAPSHOT",
+  version := "0.4-SNAPSHOT",
   scalaVersion := "2.12.10",
   scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Xsource:2.11"),
   libraryDependencies ++= Seq("chisel3","chisel-iotesters").map {
     dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep))
   },
-  libraryDependencies in Test ++= Seq(
-    "org.scalatest" %% "scalatest" % "2.2.5" % "test",
-    "org.scalacheck" %% "scalacheck" % "1.12.4" % "test"
+  libraryDependencies ++= Seq(
+    "org.scalatest" %% "scalatest" % "3.2.2" % "test",
   ),
   resolvers ++= Seq(
     Resolver.sonatypeRepo("snapshots"),
@@ -31,9 +30,6 @@ lazy val macros = (project in file("macros"))
   .dependsOn(mdf)
   .settings(commonSettings)
   .settings(
-    libraryDependencies ++= Seq(
-      "edu.berkeley.cs" %% "firrtl-interpreter" % "1.4.+" % Test
-    ),
     mainClass := Some("barstools.macros.MacroCompiler")
   )
   .enablePlugins(sbtassembly.AssemblyPlugin)
diff --git a/iocell/src/main/scala/chisel/Analog.scala b/iocell/src/main/scala/barstools/iocell/chisel/Analog.scala
similarity index 61%
rename from iocell/src/main/scala/chisel/Analog.scala
rename to iocell/src/main/scala/barstools/iocell/chisel/Analog.scala
index e1b4fc78..0cdfc493 100644
--- a/iocell/src/main/scala/chisel/Analog.scala
+++ b/iocell/src/main/scala/barstools/iocell/chisel/Analog.scala
@@ -6,8 +6,10 @@ import chisel3._
 import chisel3.util.{HasBlackBoxResource}
 import chisel3.experimental.{Analog, IntParam}
 
-class AnalogConst(value: Int, width: Int = 1) extends BlackBox(Map("CONST" -> IntParam(value), "WIDTH" -> IntParam(width))) with HasBlackBoxResource{
-  val io = IO(new Bundle {val io = Analog(width.W) } )
+class AnalogConst(value: Int, width: Int = 1)
+    extends BlackBox(Map("CONST" -> IntParam(value), "WIDTH" -> IntParam(width)))
+    with HasBlackBoxResource {
+  val io = IO(new Bundle { val io = Analog(width.W) })
   addResource("/barstools/iocell/vsrc/Analog.v")
 }
 
diff --git a/iocell/src/main/scala/chisel/IOCell.scala b/iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala
similarity index 73%
rename from iocell/src/main/scala/chisel/IOCell.scala
rename to iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala
index a5926030..d244d298 100644
--- a/iocell/src/main/scala/chisel/IOCell.scala
+++ b/iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala
@@ -4,7 +4,7 @@ package barstools.iocell.chisel
 
 import chisel3._
 import chisel3.util.{Cat, HasBlackBoxResource}
-import chisel3.experimental.{Analog, DataMirror, IO, BaseModule}
+import chisel3.experimental.{Analog, BaseModule, DataMirror, IO}
 
 // The following four IO cell bundle types are bare-minimum functional connections
 // for modeling 4 different IO cell scenarios. The intention is that the user
@@ -13,24 +13,22 @@ import chisel3.experimental.{Analog, DataMirror, IO, BaseModule}
 // (https://github.com/sifive/sifive-blocks/blob/master/src/main/scala/devices/pinctrl/PinCtrl.scala),
 // but we want to avoid a dependency on an external libraries.
 
-/**
- * The base IO bundle for an analog signal (typically something with no digital buffers inside)
- *  pad: off-chip (external) connection
- *  core: internal connection
- */
+/** The base IO bundle for an analog signal (typically something with no digital buffers inside)
+  *  pad: off-chip (external) connection
+  *  core: internal connection
+  */
 class AnalogIOCellBundle extends Bundle {
-  val pad = Analog(1.W)   // Pad/bump signal (off-chip)
-  val core = Analog(1.W)  // core signal (on-chip)
+  val pad = Analog(1.W) // Pad/bump signal (off-chip)
+  val core = Analog(1.W) // core signal (on-chip)
 }
 
-/**
- * The base IO bundle for a signal with runtime-controllable direction
- *  pad: off-chip (external) connection
- *  i: input to chip logic (output from IO cell)
- *  ie: enable signal for i
- *  o: output from chip logic (input to IO cell)
- *  oe: enable signal for o
- */
+/** The base IO bundle for a signal with runtime-controllable direction
+  *  pad: off-chip (external) connection
+  *  i: input to chip logic (output from IO cell)
+  *  ie: enable signal for i
+  *  o: output from chip logic (input to IO cell)
+  *  oe: enable signal for o
+  */
 class DigitalGPIOCellBundle extends Bundle {
   val pad = Analog(1.W)
   val i = Output(Bool())
@@ -39,24 +37,22 @@ class DigitalGPIOCellBundle extends Bundle {
   val oe = Input(Bool())
 }
 
-/**
- * The base IO bundle for a digital output signal
- *  pad: off-chip (external) connection
- *  o: output from chip logic (input to IO cell)
- *  oe: enable signal for o
- */
+/** The base IO bundle for a digital output signal
+  *  pad: off-chip (external) connection
+  *  o: output from chip logic (input to IO cell)
+  *  oe: enable signal for o
+  */
 class DigitalOutIOCellBundle extends Bundle {
   val pad = Output(Bool())
   val o = Input(Bool())
   val oe = Input(Bool())
 }
 
-/**
- * The base IO bundle for a digital input signal
- *  pad: off-chip (external) connection
- *  i: input to chip logic (output from IO cell)
- *  ie: enable signal for i
- */
+/** The base IO bundle for a digital input signal
+  *  pad: off-chip (external) connection
+  *  i: input to chip logic (output from IO cell)
+  *  ie: enable signal for i
+  */
 class DigitalInIOCellBundle extends Bundle {
   val pad = Input(Bool())
   val i = Output(Bool())
@@ -102,11 +98,10 @@ class GenericDigitalOutIOCell extends GenericIOCell with DigitalOutIOCell {
   val io = IO(new DigitalOutIOCellBundle)
 }
 
-
 trait IOCellTypeParams {
   def analog(): AnalogIOCell
-  def gpio(): DigitalGPIOCell
-  def input(): DigitalInIOCell
+  def gpio():   DigitalGPIOCell
+  def input():  DigitalInIOCell
   def output(): DigitalOutIOCell
 }
 
@@ -118,47 +113,49 @@ case class GenericIOCellParams() extends IOCellTypeParams {
 }
 
 object IOCell {
-  /**
-   * From within a RawModule or MultiIOModule context, generate new module IOs from a given
-   * signal and return the new IO and a Seq containing all generated IO cells.
-   * @param coreSignal The signal onto which to add IO cells
-   * @param name An optional name or name prefix to use for naming IO cells
-   * @param abstractResetAsAsync When set, will coerce abstract resets to
-   *        AsyncReset, and otherwise to Bool (sync reset)
-   * @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances)
-   */
-  def generateIOFromSignal[T <: Data](coreSignal: T, name: String,
-    typeParams: IOCellTypeParams = GenericIOCellParams(),
-    abstractResetAsAsync: Boolean = false): (T, Seq[IOCell]) =
-  {
+
+  /** From within a RawModule or MultiIOModule context, generate new module IOs from a given
+    * signal and return the new IO and a Seq containing all generated IO cells.
+    * @param coreSignal The signal onto which to add IO cells
+    * @param name An optional name or name prefix to use for naming IO cells
+    * @param abstractResetAsAsync When set, will coerce abstract resets to
+    *        AsyncReset, and otherwise to Bool (sync reset)
+    * @return A tuple of (the generated IO data node, a Seq of all generated IO cell instances)
+    */
+  def generateIOFromSignal[T <: Data](
+    coreSignal:           T,
+    name:                 String,
+    typeParams:           IOCellTypeParams = GenericIOCellParams(),
+    abstractResetAsAsync: Boolean = false
+  ): (T, Seq[IOCell]) = {
     val padSignal = IO(DataMirror.internal.chiselTypeClone[T](coreSignal)).suggestName(name)
     val resetFn = if (abstractResetAsAsync) toAsyncReset else toSyncReset
     val iocells = IOCell.generateFromSignal(coreSignal, padSignal, Some(s"iocell_$name"), typeParams, resetFn)
     (padSignal, iocells)
   }
 
-  /**
-   * Connect two identical signals together by adding IO cells between them and return a Seq
-   * containing all generated IO cells.
-   * @param coreSignal The core-side (internal) signal onto which to connect/add IO cells
-   * @param padSignal The pad-side (external) signal onto which to connect IO cells
-   * @param name An optional name or name prefix to use for naming IO cells
-   * @return A Seq of all generated IO cell instances
-   */
-  val toSyncReset: (Reset) => Bool = _.toBool
+  /** Connect two identical signals together by adding IO cells between them and return a Seq
+    * containing all generated IO cells.
+    * @param coreSignal The core-side (internal) signal onto which to connect/add IO cells
+    * @param padSignal The pad-side (external) signal onto which to connect IO cells
+    * @param name An optional name or name prefix to use for naming IO cells
+    * @return A Seq of all generated IO cell instances
+    */
+  val toSyncReset:  (Reset) => Bool = _.toBool
   val toAsyncReset: (Reset) => AsyncReset = _.asAsyncReset
   def generateFromSignal[T <: Data, R <: Reset](
-    coreSignal: T,
-    padSignal: T,
-    name: Option[String] = None,
-    typeParams: IOCellTypeParams = GenericIOCellParams(),
-    concretizeResetFn : (Reset) => R = toSyncReset): Seq[IOCell] =
-  {
+    coreSignal:        T,
+    padSignal:         T,
+    name:              Option[String] = None,
+    typeParams:        IOCellTypeParams = GenericIOCellParams(),
+    concretizeResetFn: (Reset) => R = toSyncReset
+  ): Seq[IOCell] = {
     def genCell[T <: Data](
-        castToBool: (T) => Bool,
-        castFromBool: (Bool) => T)(
-        coreSignal: T,
-        padSignal: T): Seq[IOCell] = {
+      castToBool:   (T) => Bool,
+      castFromBool: (Bool) => T
+    )(coreSignal:   T,
+      padSignal:    T
+    ): Seq[IOCell] = {
       DataMirror.directionOf(coreSignal) match {
         case ActualDirection.Input => {
           val iocell = typeParams.input()
@@ -188,7 +185,10 @@ object IOCell {
         if (coreSignal.getWidth == 0) {
           Seq()
         } else {
-          require(coreSignal.getWidth == 1, "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)")
+          require(
+            coreSignal.getWidth == 1,
+            "Analogs wider than 1 bit are not supported because we can't bit-select Analogs (https://github.com/freechipsproject/chisel3/issues/536)"
+          )
           val iocell = typeParams.analog()
           name.foreach(n => iocell.suggestName(n))
           iocell.io.core <> coreSignal
@@ -204,7 +204,7 @@ object IOCell {
           // This dummy assignment will prevent invalid firrtl from being emitted
           DataMirror.directionOf(coreSignal) match {
             case ActualDirection.Input => coreSignal := 0.U
-            case _ => {}
+            case _                     => {}
           }
           Seq()
         } else {
diff --git a/macros/src/main/scala/SynFlops.scala b/macros/src/main/scala/SynFlops.scala
deleted file mode 100644
index f815b4cb..00000000
--- a/macros/src/main/scala/SynFlops.scala
+++ /dev/null
@@ -1,141 +0,0 @@
-// See LICENSE for license details.
-
-package barstools.macros
-
-import firrtl._
-import firrtl.ir._
-import firrtl.Utils._
-import firrtl.passes.MemPortUtils.{memPortField, memType}
-import Utils._
-
-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) =>
-      (res, port.maskPort) match {
-        case (_, None) =>
-          res
-        case (None, Some(_)) =>
-          Some(port.effectiveMaskGran)
-        case (Some(x), Some(_)) =>
-          assert(x == port.effectiveMaskGran)
-          res
-      }
-    ) match {
-      case None => (UIntType(IntWidth(lib.src.width)), lib.src.width)
-      case Some(gran) => (UIntType(IntWidth(gran)), gran.intValue)
-    }
-
-    val maxDepth = min(lib.src.depth, 1<<26)
-    val numMems = lib.src.depth / maxDepth
-
-    // 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 mod_macro = (new MacroCompilerPass(None,None,None,None)).compile(lib, lib_macro)
-    val (real_mod, real_macro) = mod_macro.get
-
-    val mem = DefMemory(
-      NoInfo,
-      "ram",
-      dataType,
-      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")
-    )
-
-    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))
-        case (Some(en_port), None) => portToExpression(en_port)
-        case (None, Some(re_port)) => portToExpression(re_port)
-        case (None, None) => one
-      }
-      val data = memPortField(mem, s"R_$i", "data")
-      val read = data
-      Seq(
-        Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock),
-        Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address),
-        Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable),
-        Connect(NoInfo, WRef(r.src.output.get.name), read)
-      )
-    }
-
-    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))
-        case (Some(en), None) => portToExpression(en)
-        case (None, Some(we)) => portToExpression(we)
-        case (None, None) => zero // is it possible?
-      }
-      val mask = w.src.maskPort match {
-        case Some(m) => portToExpression(m)
-        case None => one
-      }
-      val data = memPortField(mem, s"W_$i", "data")
-      val write = portToExpression(w.src.input.get)
-      Seq(
-        Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock),
-        Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address),
-        Connect(NoInfo, memPortField(mem, s"W_$i", "en"), enable),
-        Connect(NoInfo, memPortField(mem, s"W_$i", "mask"), mask),
-        Connect(NoInfo, data, write)
-      )
-    }
-
-    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 {
-        case Some(we) => portToExpression(we)
-        case None => zero // is it possible?
-      }
-      val wmask = rw.src.maskPort match {
-        case Some(wm) => portToExpression(wm)
-        case None => one
-      }
-      val enable = (rw.src.chipEnable, rw.src.readEnable) match {
-        case (Some(en), Some(re)) =>
-          and(portToExpression(en), or(portToExpression(re), wmode))
-        case (Some(en), None) => portToExpression(en)
-        case (None, Some(re)) => or(portToExpression(re), wmode)
-        case (None, None) => one
-      }
-      val wdata = memPortField(mem, s"RW_$i", "wdata")
-      val rdata = memPortField(mem, s"RW_$i", "rdata")
-      val write = portToExpression(rw.src.input.get)
-      val read = rdata
-      Seq(
-        Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock),
-        Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address),
-        Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable),
-        Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode),
-        Connect(NoInfo, memPortField(mem, s"RW_$i", "wmask"), wmask),
-        Connect(NoInfo, WRef(rw.src.output.get.name), read),
-        Connect(NoInfo, wdata, write)
-      )
-    }
-
-    extraMods.append(real_macro.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects))))
-    real_mod
-  }}).toMap
-
-  def run(c: Circuit): Circuit = {
-    if (!synflops) c
-    else c.copy(modules = (c.modules map (m => libMods.getOrElse(m.name, m))) ++ extraMods)
-  }
-}
diff --git a/macros/src/main/scala/Utils.scala b/macros/src/main/scala/Utils.scala
deleted file mode 100644
index c416ca6a..00000000
--- a/macros/src/main/scala/Utils.scala
+++ /dev/null
@@ -1,221 +0,0 @@
-// See LICENSE for license details.
-
-package barstools.macros
-
-import firrtl._
-import firrtl.ir._
-import firrtl.PrimOps
-import firrtl.passes.memlib.{MemConf, MemPort, ReadPort, WritePort, ReadWritePort, MaskedWritePort, MaskedReadWritePort}
-import firrtl.Utils.BoolType
-import mdf.macrolib.{Constant, MacroPort, SRAMMacro}
-import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge, MacroExtraPort}
-import java.io.File
-import scala.language.implicitConversions
-
-object MacroCompilerMath {
-  def ceilLog2(x: BigInt): Int = (x-1).bitLength
-}
-
-class FirrtlMacroPort(port: MacroPort) {
-  val src = port
-
-  val isReader = port.output.nonEmpty && port.input.isEmpty
-  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 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 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 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 =>
-    assert(p.portType == Constant) // TODO: release it?
-    val name = p.name
-    val width = BigInt(p.width.toLong)
-    val value = BigInt(p.value.toLong)
-    (name -> UIntLiteral(value, IntWidth(width)))
-  }
-
-  // Bundle representing this memory blackbox
-  val tpe = BundleType(firrtlPorts flatMap (_.tpe.fields))
-
-  private val modPorts = (firrtlPorts flatMap (_.ports)) ++
-    (extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
-  val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil)
-  def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body)
-}
-
-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 _ => None
-    }
-  }
-  // This utility reads a conf in and returns MDF like mdf.macrolib.Utils.readMDFFromPath
-  def readConfFromPath(path: Option[String]): Option[Seq[mdf.macrolib.Macro]] = {
-    path.map((p) => Utils.readConfFromString(scala.io.Source.fromFile(p).mkString))
-  }
-  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))
-    }
-  }
-  def portSpecToFamily(ports: Seq[MemPort]): String = {
-    val numR = ports.count(_ match { case ReadPort => true; case _ => false})
-    val numW = ports.count(_ match { case WritePort|MaskedWritePort => true; case _ => false})
-    val numRW = ports.count(_ match { case ReadWritePort|MaskedReadWritePort => true; case _ => false})
-    val numRStr = if(numR > 0) s"${numR}r" else ""
-    val numWStr = if(numW > 0) s"${numW}w" else ""
-    val numRWStr = if(numRW > 0) s"${numRW}rw" else ""
-    return numRStr + numWStr + numRWStr
-  }
-  // This translates between two represenations of ports
-  def portSpecToMacroPort(width: Int, depth: BigInt, maskGran: Option[Int], ports: Seq[MemPort]): Seq[MacroPort] = {
-    var numR = 0
-    var numW = 0
-    var numRW = 0
-    ports.map { _ match {
-      case ReadPort => {
-        val portName = s"R${numR}"
-        numR += 1
-        MacroPort(
-          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),
-          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),
-          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),
-          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),
-          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)),
-          maskPort=Some(PolarizedPort(s"${portName}_wmask", ActiveHigh)),
-          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
-        }
-      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)
-  }
-  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)
-  }
-  def makeName(g: mdf.macrolib.SRAMGroup, depth: Int, width: Int, vt: String): String = {
-    g.name.foldLeft(""){ (builder, next) =>
-      next match {
-        case "depth"|"DEPTH" => builder + depth
-        case "width"|"WIDTH" => builder + width
-        case "vt" => builder + vt.toLowerCase
-        case "VT" => builder + vt.toUpperCase
-        case "family" => builder + g.family.toLowerCase
-        case "FAMILY" => builder + g.family.toUpperCase
-        case "mux"|"MUX" => builder + g.mux
-        case other => builder + other
-      }
-    }
-  }
-
-  def and(e1: Expression, e2: Expression) =
-    DoPrim(PrimOps.And, Seq(e1, e2), Nil, e1.tpe)
-  def or(e1: Expression, e2: Expression) =
-    DoPrim(PrimOps.Or, Seq(e1, e2), Nil, e1.tpe)
-  def bits(e: Expression, high: BigInt, low: BigInt): Expression =
-    DoPrim(PrimOps.Bits, Seq(e), Seq(high, low), UIntType(IntWidth(high-low+1)))
-  def bits(e: Expression, idx: BigInt): Expression = bits(e, idx, idx)
-  def cat(es: Seq[Expression]): Expression =
-    if (es.size == 1) es.head
-    else DoPrim(PrimOps.Cat, Seq(es.head, cat(es.tail)), Nil, UnknownType)
-  def not(e: Expression) =
-    DoPrim(PrimOps.Not, Seq(e), Nil, e.tpe)
-
-  // Convert a port to a FIRRTL expression, handling polarity along the way.
-  def portToExpression(pp: PolarizedPort): Expression =
-    portToExpression(WRef(pp.name), Some(pp.polarity))
-
-  def portToExpression(exp: Expression, polarity: Option[PortPolarity]): Expression =
-    polarity match {
-      case Some(ActiveLow) | Some(NegativeEdge) => not(exp)
-      case _ => exp
-    }
-
-  // Check if a number is a power of two
-  def isPowerOfTwo(x: Int): Boolean = (x & (x - 1)) == 0
-}
diff --git a/macros/src/main/scala/CostMetric.scala b/macros/src/main/scala/barstools/macros/CostMetric.scala
similarity index 69%
rename from macros/src/main/scala/CostMetric.scala
rename to macros/src/main/scala/barstools/macros/CostMetric.scala
index b80324aa..3b9de124 100644
--- a/macros/src/main/scala/CostMetric.scala
+++ b/macros/src/main/scala/barstools/macros/CostMetric.scala
@@ -2,27 +2,25 @@
 
 package barstools.macros
 
-/**
- * Trait which can calculate the cost of compiling a memory against a certain
- * library memory macro using a cost function.
- */
+/** 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
-   * macro.
-   *
-   * @param mem Memory macro to compile (target memory)
-   * @param lib Library memory macro to use (library memory)
-   * @return The cost of this compile, defined by this cost metric, or None if
-   *         it cannot be compiled.
-   */
+
+  /** Cost function that returns the cost of compiling a memory using a certain
+    * macro.
+    *
+    * @param mem Memory macro to compile (target memory)
+    * @param lib Library memory macro to use (library memory)
+    * @return The cost of this compile, defined by this cost metric, or None if
+    *         it cannot be compiled.
+    */
   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]
 
   // We also want this to show up for the class itself.
@@ -40,8 +38,9 @@ trait CostMetricCompanion {
 // Some default cost functions.
 
 /** 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. */
+  * TODO: figure out what is the difference between this metric and the current
+  * 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,17 +57,17 @@ object OldMetric extends CostMetric with CostMetricCompanion {
   override def construct(m: Map[String, String]) = OldMetric
 }
 
-/**
- * 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
- * Double.
- */
+/** 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
+  * Double.
+  */
 class ExternalMetric(path: String) extends CostMetric {
   import mdf.macrolib.Utils.writeMacroToPath
+
   import java.io._
-  import scala.language.postfixOps // for !! postfix op
+  import scala.language.postfixOps
   import sys.process._
 
   override def cost(mem: Macro, lib: Macro): Option[Double] = {
@@ -104,7 +103,7 @@ object ExternalMetric extends CostMetricCompanion {
   override def construct(m: Map[String, String]) = {
     val pathOption = m.get("path")
     pathOption match {
-      case Some(path:String) => new ExternalMetric(path)
+      case Some(path: String) => new ExternalMetric(path)
       case _ => throw new IllegalArgumentException("ExternalMetric missing option 'path'")
     }
   }
@@ -114,14 +113,17 @@ 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
+        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
       }
     }
     val depthCost = math.ceil(mem.src.depth.toDouble / lib.src.depth.toDouble)
@@ -129,10 +131,10 @@ object DefaultMetric extends CostMetric with CostMetricCompanion {
     val bitsCost = (lib.src.depth * lib.src.width).toDouble
     // Fraction of wasted bits plus const per mem
     val requestedBits = (mem.src.depth * mem.src.width).toDouble
-    val bitsWasted = depthCost*widthCost*bitsCost - requestedBits
+    val bitsWasted = depthCost * widthCost * bitsCost - requestedBits
     val wastedConst = 0.05 // 0 means waste as few bits with no regard for instance count
-    val costPerInst = wastedConst*depthCost*widthCost
-    Some(1.0*bitsWasted/requestedBits+costPerInst)
+    val costPerInst = wastedConst * depthCost * widthCost
+    Some(1.0 * bitsWasted / requestedBits + costPerInst)
   }
 
   override def commandLineParams = Map()
@@ -147,10 +149,11 @@ 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)
+    val oos:  ObjectOutputStream = new ObjectOutputStream(baos)
     oos.writeObject(o)
     oos.close()
     return Base64.getEncoder.encodeToString(baos.toByteArray)
@@ -167,6 +170,7 @@ object MacroCompilerUtil {
 }
 
 object CostMetric {
+
   /** Define some default metric. */
   val default: CostMetric = DefaultMetric
 
@@ -177,13 +181,12 @@ object CostMetric {
   registerCostMetric(ExternalMetric)
   registerCostMetric(DefaultMetric)
 
-  /**
-   * Register a cost metric.
-   * @param createFuncHelper Companion object to fetch the name and construct
-   *                         the metric.
-   */
+  /** Register a cost metric.
+    * @param createFuncHelper Companion object to fetch the name and construct
+    *                         the metric.
+    */
   def registerCostMetric(createFuncHelper: CostMetricCompanion): Unit = {
-    costMetricCreators.update(createFuncHelper.name, createFuncHelper)
+    costMetricCreators.update(createFuncHelper.name(), createFuncHelper)
   }
 
   /** Select a cost metric from string. */
@@ -193,7 +196,7 @@ object CostMetric {
     } else if (!costMetricCreators.contains(m)) {
       throw new IllegalArgumentException("Invalid cost metric " + m)
     } else {
-      costMetricCreators.get(m).get.construct(params)
+      costMetricCreators(m).construct(params)
     }
   }
 }
diff --git a/macros/src/main/scala/MacroCompiler.scala b/macros/src/main/scala/barstools/macros/MacroCompiler.scala
similarity index 65%
rename from macros/src/main/scala/MacroCompiler.scala
rename to macros/src/main/scala/barstools/macros/MacroCompiler.scala
index c057baa6..bfcf78da 100644
--- a/macros/src/main/scala/MacroCompiler.scala
+++ b/macros/src/main/scala/barstools/macros/MacroCompiler.scala
@@ -1,25 +1,24 @@
 // See LICENSE for license details.
 
-/**
- * Terminology note:
- * mem - target memory to compile, in design (e.g. Mem() in rocket)
- * lib - technology SRAM(s) to use to compile mem
- */
+/** Terminology note:
+  * mem - target memory to compile, in design (e.g. Mem() in rocket)
+  * lib - technology SRAM(s) to use to compile mem
+  */
 
 package barstools.macros
 
-import firrtl._
-import firrtl.ir._
-import firrtl.PrimOps
+import barstools.macros.Utils._
 import firrtl.Utils._
 import firrtl.annotations._
-import firrtl.transforms.{NoDCEAnnotation}
-import firrtl.CompilerUtils.getLoweringTransforms
-import mdf.macrolib.{PolarizedPort, PortPolarity, SRAMMacro, SRAMGroup, SRAMCompiler}
-import scala.collection.mutable.{ArrayBuffer, HashMap}
+import firrtl.ir._
+import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation}
+import firrtl.transforms.NoDCEAnnotation
+import firrtl.{PrimOps, _}
+import mdf.macrolib._
+
 import java.io.{File, FileWriter}
-import scala.io.{Source}
-import Utils._
+import scala.collection.mutable.{ArrayBuffer, HashMap}
+import scala.io.Source
 
 case class MacroCompilerException(msg: String) extends Exception(msg)
 
@@ -30,56 +29,75 @@ case class MacroCompilerAnnotation(content: String) extends NoTargetAnnotation {
   def params: Params = MacroCompilerUtil.objFromString(content).asInstanceOf[Params]
 }
 
-
-/**
- * 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]].
- *
- */
+/** 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. **/
+
+  /** 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. **/
+
+  /** CompileAvailable - compile what is possible and do nothing with uncompiled memories. * */
   case object CompileAvailable extends CompilerMode
 
-  /**
-   * 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?
-   */
+  /** 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?
+    */
   val Default = CompileAvailable
 
   // Options as list of (CompilerMode, command-line name, description)
   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)
+    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))
@@ -90,26 +108,34 @@ 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])
-
-  /**
-   * Create a MacroCompilerAnnotation.
-   * @param c Top-level circuit name (see class description)
-   * @param p Parameters (see above).
-   */
+  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.
+    * @param c Top-level circuit name (see class description)
+    * @param p Parameters (see above).
+    */
   def apply(c: String, p: Params): MacroCompilerAnnotation =
     MacroCompilerAnnotation(MacroCompilerUtil.objToString(p))
 
 }
 
-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 {
+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 {
   // 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
@@ -121,8 +147,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.
@@ -133,7 +158,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
@@ -204,7 +229,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()
               }
             }
@@ -267,9 +294,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)
@@ -288,14 +317,14 @@ 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)
         val nodeName = s"${ref.name}_sel"
-        val tpe = UIntType(IntWidth(high-low))
+        val tpe = UIntType(IntWidth(high - low))
         selects(ref.name) = WRef(nodeName, tpe)
-        stmts += DefNode(NoInfo, nodeName, bits(ref, high-1, low))
+        stmts += DefNode(NoInfo, nodeName, bits(ref, high - 1, low))
         // Donggyu: output selection should be piped
         if (port.output.isDefined) {
           val regName = s"${ref.name}_sel_reg"
@@ -304,7 +333,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
               and(WRef(ce.name, BoolType), WRef(re.name, BoolType))
             case (Some(ce), None) => WRef(ce.name, BoolType)
             case (None, Some(re)) => WRef(re.name, BoolType)
-            case (None, None) => one
+            case (None, None)     => one
           }
           selectRegs(ref.name) = WRef(regName, tpe)
           stmts += DefRegister(NoInfo, regName, tpe, WRef(port.clock.get.name), zero, WRef(regName))
@@ -318,18 +347,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)))
@@ -342,29 +371,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 {
@@ -374,20 +396,20 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
                * done after generating all the memories.  This saves up the
                * output statements for later. */
               val name = s"${mem}_${i}_${j}" // This name is the output from the instance (mem vs ${mem}).
-              val exp = portToExpression(bits(WSubField(inst, lib), high-low, 0), Some(lib_polarity))
+              val exp = portToExpression(bits(WSubField(inst, lib), high - low, 0), Some(lib_polarity))
               stmts += DefNode(NoInfo, name, exp)
               cats += WRef(name)
             case (None, Some(lib)) =>
-              /* Palmer: If the inner memory has an output port but the outer
-               * one doesn't then it's safe to just leave the outer
-               * port floating. */
+            /* Palmer: If the inner memory has an output port but the outer
+             * one doesn't then it's safe to just leave the outer
+             * port floating. */
             case (None, None) =>
-              /* Palmer: If there's no output ports at all (ie, read-only
-               * port on the memory) then just don't worry about it,
-               * there's nothing to do. */
+            /* Palmer: If there's no output ports at all (ie, read-only
+             * port on the memory) then just don't worry about it,
+             * there's nothing to do. */
             case (Some(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
           }
 
@@ -397,7 +419,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
               /* Palmer: The input port to a memory just needs to happen in parallel,
                * this does a part select to narrow the memory down. */
               stmts += connectPorts(bits(WRef(mem), high, low), lib, lib_polarity)
-              case (None, Some(lib)) =>
+            case (None, Some(lib)) =>
               /* Palmer: If the inner memory has an input port but the other
                * one doesn't then it's safe to just leave the inner
                * port floating.  This should be handled by the
@@ -406,12 +428,12 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
               //Firrtl cares about dangling inputs now tie it off
               stmts += IsInvalid(NoInfo, WSubField(inst, lib.name))
             case (None, None) =>
-              /* Palmer: If there's no input ports at all (ie, read-only
-               * port on the memory) then just don't worry about it,
-               * there's nothing to do. */
+            /* Palmer: If there's no input ports at all (ie, read-only
+             * port on the memory) then just don't worry about it,
+             * there's nothing to do. */
             case (Some(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
           }
 
@@ -430,26 +452,33 @@ 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)
-                  memPort.src.maskGran.get
-                else
-                  libPort.src.width.get
-
-                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.
-                    zero
-                  } else {
-                    if ((low + i) >= memPort.src.width.get) {
-                      // If our bit is larger than the whole width of the mem, just zero out the upper bits.
-                      zero
-                    } else {
-                      // Pick the appropriate bit from the mem mask.
-                      bits(WRef(mem), (low + i) / memPort.src.effectiveMaskGran)
-                    }
-                  }
-                })).reverse)
+                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 => {
+                        if (usingLessThanLibMaskGran && i >= effectiveLibWidth) {
+                          // If the memMaskGran is smaller than the lib's gran, then
+                          // zero out the upper bits.
+                          zero
+                        } else {
+                          if ((low + i) >= memPort.src.width.get) {
+                            // If our bit is larger than the whole width of the mem, just zero out the upper bits.
+                            zero
+                          } else {
+                            // Pick the appropriate bit from the mem mask.
+                            bits(WRef(mem), (low + i) / memPort.src.effectiveMaskGran)
+                          }
+                        }
+                      })
+                    )
+                    .reverse
+                )
               }
             case None =>
               /* If there is a lib mask port but no mem mask port, just turn on
@@ -483,7 +512,7 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
           // Chip enable port mapping
           val memChipEnable = memPort.src.chipEnable match {
             case Some(PolarizedPort(mem, _)) => WRef(mem)
-            case None      => one
+            case None                        => one
           }
 
           // Read enable port mapping
@@ -502,7 +531,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)
@@ -510,8 +543,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
@@ -519,13 +551,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 {
@@ -533,8 +567,8 @@ class MacroCompilerPass(mems: Option[Seq[Macro]],
                 return None
               }
             case (None, None, None) =>
-              // No write ports to match up (this may be a read-only port).
-              // This isn't necessarily an error condition.
+            // No write ports to match up (this may be a read-only port).
+            // This isn't necessarily an error condition.
           }
         }
         // Cat macro outputs for selection
@@ -542,7 +576,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 _ =>
         }
@@ -550,15 +584,17 @@ 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(select) =>
-            val output = (select foldRight (zeroOutputValue)) {
-              case ((cond, tval), fval) => Mux(cond, tval, fval, fval.tpe) }
-            stmts += Connect(NoInfo, WRef(mem), output)
-          case None =>
-        }
+        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)
+              }
+              stmts += Connect(NoInfo, WRef(mem), output)
+            case None =>
+          }
         case None =>
       }
     }
@@ -573,123 +609,138 @@ 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) =>
-
-        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)
-          (memMask, libMask) match {
-            case (None, _) => true
-            case (Some(_), None) => false
-            case (Some(m), Some(l)) => l <= m //Ignore memories that don't have nice mask
+        (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)
+            (memMask, libMask) match {
+              case (None, _)          => true
+              case (Some(_), None)    => false
+              case (Some(m), Some(l)) => l <= m //Ignore memories that don't have nice mask
+            }
           }
-        }
-        // 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)))
-            } )
+          // 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)))
+                })
+            }
+            case None => Seq()
           }
-          case None => Seq()
-        }
-        val fullLibs = libs ++ compLibs.flatten.flatten
-
-        // 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)){
-          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"
-            (best, cost)
-          case ((best, cost), lib) =>
-            // Run the cost function to evaluate this potential compile.
-            costMetric.cost(mem, lib) match {
-              case Some(newCost) => {
-                //System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${newCost}")
-                // Try compiling
-                compile(mem, lib) match {
-                  // If it was successful and the new cost is lower
-                  case Some(p) if (newCost < cost) => (Some(p), newCost)
-                  case _ => (best, cost)
+          val fullLibs = libs ++ compLibs.flatten.flatten
+
+          // 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)) {
+            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")
+              (best, cost)
+            case ((best, cost), lib) =>
+              // Run the cost function to evaluate this potential compile.
+              costMetric.cost(mem, lib) match {
+                case Some(newCost) => {
+                  //System.err.println(s"Cost of ${lib.src.name} for ${mem.src.name}: ${newCost}")
+                  // Try compiling
+                  compile(mem, lib) match {
+                    // If it was successful and the new cost is lower
+                    case Some(p) if (newCost < cost) => (Some(p), newCost)
+                    case _                           => (best, cost)
+                  }
                 }
+                case _ => (best, cost) // Cost function rejected this combination.
               }
-              case _ => (best, cost) // Cost function rejected this combination.
-            }
-        }
-
-        // If we were able to compile anything, then replace the original module
-        // in the modules list with a compiled version, as well as the extmodule
-        // stub for the lib.
-        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.")
-            else
-              modules
           }
-          case Some((mod, bb)) =>
-            hammerIR match {
-              case Some(f) => {
-                val hammerIRWriter = new FileWriter(new File(f), !firstLib)
-                if(firstLib) hammerIRWriter.write("[\n")
-                hammerIRWriter.write(bb.src.toJSON().toString())
-                hammerIRWriter.write("\n,\n")
-                hammerIRWriter.close()
-                firstLib = false
-              }
-              case None =>
+
+          // If we were able to compile anything, then replace the original module
+          // in the modules list with a compiled version, as well as the extmodule
+          // stub for the lib.
+          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."
+                )
+              else
+                modules
             }
-            (modules filterNot (m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox)
+            case Some((mod, bb)) =>
+              hammerIR match {
+                case Some(f) => {
+                  val hammerIRWriter = new FileWriter(new File(f), !firstLib)
+                  if (firstLib) hammerIRWriter.write("[\n")
+                  hammerIRWriter.write(bb.src.toJSON().toString())
+                  hammerIRWriter.write("\n,\n")
+                  hammerIRWriter.close()
+                  firstLib = false
+                }
+                case None =>
+              }
+              (modules.filterNot(m => m.name == mod.name || m.name == bb.blackbox.name)) ++ Seq(mod, bb.blackbox)
+          }
         }
-      }
       case _ => c.modules
     }
     c.copy(modules = modules)
   }
 }
 
-class MacroCompilerTransform extends Transform {
-  def inputForm = MidForm
-  def outputForm = MidForm
+class MacroCompilerTransform extends Transform with DependencyAPIMigration {
+  override def prerequisites = Forms.LowForm
+  override def optionalPrerequisites = Forms.LowFormOptimized
+  override def optionalPrerequisiteOf = Forms.LowEmitters
+  override def invalidates(a: Transform) = false
 
   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 {
         case Some("conf") => Utils.readConfFromPath(Some(memFile))
-        case _ => mdf.macrolib.Utils.readMDFFromPath(Some(memFile))
+        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(_)})
+        case Some(x: Seq[mdf.macrolib.Macro]) =>
+          Some(Utils.filterForSRAM(Some(x)).getOrElse(List()).map { new Macro(_) })
         case _ => None
       }
       val libs: Option[Seq[Macro]] = mdf.macrolib.Utils.readMDFFromPath(libFile) match {
-        case Some(x:Seq[mdf.macrolib.Macro]) =>
-          Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)})
+        case Some(x: Seq[mdf.macrolib.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){
+        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)
@@ -707,21 +758,25 @@ class MacroCompilerTransform extends Transform {
 
       val transforms = Seq(
         new MacroCompilerPass(memCompile, libs, compilers, hammerIR, costMetric, mode),
-        new SynFlopsPass(true, memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) {
-          libs.get
-        } else {
-          Seq.empty
-        })))
-      (transforms foldLeft state) ((s, xform) => xform runTransform s).copy(form = outputForm)
+        new SynFlopsPass(
+          true,
+          memSynflops ++ (if (mode == MacroCompilerAnnotation.CompileAndSynflops) {
+                            libs.get
+                          } else {
+                            Seq.empty
+                          })
+        )
+      )
+      (transforms.foldLeft(state))((s, xform) => xform.runTransform(s))
     case _ => state
   }
 }
 
-// FIXME: Use firrtl.LowerFirrtlOptimizations
-class MacroCompilerOptimizations extends SeqTransform {
-  def inputForm: CircuitForm = LowForm
-
-  def outputForm: CircuitForm = LowForm
+class MacroCompilerOptimizations extends SeqTransform with DependencyAPIMigration {
+  override def prerequisites = Forms.LowForm
+  override def optionalPrerequisites = Forms.LowFormOptimized
+  override def optionalPrerequisiteOf = Forms.LowEmitters
+  override def invalidates(a: Transform) = false
 
   def transforms: Seq[Transform] = Seq(
     passes.RemoveValidIf,
@@ -730,16 +785,8 @@ class MacroCompilerOptimizations extends SeqTransform {
     new firrtl.transforms.ConstantPropagation,
     passes.Legalize,
     passes.SplitExpressions,
-    passes.CommonSubexpressionElimination)
-}
-
-class MacroCompiler extends Compiler {
-  def emitter: Emitter = new VerilogEmitter
-
-  def transforms: Seq[Transform] =
-    Seq(new MacroCompilerTransform) ++
-      getLoweringTransforms(firrtl.ChirrtlForm, firrtl.LowForm) ++
-      Seq(new MacroCompilerOptimizations)
+    passes.CommonSubexpressionElimination
+  )
 }
 
 object MacroCompiler extends App {
@@ -757,8 +804,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)",
@@ -773,16 +821,20 @@ 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"
-
-  def parseArgs(map: MacroParamMap, costMap: CostParamMap, forcedMemories: ForcedMemories,
-                args: List[String]): (MacroParamMap, CostParamMap, ForcedMemories) =
+  ) ++ modeOptions).mkString("\n")
+
+  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 =>
-        parseArgs(map + (Macros  -> value) + (MacrosFormat -> "conf"), costMap, forcedMemories, tail)
+        parseArgs(map + (Macros -> value) + (MacrosFormat -> "conf"), costMap, forcedMemories, tail)
       case ("-m" | "--macro-mdf") :: value :: tail =>
-        parseArgs(map + (Macros  -> value) + (MacrosFormat -> "mdf"), costMap, forcedMemories, tail)
+        parseArgs(map + (Macros -> value) + (MacrosFormat -> "mdf"), costMap, forcedMemories, tail)
       case ("-l" | "--library") :: value :: tail =>
         parseArgs(map + (Library -> value), costMap, forcedMemories, tail)
       case ("-u" | "--use-compiler") :: tail =>
@@ -810,11 +862,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) {
@@ -822,35 +880,39 @@ object MacroCompiler extends App {
         // determined as the firrtl "top-level module".
         val circuit = Circuit(NoInfo, macros, macros.last.name)
         val annotations = AnnotationSeq(
-          Seq(MacroCompilerAnnotation(
-            circuit.main,
-            MacroCompilerAnnotation.Params(
-              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
+          Seq(
+            MacroCompilerAnnotation(
+              circuit.main,
+              MacroCompilerAnnotation.Params(
+                params(Macros),
+                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
+              )
             )
-          ))
+          )
         )
 
         // The actual MacroCompilerTransform basically just generates an input circuit
-        val macroCompilerInput = CircuitState(circuit, MidForm, annotations)
+        val macroCompilerInput = CircuitState(circuit, 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(
-            outputFileNameOverride = params.get(Verilog).getOrElse(""),
-            noDCE = true,
-            firrtlSource = Some(macroCompiled.circuit.serialize)
-          )
-        }
-
         // Run FIRRTL compiler
-        Driver.execute(firOptions)
+        (new FirrtlStage).execute(
+          Array.empty,
+          Seq(
+            OutputFileAnnotation(params.getOrElse(Verilog, "")),
+            RunFirrtlTransformAnnotation(new VerilogEmitter),
+            EmitCircuitAnnotation(classOf[VerilogEmitter]),
+            NoDCEAnnotation,
+            FirrtlSourceAnnotation(macroCompiled.circuit.serialize)
+          )
+        )
 
         params.get(HammerIR) match {
           case Some(hammerIRFile: String) => {
@@ -865,7 +927,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 {
@@ -879,8 +941,11 @@ object MacroCompiler extends App {
       }
     } catch {
       case e: java.util.NoSuchElementException =>
-        e.printStackTrace()
-        println(usage)
+        if (args.isEmpty) {
+          println("Command line arguments must be specified")
+        } else {
+          e.printStackTrace()
+        }
         e.printStackTrace()
         sys.exit(1)
       case e: MacroCompilerException =>
diff --git a/macros/src/main/scala/barstools/macros/SynFlops.scala b/macros/src/main/scala/barstools/macros/SynFlops.scala
new file mode 100644
index 00000000..77ea4c96
--- /dev/null
+++ b/macros/src/main/scala/barstools/macros/SynFlops.scala
@@ -0,0 +1,151 @@
+// See LICENSE for license details.
+
+package barstools.macros
+
+import barstools.macros.Utils._
+import firrtl.Utils._
+import firrtl._
+import firrtl.ir._
+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) =>
+        (res, port.maskPort) match {
+          case (_, None) =>
+            res
+          case (None, Some(_)) =>
+            Some(port.effectiveMaskGran)
+          case (Some(x), Some(_)) =>
+            assert(x == port.effectiveMaskGran)
+            res
+        }
+      ) match {
+        case None       => (UIntType(IntWidth(lib.src.width)), lib.src.width)
+        case Some(gran) => (UIntType(IntWidth(gran)), gran.intValue)
+      }
+
+      val maxDepth = min(lib.src.depth, 1 << 26)
+      val numMems = lib.src.depth / maxDepth
+
+      // 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 mod_macro = (new MacroCompilerPass(None, None, None, None)).compile(lib, lib_macro)
+      val (real_mod, real_macro) = mod_macro.get
+
+      val mem = DefMemory(
+        NoInfo,
+        "ram",
+        dataType,
+        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")
+      )
+
+      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))
+          case (Some(en_port), None) => portToExpression(en_port)
+          case (None, Some(re_port)) => portToExpression(re_port)
+          case (None, None)          => one
+        }
+        val data = memPortField(mem, s"R_$i", "data")
+        val read = data
+        Seq(
+          Connect(NoInfo, memPortField(mem, s"R_$i", "clk"), clock),
+          Connect(NoInfo, memPortField(mem, s"R_$i", "addr"), address),
+          Connect(NoInfo, memPortField(mem, s"R_$i", "en"), enable),
+          Connect(NoInfo, WRef(r.src.output.get.name), read)
+        )
+      }
+
+      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))
+          case (Some(en), None) => portToExpression(en)
+          case (None, Some(we)) => portToExpression(we)
+          case (None, None)     => zero // is it possible?
+        }
+        val mask = w.src.maskPort match {
+          case Some(m) => portToExpression(m)
+          case None    => one
+        }
+        val data = memPortField(mem, s"W_$i", "data")
+        val write = portToExpression(w.src.input.get)
+        Seq(
+          Connect(NoInfo, memPortField(mem, s"W_$i", "clk"), clock),
+          Connect(NoInfo, memPortField(mem, s"W_$i", "addr"), address),
+          Connect(NoInfo, memPortField(mem, s"W_$i", "en"), enable),
+          Connect(NoInfo, memPortField(mem, s"W_$i", "mask"), mask),
+          Connect(NoInfo, data, write)
+        )
+      }
+
+      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 {
+          case Some(we) => portToExpression(we)
+          case None     => zero // is it possible?
+        }
+        val wmask = rw.src.maskPort match {
+          case Some(wm) => portToExpression(wm)
+          case None     => one
+        }
+        val enable = (rw.src.chipEnable, rw.src.readEnable) match {
+          case (Some(en), Some(re)) =>
+            and(portToExpression(en), or(portToExpression(re), wmode))
+          case (Some(en), None) => portToExpression(en)
+          case (None, Some(re)) => or(portToExpression(re), wmode)
+          case (None, None)     => one
+        }
+        val wdata = memPortField(mem, s"RW_$i", "wdata")
+        val rdata = memPortField(mem, s"RW_$i", "rdata")
+        val write = portToExpression(rw.src.input.get)
+        val read = rdata
+        Seq(
+          Connect(NoInfo, memPortField(mem, s"RW_$i", "clk"), clock),
+          Connect(NoInfo, memPortField(mem, s"RW_$i", "addr"), address),
+          Connect(NoInfo, memPortField(mem, s"RW_$i", "en"), enable),
+          Connect(NoInfo, memPortField(mem, s"RW_$i", "wmode"), wmode),
+          Connect(NoInfo, memPortField(mem, s"RW_$i", "wmask"), wmask),
+          Connect(NoInfo, WRef(rw.src.output.get.name), read),
+          Connect(NoInfo, wdata, write)
+        )
+      }
+
+      extraMods.append(real_macro.module(Block(mem +: (readConnects ++ writeConnects ++ readwriteConnects))))
+      real_mod
+    }
+  }).toMap
+
+  def run(c: Circuit): Circuit = {
+    if (!synflops) c
+    else c.copy(modules = (c.modules.map(m => libMods.getOrElse(m.name, m))) ++ extraMods)
+  }
+}
diff --git a/macros/src/main/scala/barstools/macros/Utils.scala b/macros/src/main/scala/barstools/macros/Utils.scala
new file mode 100644
index 00000000..9afa51f3
--- /dev/null
+++ b/macros/src/main/scala/barstools/macros/Utils.scala
@@ -0,0 +1,269 @@
+// See LICENSE for license details.
+
+package barstools.macros
+
+import firrtl.Utils.BoolType
+import firrtl.ir._
+import firrtl.passes.memlib._
+import firrtl.{PrimOps, _}
+import mdf.macrolib.{Input => _, Output => _, _}
+
+import scala.language.implicitConversions
+
+object MacroCompilerMath {
+  def ceilLog2(x: BigInt): Int = (x - 1).bitLength
+}
+
+class FirrtlMacroPort(port: MacroPort) {
+  val src = port
+
+  val isReader = port.output.nonEmpty && port.input.isEmpty
+  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 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 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 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 =>
+    assert(p.portType == Constant) // TODO: release it?
+    val name = p.name
+    val width = BigInt(p.width.toLong)
+    val value = BigInt(p.value.toLong)
+    (name -> UIntLiteral(value, IntWidth(width)))
+  }
+
+  // Bundle representing this memory blackbox
+  val tpe = BundleType(firrtlPorts.flatMap(_.tpe.fields))
+
+  private val modPorts = (firrtlPorts.flatMap(_.ports)) ++
+    (extraPorts.map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
+  val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil)
+  def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body)
+}
+
+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 _ => None
+    }
+  }
+  // This utility reads a conf in and returns MDF like mdf.macrolib.Utils.readMDFFromPath
+  def readConfFromPath(path: Option[String]): Option[Seq[mdf.macrolib.Macro]] = {
+    path.map((p) => Utils.readConfFromString(scala.io.Source.fromFile(p).mkString))
+  }
+  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)
+      )
+    }
+  }
+  def portSpecToFamily(ports: Seq[MemPort]): String = {
+    val numR = ports.count(_ match { case ReadPort => true; case _ => false })
+    val numW = ports.count(_ match { case WritePort | MaskedWritePort => true; case _ => false })
+    val numRW = ports.count(_ match { case ReadWritePort | MaskedReadWritePort => true; case _ => false })
+    val numRStr = if (numR > 0) s"${numR}r" else ""
+    val numWStr = if (numW > 0) s"${numW}w" else ""
+    val numRWStr = if (numRW > 0) s"${numRW}rw" else ""
+    return numRStr + numWStr + numRWStr
+  }
+  // This translates between two represenations of ports
+  def portSpecToMacroPort(width: Int, depth: BigInt, maskGran: Option[Int], ports: Seq[MemPort]): Seq[MacroPort] = {
+    var numR = 0
+    var numW = 0
+    var numRW = 0
+    ports.map {
+      _ match {
+        case ReadPort => {
+          val portName = s"R${numR}"
+          numR += 1
+          MacroPort(
+            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),
+            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),
+            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),
+            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),
+            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)),
+            maskPort = Some(PolarizedPort(s"${portName}_wmask", ActiveHigh)),
+            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
+        }
+      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
+    )
+  }
+  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
+    )
+  }
+  def makeName(g: mdf.macrolib.SRAMGroup, depth: Int, width: Int, vt: String): String = {
+    g.name.foldLeft("") { (builder, next) =>
+      next match {
+        case "depth" | "DEPTH" => builder + depth
+        case "width" | "WIDTH" => builder + width
+        case "vt"              => builder + vt.toLowerCase
+        case "VT"              => builder + vt.toUpperCase
+        case "family"          => builder + g.family.toLowerCase
+        case "FAMILY"          => builder + g.family.toUpperCase
+        case "mux" | "MUX"     => builder + g.mux
+        case other             => builder + other
+      }
+    }
+  }
+
+  def and(e1: Expression, e2: Expression) =
+    DoPrim(PrimOps.And, Seq(e1, e2), Nil, e1.tpe)
+  def or(e1: Expression, e2: Expression) =
+    DoPrim(PrimOps.Or, Seq(e1, e2), Nil, e1.tpe)
+  def bits(e: Expression, high: BigInt, low: BigInt): Expression =
+    DoPrim(PrimOps.Bits, Seq(e), Seq(high, low), UIntType(IntWidth(high - low + 1)))
+  def bits(e: Expression, idx: BigInt): Expression = bits(e, idx, idx)
+  def cat(es: Seq[Expression]): Expression =
+    if (es.size == 1) es.head
+    else DoPrim(PrimOps.Cat, Seq(es.head, cat(es.tail)), Nil, UnknownType)
+  def not(e: Expression) =
+    DoPrim(PrimOps.Not, Seq(e), Nil, e.tpe)
+
+  // Convert a port to a FIRRTL expression, handling polarity along the way.
+  def portToExpression(pp: PolarizedPort): Expression =
+    portToExpression(WRef(pp.name), Some(pp.polarity))
+
+  def portToExpression(exp: Expression, polarity: Option[PortPolarity]): Expression =
+    polarity match {
+      case Some(ActiveLow) | Some(NegativeEdge) => not(exp)
+      case _                                    => exp
+    }
+
+  // Check if a number is a power of two
+  def isPowerOfTwo(x: Int): Boolean = (x & (x - 1)) == 0
+}
diff --git a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala
similarity index 82%
rename from tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala
index 26de5425..e2c5620d 100644
--- a/tapeout/src/main/scala/transforms/AddSuffixToModuleNames.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala
@@ -2,15 +2,14 @@
 
 package barstools.tapeout.transforms
 
+import firrtl.Mappers._
 import firrtl._
+import firrtl.annotations.{CircuitTarget, ModuleTarget, SingleTargetAnnotation}
 import firrtl.ir._
-import firrtl.Mappers._
-import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, CircuitTarget}
-import firrtl.stage.TransformManager.{TransformDependency}
-import firrtl.stage.{Forms}
+import firrtl.stage.Forms
+import firrtl.stage.TransformManager.TransformDependency
 
-case class KeepNameAnnotation(target: ModuleTarget)
-    extends SingleTargetAnnotation[ModuleTarget] {
+case class KeepNameAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
   def duplicate(n: ModuleTarget) = this.copy(n)
 }
 
@@ -21,8 +20,8 @@ case class ModuleNameSuffixAnnotation(target: CircuitTarget, suffix: String)
 
 class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.LowForm
-  override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
+  override def prerequisites:          Seq[TransformDependency] = Forms.LowForm
+  override def optionalPrerequisites:  Seq[TransformDependency] = Forms.LowFormOptimized
   override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
   override def invalidates(a: Transform): Boolean = false
 
@@ -37,7 +36,7 @@ class AddSuffixToModuleNames extends Transform with DependencyAPIMigration {
     val excludeSet = state.circuit.modules.flatMap {
       case e: ExtModule => Some(e.name)
       case m if (m.name == state.circuit.main) => Some(m.name)
-      case _ => None
+      case _                                   => None
     }.toSet
 
     val renamer = { (name: String) => if (excludeSet(name)) name else name + suffix }
diff --git a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala
similarity index 73%
rename from tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala
index 76ca1006..127a37fa 100644
--- a/tapeout/src/main/scala/transforms/AvoidExtModuleCollisions.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala
@@ -3,18 +3,18 @@
 package barstools.tapeout.transforms
 
 import firrtl._
+import firrtl.annotations.NoTargetAnnotation
 import firrtl.ir._
-import firrtl.annotations.{NoTargetAnnotation}
-import firrtl.options.{Dependency}
-import firrtl.stage.TransformManager.{TransformDependency}
-import firrtl.stage.{Forms}
-import firrtl.passes.memlib.{ReplSeqMem}
+import firrtl.options.Dependency
+import firrtl.passes.memlib.ReplSeqMem
+import firrtl.stage.Forms
+import firrtl.stage.TransformManager.TransformDependency
 
 case class LinkExtModulesAnnotation(mustLink: Seq[ExtModule]) extends NoTargetAnnotation
 
 class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.HighForm
+  override def prerequisites:         Seq[TransformDependency] = Forms.HighForm
   override def optionalPrerequisites: Seq[TransformDependency] = Seq(Dependency[RemoveUnusedModules])
   override def optionalPrerequisiteOf: Seq[TransformDependency] = {
     Forms.HighEmitters :+ Dependency[ReplSeqMem]
@@ -24,10 +24,9 @@ class AvoidExtModuleCollisions extends Transform with DependencyAPIMigration {
   def execute(state: CircuitState): CircuitState = {
     val mustLink = state.annotations.flatMap {
       case LinkExtModulesAnnotation(mustLink) => mustLink
-      case _ => Nil
+      case _                                  => Nil
     }
     val newAnnos = state.annotations.filterNot(_.isInstanceOf[LinkExtModulesAnnotation])
     state.copy(circuit = state.circuit.copy(modules = state.circuit.modules ++ mustLink), annotations = newAnnos)
   }
 }
-
diff --git a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala
similarity index 82%
rename from tapeout/src/main/scala/transforms/ConvertToExtModPass.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala
index 04e645fd..a81937a3 100644
--- a/tapeout/src/main/scala/transforms/ConvertToExtModPass.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala
@@ -3,15 +3,14 @@
 package barstools.tapeout.transforms
 
 import firrtl._
+import firrtl.annotations.{ModuleTarget, ReferenceTarget, SingleTargetAnnotation}
 import firrtl.ir._
-import firrtl.annotations.{ModuleTarget, SingleTargetAnnotation, ReferenceTarget}
-import firrtl.stage.TransformManager.{TransformDependency}
-import firrtl.stage.{Forms}
-import firrtl.options.{Dependency}
-import firrtl.passes.memlib.{ReplSeqMem}
+import firrtl.options.Dependency
+import firrtl.passes.memlib.ReplSeqMem
+import firrtl.stage.Forms
+import firrtl.stage.TransformManager.TransformDependency
 
-case class ConvertToExtModAnnotation(target: ModuleTarget)
-    extends SingleTargetAnnotation[ModuleTarget] {
+case class ConvertToExtModAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
   def duplicate(n: ModuleTarget) = this.copy(n)
 }
 
@@ -20,7 +19,7 @@ case class ConvertToExtModAnnotation(target: ModuleTarget)
 // otherwise it's left alone.
 class ConvertToExtMod extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.HighForm
+  override def prerequisites:         Seq[TransformDependency] = Forms.HighForm
   override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
   override def optionalPrerequisiteOf: Seq[TransformDependency] = {
     Forms.HighEmitters ++ Seq(Dependency[RemoveUnusedModules], Dependency[ReplSeqMem])
diff --git a/tapeout/src/main/scala/transforms/EnumerateModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala
similarity index 78%
rename from tapeout/src/main/scala/transforms/EnumerateModules.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala
index 6a732d75..182b0071 100644
--- a/tapeout/src/main/scala/transforms/EnumerateModules.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala
@@ -23,10 +23,12 @@ class EnumerateModulesPass(enumerate: (Module) => Unit) extends Pass {
 }
 
 class EnumerateModules(enumerate: (Module) => Unit)
-  extends Transform with SeqTransformBased with DependencyAPIMigration {
+    extends Transform
+    with SeqTransformBased
+    with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.LowForm
-  override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
+  override def prerequisites:          Seq[TransformDependency] = Forms.LowForm
+  override def optionalPrerequisites:  Seq[TransformDependency] = Forms.LowFormOptimized
   override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
   override def invalidates(a: Transform): Boolean = false
 
diff --git a/tapeout/src/main/scala/transforms/Generate.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala
similarity index 81%
rename from tapeout/src/main/scala/transforms/Generate.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala
index 17b8781d..01ea56e0 100644
--- a/tapeout/src/main/scala/transforms/Generate.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala
@@ -5,7 +5,7 @@ import firrtl.annotations._
 import firrtl.ir._
 import firrtl.passes.memlib.ReplSeqMemAnnotation
 import firrtl.stage.FirrtlCircuitAnnotation
-import firrtl.transforms.{BlackBoxResourceFileNameAnno, DedupModules}
+import firrtl.transforms.BlackBoxResourceFileNameAnno
 import logger.LazyLogging
 
 trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions =>
@@ -13,130 +13,150 @@ trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions =>
 
   parser.note("tapeout options")
 
-  parser.opt[String]("harness-o")
+  parser
+    .opt[String]("harness-o")
     .abbr("tho")
     .valueName("<harness-output>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessOutput = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to generate a harness at <harness-output>"
     }
 
-  parser.opt[String]("syn-top")
+  parser
+    .opt[String]("syn-top")
     .abbr("tst")
     .valueName("<syn-top>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         synTop = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set synTop"
     }
 
-  parser.opt[String]("top-fir")
+  parser
+    .opt[String]("top-fir")
     .abbr("tsf")
     .valueName("<top-fir>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         topFir = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set topFir"
     }
 
-  parser.opt[String]("top-anno-out")
+  parser
+    .opt[String]("top-anno-out")
     .abbr("tsaof")
     .valueName("<top-anno-out>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         topAnnoOut = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set topAnnoOut"
     }
 
-  parser.opt[String]("top-dotf-out")
+  parser
+    .opt[String]("top-dotf-out")
     .abbr("tdf")
     .valueName("<top-dotf-out>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         topDotfOut = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set the filename for the top resource .f file"
     }
 
-  parser.opt[String]("harness-top")
+  parser
+    .opt[String]("harness-top")
     .abbr("tht")
     .valueName("<harness-top>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessTop = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set harnessTop"
     }
 
-  parser.opt[String]("harness-fir")
+  parser
+    .opt[String]("harness-fir")
     .abbr("thf")
     .valueName("<harness-fir>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessFir = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set harnessFir"
     }
 
-  parser.opt[String]("harness-anno-out")
+  parser
+    .opt[String]("harness-anno-out")
     .abbr("thaof")
     .valueName("<harness-anno-out>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessAnnoOut = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set harnessAnnoOut"
     }
 
-  parser.opt[String]("harness-dotf-out")
+  parser
+    .opt[String]("harness-dotf-out")
     .abbr("hdf")
     .valueName("<harness-dotf-out>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessDotfOut = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set the filename for the harness resource .f file"
     }
 
-  parser.opt[String]("harness-conf")
+  parser
+    .opt[String]("harness-conf")
     .abbr("thconf")
-    .valueName ("<harness-conf-file>")
+    .valueName("<harness-conf-file>")
     .foreach { x =>
       tapeoutOptions = tapeoutOptions.copy(
         harnessConf = Some(x)
       )
-    }.text {
+    }
+    .text {
       "use this to set the harness conf file location"
     }
 
 }
 
 case class TapeoutOptions(
-  harnessOutput: Option[String] = None,
-  synTop: Option[String] = None,
-  topFir: Option[String] = None,
-  topAnnoOut: Option[String] = None,
-  topDotfOut: Option[String] = None,
-  harnessTop: Option[String] = None,
-  harnessFir: Option[String] = None,
+  harnessOutput:  Option[String] = None,
+  synTop:         Option[String] = None,
+  topFir:         Option[String] = None,
+  topAnnoOut:     Option[String] = None,
+  topDotfOut:     Option[String] = None,
+  harnessTop:     Option[String] = None,
+  harnessFir:     Option[String] = None,
   harnessAnnoOut: Option[String] = None,
   harnessDotfOut: Option[String] = None,
-  harnessConf: Option[String] = None
-) extends LazyLogging
+  harnessConf:    Option[String] = None)
+    extends LazyLogging
 
 // Requires two phases, one to collect modules below synTop in the hierarchy
 // and a second to remove those modules to generate the test harness
@@ -190,9 +210,9 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
     annoFile.foreach { annoPath =>
       val outputFile = new java.io.PrintWriter(annoPath)
       outputFile.write(JsonProtocol.serialize(res.circuitState.annotations.filter(_ match {
-        case da: DeletedAnnotation => false
-        case ec: EmittedComponent => false
-        case ea: EmittedAnnotation[_] => false
+        case da:  DeletedAnnotation       => false
+        case ec:  EmittedComponent        => false
+        case ea:  EmittedAnnotation[_]    => false
         case fca: FirrtlCircuitAnnotation => false
         case _ => true
       })))
@@ -207,7 +227,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
     result match {
       case x: FirrtlExecutionSuccess =>
         dump(x, tapeoutOptions.topFir, tapeoutOptions.topAnnoOut)
-        x.circuitState.circuit.modules.collect{ case e: ExtModule => e }
+        x.circuitState.circuit.modules.collect { case e: ExtModule => e }
       case x =>
         throw new Exception(s"executeTop failed while executing FIRRTL!\n${x}")
     }
@@ -220,9 +240,9 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
 
     val harnessAnnos =
       tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++
-      harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++
-      synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+
-      LinkExtModulesAnnotation(topExtModules)
+        harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++
+        synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+
+        LinkExtModulesAnnotation(topExtModules)
 
     // For harness run, change some firrtlOptions (below) for harness phase
     // customTransforms: setup harness transforms, add AvoidExtModuleCollisions
@@ -233,7 +253,7 @@ sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App =>
       outputFileNameOverride = tapeoutOptions.harnessOutput.get,
       annotations = firrtlOptions.annotations.map({
         case ReplSeqMemAnnotation(i, o) => ReplSeqMemAnnotation(i, tapeoutOptions.harnessConf.get)
-        case a => a
+        case a                          => a
       }) ++ harnessAnnos
     )
     val harnessResult = firrtl.Driver.execute(optionsManager)
diff --git a/tapeout/src/main/scala/transforms/ReParentCircuit.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala
similarity index 66%
rename from tapeout/src/main/scala/transforms/ReParentCircuit.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala
index cbf4d2f8..10356176 100644
--- a/tapeout/src/main/scala/transforms/ReParentCircuit.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala
@@ -3,20 +3,18 @@
 package barstools.tapeout.transforms
 
 import firrtl._
-import firrtl.ir._
 import firrtl.annotations._
-import firrtl.options.{Dependency}
-import firrtl.stage.TransformManager.{TransformDependency}
-import firrtl.stage.{Forms}
+import firrtl.options.Dependency
+import firrtl.stage.Forms
+import firrtl.stage.TransformManager.TransformDependency
 
-case class ReParentCircuitAnnotation(target: ModuleTarget)
-    extends SingleTargetAnnotation[ModuleTarget] {
+case class ReParentCircuitAnnotation(target: ModuleTarget) extends SingleTargetAnnotation[ModuleTarget] {
   def duplicate(n: ModuleTarget) = this.copy(n)
 }
 
 class ReParentCircuit extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.HighForm
+  override def prerequisites:         Seq[TransformDependency] = Forms.HighForm
   override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
   override def optionalPrerequisiteOf: Seq[TransformDependency] = {
     Forms.HighEmitters :+ Dependency[RemoveUnusedModules]
@@ -25,8 +23,8 @@ class ReParentCircuit extends Transform with DependencyAPIMigration {
 
   def execute(state: CircuitState): CircuitState = {
     val c = state.circuit
-    val newTopName = state.annotations.collectFirst {
-      case ReParentCircuitAnnotation(tgt) => tgt.module
+    val newTopName = state.annotations.collectFirst { case ReParentCircuitAnnotation(tgt) =>
+      tgt.module
     }
     val newCircuit = c.copy(main = newTopName.getOrElse(c.main))
     val mainRename = newTopName.map { s =>
diff --git a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala
similarity index 72%
rename from tapeout/src/main/scala/transforms/RemoveUnusedModules.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala
index 3feb6736..5d1cbc6c 100644
--- a/tapeout/src/main/scala/transforms/RemoveUnusedModules.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala
@@ -3,18 +3,18 @@
 package barstools.tapeout.transforms
 
 import firrtl._
+import firrtl.annotations.ModuleTarget
 import firrtl.ir._
-import firrtl.annotations.{ModuleTarget}
-import firrtl.stage.TransformManager.{TransformDependency}
-import firrtl.options.{Dependency}
-import firrtl.stage.{Forms}
-import firrtl.passes.memlib.{ReplSeqMem}
+import firrtl.options.Dependency
+import firrtl.passes.memlib.ReplSeqMem
+import firrtl.stage.Forms
+import firrtl.stage.TransformManager.TransformDependency
 
 // Removes all the unused modules in a circuit by recursing through every
 // instance (starting at the main module)
 class RemoveUnusedModules extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.HighForm
+  override def prerequisites:         Seq[TransformDependency] = Forms.HighForm
   override def optionalPrerequisites: Seq[TransformDependency] = Seq.empty
   override def optionalPrerequisiteOf: Seq[TransformDependency] = {
     Forms.HighEmitters :+ Dependency[ReplSeqMem]
@@ -22,8 +22,8 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration {
   override def invalidates(a: Transform): Boolean = false
 
   def execute(state: CircuitState): CircuitState = {
-    val modulesByName = state.circuit.modules.map{
-      case m: Module => (m.name, Some(m))
+    val modulesByName = state.circuit.modules.map {
+      case m: Module    => (m.name, Some(m))
       case m: ExtModule => (m.name, None)
     }.toMap
 
@@ -33,7 +33,7 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration {
           def someStatements(statement: Statement): Seq[Statement] =
             statement match {
               case b: Block =>
-                b.stmts.map{ someStatements(_) }
+                b.stmts.map { someStatements(_) }
                   .foldLeft(Seq[Statement]())(_ ++ _)
               case when: Conditionally =>
                 someStatements(when.conseq) ++ someStatements(when.alt)
@@ -41,11 +41,11 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration {
               case _ => Seq()
             }
 
-            someStatements(m.body).map{
-              case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
-              case _ => Set[String]()
-            }.foldLeft(Set(m.name))(_ | _)
-          }
+          someStatements(m.body).map {
+            case s: DefInstance => Set(s.module) | getUsedModules(modulesByName(s.module))
+            case _ => Set[String]()
+          }.foldLeft(Set(m.name))(_ | _)
+        }
 
         case None => Set.empty[String]
       }
@@ -57,7 +57,7 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration {
 
     val renames = state.renames.getOrElse(RenameMap())
 
-    state.circuit.modules.filterNot { usedModuleSet contains _.name } foreach { x =>
+    state.circuit.modules.filterNot { usedModuleSet contains _.name }.foreach { x =>
       renames.record(ModuleTarget(state.circuit.main, x.name), Nil)
     }
 
diff --git a/tapeout/src/main/scala/transforms/ResetInverter.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala
similarity index 86%
rename from tapeout/src/main/scala/transforms/ResetInverter.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala
index 1ccb1888..33d2f78a 100644
--- a/tapeout/src/main/scala/transforms/ResetInverter.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala
@@ -20,10 +20,9 @@ object ResetN extends Pass {
   // Only works on Modules with a Bool port named reset
   def invertReset(mod: Module): Module = {
     // Check that it actually has reset
-    require(mod.ports.exists(p => p.name == "reset" && p.tpe == Bool),
-      "Can only invert reset on a module with reset!")
+    require(mod.ports.exists(p => p.name == "reset" && p.tpe == Bool), "Can only invert reset on a module with reset!")
     // Rename "reset" to "reset_n"
-    val portsx = mod.ports map {
+    val portsx = mod.ports.map {
       case Port(info, "reset", Input, Bool) =>
         Port(info, "reset_n", Input, Bool)
       case other => other
@@ -34,7 +33,7 @@ object ResetN extends Pass {
   }
 
   def run(c: Circuit): Circuit = {
-    c.copy(modules = c.modules map {
+    c.copy(modules = c.modules.map {
       case mod: Module if mod.name == c.main => invertReset(mod)
       case other => other
     })
@@ -43,8 +42,8 @@ object ResetN extends Pass {
 
 class ResetInverterTransform extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.LowForm
-  override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
+  override def prerequisites:          Seq[TransformDependency] = Forms.LowForm
+  override def optionalPrerequisites:  Seq[TransformDependency] = Forms.LowFormOptimized
   override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
   override def invalidates(a: Transform): Boolean = false
 
@@ -64,7 +63,7 @@ trait ResetInverter {
   def invert[T <: chisel3.internal.LegacyModule](module: T): Unit = {
     chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform {
       def transformClass: Class[_ <: Transform] = classOf[ResetInverterTransform]
-      def toFirrtl: Annotation = ResetInverterAnnotation(module.toNamed)
+      def toFirrtl:       Annotation = ResetInverterAnnotation(module.toNamed)
     })
   }
 }
diff --git a/tapeout/src/main/scala/transforms/retime/Retime.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala
similarity index 62%
rename from tapeout/src/main/scala/transforms/retime/Retime.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala
index 010ef40b..931af88d 100644
--- a/tapeout/src/main/scala/transforms/retime/Retime.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala
@@ -14,23 +14,24 @@ case class RetimeAnnotation(target: Named) extends SingleTargetAnnotation[Named]
 
 class RetimeTransform extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.LowForm
-  override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
+  override def prerequisites:          Seq[TransformDependency] = Forms.LowForm
+  override def optionalPrerequisites:  Seq[TransformDependency] = Forms.LowFormOptimized
   override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
   override def invalidates(a: Transform): Boolean = false
 
   override def execute(state: CircuitState): CircuitState = {
     state.annotations.filter(_.isInstanceOf[RetimeAnnotation]) match {
       case Nil => state
-      case seq => seq.foreach {
-        case RetimeAnnotation(ModuleName(module, CircuitName(_))) =>
-          logger.info(s"Retiming module $module")
-        case RetimeAnnotation(ComponentName(name, ModuleName(module, CircuitName(_)))) =>
-          logger.info(s"Retiming instance $module.$name")
-        case _ =>
-          throw new Exception(s"There should be RetimeAnnotations, got ${seq.mkString(" -- ")}")
-      }
-      state
+      case seq =>
+        seq.foreach {
+          case RetimeAnnotation(ModuleName(module, CircuitName(_))) =>
+            logger.info(s"Retiming module $module")
+          case RetimeAnnotation(ComponentName(name, ModuleName(module, CircuitName(_)))) =>
+            logger.info(s"Retiming instance $module.$name")
+          case _ =>
+            throw new Exception(s"There should be RetimeAnnotations, got ${seq.mkString(" -- ")}")
+        }
+        state
     }
   }
 }
@@ -41,7 +42,7 @@ trait RetimeLib {
   def retime[T <: chisel3.internal.LegacyModule](module: T): Unit = {
     chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform {
       def transformClass: Class[_ <: Transform] = classOf[RetimeTransform]
-      def toFirrtl: Annotation = RetimeAnnotation(module.toNamed)
+      def toFirrtl:       Annotation = RetimeAnnotation(module.toNamed)
     })
   }
 }
diff --git a/tapeout/src/main/scala/transforms/utils/FileUtils.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala
similarity index 78%
rename from tapeout/src/main/scala/transforms/utils/FileUtils.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala
index ded0474d..86bf43de 100644
--- a/tapeout/src/main/scala/transforms/utils/FileUtils.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala
@@ -1,6 +1,6 @@
 // See LICENSE for license details.
 
-package barstools.tapeout.transforms
+package barstools.tapeout.transforms.utils
 
 import chisel3.experimental.{ChiselAnnotation, annotate}
 import firrtl._
@@ -12,7 +12,7 @@ import firrtl.transforms.BlackBoxTargetDirAnno
 object WriteConfig {
   def apply(dir: String, file: String, contents: String): Unit = {
     val writer = new java.io.PrintWriter(new java.io.File(s"$dir/$file"))
-    writer write contents
+    writer.write(contents)
     writer.close()
   }
 }
@@ -22,14 +22,14 @@ object GetTargetDir {
     val annos = state.annotations
     val destDir = annos.map {
       case BlackBoxTargetDirAnno(s) => Some(s)
-      case _ => None
+      case _                        => None
     }.flatten
     val loc = {
       if (destDir.isEmpty) "."
       else destDir.head
     }
     val targetDir = new java.io.File(loc)
-    if(!targetDir.exists()) FileUtils.makeDirectory(targetDir.getAbsolutePath)
+    if (!targetDir.exists()) FileUtils.makeDirectory(targetDir.getAbsolutePath)
     loc
   }
 }
@@ -53,8 +53,8 @@ case class TechnologyLocationAnnotation(dir: String) extends SingleTargetAnnotat
 
 class TechnologyLocation extends Transform with DependencyAPIMigration {
 
-  override def prerequisites: Seq[TransformDependency] = Forms.LowForm
-  override def optionalPrerequisites: Seq[TransformDependency] = Forms.LowFormOptimized
+  override def prerequisites:          Seq[TransformDependency] = Forms.LowForm
+  override def optionalPrerequisites:  Seq[TransformDependency] = Forms.LowFormOptimized
   override def optionalPrerequisiteOf: Seq[TransformDependency] = Forms.LowEmitters
 
   def execute(state: CircuitState): CircuitState = {
@@ -65,18 +65,15 @@ class TechnologyLocation extends Transform with DependencyAPIMigration {
     val annos = state.annotations
     val dir = annos.flatMap {
       case TechnologyLocationAnnotation(dir) => Some(dir)
-      case _ => None
+      case _                                 => None
     }
     dir.length match {
       case 0 => ""
       case 1 =>
         val targetDir = new java.io.File(dir.head)
-        if(!targetDir.exists()) throw new Exception(s"Technology yaml directory $targetDir doesn't exist!")
+        if (!targetDir.exists()) throw new Exception(s"Technology yaml directory $targetDir doesn't exist!")
         dir.head
       case _ => throw new Exception("Only 1 tech directory annotation allowed!")
     }
   }
 }
-
-
-
diff --git a/tapeout/src/main/scala/transforms/utils/LowerAnnotations.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala
similarity index 54%
rename from tapeout/src/main/scala/transforms/utils/LowerAnnotations.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala
index a11bfa19..45502d6d 100644
--- a/tapeout/src/main/scala/transforms/utils/LowerAnnotations.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala
@@ -1,5 +1,5 @@
-package barstools.tapeout.transforms
+package barstools.tapeout.transforms.utils
 
 object LowerName {
-  def apply(s: String): String = s.replace(".", "_").replace("[", "_")replace("]", "")
-}
\ No newline at end of file
+  def apply(s: String): String = s.replace(".", "_").replace("[", "_").replace("]", "")
+}
diff --git a/tapeout/src/main/scala/transforms/utils/ProgrammaticBundle.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala
similarity index 72%
rename from tapeout/src/main/scala/transforms/utils/ProgrammaticBundle.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala
index d73d05db..66200e61 100644
--- a/tapeout/src/main/scala/transforms/utils/ProgrammaticBundle.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala
@@ -1,20 +1,21 @@
-package barstools.tapeout.transforms
+package barstools.tapeout.transforms.utils
 
 import chisel3._
+
 import scala.collection.immutable.ListMap
 
 class CustomBundle[T <: Data](elts: (String, T)*) extends Record {
-  val elements = ListMap(elts map { case (field, elt) => field -> chiselTypeOf(elt) }: _*)
+  val elements = ListMap(elts.map { case (field, elt) => field -> chiselTypeOf(elt) }: _*)
   def apply(elt: String): T = elements(elt)
-  def apply(elt: Int): T = elements(elt.toString)
+  def apply(elt: Int):    T = elements(elt.toString)
   override def cloneType = (new CustomBundle(elements.toList: _*)).asInstanceOf[this.type]
 }
 
 class CustomIndexedBundle[T <: Data](elts: (Int, T)*) extends Record {
   // Must be String, Data
-  val elements = ListMap(elts map { case (field, elt) => field.toString -> chiselTypeOf(elt) }: _*)
+  val elements = ListMap(elts.map { case (field, elt) => field.toString -> chiselTypeOf(elt) }: _*)
   // TODO: Make an equivalent to the below work publicly (or only on subclasses?)
-  def indexedElements = ListMap(elts map { case (field, elt) => field -> chiselTypeOf(elt) }: _*)
+  def indexedElements = ListMap(elts.map { case (field, elt) => field -> chiselTypeOf(elt) }: _*)
   def apply(elt: Int): T = elements(elt.toString)
   override def cloneType = (new CustomIndexedBundle(indexedElements.toList: _*)).asInstanceOf[this.type]
 }
@@ -22,5 +23,7 @@ class CustomIndexedBundle[T <: Data](elts: (Int, T)*) extends Record {
 object CustomIndexedBundle {
   def apply[T <: Data](gen: T, idxs: Seq[Int]) = new CustomIndexedBundle(idxs.map(_ -> gen): _*)
   // Allows Vecs of elements of different types/widths
-  def apply[T <: Data](gen: Seq[T]) = new CustomIndexedBundle(gen.zipWithIndex.map{ case (elt, field) => field -> elt }: _*)
+  def apply[T <: Data](gen: Seq[T]) = new CustomIndexedBundle(gen.zipWithIndex.map { case (elt, field) =>
+    field -> elt
+  }: _*)
 }
diff --git a/tapeout/src/main/scala/transforms/utils/YamlHelpers.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala
similarity index 80%
rename from tapeout/src/main/scala/transforms/utils/YamlHelpers.scala
rename to tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala
index 6754136d..9a226de5 100644
--- a/tapeout/src/main/scala/transforms/utils/YamlHelpers.scala
+++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala
@@ -1,21 +1,22 @@
-package barstools.tapeout.transforms
+package barstools.tapeout.transforms.utils
 
 import net.jcazevedo.moultingyaml._
+
 import java.io.File
 
 class YamlFileReader(resource: String) {
-  def parse[A](file: String = "")(implicit reader: YamlReader[A]) : Seq[A] = {
+  def parse[A](file: String = "")(implicit reader: YamlReader[A]): Seq[A] = {
     // If the user doesn't provide a Yaml file name, use defaults
     val yamlString = file match {
-      case f if f.isEmpty => 
+      case f if f.isEmpty =>
         // Use example config if no file is provided
         val stream = getClass.getResourceAsStream(resource)
         io.Source.fromInputStream(stream).mkString
-      case f if new File(f).exists => 
+      case f if new File(f).exists =>
         scala.io.Source.fromFile(f).getLines.mkString("\n")
-      case _ => 
+      case _ =>
         throw new Exception("No valid Yaml file found!")
     }
     yamlString.parseYamls.map(x => reader.read(x))
   }
-}
\ No newline at end of file
+}


Test patch:
diff --git a/macros/src/test/resources/lib-MaskPortTest.json b/macros/src/test/resources/lib-MaskPortTest.json
index 72df7947..784aeafb 100644
--- a/macros/src/test/resources/lib-MaskPortTest.json
+++ b/macros/src/test/resources/lib-MaskPortTest.json
@@ -1,27 +1,29 @@
 [
   {
-    "type" : "sram",
-    "name" : "fake_mem",
-    "width" : 64,
-    "depth" : "512",
-    "mux" : 4,
-    "family" : "1rw",
-    "ports" : [ {
-        "address port name" : "addr",
-        "address port polarity" : "active high",
-        "clock port name" : "clk",
-        "clock port polarity" : "positive edge",
-        "write enable port name" : "wen",
-        "write enable port polarity" : "active high",
-        "read enable port name" : "ren",
-        "read enable port polarity" : "active high",
-        "output port name" : "dataout",
-        "output port polarity" : "active high",
-        "input port name" : "datain",
-        "input port polarity" : "active high",
-        "mask port name" : "mport",
-        "mask port polarity" : "active low",
-        "mask granularity" : 1
-    } ]
+    "type": "sram",
+    "name": "fake_mem",
+    "width": 64,
+    "depth": "512",
+    "mux": 4,
+    "family": "1rw",
+    "ports": [
+      {
+        "address port name": "addr",
+        "address port polarity": "active high",
+        "clock port name": "clk",
+        "clock port polarity": "positive edge",
+        "write enable port name": "wen",
+        "write enable port polarity": "active high",
+        "read enable port name": "ren",
+        "read enable port polarity": "active high",
+        "output port name": "dataout",
+        "output port polarity": "active high",
+        "input port name": "datain",
+        "input port polarity": "active high",
+        "mask port name": "mport",
+        "mask port polarity": "active low",
+        "mask granularity": 1
+      }
+    ]
   }
 ]
diff --git a/macros/src/test/resources/lib-WriteEnableTest.json b/macros/src/test/resources/lib-WriteEnableTest.json
index be7852a6..50acef41 100644
--- a/macros/src/test/resources/lib-WriteEnableTest.json
+++ b/macros/src/test/resources/lib-WriteEnableTest.json
@@ -1,24 +1,26 @@
 [
   {
-    "type" : "sram",
-    "name" : "fake_mem",
-    "width" : 64,
-    "depth" : "4096",
-    "mux" : 4,
-    "family" : "1rw",
-    "ports" : [ {
-        "address port name" : "addr",
-        "address port polarity" : "active high",
-        "clock port name" : "clk",
-        "clock port polarity" : "positive edge",
-        "write enable port name" : "wen",
-        "write enable port polarity" : "active high",
-        "read enable port name" : "ren",
-        "read enable port polarity" : "active high",
-        "output port name" : "dataout",
-        "output port polarity" : "active high",
-        "input port name" : "datain",
-        "input port polarity" : "active high"
-    } ]
+    "type": "sram",
+    "name": "fake_mem",
+    "width": 64,
+    "depth": "4096",
+    "mux": 4,
+    "family": "1rw",
+    "ports": [
+      {
+        "address port name": "addr",
+        "address port polarity": "active high",
+        "clock port name": "clk",
+        "clock port polarity": "positive edge",
+        "write enable port name": "wen",
+        "write enable port polarity": "active high",
+        "read enable port name": "ren",
+        "read enable port polarity": "active high",
+        "output port name": "dataout",
+        "output port polarity": "active high",
+        "input port name": "datain",
+        "input port polarity": "active high"
+      }
+    ]
   }
 ]
diff --git a/macros/src/test/scala/MacroCompilerSpec.scala b/macros/src/test/scala/MacroCompilerSpec.scala
deleted file mode 100644
index 8cdcf354..00000000
--- a/macros/src/test/scala/MacroCompilerSpec.scala
+++ /dev/null
@@ -1,453 +0,0 @@
-// See LICENSE for license details.
-
-package barstools.macros
-
-import firrtl.ir.{Circuit, NoInfo}
-import firrtl.passes.RemoveEmpty
-import firrtl.Parser.parse
-
-import java.io.{File, StringWriter}
-
-import mdf.macrolib.SRAMMacro
-
-abstract class MacroCompilerSpec extends org.scalatest.FlatSpec with org.scalatest.Matchers {
-  import scala.language.implicitConversions
-  implicit def String2SomeString(i: String): Option[String] = Some(i)
-  val testDir: String = "test_run_dir/macros"
-  new File(testDir).mkdirs // Make sure the testDir exists
-
-  // Override these to change the prefixing of macroDir and testDir
-  val memPrefix: String = testDir
-  val libPrefix: String = testDir
-  val vPrefix: String = testDir
-
-  // Override this to use a different cost metric.
-  // If this is None, the compile() call will not have any -c/-cp arguments, and
-  // execute() will use CostMetric.default.
-  val costMetric: Option[CostMetric] = None
-  private def getCostMetric: CostMetric = costMetric.getOrElse(CostMetric.default)
-
-  private def costMetricCmdLine = {
-    costMetric match {
-      case None => Nil
-      case Some(m) => {
-        val name = m.name
-        val params = m.commandLineParams
-        List("-c", name) ++ params.flatMap{ case (key, value) => List("-cp", key, value) }
-      }
-    }
-  }
-
-  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) }) ++
-    costMetricCmdLine ++
-    (if (synflops) List("--mode", "synflops") else Nil) ++
-    (if (useCompiler) List("--use-compiler") else Nil)
-
-  // Run the full compiler as if from the command line interface.
-  // Generates the Verilog; useful in testing since an error will throw an
-  // exception.
-  def compile(mem: String, lib: String, v: String, synflops: Boolean) {
-    compile(mem, Some(lib), v, synflops)
-  }
-  def compile(mem: String, lib: Option[String], v: String, synflops: Boolean, useCompiler: Boolean = false) {
-    var mem_full = concat(memPrefix, mem)
-    var lib_full = concat(libPrefix, lib)
-    var v_full = concat(vPrefix, v)
-
-    MacroCompiler.run(args(mem_full, lib_full, v_full, synflops, useCompiler))
-  }
-
-  // Helper functions to write macro libraries to the given files.
-  def writeToLib(lib: String, libs: Seq[mdf.macrolib.Macro]) = {
-    mdf.macrolib.Utils.writeMDFToPath(Some(concat(libPrefix, lib)), libs)
-  }
-
-  def writeToMem(mem: String, mems: Seq[mdf.macrolib.Macro]) = {
-    mdf.macrolib.Utils.writeMDFToPath(Some(concat(memPrefix, mem)), mems)
-  }
-
-  // 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 = {
-    compile(mem, lib, v, synflops, useCompiler)
-    val result = execute(mem, lib, synflops, useCompiler)
-    test(result, output)
-  }
-
-  // Compare FIRRTL outputs after reparsing output with ScalaTest ("should be").
-  def test(result: Circuit, output: String): Unit = {
-    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, 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 libs: Option[Seq[Macro]] = if(useCompiler) {
-      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 None => None
-      }
-    }
-    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)
-    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] = {
-    b match {
-      case Some(b2:String) => Some(a + "/" + b2)
-      case _ => None
-    }
-  }
-}
-
-// A collection of standard SRAM generators.
-trait HasSRAMGenerator {
-  import mdf.macrolib._
-  import scala.language.implicitConversions
-  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(
-    prefix: String,
-    width: Option[Int],
-    depth: Option[BigInt],
-    maskGran: Option[Int] = None,
-    read: Boolean,
-    readEnable: Boolean = false,
-    write: Boolean,
-    writeEnable: Boolean = false
-  ): MacroPort = {
-    val realPrefix = if (prefix == "") "" else prefix + "_"
-
-    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,
-
-      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.
-    )
-  }
-
-  // Generate a read port for testing.
-  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 = {
-    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 = {
-    generateTestPort(
-      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 = {
-    SRAMMacro(
-      name = name,
-      width = width,
-      depth = depth,
-      family = "1rw",
-      ports = Seq(generateReadWritePort(prefix, width, depth, maskGran)),
-      extraPorts = extraPorts
-    )
-  }
-
-  // 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)))
-  }
-
-  // '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(
-      generateSimpleSRAMGroup(prefix, 2, Range(16, 512, 8), Range(8, 288, 2)),
-      generateSimpleSRAMGroup(prefix, 4, Range(32, 1024, 16), Range(4, 144, 1))
-    ))
-  }
-}
-
-// Generic "simple" test generator.
-// Set up scaffolding for generating memories, files, etc.
-// Override this generator to specify the expected FIRRTL output.
-trait HasSimpleTestGenerator {
-  this: MacroCompilerSpec with HasSRAMGenerator =>
-    // Override these with "override lazy val".
-    // Why lazy? These are used in the constructor here so overriding non-lazily
-    // would be too late.
-    def useCompiler: Boolean = false
-    def memWidth: Int
-    def libWidth: Int
-    def memDepth: BigInt
-    def libDepth: BigInt
-    def memMaskGran: Option[Int] = None
-    def libMaskGran: Option[Int] = None
-    def extraPorts: Seq[mdf.macrolib.MacroExtraPort] = List()
-    def extraTag: String = ""
-
-    // "Effective" libMaskGran by considering write_enable.
-    val effectiveLibMaskGran = libMaskGran.getOrElse(libWidth)
-
-    // Override this in the sub-generator if you need a more specific name.
-    // Defaults to using reflection to pull the name of the test using this
-    // generator.
-    def generatorType: String = this.getClass.getSimpleName
-
-    //require (memDepth >= libDepth)
-
-    // Convenience variables to check if a mask exists.
-    val memHasMask = memMaskGran != None
-    val libHasMask = libMaskGran != None
-    // We need to figure out how many mask bits there are in the mem.
-    val memMaskBits = if (memHasMask) memWidth / memMaskGran.get else 0
-    val libMaskBits = if (libHasMask) libWidth / libMaskGran.get else 0
-
-    val extraTagPrefixed = if (extraTag == "") "" else ("-" + extraTag)
-
-    val mem = s"mem-${generatorType}${extraTagPrefixed}.json"
-    val lib = s"lib-${generatorType}${extraTagPrefixed}.json"
-    val v = s"${generatorType}${extraTagPrefixed}.v"
-
-    lazy val mem_name = "target_memory"
-    val mem_addr_width = MacroCompilerMath.ceilLog2(memDepth)
-
-    lazy val lib_name = "awesome_lib_mem"
-    val lib_addr_width = MacroCompilerMath.ceilLog2(libDepth)
-
-    // Override these to change the port prefixes if needed.
-    def libPortPrefix: String = "lib"
-    def memPortPrefix: String = "outer"
-
-    // These generate "simple" SRAMs (1 masked read-write port) by default,
-    // but can be overridden if need be.
-    def generateLibSRAM() = generateSRAM(lib_name, libPortPrefix, libWidth, libDepth, libMaskGran, extraPorts)
-    def generateMemSRAM() = generateSRAM(mem_name, memPortPrefix, memWidth, memDepth, memMaskGran)
-
-    def libSRAM = generateLibSRAM
-    def memSRAM = generateMemSRAM
-
-    def libSRAMs: Seq[SRAMMacro] = Seq(libSRAM)
-    def memSRAMs: Seq[SRAMMacro] = Seq(memSRAM)
-
-    writeToLib(lib, libSRAMs)
-    writeToMem(mem, memSRAMs)
-
-    // For masks, width it's a bit tricky since we have to consider cases like
-    // memMaskGran = 4 and libMaskGran = 8.
-    // Consider the actually usable libWidth in cases like the above.
-    val usableLibWidth = if (memMaskGran.getOrElse(Int.MaxValue) < effectiveLibMaskGran) memMaskGran.get else libWidth
-
-    // Number of lib instances needed to hold the mem, in both directions.
-    // Round up (e.g. 1.5 instances = effectively 2 instances)
-    val depthInstances = math.ceil(memDepth.toFloat / libDepth.toFloat).toInt
-    val widthInstances = math.ceil(memWidth.toFloat / usableLibWidth).toInt
-
-    // Number of width bits in the last width-direction memory.
-    // e.g. if memWidth = 16 and libWidth = 8, this would be 8 since the last memory 0_1 has 8 bits of input width.
-    // e.g. if memWidth = 9 and libWidth = 8, this would be 1 since the last memory 0_1 has 1 bit of input width.
-    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.
-     * @param widthInst Width instance (mem_0_x)
-     * @param depthInst Depth instance (mem_x_0)
-     */
-    def generateMaskStatement(widthInst: Int, depthInst: Int): String = {
-      // Width of this submemory.
-      val myMemWidth = if (widthInst == widthInstances - 1) lastWidthBits else usableLibWidth
-      // Base bit of this submemory.
-      // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this
-      // would be 16.
-      val myBaseBit = usableLibWidth*widthInst
-
-      if (libMaskGran.isDefined) {
-        if (memMaskGran.isEmpty) {
-          // If there is no memory mask, we should just turn all the lib mask
-          // bits high.
-          s"""mem_${depthInst}_${widthInst}.lib_mask <= UInt<${libMaskBits}>("h${((1 << libMaskBits) - 1).toHexString}")"""
-        } else {
-          // Calculate which bit of outer_mask contains the given bit.
-          // e.g. if memMaskGran = 2, libMaskGran = 1 and libWidth = 4, then
-          // 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 => {
-            if (x*libMaskGran.get > myMemWidth) {
-              // If we have extra mask bits leftover after the effective width,
-              // disable those bits.
-              """UInt<1>("h0")"""
-            } else {
-              val outerMaskBit = calculateMaskBit(x*libMaskGran.get + myBaseBit)
-              s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})"
-            }
-          }))
-          val maskVal = bitsArr.reduceRight((bit, rest) => s"cat($bit, $rest)")
-          s"mem_${depthInst}_${widthInst}.lib_mask <= ${maskVal}"
-        }
-      } else ""
-    }
-
-    /** Helper function to generate a port.
-      *
-      * @param prefix      Memory port prefix (e.g. "x" for ports like "x_clk")
-      * @param addrWidth   Address port width
-      * @param width       data width
-      * @param write       Has a write port?
-      * @param writeEnable Has a write enable port?
-      * @param read        Has a read port?
-      * @param readEnable  Has a read enable port?
-      * @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 = {
-      val realPrefix = if (prefix == "") "" else prefix + "_"
-
-      val readStr = if (read) s"output ${realPrefix}dout : UInt<$width>" else ""
-      val writeStr = if (write) s"input ${realPrefix}din : UInt<$width>" else ""
-      val readEnableStr = if (readEnable) s"input ${realPrefix}read_en : UInt<1>" else ""
-      val writeEnableStr = if (writeEnable) s"input ${realPrefix}write_en : UInt<1>" else ""
-      val maskStr = mask match {
-        case Some(maskBits: Int) => s"input ${realPrefix}mask : UInt<$maskBits>"
-        case _ => ""
-      }
-      val extraPortsStr = extraPorts.map { case (name, bits) => s"    input $name : UInt<$bits>" }.mkString("\n")
-      s"""
-    input ${realPrefix}addr : UInt<$addrWidth>
-    input ${realPrefix}clk : Clock
-    $writeStr
-    $readStr
-    $readEnableStr
-    $writeEnableStr
-    $maskStr
-$extraPortsStr
-  """
-    }
-
-    /**
-      * 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)
-    }
-
-    /** 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. */
-    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)
-    }
-
-    // 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)
-    }
-
-    // Generate the header (contains the circuit statement and the target memory
-    // module.
-    def generateHeader(): String = {
-      s"""
-circuit $mem_name :
-  module $mem_name :
-${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)))
-    }
-
-    // Generate the footer (contains the target memory extmodule declaration by default).
-    def generateFooter(): String = {
-      s"""
-  extmodule $lib_name :
-${generateFooterPorts}
-
-    defname = $lib_name
-  """
-    }
-
-    // Abstract method to generate body; to be overridden by specific generator type.
-    def generateBody(): String
-
-    // Generate the entire output from header, body, and footer.
-    def generateOutput(): String = {
-      s"""
-${generateHeader}
-${generateBody}
-${generateFooter}
-      """
-    }
-
-    val output = generateOutput()
-}
-
-// Use this trait for tests that invoke the memory compiler without lib.
-trait HasNoLibTestGenerator extends HasSimpleTestGenerator {
-  this: MacroCompilerSpec with HasSRAMGenerator =>
-
-    // If there isn't a lib, then the "lib" will become a FIRRTL "mem", which
-    // in turn becomes synthesized flops.
-    // Therefore, make "lib" width/depth equal to the mem.
-    override lazy val libDepth = memDepth
-    override lazy val libWidth = memWidth
-    override lazy val lib_name = mem_name
-    // Do the same for port names.
-    override lazy val libPortPrefix = memPortPrefix
-
-    // If there is no lib, don't generate a body.
-    override def generateBody = ""
-}
-
diff --git a/macros/src/test/scala/CostFunction.scala b/macros/src/test/scala/barstools/macros/CostFunction.scala
similarity index 86%
rename from macros/src/test/scala/CostFunction.scala
rename to macros/src/test/scala/barstools/macros/CostFunction.scala
index b8a27f7f..ceb7a61a 100644
--- a/macros/src/test/scala/CostFunction.scala
+++ b/macros/src/test/scala/barstools/macros/CostFunction.scala
@@ -4,10 +4,9 @@ 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
- * the metric is chosen properly.
- */
+/** A test metric that simply favours memories with smaller widths, to test that
+  * the metric is chosen properly.
+  */
 object TestMinWidthMetric extends CostMetric with CostMetricCompanion {
   // Smaller width = lower cost = favoured
   override def cost(mem: Macro, lib: Macro): Option[Double] = Some(lib.src.width)
@@ -30,29 +29,29 @@ class SelectCostMetric extends MacroCompilerSpec with HasSRAMGenerator {
 
   val libSRAMs = Seq(
     SRAMMacro(
-      name="SRAM_WIDTH_128",
-      depth=BigInt(1024),
-      width=128,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM_WIDTH_128",
+      depth = BigInt(1024),
+      width = 128,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 128, BigInt(1024))
       )
     ),
     SRAMMacro(
-      name="SRAM_WIDTH_64",
-      depth=BigInt(1024),
-      width=64,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM_WIDTH_64",
+      depth = BigInt(1024),
+      width = 64,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 64, BigInt(1024))
       )
     ),
     SRAMMacro(
-      name="SRAM_WIDTH_32",
-      depth=BigInt(1024),
-      width=32,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM_WIDTH_32",
+      depth = BigInt(1024),
+      width = 32,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 32, BigInt(1024))
       )
     )
@@ -65,7 +64,7 @@ class SelectCostMetric extends MacroCompilerSpec with HasSRAMGenerator {
 
   // Check that the min width SRAM was chosen, even though it is less efficient.
   val output =
-"""
+    """
 circuit target_memory :
   module target_memory :
     input addr : UInt<10>
diff --git a/macros/src/test/scala/Functional.scala b/macros/src/test/scala/barstools/macros/Functional.scala
similarity index 100%
rename from macros/src/test/scala/Functional.scala
rename to macros/src/test/scala/barstools/macros/Functional.scala
diff --git a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala
new file mode 100644
index 00000000..2b239227
--- /dev/null
+++ b/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala
@@ -0,0 +1,556 @@
+// See LICENSE for license details.
+
+package barstools.macros
+
+import firrtl.Parser.parse
+import firrtl.ir.{Circuit, NoInfo}
+import firrtl.passes.RemoveEmpty
+import mdf.macrolib.SRAMMacro
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
+import java.io.File
+
+abstract class MacroCompilerSpec extends AnyFlatSpec with Matchers {
+  import scala.language.implicitConversions
+  implicit def String2SomeString(i: String): Option[String] = Some(i)
+  val testDir: String = "test_run_dir/macros"
+  new File(testDir).mkdirs // Make sure the testDir exists
+
+  // Override these to change the prefixing of macroDir and testDir
+  val memPrefix: String = testDir
+  val libPrefix: String = testDir
+  val vPrefix:   String = testDir
+
+  // Override this to use a different cost metric.
+  // If this is None, the compile() call will not have any -c/-cp arguments, and
+  // execute() will use CostMetric.default.
+  val costMetric:            Option[CostMetric] = None
+  private def getCostMetric: CostMetric = costMetric.getOrElse(CostMetric.default)
+
+  private def costMetricCmdLine = {
+    costMetric match {
+      case None => Nil
+      case Some(m) => {
+        val name = m.name
+        val params = m.commandLineParams
+        List("-c", name) ++ params.flatMap { case (key, value) => List("-cp", key, value) }
+      }
+    }
+  }
+
+  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)
+      }) ++
+      costMetricCmdLine ++
+      (if (synflops) List("--mode", "synflops") else Nil) ++
+      (if (useCompiler) List("--use-compiler") else Nil)
+
+  // Run the full compiler as if from the command line interface.
+  // Generates the Verilog; useful in testing since an error will throw an
+  // exception.
+  def compile(mem: String, lib: String, v: String, synflops: Boolean) {
+    compile(mem, Some(lib), v, synflops)
+  }
+  def compile(mem: String, lib: Option[String], v: String, synflops: Boolean, useCompiler: Boolean = false) {
+    var mem_full = concat(memPrefix, mem)
+    var lib_full = concat(libPrefix, lib)
+    var v_full = concat(vPrefix, v)
+
+    MacroCompiler.run(args(mem_full, lib_full, v_full, synflops, useCompiler))
+  }
+
+  // Helper functions to write macro libraries to the given files.
+  def writeToLib(lib: String, libs: Seq[mdf.macrolib.Macro]) = {
+    mdf.macrolib.Utils.writeMDFToPath(Some(concat(libPrefix, lib)), libs)
+  }
+
+  def writeToMem(mem: String, mems: Seq[mdf.macrolib.Macro]) = {
+    mdf.macrolib.Utils.writeMDFToPath(Some(concat(memPrefix, mem)), mems)
+  }
+
+  // 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 = {
+    compile(mem, lib, v, synflops, useCompiler)
+    val result = execute(mem, lib, synflops, useCompiler)
+    test(result, output)
+  }
+
+  // Compare FIRRTL outputs after reparsing output with ScalaTest ("should be").
+  def test(result: Circuit, output: String): Unit = {
+    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, 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 libs: Option[Seq[Macro]] = if (useCompiler) {
+      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 None    => None
+      }
+    }
+    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))
+    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] = {
+    b match {
+      case Some(b2: String) => Some(a + "/" + b2)
+      case _ => None
+    }
+  }
+}
+
+// A collection of standard SRAM generators.
+trait HasSRAMGenerator {
+  import mdf.macrolib._
+
+  import scala.language.implicitConversions
+  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(
+    prefix:      String,
+    width:       Option[Int],
+    depth:       Option[BigInt],
+    maskGran:    Option[Int] = None,
+    read:        Boolean,
+    readEnable:  Boolean = false,
+    write:       Boolean,
+    writeEnable: Boolean = false
+  ): MacroPort = {
+    val realPrefix = if (prefix == "") "" else prefix + "_"
+
+    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,
+      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.
+    )
+  }
+
+  // Generate a read port for testing.
+  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 = {
+    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 = {
+    generateTestPort(
+      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 = {
+    SRAMMacro(
+      name = name,
+      width = width,
+      depth = depth,
+      family = "1rw",
+      ports = Seq(generateReadWritePort(prefix, width, depth, maskGran)),
+      extraPorts = extraPorts
+    )
+  }
+
+  // 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))
+    )
+  }
+
+  // '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(
+        generateSimpleSRAMGroup(prefix, 2, Range(16, 512, 8), Range(8, 288, 2)),
+        generateSimpleSRAMGroup(prefix, 4, Range(32, 1024, 16), Range(4, 144, 1))
+      )
+    )
+  }
+}
+
+// Generic "simple" test generator.
+// Set up scaffolding for generating memories, files, etc.
+// Override this generator to specify the expected FIRRTL output.
+trait HasSimpleTestGenerator {
+  this: MacroCompilerSpec with HasSRAMGenerator =>
+  // Override these with "override lazy val".
+  // Why lazy? These are used in the constructor here so overriding non-lazily
+  // would be too late.
+  def useCompiler: Boolean = false
+  def memWidth: Int
+  def libWidth: Int
+  def memDepth: BigInt
+  def libDepth: BigInt
+  def memMaskGran: Option[Int] = None
+  def libMaskGran: Option[Int] = None
+  def extraPorts:  Seq[mdf.macrolib.MacroExtraPort] = List()
+  def extraTag:    String = ""
+
+  // "Effective" libMaskGran by considering write_enable.
+  val effectiveLibMaskGran = libMaskGran.getOrElse(libWidth)
+
+  // Override this in the sub-generator if you need a more specific name.
+  // Defaults to using reflection to pull the name of the test using this
+  // generator.
+  def generatorType: String = this.getClass.getSimpleName
+
+  //require (memDepth >= libDepth)
+
+  // Convenience variables to check if a mask exists.
+  val memHasMask = memMaskGran != None
+  val libHasMask = libMaskGran != None
+  // We need to figure out how many mask bits there are in the mem.
+  val memMaskBits = if (memHasMask) memWidth / memMaskGran.get else 0
+  val libMaskBits = if (libHasMask) libWidth / libMaskGran.get else 0
+
+  val extraTagPrefixed = if (extraTag == "") "" else ("-" + extraTag)
+
+  val mem = s"mem-${generatorType}${extraTagPrefixed}.json"
+  val lib = s"lib-${generatorType}${extraTagPrefixed}.json"
+  val v = s"${generatorType}${extraTagPrefixed}.v"
+
+  lazy val mem_name = "target_memory"
+  val mem_addr_width = MacroCompilerMath.ceilLog2(memDepth)
+
+  lazy val lib_name = "awesome_lib_mem"
+  val lib_addr_width = MacroCompilerMath.ceilLog2(libDepth)
+
+  // Override these to change the port prefixes if needed.
+  def libPortPrefix: String = "lib"
+  def memPortPrefix: String = "outer"
+
+  // These generate "simple" SRAMs (1 masked read-write port) by default,
+  // but can be overridden if need be.
+  def generateLibSRAM() = generateSRAM(lib_name, libPortPrefix, libWidth, libDepth, libMaskGran, extraPorts)
+  def generateMemSRAM() = generateSRAM(mem_name, memPortPrefix, memWidth, memDepth, memMaskGran)
+
+  def libSRAM = generateLibSRAM
+  def memSRAM = generateMemSRAM
+
+  def libSRAMs: Seq[SRAMMacro] = Seq(libSRAM)
+  def memSRAMs: Seq[SRAMMacro] = Seq(memSRAM)
+
+  writeToLib(lib, libSRAMs)
+  writeToMem(mem, memSRAMs)
+
+  // For masks, width it's a bit tricky since we have to consider cases like
+  // memMaskGran = 4 and libMaskGran = 8.
+  // Consider the actually usable libWidth in cases like the above.
+  val usableLibWidth = if (memMaskGran.getOrElse(Int.MaxValue) < effectiveLibMaskGran) memMaskGran.get else libWidth
+
+  // Number of lib instances needed to hold the mem, in both directions.
+  // Round up (e.g. 1.5 instances = effectively 2 instances)
+  val depthInstances = math.ceil(memDepth.toFloat / libDepth.toFloat).toInt
+  val widthInstances = math.ceil(memWidth.toFloat / usableLibWidth).toInt
+
+  // Number of width bits in the last width-direction memory.
+  // e.g. if memWidth = 16 and libWidth = 8, this would be 8 since the last memory 0_1 has 8 bits of input width.
+  // e.g. if memWidth = 9 and libWidth = 8, this would be 1 since the last memory 0_1 has 1 bit of input width.
+  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.
+    * @param widthInst Width instance (mem_0_x)
+    * @param depthInst Depth instance (mem_x_0)
+    */
+  def generateMaskStatement(widthInst: Int, depthInst: Int): String = {
+    // Width of this submemory.
+    val myMemWidth = if (widthInst == widthInstances - 1) lastWidthBits else usableLibWidth
+    // Base bit of this submemory.
+    // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this
+    // would be 16.
+    val myBaseBit = usableLibWidth * widthInst
+
+    if (libMaskGran.isDefined) {
+      if (memMaskGran.isEmpty) {
+        // If there is no memory mask, we should just turn all the lib mask
+        // bits high.
+        s"""mem_${depthInst}_${widthInst}.lib_mask <= UInt<${libMaskBits}>("h${((1 << libMaskBits) - 1).toHexString}")"""
+      } else {
+        // Calculate which bit of outer_mask contains the given bit.
+        // e.g. if memMaskGran = 2, libMaskGran = 1 and libWidth = 4, then
+        // 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 => {
+          if (x * libMaskGran.get > myMemWidth) {
+            // If we have extra mask bits leftover after the effective width,
+            // disable those bits.
+            """UInt<1>("h0")"""
+          } else {
+            val outerMaskBit = calculateMaskBit(x * libMaskGran.get + myBaseBit)
+            s"bits(outer_mask, ${outerMaskBit}, ${outerMaskBit})"
+          }
+        }))
+        val maskVal = bitsArr.reduceRight((bit, rest) => s"cat($bit, $rest)")
+        s"mem_${depthInst}_${widthInst}.lib_mask <= ${maskVal}"
+      }
+    } else ""
+  }
+
+  /** Helper function to generate a port.
+    *
+    * @param prefix      Memory port prefix (e.g. "x" for ports like "x_clk")
+    * @param addrWidth   Address port width
+    * @param width       data width
+    * @param write       Has a write port?
+    * @param writeEnable Has a write enable port?
+    * @param read        Has a read port?
+    * @param readEnable  Has a read enable port?
+    * @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 = {
+    val realPrefix = if (prefix == "") "" else prefix + "_"
+
+    val readStr = if (read) s"output ${realPrefix}dout : UInt<$width>" else ""
+    val writeStr = if (write) s"input ${realPrefix}din : UInt<$width>" else ""
+    val readEnableStr = if (readEnable) s"input ${realPrefix}read_en : UInt<1>" else ""
+    val writeEnableStr = if (writeEnable) s"input ${realPrefix}write_en : UInt<1>" else ""
+    val maskStr = mask match {
+      case Some(maskBits: Int) => s"input ${realPrefix}mask : UInt<$maskBits>"
+      case _ => ""
+    }
+    val extraPortsStr = extraPorts.map { case (name, bits) => s"    input $name : UInt<$bits>" }.mkString("\n")
+    s"""
+    input ${realPrefix}addr : UInt<$addrWidth>
+    input ${realPrefix}clk : Clock
+    $writeStr
+    $readStr
+    $readEnableStr
+    $writeEnableStr
+    $maskStr
+$extraPortsStr
+  """
+  }
+
+  /** 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
+    )
+  }
+
+  /** 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.
+    */
+  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
+    )
+  }
+
+  // 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
+    )
+  }
+
+  // Generate the header (contains the circuit statement and the target memory
+  // module.
+  def generateHeader(): String = {
+    s"""
+circuit $mem_name :
+  module $mem_name :
+${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))
+    )
+  }
+
+  // Generate the footer (contains the target memory extmodule declaration by default).
+  def generateFooter(): String = {
+    s"""
+  extmodule $lib_name :
+${generateFooterPorts}
+
+    defname = $lib_name
+  """
+  }
+
+  // Abstract method to generate body; to be overridden by specific generator type.
+  def generateBody(): String
+
+  // Generate the entire output from header, body, and footer.
+  def generateOutput(): String = {
+    s"""
+${generateHeader}
+${generateBody}
+${generateFooter}
+      """
+  }
+
+  val output = generateOutput()
+}
+
+// Use this trait for tests that invoke the memory compiler without lib.
+trait HasNoLibTestGenerator extends HasSimpleTestGenerator {
+  this: MacroCompilerSpec with HasSRAMGenerator =>
+
+  // If there isn't a lib, then the "lib" will become a FIRRTL "mem", which
+  // in turn becomes synthesized flops.
+  // Therefore, make "lib" width/depth equal to the mem.
+  override lazy val libDepth = memDepth
+  override lazy val libWidth = memWidth
+  override lazy val lib_name = mem_name
+  // Do the same for port names.
+  override lazy val libPortPrefix = memPortPrefix
+
+  // If there is no lib, don't generate a body.
+  override def generateBody = ""
+}
diff --git a/macros/src/test/scala/Masks.scala b/macros/src/test/scala/barstools/macros/Masks.scala
similarity index 55%
rename from macros/src/test/scala/Masks.scala
rename to macros/src/test/scala/barstools/macros/Masks.scala
index a091a42a..c472669a 100644
--- a/macros/src/test/scala/Masks.scala
+++ b/macros/src/test/scala/barstools/macros/Masks.scala
@@ -1,37 +1,39 @@
 package barstools.macros
 
-import mdf.macrolib._
-
 // Test the ability of the compiler to deal with various mask combinations.
 
 trait MasksTestSettings {
   this: MacroCompilerSpec with HasSRAMGenerator with HasSimpleDepthTestGenerator =>
-    override lazy val memDepth = BigInt(2048)
-    override lazy val libDepth = BigInt(1024)
+  override lazy val memDepth = BigInt(2048)
+  override lazy val libDepth = BigInt(1024)
 }
 
 // Try all four different kinds of mask config:
-/**
- *
- *                    Non-masked mem     Masked mem
- *                  ---------------------------------
- *  Non-masked lib  |                |              |
- *                  ---------------------------------
- *  Masked lib      |                |              |
- *                  ---------------------------------
- */
-
-class Masks_FourTypes_NonMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
+/**                    Non-masked mem     Masked mem
+  *                  ---------------------------------
+  *  Non-masked lib  |                |              |
+  *                  ---------------------------------
+  *  Masked lib      |                |              |
+  *                  ---------------------------------
+  */
+
+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
-  override lazy val libWidth = 8 
+  override lazy val libWidth = 8
   override lazy val libMaskGran = None
 
   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
@@ -41,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)
@@ -51,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)
@@ -61,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)
@@ -71,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)
@@ -81,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)
@@ -105,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)
@@ -115,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)
@@ -123,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)
@@ -131,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)
@@ -139,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)
@@ -149,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)
@@ -157,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)
@@ -165,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)
@@ -175,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)
@@ -183,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)
@@ -200,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)
@@ -208,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)
@@ -216,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)
@@ -224,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)
@@ -232,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)
@@ -242,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)
 }
diff --git a/macros/src/test/scala/MultiPort.scala b/macros/src/test/scala/barstools/macros/MultiPort.scala
similarity index 76%
rename from macros/src/test/scala/MultiPort.scala
rename to macros/src/test/scala/barstools/macros/MultiPort.scala
index 3899f835..1968f6aa 100644
--- a/macros/src/test/scala/MultiPort.scala
+++ b/macros/src/test/scala/barstools/macros/MultiPort.scala
@@ -13,42 +13,70 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim
 
   override def generateMemSRAM() = {
     SRAMMacro(
-      name=mem_name,
-      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
-      ))
+      name = mem_name,
+      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
+        )
+      )
     )
   }
 
   override def generateLibSRAM() = {
     SRAMMacro(
-      name=lib_name,
-      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
-      ))
+      name = lib_name,
+      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
+        )
+      )
     )
   }
 
   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() = {
@@ -56,7 +84,7 @@ class SplitWidth_2rw extends MacroCompilerSpec with HasSRAMGenerator with HasSim
   }
 
   override def generateBody() =
-"""
+    """
     inst mem_0_0 of awesome_lib_mem
     inst mem_0_1 of awesome_lib_mem
     inst mem_0_2 of awesome_lib_mem
@@ -128,56 +156,112 @@ class SplitWidth_1r_1w extends MacroCompilerSpec with HasSRAMGenerator with HasS
 
   override def generateMemSRAM() = {
     SRAMMacro(
-      name=mem_name,
-      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
-      ))
+      name = mem_name,
+      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
+        )
+      )
     )
   }
 
   override def generateLibSRAM() = {
     SRAMMacro(
-      name=lib_name,
-      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
-      ))
+      name = lib_name,
+      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
+        )
+      )
     )
   }
 
   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() =
-"""
+    """
     inst mem_0_0 of awesome_lib_mem
     inst mem_0_1 of awesome_lib_mem
     inst mem_0_2 of awesome_lib_mem
@@ -234,42 +318,70 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera
   override def generateMemSRAM() = {
     println(memMaskGranB)
     SRAMMacro(
-      name=mem_name,
-      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
-      ))
+      name = mem_name,
+      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
+        )
+      )
     )
   }
 
   override def generateLibSRAM() = {
     SRAMMacro(
-      name=lib_name,
-      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
-      ))
+      name = lib_name,
+      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
+        )
+      )
     )
   }
 
   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() = {
@@ -277,7 +389,7 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera
   }
 
   override def generateBody() =
-"""
+    """
     inst mem_0_0 of awesome_lib_mem
     inst mem_0_1 of awesome_lib_mem
     inst mem_0_2 of awesome_lib_mem
diff --git a/macros/src/test/scala/SRAMCompiler.scala b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala
similarity index 85%
rename from macros/src/test/scala/SRAMCompiler.scala
rename to macros/src/test/scala/barstools/macros/SRAMCompiler.scala
index 5cae4745..17f49601 100644
--- a/macros/src/test/scala/SRAMCompiler.scala
+++ b/macros/src/test/scala/barstools/macros/SRAMCompiler.scala
@@ -1,7 +1,5 @@
 package barstools.macros
 
-import mdf.macrolib._
-
 class SRAMCompiler extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleWidthTestGenerator {
   val compiler = generateSRAMCompiler("awesome", "A")
   val verilog = s"v-SRAMCompiler.v"
@@ -15,8 +13,7 @@ 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)
+  compileExecuteAndTest(mem, Some(lib), verilog, output = output, false, true)
 }
diff --git a/macros/src/test/scala/SimpleSplitDepth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala
similarity index 86%
rename from macros/src/test/scala/SimpleSplitDepth.scala
rename to macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala
index e3560f9a..5a7fc77d 100644
--- a/macros/src/test/scala/SimpleSplitDepth.scala
+++ b/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala
@@ -1,40 +1,41 @@
 package barstools.macros
 
-import mdf.macrolib._
-
 // Test the depth splitting aspect of the memory compiler.
 // This file is for simple tests: one read-write port, powers of two sizes, etc.
 // For example, implementing a 4096x32 memory using four 1024x32 memories.
 
 trait HasSimpleDepthTestGenerator extends HasSimpleTestGenerator {
   this: MacroCompilerSpec with HasSRAMGenerator =>
-    def width: Int
+  def width: Int
 
-    override lazy val memWidth = width
-    override lazy val libWidth = width
+  override lazy val memWidth = width
+  override lazy val libWidth = width
 
-    // Generate a depth-splitting body.
-    override def generateBody(): String = {
-      val output = new StringBuilder
+  // Generate a depth-splitting body.
+  override def generateBody(): String = {
+    val output = new StringBuilder
 
-      if (selectBits > 0) {
-        output.append (
-s"""
+    if (selectBits > 0) {
+      output.append(
+        s"""
     node ${memPortPrefix}_addr_sel = bits(${memPortPrefix}_addr, ${mem_addr_width - 1}, $lib_addr_width)
     reg ${memPortPrefix}_addr_sel_reg : UInt<${selectBits}>, ${memPortPrefix}_clk with :
       reset => (UInt<1>("h0"), ${memPortPrefix}_addr_sel_reg)
     ${memPortPrefix}_addr_sel_reg <= mux(UInt<1>("h1"), ${memPortPrefix}_addr_sel, ${memPortPrefix}_addr_sel_reg)
 """
-        )
-      }
+      )
+    }
 
-      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 chipEnable = s"""UInt<1>("h1")"""
-        val writeEnable = if (memMaskGran.isEmpty) s"and(${memPortPrefix}_write_en, ${chipEnable})" else s"${memPortPrefix}_write_en"
-        output.append(
-  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 chipEnable = s"""UInt<1>("h1")"""
+      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}
     mem_${i}_0.${libPortPrefix}_clk <= ${memPortPrefix}_clk
     mem_${i}_0.${libPortPrefix}_addr <= ${memPortPrefix}_addr
@@ -44,26 +45,29 @@ s"""
     mem_${i}_0.${libPortPrefix}_write_en <= and(and(${writeEnable}, UInt<1>("h1")), ${enableIdentifier})
     node ${memPortPrefix}_dout_${i} = ${memPortPrefix}_dout_${i}_0
   """
-        )
-      }
-      def generate_outer_dout_tree(i:Int, depthInstances: Int): String = {
-        if (i > depthInstances - 1) {
-          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)
-          )
-        }
-      }
-      output append s"  ${memPortPrefix}_dout <= "
-      if (selectBits > 0) {
-        output append generate_outer_dout_tree(0, depthInstances)
+      )
+    }
+    def generate_outer_dout_tree(i: Int, depthInstances: Int): String = {
+      if (i > depthInstances - 1) {
+        s"""UInt<${libWidth}>("h0")"""
       } else {
-        output append s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))"""
+        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)
+        )
       }
-
-      output.toString
     }
+    output.append(s"  ${memPortPrefix}_dout <= ")
+    if (selectBits > 0) {
+      output.append(generate_outer_dout_tree(0, depthInstances))
+    } else {
+      output.append(s"""mux(UInt<1>("h1"), ${memPortPrefix}_dout_0, UInt<${libWidth}>("h0"))""")
+    }
+
+    output.toString
+  }
 }
 
 // Try different widths
@@ -156,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)
@@ -167,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)
@@ -215,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)
 }
 
@@ -226,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)
 }
 
@@ -237,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)
 }
 
@@ -249,12 +259,12 @@ class SplitDepth2048x8_extraPort extends MacroCompilerSpec with HasSRAMGenerator
   override lazy val memDepth = BigInt(2048)
   override lazy val libDepth = BigInt(1024)
   override lazy val extraPorts = List(
-    MacroExtraPort(name="extra_port", width=8, portType=Constant, value=0xff)
+    MacroExtraPort(name = "extra_port", width = 8, portType = Constant, value = 0xff)
   )
   override lazy val extraTag = "extraPort"
 
   override def generateOutput(): String =
-"""
+    """
 circuit target_memory :
   module target_memory :
     input outer_addr : UInt<11>
@@ -319,22 +329,22 @@ class SplitDepth_SplitPortsNonMasked extends MacroCompilerSpec with HasSRAMGener
     val v = "split_depth-r-w-split-lib-split-mem.v"
 
     val libMacro = SRAMMacro(
-      name="awesome_lib_mem",
-      width=width,
-      depth=libDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "awesome_lib_mem",
+      width = width,
+      depth = libDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("innerA", width, libDepth),
         generateWritePort("innerB", width, libDepth)
       )
     )
 
     val memMacro = SRAMMacro(
-      name="target_memory",
-      width=width,
-      depth=memDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "target_memory",
+      width = width,
+      depth = memDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("outerB", width, memDepth),
         generateWritePort("outerA", width, memDepth)
       )
@@ -344,7 +354,7 @@ class SplitDepth_SplitPortsNonMasked extends MacroCompilerSpec with HasSRAMGener
     writeToLib(lib, Seq(libMacro))
 
     val output =
-"""
+      """
 circuit target_memory :
   module target_memory :
     input outerB_addr : UInt<11>
@@ -406,11 +416,11 @@ circuit target_memory :
     val v = "split_depth-r-w-regular-lib-split-mem.v"
 
     val memMacro = SRAMMacro(
-      name="target_memory",
-      width=width,
-      depth=memDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "target_memory",
+      width = width,
+      depth = memDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("outerB", width, memDepth),
         generateWritePort("outerA", width, memDepth)
       )
@@ -420,7 +430,7 @@ circuit target_memory :
     writeToLib(lib, Seq(generateSRAM("awesome_lib_mem", "lib", width, libDepth)))
 
     val output =
-"""
+      """
 TODO
 """
 
@@ -439,11 +449,11 @@ TODO
     val v = "split_depth-r-w-split-lib-regular-mem.v"
 
     val libMacro = SRAMMacro(
-      name="awesome_lib_mem",
-      width=width,
-      depth=libDepth,
-      family="1rw",
-      ports=Seq(
+      name = "awesome_lib_mem",
+      width = width,
+      depth = libDepth,
+      family = "1rw",
+      ports = Seq(
         generateReadPort("innerA", width, libDepth),
         generateWritePort("innerB", width, libDepth)
       )
@@ -453,7 +463,7 @@ TODO
     writeToLib(lib, Seq(libMacro))
 
     val output =
-"""
+      """
 TODO
 """
 
@@ -480,22 +490,22 @@ class SplitDepth_SplitPortsMasked extends MacroCompilerSpec with HasSRAMGenerato
     val v = "split_depth-r-mw-split-lib-split-mem.v"
 
     val libMacro = SRAMMacro(
-      name="awesome_lib_mem",
-      width=width,
-      depth=libDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "awesome_lib_mem",
+      width = width,
+      depth = libDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("innerA", width, libDepth),
         generateWritePort("innerB", width, libDepth, libMaskGran)
       )
     )
 
     val memMacro = SRAMMacro(
-      name="target_memory",
-      width=width,
-      depth=memDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "target_memory",
+      width = width,
+      depth = memDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("outerB", width, memDepth),
         generateWritePort("outerA", width, memDepth, memMaskGran)
       )
@@ -505,7 +515,7 @@ class SplitDepth_SplitPortsMasked extends MacroCompilerSpec with HasSRAMGenerato
     writeToLib(lib, Seq(libMacro))
 
     val output =
-"""
+      """
 circuit target_memory :
   module target_memory :
     input outerB_addr : UInt<11>
@@ -571,11 +581,11 @@ circuit target_memory :
     val v = "split_depth-r-mw-regular-lib-split-mem.v"
 
     val memMacro = SRAMMacro(
-      name="target_memory",
-      width=width,
-      depth=memDepth,
-      family="1r1w",
-      ports=Seq(
+      name = "target_memory",
+      width = width,
+      depth = memDepth,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("outerB", width, memDepth),
         generateWritePort("outerA", width, memDepth, memMaskGran)
       )
@@ -585,7 +595,7 @@ circuit target_memory :
     writeToLib(lib, Seq(generateSRAM("awesome_lib_mem", "lib", width, libDepth, libMaskGran)))
 
     val output =
-"""
+      """
 TODO
 """
 
@@ -604,11 +614,11 @@ TODO
     val v = "split_depth-r-mw-split-lib-regular-mem.v"
 
     val libMacro = SRAMMacro(
-      name="awesome_lib_mem",
-      width=width,
-      depth=libDepth,
-      family="1rw",
-      ports=Seq(
+      name = "awesome_lib_mem",
+      width = width,
+      depth = libDepth,
+      family = "1rw",
+      ports = Seq(
         generateReadPort("innerA", width, libDepth),
         generateWritePort("innerB", width, libDepth, libMaskGran)
       )
@@ -618,7 +628,7 @@ TODO
     writeToLib(lib, Seq(libMacro))
 
     val output =
-"""
+      """
 TODO
 """
 
diff --git a/macros/src/test/scala/SimpleSplitWidth.scala b/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala
similarity index 75%
rename from macros/src/test/scala/SimpleSplitWidth.scala
rename to macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala
index 843eed49..3cd0a6df 100644
--- a/macros/src/test/scala/SimpleSplitWidth.scala
+++ b/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala
@@ -5,43 +5,45 @@ package barstools.macros
 
 trait HasSimpleWidthTestGenerator extends HasSimpleTestGenerator {
   this: MacroCompilerSpec with HasSRAMGenerator =>
-    def depth: BigInt
+  def depth: BigInt
 
-    override lazy val memDepth = depth
-    override lazy val libDepth = depth
+  override lazy val memDepth = depth
+  override lazy val libDepth = depth
 
-    override def generateBody(): String = {
-      val output = new StringBuilder
+  override def generateBody(): String = {
+    val output = new StringBuilder
 
-      // Generate mem_0_<i> lines for number of width instances.
-      output.append(
-        ((0 to widthInstances - 1) map {i:Int => s"""
+    // Generate mem_0_<i> lines for number of width instances.
+    output.append(
+      ((0 to widthInstances - 1).map { i: Int =>
+        s"""
     inst mem_0_${i} of ${lib_name}
 """
-        }).reduceLeft(_ + _)
-      )
+      }).reduceLeft(_ + _)
+    )
 
-      // Generate submemory connection blocks.
-      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.
-        // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this
-        // would be 16.
-        val myBaseBit = usableLibWidth*i
-
-        val maskStatement = generateMaskStatement(i, 0)
-
-        // We need to use writeEnable as a crude "mask" if mem has a mask but
-        // lib does not.
-        val writeEnableBit = if (libMaskGran.isEmpty && memMaskGran.isDefined) {
-          val outerMaskBit = myBaseBit / memMaskGran.get
-          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"
-
-s"""
+    // Generate submemory connection blocks.
+    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.
+      // e.g. if libWidth is 8 and this is submemory 2 (0-indexed), then this
+      // would be 16.
+      val myBaseBit = usableLibWidth * i
+
+      val maskStatement = generateMaskStatement(i, 0)
+
+      // We need to use writeEnable as a crude "mask" if mem has a mask but
+      // lib does not.
+      val writeEnableBit = if (libMaskGran.isEmpty && memMaskGran.isDefined) {
+        val outerMaskBit = myBaseBit / memMaskGran.get
+        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"
+
+      s"""
     mem_0_${i}.${libPortPrefix}_clk <= ${memPortPrefix}_clk
     mem_0_${i}.${libPortPrefix}_addr <= ${memPortPrefix}_addr
     node ${memPortPrefix}_dout_0_${i} = bits(mem_0_${i}.${libPortPrefix}_dout, ${myMemWidth - 1}, 0)
@@ -49,24 +51,23 @@ s"""
     ${maskStatement}
     mem_0_${i}.${libPortPrefix}_write_en <= and(and(${writeEnableExpr}, ${writeEnableBit}), UInt<1>("h1"))
 """
-      }).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}"))
-        val catStmt = doutStatements.init.foldRight(doutStatements.last)((l: String, r: String) => s"cat($l, $r)")
-s"""
+    }).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}"))
+      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
-    }
+""")
+    output.toString
+  }
 }
 
 // Try different widths against a base memory width of 8.
@@ -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)
@@ -395,20 +426,27 @@ class SplitWidth1024x32_readEnable_Lib extends MacroCompilerSpec with HasSRAMGen
 
   override def generateLibSRAM() = {
     SRAMMacro(
-      name=lib_name,
-      width=libWidth,
-      depth=libDepth,
-      family="1rw",
-      ports=Seq(generateTestPort(
-        "lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran,
-        write=true, writeEnable=true,
-        read=true, readEnable=true
-      ))
+      name = lib_name,
+      width = libWidth,
+      depth = libDepth,
+      family = "1rw",
+      ports = Seq(
+        generateTestPort(
+          "lib",
+          Some(libWidth),
+          Some(libDepth),
+          maskGran = libMaskGran,
+          write = true,
+          writeEnable = true,
+          read = true,
+          readEnable = true
+        )
+      )
     )
   }
 
   override def generateBody() =
-"""
+    """
     inst mem_0_0 of awesome_lib_mem
     inst mem_0_1 of awesome_lib_mem
     inst mem_0_2 of awesome_lib_mem
@@ -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)
@@ -453,15 +494,22 @@ class SplitWidth1024x32_readEnable_Mem extends MacroCompilerSpec with HasSRAMGen
 
   override def generateMemSRAM() = {
     SRAMMacro(
-      name=mem_name,
-      width=memWidth,
-      depth=memDepth,
-      family="1rw",
-      ports=Seq(generateTestPort(
-        "outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran,
-        write=true, writeEnable=true,
-        read=true, readEnable=true
-      ))
+      name = mem_name,
+      width = memWidth,
+      depth = memDepth,
+      family = "1rw",
+      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)
@@ -479,34 +530,48 @@ class SplitWidth1024x32_readEnable_LibMem extends MacroCompilerSpec with HasSRAM
 
   override def generateLibSRAM() = {
     SRAMMacro(
-      name=lib_name,
-      width=libWidth,
-      depth=libDepth,
-      family="1rw",
-      ports=Seq(generateTestPort(
-        "lib", Some(libWidth), Some(libDepth), maskGran=libMaskGran,
-        write=true, writeEnable=true,
-        read=true, readEnable=true
-      ))
+      name = lib_name,
+      width = libWidth,
+      depth = libDepth,
+      family = "1rw",
+      ports = Seq(
+        generateTestPort(
+          "lib",
+          Some(libWidth),
+          Some(libDepth),
+          maskGran = libMaskGran,
+          write = true,
+          writeEnable = true,
+          read = true,
+          readEnable = true
+        )
+      )
     )
   }
 
   override def generateMemSRAM() = {
     SRAMMacro(
-      name=mem_name,
-      width=memWidth,
-      depth=memDepth,
-      family="1rw",
-      ports=Seq(generateTestPort(
-        "outer", Some(memWidth), Some(memDepth), maskGran=memMaskGran,
-        write=true, writeEnable=true,
-        read=true, readEnable=true
-      ))
+      name = mem_name,
+      width = memWidth,
+      depth = memDepth,
+      family = "1rw",
+      ports = Seq(
+        generateTestPort(
+          "outer",
+          Some(memWidth),
+          Some(memDepth),
+          maskGran = memMaskGran,
+          write = true,
+          writeEnable = true,
+          read = true,
+          readEnable = true
+        )
+      )
     )
   }
 
   override def generateBody() =
-"""
+    """
     inst mem_0_0 of awesome_lib_mem
     inst mem_0_1 of awesome_lib_mem
     inst mem_0_2 of awesome_lib_mem
diff --git a/macros/src/test/scala/SpecificExamples.scala b/macros/src/test/scala/barstools/macros/SpecificExamples.scala
similarity index 98%
rename from macros/src/test/scala/SpecificExamples.scala
rename to macros/src/test/scala/barstools/macros/SpecificExamples.scala
index e41932bb..334e3a73 100644
--- a/macros/src/test/scala/SpecificExamples.scala
+++ b/macros/src/test/scala/barstools/macros/SpecificExamples.scala
@@ -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",
@@ -58,7 +58,7 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator {
   writeToMem(mem, memSRAMs)
 
   val output =
-"""
+    """
 circuit cc_banks_0_ext :
   module cc_banks_0_ext :
     input RW0_addr : UInt<12>
@@ -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",
@@ -131,7 +131,7 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator {
   writeToMem(mem, memSRAMs)
 
   val output =
-"""
+    """
 circuit cc_dir_ext :
   module cc_dir_ext :
     input RW0_addr : UInt<9>
@@ -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",
@@ -354,7 +354,7 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator {
   writeToMem(mem, memSRAMs)
 
   val output = // TODO: check correctness...
-"""
+    """
 circuit smem_0_ext :
   module _T_182_ext :
     input R0_addr : UInt<6>
@@ -1350,14 +1350,14 @@ circuit smem_0_ext :
 
 class SmallTagArrayTest extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleTestGenerator {
   // Test that mapping a smaller memory using a larger lib can still work.
-  override def memWidth: Int = 26
-  override def memDepth: BigInt = BigInt(2)
-  override def memMaskGran: Option[Int] = Some(26)
+  override def memWidth:      Int = 26
+  override def memDepth:      BigInt = BigInt(2)
+  override def memMaskGran:   Option[Int] = Some(26)
   override def memPortPrefix: String = ""
 
-  override def libWidth: Int = 32
-  override def libDepth: BigInt = BigInt(64)
-  override def libMaskGran: Option[Int] = Some(1)
+  override def libWidth:      Int = 32
+  override def libDepth:      BigInt = BigInt(64)
+  override def libMaskGran:   Option[Int] = Some(1)
   override def libPortPrefix: String = ""
 
   override def extraPorts: Seq[MacroExtraPort] = Seq(
@@ -1388,73 +1388,73 @@ class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator {
 
   val libSRAMs = Seq(
     SRAMMacro(
-      name="SRAM1RW1024x8",
-      depth=1024,
-      width=8,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW1024x8",
+      depth = 1024,
+      width = 8,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 8, BigInt(1024))
       )
     ),
     SRAMMacro(
-      name="SRAM1RW512x32",
-      depth=512,
-      width=32,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW512x32",
+      depth = 512,
+      width = 32,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 32, BigInt(512))
       )
     ),
     SRAMMacro(
-      name="SRAM1RW64x128",
-      depth=64,
-      width=128,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW64x128",
+      depth = 64,
+      width = 128,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 128, BigInt(64))
       )
     ),
     SRAMMacro(
-      name="SRAM1RW64x32",
-      depth=64,
-      width=32,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW64x32",
+      depth = 64,
+      width = 32,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 32, BigInt(64))
       )
     ),
     SRAMMacro(
-      name="SRAM1RW64x8",
-      depth=64,
-      width=8,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW64x8",
+      depth = 64,
+      width = 8,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 8, BigInt(64))
       )
     ),
     SRAMMacro(
-      name="SRAM1RW512x8",
-      depth=512,
-      width=8,
-      family="1rw",
-      ports=Seq(
+      name = "SRAM1RW512x8",
+      depth = 512,
+      width = 8,
+      family = "1rw",
+      ports = Seq(
         generateReadWritePort("", 8, BigInt(512))
       )
     ),
     SRAMMacro(
-      name="SRAM2RW64x32",
-      depth=64,
-      width=32,
-      family="1r1w",
-      ports=Seq(
+      name = "SRAM2RW64x32",
+      depth = 64,
+      width = 32,
+      family = "1r1w",
+      ports = Seq(
         generateReadPort("portA", 32, BigInt(64)),
         generateWritePort("portB", 32, BigInt(64))
       )
     )
   )
 
-  val memSRAMs = mdf.macrolib.Utils.readMDFFromString(
-"""
+  val memSRAMs = mdf.macrolib.Utils
+    .readMDFFromString("""
 [
   {
     "type": "sram",
@@ -1537,7 +1537,7 @@ class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator {
   writeToMem(mem, memSRAMs)
 
   val output = // TODO: check correctness...
-"""
+    """
 circuit T_2172_ext :
   module tag_array_ext :
     input RW0_addr : UInt<6>
diff --git a/macros/src/test/scala/SynFlops.scala b/macros/src/test/scala/barstools/macros/SynFlops.scala
similarity index 87%
rename from macros/src/test/scala/SynFlops.scala
rename to macros/src/test/scala/barstools/macros/SynFlops.scala
index f12161a1..0d39220e 100644
--- a/macros/src/test/scala/SynFlops.scala
+++ b/macros/src/test/scala/barstools/macros/SynFlops.scala
@@ -4,13 +4,13 @@ package barstools.macros
 
 trait HasSynFlopsTestGenerator extends HasSimpleTestGenerator {
   this: MacroCompilerSpec with HasSRAMGenerator =>
-    def generateFlops: String = {
-s"""
+  def generateFlops: String = {
+    s"""
     inst mem_0_0 of split_${lib_name}
     mem_0_0.${libPortPrefix}_clk <= ${libPortPrefix}_clk
     mem_0_0.${libPortPrefix}_addr <= ${libPortPrefix}_addr
-    node ${libPortPrefix}_dout_0_0 = bits(mem_0_0.${libPortPrefix}_dout, ${libWidth-1}, 0)
-    mem_0_0.${libPortPrefix}_din <= bits(${libPortPrefix}_din, ${libWidth-1}, 0)
+    node ${libPortPrefix}_dout_0_0 = bits(mem_0_0.${libPortPrefix}_dout, ${libWidth - 1}, 0)
+    mem_0_0.${libPortPrefix}_din <= bits(${libPortPrefix}_din, ${libWidth - 1}, 0)
     mem_0_0.${libPortPrefix}_write_en <= and(and(and(${libPortPrefix}_write_en, UInt<1>("h1")), UInt<1>("h1")), UInt<1>("h1"))
     node ${libPortPrefix}_dout_0 = ${libPortPrefix}_dout_0_0
     ${libPortPrefix}_dout <= mux(UInt<1>("h1"), ${libPortPrefix}_dout_0, UInt<${libWidth}>("h0"))
@@ -37,49 +37,66 @@ s"""
     ${libPortPrefix}_dout <= ram.RW_0.rdata
     ram.RW_0.wdata <= ${libPortPrefix}_din
 """
-    }
-
-    // If there is no lib, put the flops definition into the body.
-    abstract override def generateBody = {
-      if (this.isInstanceOf[HasNoLibTestGenerator]) generateFlops else super.generateBody
-    }
-
-    // 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
-s"""
+  }
+
+  // If there is no lib, put the flops definition into the body.
+  abstract override def generateBody = {
+    if (this.isInstanceOf[HasNoLibTestGenerator]) generateFlops else super.generateBody
+  }
+
+  // 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
+      s"""
   module ${lib_name} :
 ${generateFooterPorts}
 
 ${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)
@@ -103,29 +128,29 @@ class Synflops_SplitPorts_Read_Write extends MacroCompilerSpec with HasSRAMGener
   override lazy val width = 8
 
   override def generateLibSRAM = SRAMMacro(
-    name=lib_name,
-    width=width,
-    depth=libDepth,
-    family="1r1w",
-    ports=Seq(
+    name = lib_name,
+    width = width,
+    depth = libDepth,
+    family = "1r1w",
+    ports = Seq(
       generateReadPort("innerA", width, libDepth),
       generateWritePort("innerB", width, libDepth)
     )
   )
 
   override def generateMemSRAM = SRAMMacro(
-    name=mem_name,
-    width=width,
-    depth=memDepth,
-    family="1r1w",
-    ports=Seq(
+    name = mem_name,
+    width = width,
+    depth = memDepth,
+    family = "1r1w",
+    ports = Seq(
       generateReadPort("outerB", width, memDepth),
       generateWritePort("outerA", width, memDepth)
     )
   )
 
   override def generateHeader =
-"""
+    """
 circuit target_memory :
   module target_memory :
     input outerB_addr : UInt<11>
@@ -138,7 +163,7 @@ circuit target_memory :
 """
 
   override def generateBody =
-"""
+    """
     node outerB_addr_sel = bits(outerB_addr, 10, 10)
     reg outerB_addr_sel_reg : UInt<1>, outerB_clk with :
       reset => (UInt<1>("h0"), outerB_addr_sel_reg)
@@ -166,7 +191,7 @@ circuit target_memory :
 """
 
   override def generateFooterPorts =
-"""
+    """
     input innerA_addr : UInt<10>
     input innerA_clk : Clock
     output innerA_dout : UInt<8>
@@ -177,7 +202,7 @@ circuit target_memory :
 """
 
   override def generateFlops =
-"""
+    """
     inst mem_0_0 of split_awesome_lib_mem
     mem_0_0.innerB_clk <= innerB_clk
     mem_0_0.innerB_addr <= innerB_addr
@@ -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)
@@ -232,29 +261,29 @@ class Synflops_SplitPorts_MaskedMem_Read_MaskedWrite extends MacroCompilerSpec w
   override lazy val libMaskGran = Some(1)
 
   override def generateLibSRAM = SRAMMacro(
-    name=lib_name,
-    width=width,
-    depth=libDepth,
-    family="1r1w",
-    ports=Seq(
+    name = lib_name,
+    width = width,
+    depth = libDepth,
+    family = "1r1w",
+    ports = Seq(
       generateReadPort("innerA", width, libDepth),
       generateWritePort("innerB", width, libDepth, libMaskGran)
     )
   )
 
   override def generateMemSRAM = SRAMMacro(
-    name=mem_name,
-    width=width,
-    depth=memDepth,
-    family="1r1w",
-    ports=Seq(
+    name = mem_name,
+    width = width,
+    depth = memDepth,
+    family = "1r1w",
+    ports = Seq(
       generateReadPort("outerB", width, memDepth),
       generateWritePort("outerA", width, memDepth, memMaskGran)
     )
   )
 
   override def generateHeader =
-"""
+    """
 circuit target_memory :
   module target_memory :
     input outerB_addr : UInt<11>
@@ -268,7 +297,7 @@ circuit target_memory :
 """
 
   override def generateBody =
-"""
+    """
     node outerB_addr_sel = bits(outerB_addr, 10, 10)
     reg outerB_addr_sel_reg : UInt<1>, outerB_clk with :
       reset => (UInt<1>("h0"), outerB_addr_sel_reg)
@@ -298,7 +327,7 @@ circuit target_memory :
 """
 
   override def generateFooterPorts =
-"""
+    """
     input innerA_addr : UInt<10>
     input innerA_clk : Clock
     output innerA_dout : UInt<8>
@@ -310,7 +339,7 @@ circuit target_memory :
 """
 
   override def generateFlops =
-"""
+    """
     inst mem_0_0 of split_awesome_lib_mem
     inst mem_0_1 of split_awesome_lib_mem
     inst mem_0_2 of split_awesome_lib_mem
diff --git a/tapeout/src/test/scala/transforms/ResetInverterSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala
similarity index 63%
rename from tapeout/src/test/scala/transforms/ResetInverterSpec.scala
rename to tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala
index 9f23c3a8..701c7845 100644
--- a/tapeout/src/test/scala/transforms/ResetInverterSpec.scala
+++ b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala
@@ -3,9 +3,10 @@
 package barstools.tapeout.transforms
 
 import chisel3._
-import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
+import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
 import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation}
-import org.scalatest.{FreeSpec, Matchers}
+import org.scalatest.freespec.AnyFreeSpec
+import org.scalatest.matchers.should.Matchers
 
 class ExampleModuleNeedsResetInverted extends Module with ResetInverter {
   val io = IO(new Bundle {
@@ -19,7 +20,7 @@ class ExampleModuleNeedsResetInverted extends Module with ResetInverter {
   invert(this)
 }
 
-class ResetNSpec extends FreeSpec with Matchers {
+class ResetNSpec extends AnyFreeSpec with Matchers {
   "Inverting reset needs to be done throughout module in Chirrtl" in {
     val chirrtl = (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted)
     chirrtl should include("input reset :")
@@ -29,14 +30,17 @@ class ResetNSpec extends FreeSpec with Matchers {
 
   "Inverting reset needs to be done throughout module when generating firrtl" in {
     // generate low-firrtl
-    val firrtl = (new ChiselStage).execute(
-      Array("-X", "low"),
-      Seq(ChiselGeneratorAnnotation(() => new ExampleModuleNeedsResetInverted))
-    ).collect {
-      case EmittedFirrtlCircuitAnnotation(a) => a
-      case EmittedFirrtlModuleAnnotation(a)  => a
-    }.map(_.value)
-    .mkString("")
+    val firrtl = (new ChiselStage)
+      .execute(
+        Array("-X", "low"),
+        Seq(ChiselGeneratorAnnotation(() => new ExampleModuleNeedsResetInverted))
+      )
+      .collect {
+        case EmittedFirrtlCircuitAnnotation(a) => a
+        case EmittedFirrtlModuleAnnotation(a)  => a
+      }
+      .map(_.value)
+      .mkString("")
 
     firrtl should include("input reset_n :")
     firrtl should include("node reset = not(reset_n)")
diff --git a/tapeout/src/test/scala/transforms/retime/RetimeSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala
similarity index 67%
rename from tapeout/src/test/scala/transforms/retime/RetimeSpec.scala
rename to tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala
index 35678991..a086b0b9 100644
--- a/tapeout/src/test/scala/transforms/retime/RetimeSpec.scala
+++ b/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala
@@ -1,16 +1,15 @@
 // See LICENSE for license details.
 
-package barstools.tapeout.transforms.retime.test
+package barstools.tapeout.transforms.retime
 
 import chisel3._
-import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
-import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation}
-import barstools.tapeout.transforms.retime.RetimeLib
-import firrtl.FileUtils
+import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage}
+import firrtl.{EmittedFirrtlCircuitAnnotation, EmittedFirrtlModuleAnnotation, FileUtils}
 import logger.Logger
-import org.scalatest.{FlatSpec, Matchers}
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
 
-class RetimeSpec extends FlatSpec with Matchers {
+class RetimeSpec extends AnyFlatSpec with Matchers {
   def normalized(s: String): String = {
     require(!s.contains("\n"))
     s.replaceAll("\\s+", " ").trim
@@ -21,18 +20,20 @@ class RetimeSpec extends FlatSpec with Matchers {
   }
   def getLowFirrtl[T <: RawModule](gen: () => T, extraArgs: Array[String] = Array.empty): String = {
     // generate low firrtl
-    (new ChiselStage).execute(
-      Array("-X", "low") ++ extraArgs,
-      Seq(ChiselGeneratorAnnotation(gen))
-    ).collect {
-      case EmittedFirrtlCircuitAnnotation(a) => a
-      case EmittedFirrtlModuleAnnotation(a)  => a
-    }.map(_.value)
-    .mkString("")
+    (new ChiselStage)
+      .execute(
+        Array("-X", "low") ++ extraArgs,
+        Seq(ChiselGeneratorAnnotation(gen))
+      )
+      .collect {
+        case EmittedFirrtlCircuitAnnotation(a) => a
+        case EmittedFirrtlModuleAnnotation(a)  => a
+      }
+      .map(_.value)
+      .mkString("")
   }
 
-
-  behavior of "retime library"
+  behavior.of("retime library")
 
   it should "pass simple retime module annotation" in {
     val gen = () => new RetimeModule
@@ -43,15 +44,18 @@ class RetimeSpec extends FlatSpec with Matchers {
       Logger.setOutput(captor.printStream)
 
       // generate low firrtl
-      val firrtl = getLowFirrtl(gen,
-        Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info"))
+      val firrtl = getLowFirrtl(
+        gen,
+        Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info")
+      )
 
       firrtl.nonEmpty should be(true)
       //Make sure we got the RetimeTransform scheduled
-      captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform")
+      captor.getOutputAsString should include("barstools.tapeout.transforms.retime.RetimeTransform")
     }
 
-    val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
+    val lines = FileUtils
+      .getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
       .map(normalized)
       .mkString("\n")
     lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation")
@@ -67,15 +71,18 @@ class RetimeSpec extends FlatSpec with Matchers {
       Logger.setOutput(captor.printStream)
 
       // generate low firrtl
-      val firrtl = getLowFirrtl(gen,
-        Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info"))
+      val firrtl = getLowFirrtl(
+        gen,
+        Array("-td", s"test_run_dir/$dir", "-foaf", s"test_run_dir/$dir/final", "--log-level", "info")
+      )
 
       firrtl.nonEmpty should be(true)
       //Make sure we got the RetimeTransform scheduled
-      captor.getOutputAsString should include ("barstools.tapeout.transforms.retime.RetimeTransform")
+      captor.getOutputAsString should include("barstools.tapeout.transforms.retime.RetimeTransform")
     }
 
-    val lines = FileUtils.getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
+    val lines = FileUtils
+      .getLines(s"test_run_dir/$dir/test_run_dir/$dir/final.anno.json")
       .map(normalized)
       .mkString("\n")
     lines should include("barstools.tapeout.transforms.retime.RetimeAnnotation")