From c907a7377cca17422bab16cdf4c42cc83d3b97ee Mon Sep 17 00:00:00 2001 From: chick Date: Fri, 6 Aug 2021 13:09:45 -0700 Subject: [PATCH 1/8] Moved a zillion files all over the place so that everything is now in tapeout/src in the correct directory corresponding to internal packages. Everything compiles and tests run TODO: - Figure out assembly step for MacroCompiler - Does root project matter? --- .gitmodules | 3 - build.sbt | 14 +- macros/build.sbt | 1 - mdf | 1 - .../resources/barstools/iocell/vsrc/Analog.v | 0 .../resources/barstools/iocell/vsrc/IOCell.v | 0 .../barstools/iocell/chisel/Analog.scala | 0 .../barstools/iocell/chisel/IOCell.scala | 2 +- .../scala/barstools/macros/CostMetric.scala | 0 .../barstools/macros/MacroCompiler.scala | 0 .../scala/barstools/macros/SynFlops.scala | 2 +- .../main/scala/barstools/macros/Utils.scala | 0 .../main/scala/mdf/macrolib/ConfReader.scala | 95 ++++ .../scala/mdf/macrolib/FillerMacroBase.scala | 61 +++ .../scala/mdf/macrolib/FlipChipMacro.scala | 72 +++ .../src/main/scala/mdf/macrolib/IOMacro.scala | 147 ++++++ .../main/scala/mdf/macrolib/MacroLib.scala | 19 + .../src/main/scala/mdf/macrolib/SRAM.scala | 444 ++++++++++++++++++ .../src/main/scala/mdf/macrolib/Utils.scala | 87 ++++ .../src/test/resources/lib-BOOMTest.json | 0 .../src/test/resources/lib-MaskPortTest.json | 0 .../test/resources/lib-WriteEnableTest.json | 0 .../scala/barstools/macros/CostFunction.scala | 0 .../scala/barstools/macros/Functional.scala | 0 .../barstools/macros/MacroCompilerSpec.scala | 0 .../test/scala/barstools/macros/Masks.scala | 0 .../scala/barstools/macros/MultiPort.scala | 0 .../scala/barstools/macros/SRAMCompiler.scala | 0 .../barstools/macros/SimpleSplitDepth.scala | 0 .../barstools/macros/SimpleSplitWidth.scala | 0 .../barstools/macros/SpecificExamples.scala | 6 +- .../scala/barstools/macros/SynFlops.scala | 0 .../tapeout/transforms/GenerateSpec.scala | 2 +- .../transforms/ResetInverterSpec.scala | 4 +- .../scala/mdf/macrolib/ConfReaderSpec.scala | 101 ++++ .../mdf/macrolib/FlipChipMacroSpec.scala | 14 + .../test/scala/mdf/macrolib/IOMacroSpec.scala | 67 +++ .../scala/mdf/macrolib/IOPropertiesSpec.scala | 14 + .../scala/mdf/macrolib/MacroLibOutput.scala | 270 +++++++++++ .../scala/mdf/macrolib/MacroLibSpec.scala | 406 ++++++++++++++++ 40 files changed, 1809 insertions(+), 23 deletions(-) delete mode 100644 .gitmodules delete mode 100644 macros/build.sbt delete mode 160000 mdf rename {iocell => tapeout}/src/main/resources/barstools/iocell/vsrc/Analog.v (100%) rename {iocell => tapeout}/src/main/resources/barstools/iocell/vsrc/IOCell.v (100%) rename {iocell => tapeout}/src/main/scala/barstools/iocell/chisel/Analog.scala (100%) rename {iocell => tapeout}/src/main/scala/barstools/iocell/chisel/IOCell.scala (99%) rename {macros => tapeout}/src/main/scala/barstools/macros/CostMetric.scala (100%) rename {macros => tapeout}/src/main/scala/barstools/macros/MacroCompiler.scala (100%) rename {macros => tapeout}/src/main/scala/barstools/macros/SynFlops.scala (98%) rename {macros => tapeout}/src/main/scala/barstools/macros/Utils.scala (100%) create mode 100644 tapeout/src/main/scala/mdf/macrolib/ConfReader.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/IOMacro.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/MacroLib.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/SRAM.scala create mode 100644 tapeout/src/main/scala/mdf/macrolib/Utils.scala rename {macros => tapeout}/src/test/resources/lib-BOOMTest.json (100%) rename {macros => tapeout}/src/test/resources/lib-MaskPortTest.json (100%) rename {macros => tapeout}/src/test/resources/lib-WriteEnableTest.json (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/CostFunction.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/Functional.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/MacroCompilerSpec.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/Masks.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/MultiPort.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/SRAMCompiler.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/SimpleSplitDepth.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/SimpleSplitWidth.scala (100%) rename {macros => tapeout}/src/test/scala/barstools/macros/SpecificExamples.scala (99%) rename {macros => tapeout}/src/test/scala/barstools/macros/SynFlops.scala (100%) create mode 100644 tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala create mode 100644 tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala create mode 100644 tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala create mode 100644 tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala create mode 100644 tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala create mode 100644 tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 733ebcf6..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "mdf"] - path = mdf - url = https://github.com/ucb-bar/plsi-mdf.git diff --git a/build.sbt b/build.sbt index d8840865..1fe83505 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,8 @@ lazy val commonSettings = Seq( dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }, libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" % "3.2.2" % "test", + "com.typesafe.play" %% "play-json" % "2.9.2", + "org.scalatest" %% "scalatest" % "3.2.9" % "test", ), resolvers ++= Seq( Resolver.sonatypeRepo("snapshots"), @@ -25,17 +26,10 @@ lazy val commonSettings = Seq( disablePlugins(sbtassembly.AssemblyPlugin) -lazy val mdf = (project in file("mdf/scalalib")) -lazy val macros = (project in file("macros")) - .dependsOn(mdf) - .settings(commonSettings) - .settings( - mainClass := Some("barstools.macros.MacroCompiler") - ) - .enablePlugins(sbtassembly.AssemblyPlugin) +enablePlugins(sbtassembly.AssemblyPlugin) lazy val tapeout = (project in file("tapeout")) .settings(commonSettings) .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) -lazy val root = (project in file(".")).aggregate(macros, tapeout) +lazy val root = (project in file(".")).aggregate(tapeout) diff --git a/macros/build.sbt b/macros/build.sbt deleted file mode 100644 index 65e9704a..00000000 --- a/macros/build.sbt +++ /dev/null @@ -1 +0,0 @@ -enablePlugins(sbtassembly.AssemblyPlugin) diff --git a/mdf b/mdf deleted file mode 160000 index e588024d..00000000 --- a/mdf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e588024d706220b73f2c97ca75d6fec8dd0d41b1 diff --git a/iocell/src/main/resources/barstools/iocell/vsrc/Analog.v b/tapeout/src/main/resources/barstools/iocell/vsrc/Analog.v similarity index 100% rename from iocell/src/main/resources/barstools/iocell/vsrc/Analog.v rename to tapeout/src/main/resources/barstools/iocell/vsrc/Analog.v diff --git a/iocell/src/main/resources/barstools/iocell/vsrc/IOCell.v b/tapeout/src/main/resources/barstools/iocell/vsrc/IOCell.v similarity index 100% rename from iocell/src/main/resources/barstools/iocell/vsrc/IOCell.v rename to tapeout/src/main/resources/barstools/iocell/vsrc/IOCell.v diff --git a/iocell/src/main/scala/barstools/iocell/chisel/Analog.scala b/tapeout/src/main/scala/barstools/iocell/chisel/Analog.scala similarity index 100% rename from iocell/src/main/scala/barstools/iocell/chisel/Analog.scala rename to tapeout/src/main/scala/barstools/iocell/chisel/Analog.scala diff --git a/iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala similarity index 99% rename from iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala rename to tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala index d244d298..47b7cf2e 100644 --- a/iocell/src/main/scala/barstools/iocell/chisel/IOCell.scala +++ b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala @@ -148,7 +148,7 @@ object IOCell { padSignal: T, name: Option[String] = None, typeParams: IOCellTypeParams = GenericIOCellParams(), - concretizeResetFn: (Reset) => R = toSyncReset + concretizeResetFn: (Reset) => R = toSyncReset _ ): Seq[IOCell] = { def genCell[T <: Data]( castToBool: (T) => Bool, diff --git a/macros/src/main/scala/barstools/macros/CostMetric.scala b/tapeout/src/main/scala/barstools/macros/CostMetric.scala similarity index 100% rename from macros/src/main/scala/barstools/macros/CostMetric.scala rename to tapeout/src/main/scala/barstools/macros/CostMetric.scala diff --git a/macros/src/main/scala/barstools/macros/MacroCompiler.scala b/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala similarity index 100% rename from macros/src/main/scala/barstools/macros/MacroCompiler.scala rename to tapeout/src/main/scala/barstools/macros/MacroCompiler.scala diff --git a/macros/src/main/scala/barstools/macros/SynFlops.scala b/tapeout/src/main/scala/barstools/macros/SynFlops.scala similarity index 98% rename from macros/src/main/scala/barstools/macros/SynFlops.scala rename to tapeout/src/main/scala/barstools/macros/SynFlops.scala index 77ea4c96..5d39cda9 100644 --- a/macros/src/main/scala/barstools/macros/SynFlops.scala +++ b/tapeout/src/main/scala/barstools/macros/SynFlops.scala @@ -64,7 +64,7 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa 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 { + 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) diff --git a/macros/src/main/scala/barstools/macros/Utils.scala b/tapeout/src/main/scala/barstools/macros/Utils.scala similarity index 100% rename from macros/src/main/scala/barstools/macros/Utils.scala rename to tapeout/src/main/scala/barstools/macros/Utils.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/ConfReader.scala b/tapeout/src/main/scala/mdf/macrolib/ConfReader.scala new file mode 100644 index 00000000..ec701d6e --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/ConfReader.scala @@ -0,0 +1,95 @@ +package mdf.macrolib + +object ConfReader { + import scala.util.matching.Regex._ + + type ConfPort = (String, Boolean) // prefix (e.g. "RW0") and true if masked + + /** Rename ports like "read" to R0, "write" to W0, and "rw" to RW0, and + * return a count of read, write, and readwrite ports. + */ + def renamePorts(ports: Seq[String]): (Seq[ConfPort], Int, Int, Int) = { + var readCount = 0 + var writeCount = 0 + var readWriteCount = 0 + ( + ports.map { + _ match { + case "read" => readCount += 1; (s"R${readCount - 1}", false) + case "write" => writeCount += 1; (s"W${writeCount - 1}", false) + case "mwrite" => writeCount += 1; (s"W${writeCount - 1}", true) + case "rw" => readWriteCount += 1; (s"RW${readWriteCount - 1}", false) + case "mrw" => readWriteCount += 1; (s"RW${readWriteCount - 1}", true) + } + }, + readCount, + writeCount, + readWriteCount + ) + } + + def generateFirrtlPort(port: ConfPort, width: Int, depth: Int, maskGran: Option[Int]): MacroPort = { + val (prefix, masked) = port + val isReadWriter = prefix.startsWith("RW") + val isReader = prefix.startsWith("R") && !isReadWriter + val isWriter = prefix.startsWith("W") + val r = if (isReadWriter) "r" else "" + val w = if (isReadWriter) "w" else "" + MacroPort( + address = PolarizedPort(s"${prefix}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"${prefix}_clk", PositiveEdge)), + writeEnable = if (isReadWriter) Some(PolarizedPort(s"${prefix}_${w}mode", ActiveHigh)) else None, + output = if (isReader || isReadWriter) Some(PolarizedPort(s"${prefix}_${w}data", ActiveHigh)) else None, + input = if (isWriter || isReadWriter) Some(PolarizedPort(s"${prefix}_${r}data", ActiveHigh)) else None, + maskPort = if (masked) Some(PolarizedPort(s"${prefix}_${w}mask", ActiveHigh)) else None, + maskGran = if (masked) maskGran else None, + width = Some(width), + depth = Some(depth) + ) + } + + /** Read a conf line into a SRAMMacro, but returns an error string in Left + * instead of throwing errors if the line is malformed. + */ + def readSingleLineSafe(line: String): Either[String, SRAMMacro] = { + val pattern = """name ([^\s]+) depth (\d+) width (\d+) ports ([a-z,]+)\s?(?:mask_gran (\d+))?""".r + pattern.findFirstMatchIn(line) match { + case Some(m: Match) => { + val name: String = m.group(1) + val depth: Int = (m.group(2)).toInt + val width: Int = (m.group(3)).toInt + val ports: Seq[String] = (m.group(4)).split(",") + val (firrtlPorts, readPortCount, writePortCount, readWritePortCount) = renamePorts(ports) + val familyStr = + (if (readPortCount > 0) s"${readPortCount}r" else "") + + (if (writePortCount > 0) s"${writePortCount}w" else "") + + (if (readWritePortCount > 0) s"${readWritePortCount}rw" else "") + val maskGran: Option[Int] = Option(m.group(5)).map(_.toInt) + Right( + SRAMMacro( + name = name, + width = width, + depth = depth, + family = familyStr, + vt = "", + mux = 1, + ports = firrtlPorts.map(generateFirrtlPort(_, width, depth, maskGran)), + extraPorts = List() + ) + ) + } + case _ => Left("Input line did not match conf regex") + } + } + + /** Read a conf line into a SRAMMacro. */ + def readSingleLine(line: String): SRAMMacro = { + readSingleLineSafe(line).right.get + } + + /** Read the contents of the conf file into a seq of SRAMMacro. */ + def readFromString(contents: String): Seq[SRAMMacro] = { + // Trim, remove empty lines, then pass to readSingleLine + contents.split("\n").map(_.trim).filter(_ != "").map(readSingleLine(_)) + } +} diff --git a/tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala b/tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala new file mode 100644 index 00000000..688871b5 --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala @@ -0,0 +1,61 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.language.implicitConversions + +// Filler and metal filler +abstract class FillerMacroBase(name: String, vt: String) extends Macro { + override def toString(): String = { + s"${this.getClass.getSimpleName}(name=${name}, vt=${vt})" + } + + override def toJSON(): JsObject = { + JsObject( + Seq( + "type" -> JsString(typeStr), + "name" -> Json.toJson(name), + "vt" -> Json.toJson(vt) + ) + ) + } +} +object FillerMacroBase { + def parseJSON(json: Map[String, JsValue]): Option[FillerMacroBase] = { + val typee: String = json.get("type") match { + case Some(x: JsString) => + x.value match { + case "" => return None + case x => x + } + case _ => return None + } + val name: String = json.get("name") match { + case Some(x: JsString) => + x.value match { + case "" => return None + case x => x + } + case _ => return None + } + val vt: String = json.get("vt") match { + case Some(x: JsString) => + x.value match { + case "" => return None + case x => x + } + case _ => return None + } + typee match { + case "metal filler cell" => Some(MetalFillerMacro(name, vt)) + case "filler cell" => Some(FillerMacro(name, vt)) + case _ => None + } + } +} + +case class FillerMacro(name: String, vt: String) extends FillerMacroBase(name, vt) { + override def typeStr = "filler cell" +} +case class MetalFillerMacro(name: String, vt: String) extends FillerMacroBase(name, vt) { + override def typeStr = "metal filler cell" +} diff --git a/tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala b/tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala new file mode 100644 index 00000000..45b49d86 --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala @@ -0,0 +1,72 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.collection.mutable.ListBuffer +import scala.language.implicitConversions + +// Flip Chip Macro +case class FlipChipMacro( + name: String, + bumpDimensions: (Int, Int), + bumpLocations: Seq[Seq[String]]) + extends Macro { + override def toJSON(): JsObject = { + + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "name" -> Json.toJson(name), + "type" -> Json.toJson(typeStr), + "bump_dimensions" -> JsArray(Seq(bumpDimensions._1, bumpDimensions._2).map { JsNumber(_) }), + "bump_locations" -> JsArray(bumpLocations.map(l => JsArray(l.map(JsString)))) + ) + ) + + JsObject(output) + } + val maxIONameSize = bumpLocations.foldLeft(0) { (size, row) => + row.foldLeft(size) { (size, str) => scala.math.max(size, str.length) } + } + def visualize: String = { + val output = new StringBuffer() + for (x <- 0 until bumpDimensions._1) { + for (y <- 0 until bumpDimensions._2) { + val name = bumpLocations(x)(y).drop(1).dropRight(1) + val extra = maxIONameSize - name.length() + val leftSpace = " " * (extra / 2) + val rightSpace = " " * (extra / 2 + extra % 2) + output.append(leftSpace + name + rightSpace + "|") + } + output.append("\n") + } + output.toString() + } + + override def typeStr = "flipchip" +} + +object FlipChipMacro { + def parseJSON(json: Map[String, JsValue]): Option[FlipChipMacro] = { + val name: String = json.get("name") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + + val bumpDimensions: (Int, Int) = json.get("bump_dimensions") match { + case Some(JsArray(x)) if x.size == 2 => + val z = x.map(_.as[JsNumber].value.intValue()) + (z(0), z(1)) + case None => return None + } + val bumpLocations: Seq[Seq[String]] = json.get("bump_locations") match { + case Some(JsArray(array)) => + array.collect { case JsArray(a2) => a2.map(_.toString) } + case _ => return None + } + // Can't have dimensions and locations which don't match + if (bumpLocations.size != bumpDimensions._1) return None + if (bumpLocations.collect { case x if x.size != bumpDimensions._2 => x }.nonEmpty) return None + + Some(FlipChipMacro(name, bumpDimensions, bumpLocations)) + } +} diff --git a/tapeout/src/main/scala/mdf/macrolib/IOMacro.scala b/tapeout/src/main/scala/mdf/macrolib/IOMacro.scala new file mode 100644 index 00000000..3f8ead8c --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/IOMacro.scala @@ -0,0 +1,147 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.collection.mutable.ListBuffer +import scala.language.implicitConversions + +sealed abstract class PortType { def toJSON(): JsString = JsString(toString) } +case object Digital extends PortType { override def toString: String = "digital" } +case object Analog extends PortType { override def toString: String = "analog" } +case object Power extends PortType { override def toString: String = "power" } +case object Ground extends PortType { override def toString: String = "ground" } +case object NoConnect extends PortType { override def toString: String = "NC" } + +sealed abstract class Direction { def toJSON(): JsString = JsString(toString) } +case object Input extends Direction { override def toString: String = "input" } +case object Output extends Direction { override def toString: String = "output" } +case object InOut extends Direction { override def toString: String = "inout" } + +sealed abstract class Termination { def toJSON(): JsValue } +case object CMOS extends Termination { override def toJSON(): JsString = JsString("CMOS") } +case class Resistive(ohms: Int) extends Termination { override def toJSON(): JsNumber = JsNumber(ohms) } + +sealed abstract class TerminationType { def toJSON(): JsString } +case object Single extends TerminationType { override def toJSON(): JsString = JsString("single") } +case object Differential extends TerminationType { override def toJSON(): JsString = JsString("differential") } + +// IO macro +case class IOMacro( + name: String, + tpe: PortType, + direction: Option[Direction] = None, + termination: Option[Termination] = None, + terminationType: Option[TerminationType] = None, + terminationReference: Option[String] = None, + matching: Seq[String] = Seq.empty[String], + bbname: Option[String] = None) + extends Macro { + override def toJSON(): JsObject = { + + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "name" -> Json.toJson(name), + "type" -> tpe.toJSON() + ) + ) + if (direction.isDefined) output.append("direction" -> direction.get.toJSON) + if (termination.isDefined) output.append("termination" -> termination.get.toJSON) + if (terminationType.isDefined) output.append("terminationType" -> terminationType.get.toJSON) + if (terminationReference.isDefined) output.append("terminationReference" -> JsString(terminationReference.get)) + if (matching.nonEmpty) output.append("match" -> JsArray(matching.map(JsString))) + if (bbname.nonEmpty) output.append("blackBox" -> JsString(bbname.get)) + + JsObject(output) + } + + override def typeStr = "iomacro" +} +object IOMacro { + def parseJSON(json: Map[String, JsValue]): Option[IOMacro] = { + val name: String = json.get("name") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + val tpe: PortType = json.get("type") match { + case Some(JsString("power")) => Power + case Some(JsString("ground")) => Ground + case Some(JsString("digital")) => Digital + case Some(JsString("analog")) => Analog + case Some(JsString("NC")) => NoConnect + case _ => return None + } + val direction: Option[Direction] = json.get("direction") match { + case Some(JsString("input")) => Some(Input) + case Some(JsString("output")) => Some(Output) + case Some(JsString("inout")) => Some(InOut) + case _ => None + } + val termination: Option[Termination] = json.get("termination") match { + case Some(JsNumber(x)) => Some(Resistive(x.toInt)) + case Some(JsString("CMOS")) => Some(CMOS) + case _ => None + } + val terminationType: Option[TerminationType] = json.get("terminationType") match { + case Some(JsString("differential")) => Some(Differential) + case Some(JsString("single")) => Some(Single) + case _ => None + } + val terminationRef: Option[String] = json.get("terminationReference") match { + case Some(JsString(x)) => Some(x) + case _ if terminationType.isDefined => return None + case _ => None + } + val matching: Seq[String] = json.get("match") match { + case Some(JsArray(array)) => array.map(_.as[JsString].value).toList + case _ => Seq.empty[String] + } + val bbname: Option[String] = json.get("blackBox") match { + case Some(JsString(module)) => Some(module) + case Some(_) => return None + case _ => None + } + Some(IOMacro(name, tpe, direction, termination, terminationType, terminationRef, matching, bbname)) + } +} + +case class IOProperties(name: String, top: String, ios: Seq[IOMacro]) extends Macro { + override def toJSON(): JsObject = { + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "name" -> Json.toJson(name), + "top" -> Json.toJson(top), + "type" -> Json.toJson(typeStr), + "ios" -> JsArray(ios.map(_.toJSON)) + ) + ) + JsObject(output) + } + + override def typeStr = "io_properties" + +} + +object IOProperties { + def parseJSON(json: Map[String, JsValue]): Option[IOProperties] = { + val name: String = json.get("name") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + val top: String = json.get("top") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + val ios: Seq[IOMacro] = json.get("ios") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + val b = IOMacro.parseJSON(a); + if (b == None) { + return None + } else b.get + } + case _ => List() + } + Some(IOProperties(name, top, ios)) + } +} diff --git a/tapeout/src/main/scala/mdf/macrolib/MacroLib.scala b/tapeout/src/main/scala/mdf/macrolib/MacroLib.scala new file mode 100644 index 00000000..569c4dac --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/MacroLib.scala @@ -0,0 +1,19 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.collection.mutable.ListBuffer +import scala.language.implicitConversions + +// TODO: decide if we should always silently absorb errors + +// See macro_format.yml for the format description. + +// "Base class" for macros +abstract class Macro { + def name: String + + // Type of macro is determined by subclass + def typeStr: String + + def toJSON(): JsObject +} diff --git a/tapeout/src/main/scala/mdf/macrolib/SRAM.scala b/tapeout/src/main/scala/mdf/macrolib/SRAM.scala new file mode 100644 index 00000000..ea51b049 --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/SRAM.scala @@ -0,0 +1,444 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.collection.mutable.ListBuffer +import scala.language.implicitConversions + +// SRAM macro +case class SRAMMacro( + name: String, + width: Int, + depth: BigInt, + family: String, + ports: Seq[MacroPort], + vt: String = "", + mux: Int = 1, + extraPorts: Seq[MacroExtraPort] = List()) + extends Macro { + override def toJSON(): JsObject = { + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "type" -> JsString("sram"), + "name" -> Json.toJson(name), + "width" -> Json.toJson(width), + "depth" -> Json.toJson(depth.toString), + "mux" -> Json.toJson(mux), + "mask" -> Json.toJson(ports.exists(p => p.maskPort.isDefined)), + "ports" -> JsArray(ports.map { _.toJSON }) + ) + ) + if (family != "") { + output.appendAll(Seq("family" -> Json.toJson(family))) + } + if (vt != "") { + output.appendAll(Seq("vt" -> Json.toJson(vt))) + } + if (extraPorts.length > 0) { + output.appendAll(Seq("extra ports" -> JsArray(extraPorts.map { _.toJSON }))) + } + + JsObject(output) + } + + override def typeStr = "sram" +} +object SRAMMacro { + def parseJSON(json: Map[String, JsValue]): Option[SRAMMacro] = { + val name: String = json.get("name") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + val width: Int = json.get("width") match { + case Some(x: JsNumber) => x.value.intValue + case _ => return None + } + val depth: BigInt = json.get("depth") match { + case Some(x: JsString) => + try { BigInt(x.as[String]) } + catch { case _: Throwable => return None } + case _ => return None + } + val family: String = json.get("family") match { + case Some(x: JsString) => x.as[String] + case _ => "" // optional + } + val vt: String = json.get("vt") match { + case Some(x: JsString) => x.as[String] + case _ => "" // optional + } + val mux: Int = json.get("mux") match { + case Some(x: JsNumber) => x.value.intValue + case _ => 1 // default + } + val ports: Seq[MacroPort] = json.get("ports") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + val b = MacroPort.parseJSON(a, width, depth); + if (b == None) { + return None + } else b.get + } + case _ => List() + } + if (ports.length == 0) { + // Can't have portless memories. + return None + } + val extraPorts: Seq[MacroExtraPort] = json.get("extra ports") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + val b = MacroExtraPort.parseJSON(a); + if (b == None) { + return None + } else b.get + } + case _ => List() + } + Some(SRAMMacro(name, width, depth, family, ports, vt, mux, extraPorts)) + } +} + +// SRAM compiler +case class SRAMGroup( + name: Seq[String], + family: String, + vt: Seq[String], + mux: Int, + depth: Range, + width: Range, + ports: Seq[MacroPort], + extraPorts: Seq[MacroExtraPort] = List()) { + def toJSON: JsObject = { + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "name" -> JsArray(name.map(Json.toJson(_))), + "vt" -> JsArray(vt.map(Json.toJson(_))), + "mux" -> Json.toJson(mux), + "depth" -> JsArray(Seq(depth.start, depth.end, depth.step).map { x => Json.toJson(x) }), + "width" -> JsArray(Seq(width.start, width.end, width.step).map { x => Json.toJson(x) }), + "ports" -> JsArray(ports.map { _.toJSON }) + ) + ) + if (family != "") { + output.appendAll(Seq("family" -> Json.toJson(family))) + } + if (extraPorts.length > 0) { + output.appendAll(Seq("extra ports" -> JsArray(extraPorts.map { _.toJSON }))) + } + JsObject(output) + } +} +object SRAMGroup { + def parseJSON(json: Map[String, JsValue]): Option[SRAMGroup] = { + val family: String = json.get("family") match { + case Some(x: JsString) => x.as[String] + case _ => "" // optional + } + val name: Seq[String] = json.get("name") match { + case Some(x: JsArray) => x.as[List[JsString]].map(_.as[String]) + case _ => return None + } + val vt: Seq[String] = json.get("vt") match { + case Some(x: JsArray) => x.as[List[JsString]].map(_.as[String]) + case _ => return None + } + val mux: Int = json.get("mux") match { + case Some(x: JsNumber) => x.value.intValue + case _ => return None + } + val depth: Range = json.get("depth") match { + case Some(x: JsArray) => + val seq = x.as[List[JsNumber]].map(_.value.intValue) + Range.inclusive(seq(0), seq(1), seq(2)) + case _ => return None + } + val width: Range = json.get("width") match { + case Some(x: JsArray) => + val seq = x.as[List[JsNumber]].map(_.value.intValue) + Range.inclusive(seq(0), seq(1), seq(2)) + case _ => return None + } + val ports: Seq[MacroPort] = json.get("ports") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + { + val b = MacroPort.parseJSON(a, None, None); + if (b == None) { + return None + } else b.get + } + } + case _ => List() + } + if (ports.length == 0) { + // Can't have portless memories. + return None + } + val extraPorts: Seq[MacroExtraPort] = json.get("extra ports") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + { + val b = MacroExtraPort.parseJSON(a); + if (b == None) { + return None + } else b.get + } + } + case _ => List() + } + Some(SRAMGroup(name, family, vt, mux, depth, width, ports, extraPorts)) + } +} + +case class SRAMCompiler( + name: String, + groups: Seq[SRAMGroup]) + extends Macro { + override def toJSON(): JsObject = { + val output = new ListBuffer[(String, JsValue)]() + output.appendAll( + Seq( + "type" -> Json.toJson("sramcompiler"), + "name" -> Json.toJson(name), + "groups" -> JsArray(groups.map { _.toJSON }) + ) + ) + + JsObject(output) + } + + override def typeStr = "sramcompiler" +} +object SRAMCompiler { + def parseJSON(json: Map[String, JsValue]): Option[SRAMCompiler] = { + val name: String = json.get("name") match { + case Some(x: JsString) => x.as[String] + case _ => return None + } + val groups: Seq[SRAMGroup] = json.get("groups") match { + case Some(x: JsArray) => + x.as[List[Map[String, JsValue]]].map { a => + { + val b = SRAMGroup.parseJSON(a); + if (b == None) { return None } + else b.get + } + } + case _ => List() + } + if (groups.length == 0) { + // Can't have portless memories. + return None + } + Some(SRAMCompiler(name, groups)) + } +} + +// Type of extra port +sealed abstract class MacroExtraPortType +case object Constant extends MacroExtraPortType +object MacroExtraPortType { + implicit def toMacroExtraPortType(s: Any): Option[MacroExtraPortType] = { + s match { + case "constant" => Some(Constant) + case _ => None + } + } + + implicit def toString(t: MacroExtraPortType): String = { + t match { + case Constant => "constant" + case _ => "" + } + } +} + +// Extra port in SRAM +case class MacroExtraPort( + name: String, + width: Int, + portType: MacroExtraPortType, + value: BigInt) { + def toJSON(): JsObject = { + JsObject( + Seq( + "name" -> Json.toJson(name), + "width" -> Json.toJson(width), + "type" -> JsString(MacroExtraPortType.toString(portType)), + "value" -> JsNumber(BigDecimal(value)) + ) + ) + } +} +object MacroExtraPort { + def parseJSON(json: Map[String, JsValue]): Option[MacroExtraPort] = { + val name = json.get("name") match { + case Some(x: JsString) => x.value + case _ => return None + } + val width = json.get("width") match { + case Some(x: JsNumber) => x.value.intValue + case _ => return None + } + val portType: MacroExtraPortType = json.get("type") match { + case Some(x: JsString) => + MacroExtraPortType.toMacroExtraPortType(x.value) match { + case Some(t: MacroExtraPortType) => t + case _ => return None + } + case _ => return None + } + val value = json.get("value") match { + case Some(x: JsNumber) => x.value.toBigInt + case _ => return None + } + Some(MacroExtraPort(name, width, portType, value)) + } +} + +// A named port that also has polarity. +case class PolarizedPort(name: String, polarity: PortPolarity) { + def toSeqMap(prefix: String): Seq[Tuple2[String, JsValue]] = { + Seq( + prefix + " port name" -> Json.toJson(name), + prefix + " port polarity" -> JsString(polarity) + ) + } +} +object PolarizedPort { + // Parse a pair of " port name" and " port polarity" keys into a + // polarized port definition. + def parseJSON(json: Map[String, JsValue], prefix: String): Option[PolarizedPort] = { + val name = json.get(prefix + " port name") match { + case Some(x: JsString) => Some(x.value) + case _ => None + } + val polarity: Option[PortPolarity] = json.get(prefix + " port polarity") match { + case Some(x: JsString) => Some(x.value) + case _ => None + } + + (name, polarity) match { + case (Some(n: String), Some(p: PortPolarity)) => Some(PolarizedPort(n, p)) + case _ => None + } + } +} + +// A SRAM memory port +case class MacroPort( + address: PolarizedPort, + clock: Option[PolarizedPort] = None, + writeEnable: Option[PolarizedPort] = None, + readEnable: Option[PolarizedPort] = None, + chipEnable: Option[PolarizedPort] = None, + output: Option[PolarizedPort] = None, + input: Option[PolarizedPort] = None, + maskPort: Option[PolarizedPort] = None, + maskGran: Option[Int] = None, + // For internal use only; these aren't port-specific. + width: Option[Int], + depth: Option[BigInt]) { + def effectiveMaskGran = maskGran.getOrElse(width.get) + + def toJSON(): JsObject = { + val keys: Seq[Tuple2[String, Option[Any]]] = Seq( + "address" -> Some(address), + "clock" -> clock, + "write enable" -> writeEnable, + "read enable" -> readEnable, + "chip enable" -> chipEnable, + "output" -> output, + "input" -> input, + "mask" -> maskPort, + "mask granularity" -> maskGran + ) + JsObject(keys.flatMap(k => { + val (key, value) = k + value match { + case Some(x: Int) => Seq(key -> JsNumber(x)) + case Some(x: PolarizedPort) => x.toSeqMap(key) + case _ => List() + } + })) + } + + // Check that all port names are unique. + private val polarizedPorts = + List(Some(address), clock, writeEnable, readEnable, chipEnable, output, input, maskPort).flatten + assert(polarizedPorts.distinct.size == polarizedPorts.size, "All port names must be unique") +} +object MacroPort { + def parseJSON(json: Map[String, JsValue]): Option[MacroPort] = parseJSON(json, None, None) + def parseJSON(json: Map[String, JsValue], width: Int, depth: BigInt): Option[MacroPort] = + parseJSON(json, Some(width), Some(depth)) + def parseJSON(json: Map[String, JsValue], width: Option[Int], depth: Option[BigInt]): Option[MacroPort] = { + val address = PolarizedPort.parseJSON(json, "address") + if (address == None) { + return None + } + + val clock = PolarizedPort.parseJSON(json, "clock") + // TODO: validate based on family (e.g. 1rw must have a write enable, etc) + val writeEnable = PolarizedPort.parseJSON(json, "write enable") + val readEnable = PolarizedPort.parseJSON(json, "read enable") + val chipEnable = PolarizedPort.parseJSON(json, "chip enable") + + val output = PolarizedPort.parseJSON(json, "output") + val input = PolarizedPort.parseJSON(json, "input") + + val maskPort = PolarizedPort.parseJSON(json, "mask") + val maskGran: Option[Int] = json.get("mask granularity") match { + case Some(x: JsNumber) => Some(x.value.intValue) + case _ => None + } + + if (maskPort.isDefined != maskGran.isDefined) { + return None + } + + Some( + MacroPort( + width = width, + depth = depth, + address = address.get, + clock = clock, + writeEnable = writeEnable, + readEnable = readEnable, + chipEnable = chipEnable, + output = output, + input = input, + maskPort = maskPort, + maskGran = maskGran + ) + ) + } +} + +// Port polarity +trait PortPolarity +case object ActiveLow extends PortPolarity +case object ActiveHigh extends PortPolarity +case object NegativeEdge extends PortPolarity +case object PositiveEdge extends PortPolarity +object PortPolarity { + implicit def toPortPolarity(s: String): PortPolarity = (s: @unchecked) match { + case "active low" => ActiveLow + case "active high" => ActiveHigh + case "negative edge" => NegativeEdge + case "positive edge" => PositiveEdge + } + implicit def toPortPolarity(s: Option[String]): Option[PortPolarity] = + s.map(toPortPolarity) + + implicit def toString(p: PortPolarity): String = { + p match { + case ActiveLow => "active low" + case ActiveHigh => "active high" + case NegativeEdge => "negative edge" + case PositiveEdge => "positive edge" + } + } +} diff --git a/tapeout/src/main/scala/mdf/macrolib/Utils.scala b/tapeout/src/main/scala/mdf/macrolib/Utils.scala new file mode 100644 index 00000000..795cff0a --- /dev/null +++ b/tapeout/src/main/scala/mdf/macrolib/Utils.scala @@ -0,0 +1,87 @@ +package mdf.macrolib + +import play.api.libs.json._ +import scala.collection.mutable.ListBuffer +import scala.language.implicitConversions + +object Utils { + // Read a MDF file from a String. + def readMDFFromString(str: String): Option[Seq[Macro]] = { + Json.parse(str) match { + // Make sure that the document is a list. + case arr: JsArray => { + val result: List[Option[Macro]] = arr.as[List[Map[String, JsValue]]].map { obj => + // Check the type of object. + val objTypeStr: String = obj.get("type") match { + case Some(x: JsString) => x.as[String] + case _ => return None // error, no type found + } + objTypeStr match { + case "filler cell" | "metal filler cell" => FillerMacroBase.parseJSON(obj) + case "sram" => SRAMMacro.parseJSON(obj) + case "sramcompiler" => SRAMCompiler.parseJSON(obj) + case "io_properties" => IOProperties.parseJSON(obj) + case "flipchip" => FlipChipMacro.parseJSON(obj) + case _ => None // skip unknown macro types + } + } + // Remove all the Nones and convert back to Seq[Macro] + Some(result.filter { x => x != None }.map { x => x.get }) + } + case _ => None + } + } + + // Read a MDF file from a path. + def readMDFFromPath(path: Option[String]): Option[Seq[Macro]] = { + path match { + case None => None + // Read file into string and parse + case Some(p) => Utils.readMDFFromString(scala.io.Source.fromFile(p).mkString) + } + } + + // Write a MDF file to a String. + def writeMDFToString(s: Seq[Macro]): String = { + Json.prettyPrint(JsArray(s.map(_.toJSON))) + } + + // Write a MDF file from a path. + // Returns true upon success. + def writeMDFToPath(path: Option[String], s: Seq[Macro]): Boolean = { + path match { + case None => false + // Read file into string and parse + case Some(p: String) => { + import java.io._ + val pw = new PrintWriter(new File(p)) + pw.write(writeMDFToString(s)) + val error = pw.checkError + pw.close() + !error + } + } + } + + // Write a macro file to a String. + def writeMacroToString(s: Macro): String = { + Json.prettyPrint(s.toJSON) + } + + // Write a Macro file from a path. + // Returns true upon success. + def writeMacroToPath(path: Option[String], s: Macro): Boolean = { + path match { + case None => false + // Read file into string and parse + case Some(p: String) => { + import java.io._ + val pw = new PrintWriter(new File(p)) + pw.write(writeMacroToString(s)) + val error = pw.checkError + pw.close() + !error + } + } + } +} diff --git a/macros/src/test/resources/lib-BOOMTest.json b/tapeout/src/test/resources/lib-BOOMTest.json similarity index 100% rename from macros/src/test/resources/lib-BOOMTest.json rename to tapeout/src/test/resources/lib-BOOMTest.json diff --git a/macros/src/test/resources/lib-MaskPortTest.json b/tapeout/src/test/resources/lib-MaskPortTest.json similarity index 100% rename from macros/src/test/resources/lib-MaskPortTest.json rename to tapeout/src/test/resources/lib-MaskPortTest.json diff --git a/macros/src/test/resources/lib-WriteEnableTest.json b/tapeout/src/test/resources/lib-WriteEnableTest.json similarity index 100% rename from macros/src/test/resources/lib-WriteEnableTest.json rename to tapeout/src/test/resources/lib-WriteEnableTest.json diff --git a/macros/src/test/scala/barstools/macros/CostFunction.scala b/tapeout/src/test/scala/barstools/macros/CostFunction.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/CostFunction.scala rename to tapeout/src/test/scala/barstools/macros/CostFunction.scala diff --git a/macros/src/test/scala/barstools/macros/Functional.scala b/tapeout/src/test/scala/barstools/macros/Functional.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/Functional.scala rename to tapeout/src/test/scala/barstools/macros/Functional.scala diff --git a/macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala b/tapeout/src/test/scala/barstools/macros/MacroCompilerSpec.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/MacroCompilerSpec.scala rename to tapeout/src/test/scala/barstools/macros/MacroCompilerSpec.scala diff --git a/macros/src/test/scala/barstools/macros/Masks.scala b/tapeout/src/test/scala/barstools/macros/Masks.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/Masks.scala rename to tapeout/src/test/scala/barstools/macros/Masks.scala diff --git a/macros/src/test/scala/barstools/macros/MultiPort.scala b/tapeout/src/test/scala/barstools/macros/MultiPort.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/MultiPort.scala rename to tapeout/src/test/scala/barstools/macros/MultiPort.scala diff --git a/macros/src/test/scala/barstools/macros/SRAMCompiler.scala b/tapeout/src/test/scala/barstools/macros/SRAMCompiler.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/SRAMCompiler.scala rename to tapeout/src/test/scala/barstools/macros/SRAMCompiler.scala diff --git a/macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala b/tapeout/src/test/scala/barstools/macros/SimpleSplitDepth.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/SimpleSplitDepth.scala rename to tapeout/src/test/scala/barstools/macros/SimpleSplitDepth.scala diff --git a/macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala b/tapeout/src/test/scala/barstools/macros/SimpleSplitWidth.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/SimpleSplitWidth.scala rename to tapeout/src/test/scala/barstools/macros/SimpleSplitWidth.scala diff --git a/macros/src/test/scala/barstools/macros/SpecificExamples.scala b/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala similarity index 99% rename from macros/src/test/scala/barstools/macros/SpecificExamples.scala rename to tapeout/src/test/scala/barstools/macros/SpecificExamples.scala index 334e3a73..6ee7255a 100644 --- a/macros/src/test/scala/barstools/macros/SpecificExamples.scala +++ b/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala @@ -27,7 +27,7 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-WriteEnableTest.json" // lib. of mems to create it val v = s"WriteEnableTest.json" - override val libPrefix = "macros/src/test/resources" + override val libPrefix = "tapeout/src/test/resources" val memSRAMs = mdf.macrolib.Utils .readMDFFromString(""" @@ -97,7 +97,7 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-MaskPortTest.json" // lib. of mems to create it val v = s"MaskPortTest.json" - override val libPrefix = "macros/src/test/resources" + override val libPrefix = "tapeout/src/test/resources" val memSRAMs = mdf.macrolib.Utils .readMDFFromString(""" @@ -181,7 +181,7 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-BOOMTest.json" val v = s"BOOMTest.v" - override val libPrefix = "macros/src/test/resources" + override val libPrefix = "tapeout/src/test/resources" val memSRAMs = mdf.macrolib.Utils .readMDFFromString(""" diff --git a/macros/src/test/scala/barstools/macros/SynFlops.scala b/tapeout/src/test/scala/barstools/macros/SynFlops.scala similarity index 100% rename from macros/src/test/scala/barstools/macros/SynFlops.scala rename to tapeout/src/test/scala/barstools/macros/SynFlops.scala diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala index cefd9759..ec4822fe 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala @@ -62,7 +62,7 @@ class GenerateSpec extends AnyFreeSpec { FileUtils.makeDirectory(targetDir) val printWriter = new PrintWriter(new File(s"$targetDir/GenerateExampleTester.fir")) - printWriter.write((new ChiselStage()).emitFirrtl(new GenerateExampleTester)) + printWriter.write((new ChiselStage()).emitFirrtl(new GenerateExampleTester, Array("--target-dir", targetDir))) printWriter.close() val blackBoxInverterText = """ diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala index 701c7845..d18053f0 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala @@ -22,7 +22,7 @@ class ExampleModuleNeedsResetInverted extends Module with ResetInverter { class ResetNSpec extends AnyFreeSpec with Matchers { "Inverting reset needs to be done throughout module in Chirrtl" in { - val chirrtl = (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted) + val chirrtl = (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted, Array("--target-dir", "test_run_dir/reset_n_spec")) chirrtl should include("input reset :") (chirrtl should not).include("input reset_n :") (chirrtl should not).include("node reset = not(reset_n)") @@ -32,7 +32,7 @@ class ResetNSpec extends AnyFreeSpec with Matchers { // generate low-firrtl val firrtl = (new ChiselStage) .execute( - Array("-X", "low"), + Array("-X", "low", "--target-dir", "test_run_dir/reset_inverting_spec"), Seq(ChiselGeneratorAnnotation(() => new ExampleModuleNeedsResetInverted)) ) .collect { diff --git a/tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala b/tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala new file mode 100644 index 00000000..58680cd7 --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala @@ -0,0 +1,101 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class ConfReaderSpec extends AnyFlatSpec with Matchers { + + /** Generate a read port in accordance with RenameAnnotatedMemoryPorts. */ + def generateReadPort(num: Int, width: Int, depth: Int): MacroPort = { + MacroPort( + address = PolarizedPort(s"R${num}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"R${num}_clk", PositiveEdge)), + output = Some(PolarizedPort(s"R${num}_data", ActiveHigh)), + width = Some(width), + depth = Some(depth) + ) + } + + /** Generate a write port in accordance with RenameAnnotatedMemoryPorts. */ + def generateWritePort(num: Int, width: Int, depth: Int, maskGran: Option[Int] = None): MacroPort = { + MacroPort( + address = PolarizedPort(s"W${num}_addr", ActiveHigh), + clock = Some(PolarizedPort(s"W${num}_clk", PositiveEdge)), + input = Some(PolarizedPort(s"W${num}_data", ActiveHigh)), + maskPort = if (maskGran.isDefined) Some(PolarizedPort(s"W${num}_mask", ActiveHigh)) else None, + maskGran = maskGran, + width = Some(184), + depth = Some(128) + ) + } + + "ConfReader" should "read a 1rw conf line" in { + val confStr = "name Foo_Bar_mem123_ext depth 128 width 184 ports mrw mask_gran 23" + ConfReader.readSingleLine(confStr) shouldBe SRAMMacro( + name = "Foo_Bar_mem123_ext", + width = 184, + depth = 128, + family = "1rw", + ports = List( + MacroPort( + address = PolarizedPort("RW0_addr", ActiveHigh), + clock = Some(PolarizedPort("RW0_clk", PositiveEdge)), + writeEnable = Some(PolarizedPort("RW0_wmode", ActiveHigh)), + output = Some(PolarizedPort("RW0_wdata", ActiveHigh)), + input = Some(PolarizedPort("RW0_rdata", ActiveHigh)), + maskPort = Some(PolarizedPort("RW0_wmask", ActiveHigh)), + maskGran = Some(23), + width = Some(184), + depth = Some(128) + ) + ), + extraPorts = List() + ) + } + + "ConfReader" should "read a 1r1w conf line" in { + val confStr = "name Foo_Bar_mem321_ext depth 128 width 184 ports read,mwrite mask_gran 23" + ConfReader.readSingleLine(confStr) shouldBe SRAMMacro( + name = "Foo_Bar_mem321_ext", + width = 184, + depth = 128, + family = "1r1w", + ports = List( + generateReadPort(0, 184, 128), + generateWritePort(0, 184, 128, Some(23)) + ), + extraPorts = List() + ) + } + + "ConfReader" should "read a mixed 1r2w conf line" in { + val confStr = "name Foo_Bar_mem321_ext depth 128 width 184 ports read,mwrite,write mask_gran 23" + ConfReader.readSingleLine(confStr) shouldBe SRAMMacro( + name = "Foo_Bar_mem321_ext", + width = 184, + depth = 128, + family = "1r2w", + ports = List( + generateReadPort(0, 184, 128), + generateWritePort(0, 184, 128, Some(23)), + generateWritePort(1, 184, 128) + ), + extraPorts = List() + ) + } + + "ConfReader" should "read a 42r29w conf line" in { + val confStr = + "name Foo_Bar_mem321_ext depth 128 width 184 ports " + (Seq.fill(42)("read") ++ Seq.fill(29)("mwrite")) + .mkString(",") + " mask_gran 23" + ConfReader.readSingleLine(confStr) shouldBe SRAMMacro( + name = "Foo_Bar_mem321_ext", + width = 184, + depth = 128, + family = "42r29w", + ports = ((0 to 41).map((num: Int) => generateReadPort(num, 184, 128))) ++ + ((0 to 28).map((num: Int) => generateWritePort(num, 184, 128, Some(23)))), + extraPorts = List() + ) + } +} diff --git a/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala b/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala new file mode 100644 index 00000000..ba51e4d1 --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala @@ -0,0 +1,14 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class FlipChipMacroSpec extends AnyFlatSpec with Matchers { + "Parsing flipchipmacros" should "work" in { + val stream = getClass.getResourceAsStream("/bumps.json") + val mdf = Utils.readMDFFromString(scala.io.Source.fromInputStream(stream).getLines().mkString("\n")) + mdf match { + case Some(Seq(fcp: FlipChipMacro)) => println(fcp.visualize) + } + } +} diff --git a/tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala b/tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala new file mode 100644 index 00000000..c6ab6e10 --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala @@ -0,0 +1,67 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class IOMacroSpec extends AnyFlatSpec with Matchers { + "Ground IOs" should "be detected" in { + val json = + """{ + | "name" : "GND", + | "type" : "ground" + |}""".stripMargin + val m = JSONUtils.readStringValueMap(json).get + IOMacro.parseJSON(m) shouldBe Some(IOMacro("GND", Ground)) + } + "Power IOs" should "be detected" in { + val json = + """{ + | "name" : "VDD0V8", + | "type" : "power" + |}""".stripMargin + val m = JSONUtils.readStringValueMap(json).get + IOMacro.parseJSON(m) shouldBe Some(IOMacro("VDD0V8", Power)) + } + "Digital IOs" should "be detected" in { + val json = + """{ + | "name" : "VDDC0_SEL[1:0]", + | "type" : "digital", + | "direction" : "output", + | "termination" : "CMOS" + |}""".stripMargin + val m = JSONUtils.readStringValueMap(json).get + IOMacro.parseJSON(m) shouldBe Some(IOMacro("VDDC0_SEL[1:0]", Digital, Some(Output), Some(CMOS))) + } + "Digital IOs with termination" should "be detected" in { + val json = + """{ + | "name" : "CCLK1", + | "type" : "digital", + | "direction" : "input", + | "termination" : 50, + | "terminationType" : "single", + | "terminationReference" : "GND" + |}""".stripMargin + val m = JSONUtils.readStringValueMap(json).get + IOMacro.parseJSON(m) shouldBe Some( + IOMacro("CCLK1", Digital, Some(Input), Some(Resistive(50)), Some(Single), Some("GND")) + ) + } + "Digital IOs with matching and termination" should "be detected" in { + val json = + """{ + | "name" : "REFCLK0P", + | "type" : "analog", + | "direction" : "input", + | "match" : ["REFCLK0N"], + | "termination" : 100, + | "terminationType" : "differential", + | "terminationReference" : "GND" + |}""".stripMargin + val m = JSONUtils.readStringValueMap(json).get + IOMacro.parseJSON(m) shouldBe Some( + IOMacro("REFCLK0P", Analog, Some(Input), Some(Resistive(100)), Some(Differential), Some("GND"), List("REFCLK0N")) + ) + } +} diff --git a/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala b/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala new file mode 100644 index 00000000..ffd13be5 --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala @@ -0,0 +1,14 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class IOPropertiesSpec extends AnyFlatSpec with Matchers { + "Parsing io_properties" should "work" in { + val stream = getClass.getResourceAsStream("/io_properties.json") + val mdf = Utils.readMDFFromString(scala.io.Source.fromInputStream(stream).getLines().mkString("\n")) + mdf match { + case Some(Seq(fcp: IOProperties)) => + } + } +} diff --git a/tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala b/tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala new file mode 100644 index 00000000..85feaffa --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala @@ -0,0 +1,270 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import play.api.libs.json._ + +import java.io.File + +// Output tests (Scala -> JSON). +// TODO: unify these tests with the input tests? + +trait HasAwesomeMemData { + def getAwesomeMem() = { + SRAMMacro( + name = "awesome_mem", + width = 32, + depth = 1024, + family = "1rw", + ports = Seq( + MacroPort( + address = PolarizedPort(name = "addr", polarity = ActiveHigh), + clock = Some(PolarizedPort(name = "clk", polarity = PositiveEdge)), + writeEnable = Some(PolarizedPort(name = "write_enable", polarity = ActiveHigh)), + readEnable = Some(PolarizedPort(name = "read_enable", polarity = ActiveHigh)), + chipEnable = Some(PolarizedPort(name = "chip_enable", polarity = ActiveHigh)), + output = Some(PolarizedPort(name = "data_out", polarity = ActiveHigh)), + input = Some(PolarizedPort(name = "data_in", polarity = ActiveHigh)), + maskPort = Some(PolarizedPort(name = "mask", polarity = ActiveHigh)), + maskGran = Some(8), + width = Some(32), + depth = Some(1024) // These numbers don't matter. + ) + ), + extraPorts = List() + ) + } + + def getAwesomeMemJSON(): String = { + """ + | { + | "type": "sram", + | "name": "awesome_mem", + | "width": 32, + | "depth": "1024", + | "mux": 1, + | "mask":true, + | "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": "write_enable", + | "write enable port polarity": "active high", + | "read enable port name": "read_enable", + | "read enable port polarity": "active high", + | "chip enable port name": "chip_enable", + | "chip enable port polarity": "active high", + | "output port name": "data_out", + | "output port polarity": "active high", + | "input port name": "data_in", + | "input port polarity": "active high", + | "mask port name": "mask", + | "mask port polarity": "active high", + | "mask granularity": 8 + | } + | ] + | } + |""".stripMargin + } +} + +// Tests for filler macros. +class FillerMacroOutput extends AnyFlatSpec with Matchers { + "Valid lvt macro" should "be generated" in { + val expected = """ + | { + | "type": "filler cell", + | "name": "MY_FILLER_CELL", + | "vt": "lvt" + | } + |""".stripMargin + FillerMacro("MY_FILLER_CELL", "lvt").toJSON shouldBe Json.parse(expected) + } + + "Valid metal macro" should "be generated" in { + val expected = """ + | { + | "type": "metal filler cell", + | "name": "METAL_FILLER_CELL", + | "vt": "lvt" + | } + |""".stripMargin + MetalFillerMacro("METAL_FILLER_CELL", "lvt").toJSON shouldBe Json.parse(expected) + } + + "Valid hvt macro" should "be generated" in { + val expected = """ + | { + | "type": "filler cell", + | "name": "HVT_CELL_PROP", + | "vt": "hvt" + | } + |""".stripMargin + FillerMacro("HVT_CELL_PROP", "hvt").toJSON shouldBe Json.parse(expected) + } +} + +class SRAMPortOutput extends AnyFlatSpec with Matchers { + "Extra port" should "be generated" in { + val m = MacroExtraPort( + name = "TIE_HIGH", + width = 8, + portType = Constant, + value = ((1 << 8) - 1) + ) + val expected = """ + | { + | "type": "constant", + | "name": "TIE_HIGH", + | "width": 8, + | "value": 255 + | } + |""".stripMargin + m.toJSON shouldBe Json.parse(expected) + } + + "Minimal write port" should "be generated" in { + val m = MacroPort( + address = PolarizedPort(name = "addr", polarity = ActiveHigh), + clock = Some(PolarizedPort(name = "clk", polarity = PositiveEdge)), + writeEnable = Some(PolarizedPort(name = "write_enable", polarity = ActiveHigh)), + input = Some(PolarizedPort(name = "data_in", polarity = ActiveHigh)), + width = Some(32), + depth = Some(1024) // These numbers don't matter. + ) + val expected = """ + | { + | "address port name": "addr", + | "address port polarity": "active high", + | "clock port name": "clk", + | "clock port polarity": "positive edge", + | "write enable port name": "write_enable", + | "write enable port polarity": "active high", + | "input port name": "data_in", + | "input port polarity": "active high" + | } + |""".stripMargin + m.toJSON shouldBe Json.parse(expected) + } + + "Minimal read port" should "be generated" in { + val m = MacroPort( + address = PolarizedPort(name = "addr", polarity = ActiveHigh), + clock = Some(PolarizedPort(name = "clk", polarity = PositiveEdge)), + output = Some(PolarizedPort(name = "data_out", polarity = ActiveHigh)), + width = Some(32), + depth = Some(1024) // These numbers don't matter. + ) + val expected = """ + | { + | "address port name": "addr", + | "address port polarity": "active high", + | "clock port name": "clk", + | "clock port polarity": "positive edge", + | "output port name": "data_out", + | "output port polarity": "active high" + | } + |""".stripMargin + m.toJSON shouldBe Json.parse(expected) + } + + "Masked read port" should "be generated" in { + val m = MacroPort( + address = PolarizedPort(name = "addr", polarity = ActiveHigh), + clock = Some(PolarizedPort(name = "clk", polarity = PositiveEdge)), + output = Some(PolarizedPort(name = "data_out", polarity = ActiveHigh)), + maskPort = Some(PolarizedPort(name = "mask", polarity = ActiveHigh)), + maskGran = Some(8), + width = Some(32), + depth = Some(1024) // These numbers don't matter. + ) + val expected = """ + | { + | "address port name": "addr", + | "address port polarity": "active high", + | "clock port name": "clk", + | "clock port polarity": "positive edge", + | "output port name": "data_out", + | "output port polarity": "active high", + | "mask port name": "mask", + | "mask port polarity": "active high", + | "mask granularity": 8 + | } + |""".stripMargin + m.toJSON shouldBe Json.parse(expected) + } + + "Everything port" should "be generated" in { + val m = MacroPort( + address = PolarizedPort(name = "addr", polarity = ActiveHigh), + clock = Some(PolarizedPort(name = "clk", polarity = PositiveEdge)), + writeEnable = Some(PolarizedPort(name = "write_enable", polarity = ActiveHigh)), + readEnable = Some(PolarizedPort(name = "read_enable", polarity = ActiveHigh)), + chipEnable = Some(PolarizedPort(name = "chip_enable", polarity = ActiveHigh)), + output = Some(PolarizedPort(name = "data_out", polarity = ActiveHigh)), + input = Some(PolarizedPort(name = "data_in", polarity = ActiveHigh)), + maskPort = Some(PolarizedPort(name = "mask", polarity = ActiveHigh)), + maskGran = Some(8), + width = Some(32), + depth = Some(1024) // These numbers don't matter. + ) + val expected = """ + | { + | "address port name": "addr", + | "address port polarity": "active high", + | "clock port name": "clk", + | "clock port polarity": "positive edge", + | "write enable port name": "write_enable", + | "write enable port polarity": "active high", + | "read enable port name": "read_enable", + | "read enable port polarity": "active high", + | "chip enable port name": "chip_enable", + | "chip enable port polarity": "active high", + | "output port name": "data_out", + | "output port polarity": "active high", + | "input port name": "data_in", + | "input port polarity": "active high", + | "mask port name": "mask", + | "mask port polarity": "active high", + | "mask granularity": 8 + | } + |""".stripMargin + m.toJSON shouldBe Json.parse(expected) + } +} + +class SRAMMacroOutput extends AnyFlatSpec with Matchers with HasAwesomeMemData { + "SRAM macro" should "be generated" in { + val m = getAwesomeMem + val expected = getAwesomeMemJSON + m.toJSON shouldBe Json.parse(expected) + } +} + +class InputOutput extends AnyFlatSpec with Matchers with HasAwesomeMemData { + "Read-write string" should "preserve data" in { + val mdf = List( + FillerMacro("MY_FILLER_CELL", "lvt"), + MetalFillerMacro("METAL_GEAR_FILLER", "hvt"), + getAwesomeMem + ) + Utils.readMDFFromString(Utils.writeMDFToString(mdf)) shouldBe Some(mdf) + } + + val testDir: String = "test_run_dir" + new File(testDir).mkdirs // Make sure the testDir exists + + "Read-write file" should "preserve data" in { + val mdf = List( + FillerMacro("MY_FILLER_CELL", "lvt"), + MetalFillerMacro("METAL_GEAR_FILLER", "hvt"), + getAwesomeMem + ) + val filename = testDir + "/" + "mdf_read_write_test.json" + Utils.writeMDFToPath(Some(filename), mdf) shouldBe true + Utils.readMDFFromPath(Some(filename)) shouldBe Some(mdf) + } +} diff --git a/tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala b/tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala new file mode 100644 index 00000000..fd3210bb --- /dev/null +++ b/tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala @@ -0,0 +1,406 @@ +package mdf.macrolib + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import play.api.libs.json._ + +object JSONUtils { + def readStringValueMap(str: String): Option[Map[String, JsValue]] = { + Json.parse(str) match { + case x: JsObject => Some(x.as[Map[String, JsValue]]) + case _ => None + } + } +} + +// Tests for filler macros +class FillerMacroSpec extends AnyFlatSpec with Matchers { + "Valid lvt macros" should "be detected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "filler cell", + | "name": "MY_FILLER_CELL", + | "vt": "lvt" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe Some(FillerMacro("MY_FILLER_CELL", "lvt")) + } + + "Valid metal macro" should "be detected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "metal filler cell", + | "name": "METAL_FILLER_CELL", + | "vt": "lvt" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe Some(MetalFillerMacro("METAL_FILLER_CELL", "lvt")) + } + + "Valid hvt macros" should "be detected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "filler cell", + | "name": "HVT_CELL_PROP", + | "vt": "hvt" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe Some(FillerMacro("HVT_CELL_PROP", "hvt")) + } + + "Empty name macros" should "be rejected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "filler cell", + | "name": "", + | "vt": "hvt" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe None + } + + "Empty vt macros" should "be rejected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "metal filler cell", + | "name": "DEAD_CELL", + | "vt": "" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe None + } + + "Missing vt macros" should "be rejected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "metal filler cell", + | "name": "DEAD_CELL" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe None + } + + "Missing name macros" should "be rejected" in { + val m = JSONUtils + .readStringValueMap(""" + | { + | "type": "filler cell", + | "vt": "" + | } + |""".stripMargin) + .get + FillerMacroBase.parseJSON(m) shouldBe None + } +} + +// Tests for SRAM type and associates. +class SRAMMacroSpec extends AnyFlatSpec with Matchers { + // Simple port which can be reused in tests + // Note: assume width=depth=simplePortConstant. + val simplePortConstant = 1024 + def simplePort( + postfix: String = "", + width: Int = simplePortConstant, + depth: Int = simplePortConstant + ): (String, MacroPort) = { + val json = s""" + { + "address port name": "A_${postfix}", + "address port polarity": "active high", + "clock port name": "CLK_${postfix}", + "clock port polarity": "positive edge", + "write enable port name": "WEN_${postfix}", + "write enable port polarity": "active high", + "read enable port name": "REN_${postfix}", + "read enable port polarity": "active high", + "chip enable port name": "CEN_${postfix}", + "chip enable port polarity": "active high", + "output port name": "OUT_${postfix}", + "output port polarity": "active high", + "input port name": "IN_${postfix}", + "input port polarity": "active high", + "mask granularity": 1, + "mask port name": "MASK_${postfix}", + "mask port polarity": "active high" + } + """ + val port = MacroPort( + address = PolarizedPort(s"A_${postfix}", ActiveHigh), + clock = Some(PolarizedPort(s"CLK_${postfix}", PositiveEdge)), + writeEnable = Some(PolarizedPort(s"WEN_${postfix}", ActiveHigh)), + readEnable = Some(PolarizedPort(s"REN_${postfix}", ActiveHigh)), + chipEnable = Some(PolarizedPort(s"CEN_${postfix}", ActiveHigh)), + output = Some(PolarizedPort(s"OUT_${postfix}", ActiveHigh)), + input = Some(PolarizedPort(s"IN_${postfix}", ActiveHigh)), + maskPort = Some(PolarizedPort(s"MASK_${postfix}", ActiveHigh)), + maskGran = Some(1), + width = Some(width), + depth = Some(depth) + ) + (json, port) + } + "Simple port" should "be valid" in { + { + val (json, port) = simplePort("Simple1") + MacroPort.parseJSON(JSONUtils.readStringValueMap(json).get, simplePortConstant, simplePortConstant) shouldBe Some( + port + ) + } + { + val (json, port) = simplePort("Simple2") + MacroPort.parseJSON(JSONUtils.readStringValueMap(json).get, simplePortConstant, simplePortConstant) shouldBe Some( + port + ) + } + { + val (json, port) = simplePort("bar") + MacroPort.parseJSON(JSONUtils.readStringValueMap(json).get, simplePortConstant, simplePortConstant) shouldBe Some( + port + ) + } + { + val (json, port) = simplePort("") + MacroPort.parseJSON(JSONUtils.readStringValueMap(json).get, simplePortConstant, simplePortConstant) shouldBe Some( + port + ) + } + } + + "Simple SRAM macro" should "be detected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 2048, + "depth": "4096", + "family": "1rw", + "ports": [ + ${json} + ] +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe Some( + SRAMMacro("SRAMS_R_US", width = 2048, depth = 4096, family = "1rw", ports = List(port), extraPorts = List()) + ) + } + + "Non-power-of-two width & depth SRAM macro" should "be detected" in { + val (json, port) = simplePort("", 1234, 8888) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 1234, + "depth": "8888", + "family": "1rw", + "ports": [ + ${json} + ] +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe Some( + SRAMMacro("SRAMS_R_US", width = 1234, depth = 8888, family = "1rw", ports = List(port), extraPorts = List()) + ) + } + + "Minimal memory port" should "be detected" in { + val (json, port) = simplePort("_A", 64, 1024) + val port2 = MacroPort( + address = PolarizedPort("A_B", ActiveHigh), + clock = Some(PolarizedPort("CLK_B", PositiveEdge)), + writeEnable = Some(PolarizedPort("WEN_B", ActiveHigh)), + readEnable = None, + chipEnable = None, + output = Some(PolarizedPort("OUT_B", ActiveHigh)), + input = Some(PolarizedPort("IN_B", ActiveHigh)), + maskPort = None, + maskGran = None, + width = Some(64), + depth = Some(1024) + ) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 64, + "depth": "1024", + "family": "2rw", + "ports": [ + ${json}, + { + "address port name": "A_B", + "address port polarity": "active high", + "clock port name": "CLK_B", + "clock port polarity": "positive edge", + "write enable port name": "WEN_B", + "write enable port polarity": "active high", + "output port name": "OUT_B", + "output port polarity": "active high", + "input port name": "IN_B", + "input port polarity": "active high" + } + ] +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe Some( + SRAMMacro("SRAMS_R_US", width = 64, depth = 1024, family = "2rw", ports = List(port, port2), extraPorts = List()) + ) + } + + "Extra ports" should "be detected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "GOT_EXTRA", + "width": 2048, + "depth": "4096", + "family": "1rw", + "ports": [ + ${json} + ], + "extra ports": [ + { + "name": "TIE_DIE", + "width": 1, + "type": "constant", + "value": 1 + }, + { + "name": "TIE_MOO", + "width": 4, + "type": "constant", + "value": 0 + } + ] +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe Some( + SRAMMacro( + "GOT_EXTRA", + width = 2048, + depth = 4096, + family = "1rw", + ports = List(port), + extraPorts = List( + MacroExtraPort( + name = "TIE_DIE", + width = 1, + portType = Constant, + value = 1 + ), + MacroExtraPort( + name = "TIE_MOO", + width = 4, + portType = Constant, + value = 0 + ) + ) + ) + ) + } + + "Invalid port" should "be rejected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 2048, + "depth": "4096", + "family": "1rw", + "ports": [ + { + "address port name": "missing_polarity", + "output port name": "missing_clock" + } + ] +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe None + } + + "No ports" should "be rejected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 2048, + "depth": "4096", + "family": "1rw" +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe None + } + + "No family and ports" should "be rejected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "SRAMS_R_US", + "width": 2048, + "depth": "4096" +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe None + } + + "String width" should "be rejected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "BAD_BAD_SRAM", + "width": "wide", + "depth": "4096" +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe None + } + + "String depth" should "be rejected" in { + val (json, port) = simplePort("", 2048, 4096) + val m = JSONUtils + .readStringValueMap(s""" +{ + "type": "sram", + "name": "BAD_BAD_SRAM", + "width": 512, + "depth": "octopus_under_the_sea" +} + """) + .get + SRAMMacro.parseJSON(m) shouldBe None + } +} From db2739bb6c7901ad1f0cb05ed5a4a0b81f304374 Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 9 Aug 2021 09:47:20 -0700 Subject: [PATCH 2/8] iocell won't run without this syntax IntelliJ flags this as error, even though it compiles and runs --- tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala index 47b7cf2e..d244d298 100644 --- a/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala +++ b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala @@ -148,7 +148,7 @@ object IOCell { padSignal: T, name: Option[String] = None, typeParams: IOCellTypeParams = GenericIOCellParams(), - concretizeResetFn: (Reset) => R = toSyncReset _ + concretizeResetFn: (Reset) => R = toSyncReset ): Seq[IOCell] = { def genCell[T <: Data]( castToBool: (T) => Bool, From b107a6bdf3a1b76c350d431b65c9c6ab3cf3fc03 Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 9 Aug 2021 10:10:10 -0700 Subject: [PATCH 3/8] Add some missing resources --- build.sbt | 10 +- tapeout/src/test/resources/bumps.json | 41 ++ tapeout/src/test/resources/io_properties.json | 663 ++++++++++++++++++ 3 files changed, 711 insertions(+), 3 deletions(-) create mode 100644 tapeout/src/test/resources/bumps.json create mode 100644 tapeout/src/test/resources/io_properties.json diff --git a/build.sbt b/build.sbt index 1fe83505..45723331 100644 --- a/build.sbt +++ b/build.sbt @@ -24,12 +24,16 @@ lazy val commonSettings = Seq( ) ) -disablePlugins(sbtassembly.AssemblyPlugin) - -enablePlugins(sbtassembly.AssemblyPlugin) +//disablePlugins(sbtassembly.AssemblyPlugin) +// +//enablePlugins(sbtassembly.AssemblyPlugin) lazy val tapeout = (project in file("tapeout")) .settings(commonSettings) .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) + .settings( + mainClass := Some("barstools.macros.MacroCompiler") + ) + .enablePlugins(sbtassembly.AssemblyPlugin) lazy val root = (project in file(".")).aggregate(tapeout) diff --git a/tapeout/src/test/resources/bumps.json b/tapeout/src/test/resources/bumps.json new file mode 100644 index 00000000..21b93381 --- /dev/null +++ b/tapeout/src/test/resources/bumps.json @@ -0,0 +1,41 @@ +[ + { + "name" : "example", + "type" : "flipchip", + "bump_dimensions" : [27,27], + "bump_locations" : [ + ["-", "GND", "VDDC0_SEL[0]", "VDDC0_SEL[1]", "VDDC1_SEL[0]", "VDDC1_SEL[1]", "VDDC2_SEL[0]", "VDDC2_SEL[1]", "VDDC3_SEL[0]", "VDDC3_SEL[1]", "VDDC0_EN", "VDDC1_EN", "VDDC2_EN", "VDDC3_EN", "CCLK0", "CCLK1", "CCLK2", "RESET", "BOOT", "I2C_SDA", "I2C_SCL", "SPI_SCLK", "SPI_MOSI", "SPI_MISO", "SPI_SS_L", "GND", "-"], + [ "GND", "", "", "", "GND", "GND","GPIO[1]", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8","UART_RX","UART_TX", "GND", "GND", "GND", "GND", "", "", "", "GND"], + + ["TXP0", "VDDA", "VDDA", "GND", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "GND", "VDDA", "VDDA", "TXP4"], + ["TXN0", "VDDA", "VDDA", "GND", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "GND", "VDDA", "VDDA", "TXN4"], + [ "GND", "", "", "", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "", "", "", "GND"], + ["RXP0", "VDDA", "VDDA", "GND", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "GND", "VDDA", "VDDA", "RXP4"], + ["RXN0", "VDDA", "VDDA", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "VDDA", "VDDA", "RXN4"], + [ "GND", "", "", "", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "", "", "", "GND"], + + ["TXP1", "VDDA", "VDDA", "GND", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "GND", "VDDA", "VDDA", "TXP5"], + ["TXN1", "VDDA", "VDDA", "GND", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "GND", "VDDA", "VDDA", "TXN5"], + [ "GND", "", "", "", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "", "", "", "GND"], + ["RXP1", "VDDA", "VDDA", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "VDDA", "VDDA", "RXP5"], + ["RXN1", "VDDA", "VDDA", "GND", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "GND", "GND", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "GND", "VDDA", "VDDA", "RXN5"], + [ "GND", "", "", "", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "VDDC1", "GND", "GND", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC0", "VDDC0", "VDDC0", "VDDC0", "", "", "", "GND"], + + ["TXP2", "VDDA", "VDDA", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "VDDA", "VDDA", "TXP6"], + ["TXN2", "VDDA", "VDDA", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "VDDA", "VDDA", "TXN6"], + [ "GND", "", "", "", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "", "", "", "GND"], + ["RXP2", "VDDA", "VDDA", "GND", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC2", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "VDDC3", "GND", "VDDA", "VDDA", "RXP6"], + ["RXN2", "VDDA", "VDDA", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "VDDA", "VDDA", "RXN6"], + [ "GND", "", "", "", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "GND", "", "", "", "GND"], + + ["TXP3", "VDDA", "VDDA", "GND", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "GND", "VDDA", "VDDA", "TXP7"], + ["TXN3", "VDDA", "VDDA", "GND", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "VDD0V8", "GND", "VDDA", "VDDA", "TXN7"], + [ "GND", "", "", "", "-", "SERIAL_IN_READY", "-", "-", "SERIAL_IN_VALID", "-", "-", "-", "-", "", "-", "SERIAL_OUT_VALID", "-", "-", "SERIAL_OUT_READY", "-", "-", "GPIO[0]", "-", "", "", "", "GND"], + ["RXP3", "VDDA", "VDDA", "GND", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "GND", "VDDA", "VDDA", "RXP7"], + ["RXN3", "VDDA", "VDDA", "GND", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "GND", "VDDA", "VDDA", "RXN7"], + + [ "GND", "", "", "", "GND", "GND", "GND", "GND", "GND", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "VDD1V8", "GND", "GND", "GND", "GND", "GND", "", "", "", "GND"], + ["-", "GND", "REFCLK0P", "REFCLK0N", "GND", "SERIAL_OUT[0]", "SERIAL_OUT[1]", "SERIAL_OUT[2]", "SERIAL_OUT[3]", "SERIAL_IN[0]", "SERIAL_IN[1]", "SERIAL_IN[2]", "SERIAL_IN[3]", "JTAG_TMS", "JTAG_TCK", "JTAG_TDO", "JTAG_TDI", "CLKSEL", "PLLCLK_OUT", "GND", "PLLREFCLKP", "PLLREFCLKN", "GND", "REFCLK1P", "REFCLK1N", "GND", "-"] + ] + } +] diff --git a/tapeout/src/test/resources/io_properties.json b/tapeout/src/test/resources/io_properties.json new file mode 100644 index 00000000..93b945a3 --- /dev/null +++ b/tapeout/src/test/resources/io_properties.json @@ -0,0 +1,663 @@ +[ + { + "name": "My IOs", + "type": "io_properties", + "top": "EAGLE", + "ios": [ + { + "name": "GND", + "type": "ground" + }, + { + "name": "VDD0V8", + "type": "power" + }, + { + "name": "VDD1V8", + "type": "power" + }, + { + "name": "VDDC0", + "type": "power" + }, + { + "name": "VDDC1", + "type": "power" + }, + { + "name": "VDDC2", + "type": "power" + }, + { + "name": "VDDC3", + "type": "power" + }, + { + "name": "VDDA", + "type": "power" + }, + { + "name": "VDDC0_SEL[1:0]", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDC1_SEL[1:0]", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDC2_SEL[1:0]", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDC3_SEL[1:0]", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDDC0_EN", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDDC1_EN", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDDC2_EN", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "VDDDC3_EN", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "CCLK0", + "type": "digital", + "direction": "input", + "termination": 50, + "termination_type": "single", + "termination_reference": "GND" + }, + { + "name": "CCLK1", + "type": "digital", + "direction": "input", + "termination": 50, + "termination_type": "single", + "termination_reference": "GND" + }, + { + "name": "CCLK2", + "type": "digital", + "direction": "input", + "termination": 50, + "termination_type": "single", + "termination_reference": "GND" + }, + { + "name": "RESET", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "BOOT", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "I2C_SDA", + "type": "digital", + "direction": "inout", + "termination": "open-drain" + }, + { + "name": "I2C_SCL", + "type": "digital", + "direction": "inout", + "termination": "open-drain" + }, + { + "name": "SPI_SCLK", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SPI_MOSI", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SPI_MISO", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "SPI_SS_L", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "GPIO[1:0]", + "type": "digital", + "direction": "inout", + "termination": "CMOS" + }, + { + "name": "UART_RX", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "UART_TX", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SERIAL_IN_READY", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SERIAL_IN_VALID", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "SERIAL_OUT_READY", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "SERIAL_OUT_VALID", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SERIAL_OUT[3:0]", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "SERIAL_IN[3:0]", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "REFCLK0P", + "type": "analog", + "direction": "input", + "match": [ + "REFCLK0N" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "REFCLK0N", + "type": "analog", + "direction": "input", + "match": [ + "REFCLK0P" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "REFCLK1N", + "type": "analog", + "direction": "input", + "match": [ + "REFCLK1P" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "REFCLK1P", + "type": "analog", + "direction": "input", + "match": [ + "REFCLK1N" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "PLLREFCLKP", + "type": "analog", + "direction": "input", + "match": [ + "PLLREFCLKP" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "PLLREFCLKN", + "type": "analog", + "direction": "input", + "match": [ + "PLLREFCLKP" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "JTAG_TMS", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "JTAG_TCK", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "JTAG_TDI", + "type": "digital", + "direction": "input", + "termination": "CMOS" + }, + { + "name": "JTAG_TDO", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "PLLCLK_OUT", + "type": "digital", + "direction": "output", + "termination": "CMOS" + }, + { + "name": "TXP0", + "type": "analog", + "direction": "output", + "match": [ + "TXN0" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN0", + "type": "analog", + "direction": "output", + "match": [ + "TXP0" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP0", + "type": "analog", + "direction": "output", + "match": [ + "RXN0" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN1", + "type": "analog", + "direction": "input", + "match": [ + "RXP1" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP1", + "type": "analog", + "direction": "output", + "match": [ + "TXN1" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN1", + "type": "analog", + "direction": "output", + "match": [ + "TXP1" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP1", + "type": "analog", + "direction": "output", + "match": [ + "RXN1" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN1", + "type": "analog", + "direction": "input", + "match": [ + "RXP1" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP2", + "type": "analog", + "direction": "output", + "match": [ + "TXN2" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN2", + "type": "analog", + "direction": "output", + "match": [ + "TXP2" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP2", + "type": "analog", + "direction": "output", + "match": [ + "RXN2" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN2", + "type": "analog", + "direction": "input", + "match": [ + "RXP2" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP3", + "type": "analog", + "direction": "output", + "match": [ + "TXN3" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN3", + "type": "analog", + "direction": "output", + "match": [ + "TXP3" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP3", + "type": "analog", + "direction": "output", + "match": [ + "RXN3" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN3", + "type": "analog", + "direction": "input", + "match": [ + "RXP3" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP4", + "type": "analog", + "direction": "output", + "match": [ + "TXN4" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN4", + "type": "analog", + "direction": "output", + "match": [ + "TXP4" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP4", + "type": "analog", + "direction": "output", + "match": [ + "RXN4" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN4", + "type": "analog", + "direction": "input", + "match": [ + "RXP4" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP5", + "type": "analog", + "direction": "output", + "match": [ + "TXN5" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN5", + "type": "analog", + "direction": "output", + "match": [ + "TXP5" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP5", + "type": "analog", + "direction": "output", + "match": [ + "RXN5" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN5", + "type": "analog", + "direction": "input", + "match": [ + "RXP5" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP6", + "type": "analog", + "direction": "output", + "match": [ + "TXN6" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN6", + "type": "analog", + "direction": "output", + "match": [ + "TXP6" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP6", + "type": "analog", + "direction": "output", + "match": [ + "RXN6" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN6", + "type": "analog", + "direction": "input", + "match": [ + "RXP6" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXP7", + "type": "analog", + "direction": "output", + "match": [ + "TXN7" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "TXN7", + "type": "analog", + "direction": "output", + "match": [ + "TXP7" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXP7", + "type": "analog", + "direction": "output", + "match": [ + "RXN7" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + }, + { + "name": "RXN7", + "type": "analog", + "direction": "input", + "match": [ + "RXP7" + ], + "termination": 100, + "termination_type": "differential", + "termination_reference": "GND" + } + ] + } +] From e113a7b61977bfecbedddb564f23ee9d9b777b23 Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 9 Aug 2021 17:50:47 -0700 Subject: [PATCH 4/8] Add setting to have `sbt` not exit if a program calls System.exit Without this a useless and misleading log4j error is reported. --- build.sbt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 45723331..47e450be 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,8 @@ // See LICENSE for license details. val defaultVersions = Map( - "chisel3" -> "3.4.+", - "chisel-iotesters" -> "1.5.+" + "chisel3" -> "3.5-SNAPSHOT", + "chisel-iotesters" -> "2.5-SNAPSHOT" ) lazy val commonSettings = Seq( @@ -16,6 +16,8 @@ lazy val commonSettings = Seq( libraryDependencies ++= Seq( "com.typesafe.play" %% "play-json" % "2.9.2", "org.scalatest" %% "scalatest" % "3.2.9" % "test", + "org.apache.logging.log4j" % "log4j-api" % "2.11.2", + "org.apache.logging.log4j" % "log4j-core" % "2.11.2" ), resolvers ++= Seq( Resolver.sonatypeRepo("snapshots"), @@ -31,6 +33,7 @@ lazy val commonSettings = Seq( lazy val tapeout = (project in file("tapeout")) .settings(commonSettings) .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) + .settings(fork := true) .settings( mainClass := Some("barstools.macros.MacroCompiler") ) From 352fa91b62785ceba1575f9093bbce7e42034a6e Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 10 Aug 2021 15:28:25 -0700 Subject: [PATCH 5/8] IOCell toBool => asBool MacroCompiler needs more specific firrtl.Utils imports, Comment out legalize SynFlops more precise imports YamlHelpers use FileUtils ResetInverter LegacyModule => Module Retime use Module instead of LegacyModule YamlHelpers uses FileUtils instead of getResource ResetInvert use Module instead of LegacyModule Masks add scalatest wrappers for getting better test reports SpecificExamples drop tapeout prefix, and add scalatest blocks GenerateSpec, let ChiselStage emit the firrt directly to target dir, add some actual tests that files were created GenerateTopSpec use FileUtils FlipChipMacroSpec use FileUtils IOPropertiesSpec use FileUtils --- .../barstools/iocell/chisel/IOCell.scala | 2 +- .../barstools/macros/MacroCompiler.scala | 3 +- .../scala/barstools/macros/SynFlops.scala | 4 +- .../tapeout/transforms/ResetInverter.scala | 2 +- .../tapeout/transforms/retime/Retime.scala | 2 +- .../transforms/utils/YamlHelpers.scala | 7 +- .../src/main/scala/mdf/macrolib/Utils.scala | 11 ++- .../test/scala/barstools/macros/Masks.scala | 92 ++++++++++++++----- .../barstools/macros/SpecificExamples.scala | 25 +++-- .../tapeout/transforms/GenerateSpec.scala | 10 +- .../tapeout/transforms/GenerateTopSpec.scala | 3 +- .../mdf/macrolib/FlipChipMacroSpec.scala | 5 +- .../scala/mdf/macrolib/IOPropertiesSpec.scala | 5 +- 13 files changed, 118 insertions(+), 53 deletions(-) diff --git a/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala index d244d298..6d444936 100644 --- a/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala +++ b/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala @@ -141,7 +141,7 @@ object IOCell { * @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 toSyncReset: (Reset) => Bool = _.asBool() val toAsyncReset: (Reset) => AsyncReset = _.asAsyncReset def generateFromSignal[T <: Data, R <: Reset]( coreSignal: T, diff --git a/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala b/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala index bfcf78da..6218b593 100644 --- a/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala +++ b/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala @@ -8,7 +8,7 @@ package barstools.macros import barstools.macros.Utils._ -import firrtl.Utils._ +import firrtl.Utils.{BoolType, one, zero} import firrtl.annotations._ import firrtl.ir._ import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation} @@ -783,7 +783,6 @@ class MacroCompilerOptimizations extends SeqTransform with DependencyAPIMigratio new firrtl.transforms.ConstantPropagation, passes.memlib.VerilogMemDelays, new firrtl.transforms.ConstantPropagation, - passes.Legalize, passes.SplitExpressions, passes.CommonSubexpressionElimination ) diff --git a/tapeout/src/main/scala/barstools/macros/SynFlops.scala b/tapeout/src/main/scala/barstools/macros/SynFlops.scala index 5d39cda9..a6fe32a4 100644 --- a/tapeout/src/main/scala/barstools/macros/SynFlops.scala +++ b/tapeout/src/main/scala/barstools/macros/SynFlops.scala @@ -3,7 +3,7 @@ package barstools.macros import barstools.macros.Utils._ -import firrtl.Utils._ +import firrtl.Utils.{zero, one} import firrtl._ import firrtl.ir._ import firrtl.passes.MemPortUtils.memPortField @@ -27,7 +27,7 @@ class SynFlopsPass(synflops: Boolean, libs: Seq[Macro]) extends firrtl.passes.Pa case Some(gran) => (UIntType(IntWidth(gran)), gran.intValue) } - val maxDepth = min(lib.src.depth, 1 << 26) + val maxDepth = firrtl.Utils.min(lib.src.depth, 1 << 26) val numMems = lib.src.depth / maxDepth // Change macro to be mapped onto to look like the below mem diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala index 33d2f78a..29c9f0da 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala @@ -60,7 +60,7 @@ class ResetInverterTransform extends Transform with DependencyAPIMigration { trait ResetInverter { self: chisel3.Module => - def invert[T <: chisel3.internal.LegacyModule](module: T): Unit = { + def invert[T <: chisel3.Module](module: T): Unit = { chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform { def transformClass: Class[_ <: Transform] = classOf[ResetInverterTransform] def toFirrtl: Annotation = ResetInverterAnnotation(module.toNamed) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala index 931af88d..1a9d6668 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala @@ -39,7 +39,7 @@ class RetimeTransform extends Transform with DependencyAPIMigration { trait RetimeLib { self: chisel3.Module => - def retime[T <: chisel3.internal.LegacyModule](module: T): Unit = { + def retime[T <: chisel3.Module](module: T): Unit = { chisel3.experimental.annotate(new chisel3.experimental.ChiselAnnotation with RunFirrtlTransform { def transformClass: Class[_ <: Transform] = classOf[RetimeTransform] def toFirrtl: Annotation = RetimeAnnotation(module.toNamed) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala index 9a226de5..9b58e083 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala @@ -1,5 +1,6 @@ package barstools.tapeout.transforms.utils +import firrtl.FileUtils import net.jcazevedo.moultingyaml._ import java.io.File @@ -10,10 +11,10 @@ class YamlFileReader(resource: String) { val yamlString = file match { case f if f.isEmpty => // Use example config if no file is provided - val stream = getClass.getResourceAsStream(resource) - io.Source.fromInputStream(stream).mkString + val stream = FileUtils.getTextResource(resource) + stream case f if new File(f).exists => - scala.io.Source.fromFile(f).getLines.mkString("\n") + FileUtils.getText(f) case _ => throw new Exception("No valid Yaml file found!") } diff --git a/tapeout/src/main/scala/mdf/macrolib/Utils.scala b/tapeout/src/main/scala/mdf/macrolib/Utils.scala index 795cff0a..86d78a24 100644 --- a/tapeout/src/main/scala/mdf/macrolib/Utils.scala +++ b/tapeout/src/main/scala/mdf/macrolib/Utils.scala @@ -1,6 +1,8 @@ package mdf.macrolib import play.api.libs.json._ + +import java.io.FileNotFoundException import scala.collection.mutable.ListBuffer import scala.language.implicitConversions @@ -37,7 +39,14 @@ object Utils { path match { case None => None // Read file into string and parse - case Some(p) => Utils.readMDFFromString(scala.io.Source.fromFile(p).mkString) + case Some(p) => + try { + Utils.readMDFFromString(scala.io.Source.fromFile(p).mkString) + } catch { + case f: FileNotFoundException => + println(s"FILE NOT FOUND $p in dir ${os.pwd}") + throw f + } } } diff --git a/tapeout/src/test/scala/barstools/macros/Masks.scala b/tapeout/src/test/scala/barstools/macros/Masks.scala index c472669a..43d6b3d6 100644 --- a/tapeout/src/test/scala/barstools/macros/Masks.scala +++ b/tapeout/src/test/scala/barstools/macros/Masks.scala @@ -27,7 +27,9 @@ class Masks_FourTypes_NonMaskedMem_NonMaskedLib override lazy val libWidth = 8 override lazy val libMaskGran = None - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_NonMaskedMem_MaskedLib @@ -40,7 +42,9 @@ class Masks_FourTypes_NonMaskedMem_MaskedLib override lazy val libWidth = 8 override lazy val libMaskGran = Some(2) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_MaskedMem_NonMaskedLib @@ -53,7 +57,9 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib override lazy val libWidth = 8 override lazy val libMaskGran = None - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran @@ -66,7 +72,9 @@ class Masks_FourTypes_MaskedMem_NonMaskedLib_SmallerMaskGran override lazy val libWidth = 8 override lazy val libMaskGran = None - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_MaskedMem_MaskedLib @@ -79,7 +87,9 @@ class Masks_FourTypes_MaskedMem_MaskedLib override lazy val libWidth = 16 override lazy val libMaskGran = Some(4) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran @@ -92,7 +102,9 @@ class Masks_FourTypes_MaskedMem_MaskedLib_SameMaskGran override lazy val libWidth = 16 override lazy val libMaskGran = Some(8) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran @@ -105,7 +117,9 @@ class Masks_FourTypes_MaskedMem_MaskedLib_SmallerMaskGran override lazy val libWidth = 32 override lazy val libMaskGran = Some(8) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // Bit-mask memories to non-masked libs whose width is larger than 1. @@ -117,7 +131,9 @@ class Masks_BitMaskedMem_NonMaskedLib extends MacroCompilerSpec with HasSRAMGene override lazy val libWidth = 8 override lazy val libMaskGran = None - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // FPGA-style byte-masked memories. @@ -131,7 +147,9 @@ class Masks_FPGAStyle_32_8 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(8) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // Simple powers of two with bit-masked lib. @@ -145,7 +163,9 @@ class Masks_PowersOfTwo_8_1 override lazy val memMaskGran = Some(8) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_PowersOfTwo_16_1 @@ -157,7 +177,9 @@ class Masks_PowersOfTwo_16_1 override lazy val memMaskGran = Some(16) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_PowersOfTwo_32_1 @@ -169,7 +191,9 @@ class Masks_PowersOfTwo_32_1 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_PowersOfTwo_64_1 @@ -181,7 +205,9 @@ class Masks_PowersOfTwo_64_1 override lazy val memMaskGran = Some(64) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // Simple powers of two with non bit-masked lib. @@ -195,7 +221,9 @@ class Masks_PowersOfTwo_32_4 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(4) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_PowersOfTwo_32_8 @@ -207,7 +235,9 @@ class Masks_PowersOfTwo_32_8 override lazy val memMaskGran = Some(32) override lazy val libMaskGran = Some(8) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_PowersOfTwo_8_8 @@ -219,7 +249,9 @@ class Masks_PowersOfTwo_8_8 override lazy val memMaskGran = Some(8) override lazy val libMaskGran = Some(8) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // Width as a multiple of the mask, bit-masked lib @@ -233,7 +265,9 @@ class Masks_IntegerMaskMultiple_20_10 override lazy val memMaskGran = Some(10) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_21_7 @@ -258,7 +292,9 @@ class Masks_IntegerMaskMultiple_21_21 override lazy val memMaskGran = Some(21) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_84_21 @@ -270,7 +306,9 @@ class Masks_IntegerMaskMultiple_84_21 override lazy val memMaskGran = Some(21) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_92_23 @@ -282,7 +320,9 @@ class Masks_IntegerMaskMultiple_92_23 override lazy val memMaskGran = Some(23) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_117_13 @@ -294,7 +334,9 @@ class Masks_IntegerMaskMultiple_117_13 override lazy val memMaskGran = Some(13) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_160_20 @@ -306,7 +348,9 @@ class Masks_IntegerMaskMultiple_160_20 override lazy val memMaskGran = Some(20) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class Masks_IntegerMaskMultiple_184_23 @@ -318,7 +362,9 @@ class Masks_IntegerMaskMultiple_184_23 override lazy val memMaskGran = Some(23) override lazy val libMaskGran = Some(1) - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } // Width as an non-integer multiple of the mask, bit-masked lib diff --git a/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala b/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala index 6ee7255a..1a957199 100644 --- a/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala +++ b/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala @@ -27,7 +27,7 @@ class WriteEnableTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-WriteEnableTest.json" // lib. of mems to create it val v = s"WriteEnableTest.json" - override val libPrefix = "tapeout/src/test/resources" + override val libPrefix = "src/test/resources" val memSRAMs = mdf.macrolib.Utils .readMDFFromString(""" @@ -89,7 +89,9 @@ circuit cc_banks_0_ext : defname = fake_mem """ - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator { @@ -97,7 +99,7 @@ class MaskPortTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-MaskPortTest.json" // lib. of mems to create it val v = s"MaskPortTest.json" - override val libPrefix = "tapeout/src/test/resources" + override val libPrefix = "src/test/resources" val memSRAMs = mdf.macrolib.Utils .readMDFFromString(""" @@ -173,7 +175,9 @@ circuit cc_dir_ext : defname = fake_mem """ - compileExecuteAndTest(mem, lib, v, output) + it should "compile, exectue, and test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { @@ -181,10 +185,9 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { val lib = s"lib-BOOMTest.json" val v = s"BOOMTest.v" - override val libPrefix = "tapeout/src/test/resources" + override val libPrefix = "src/test/resources" - val memSRAMs = mdf.macrolib.Utils - .readMDFFromString(""" + val memSRAMs = mdf.macrolib.Utils.readMDFFromString(""" [ { "type" : "sram", "name" : "_T_182_ext", @@ -1345,7 +1348,9 @@ circuit smem_0_ext : defname = my_sram_1rw_64x8 """ - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute and test the boom test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class SmallTagArrayTest extends MacroCompilerSpec with HasSRAMGenerator with HasSimpleTestGenerator { @@ -1378,7 +1383,9 @@ class SmallTagArrayTest extends MacroCompilerSpec with HasSRAMGenerator with Has | dout <= mux(UInt<1>("h1"), dout_0, UInt<26>("h0")) """.stripMargin - compileExecuteAndTest(mem, lib, v, output) + it should "compile, execute, and test, the small tag array test" in { + compileExecuteAndTest(mem, lib, v, output) + } } class RocketChipTest extends MacroCompilerSpec with HasSRAMGenerator { diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala index ec4822fe..5c7d53f1 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala @@ -7,6 +7,9 @@ import chisel3.experimental.ExtModule import chisel3.stage.ChiselStage import firrtl.FileUtils import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.must.Matchers.be +import org.scalatest.matchers.should.Matchers +import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper import java.io.{File, PrintWriter} @@ -61,9 +64,7 @@ class GenerateSpec extends AnyFreeSpec { val targetDir = "test_run_dir/generate_spec_source" FileUtils.makeDirectory(targetDir) - val printWriter = new PrintWriter(new File(s"$targetDir/GenerateExampleTester.fir")) - printWriter.write((new ChiselStage()).emitFirrtl(new GenerateExampleTester, Array("--target-dir", targetDir))) - printWriter.close() + (new ChiselStage()).emitFirrtl(new GenerateExampleTester, Array("--target-dir", targetDir)) val blackBoxInverterText = """ |module BlackBoxInverter( @@ -78,7 +79,7 @@ class GenerateSpec extends AnyFreeSpec { printWriter2.write(blackBoxInverterText) printWriter2.close() - + new File(s"$targetDir/GenerateExampleTester.fir").exists() should be (true) } "generate top test" in { @@ -89,5 +90,6 @@ class GenerateSpec extends AnyFreeSpec { "-i", s"$sourceDir/GenerateExampleTester.fir", "-o", s"$targetDir/GenerateExampleTester.v" )) + new File(s"$targetDir/GenerateExampleTester.v").exists() should be (true) } } diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala index 02afa79a..e4824c4c 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -27,8 +27,7 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { val targetDir = "test_run_dir/generate_top_spec" FileUtils.makeDirectory(targetDir) - val stream = getClass.getResourceAsStream("/BlackBoxFloatTester.fir") - val input = scala.io.Source.fromInputStream(stream).getLines() + val input = FileUtils.getLinesResource("/BlackBoxFloatTester.fir") val printWriter = new PrintWriter(new File(s"$targetDir/BlackBoxFloatTester.fir")) printWriter.write(input.mkString("\n")) printWriter.close() diff --git a/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala b/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala index ba51e4d1..c6a9e7ce 100644 --- a/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala +++ b/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala @@ -1,12 +1,13 @@ package mdf.macrolib +import firrtl.FileUtils import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class FlipChipMacroSpec extends AnyFlatSpec with Matchers { "Parsing flipchipmacros" should "work" in { - val stream = getClass.getResourceAsStream("/bumps.json") - val mdf = Utils.readMDFFromString(scala.io.Source.fromInputStream(stream).getLines().mkString("\n")) + val stream = FileUtils.getLinesResource("/bumps.json") + val mdf = Utils.readMDFFromString(stream.mkString("\n")) mdf match { case Some(Seq(fcp: FlipChipMacro)) => println(fcp.visualize) } diff --git a/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala b/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala index ffd13be5..b09422a7 100644 --- a/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala +++ b/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala @@ -1,12 +1,13 @@ package mdf.macrolib +import firrtl.FileUtils import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class IOPropertiesSpec extends AnyFlatSpec with Matchers { "Parsing io_properties" should "work" in { - val stream = getClass.getResourceAsStream("/io_properties.json") - val mdf = Utils.readMDFFromString(scala.io.Source.fromInputStream(stream).getLines().mkString("\n")) + val stream = FileUtils.getLinesResource("/io_properties.json") + val mdf = Utils.readMDFFromString(stream.mkString("\n")) mdf match { case Some(Seq(fcp: IOProperties)) => } From 74d5da6f4af737e950f2d1516ed88101abef1041 Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 10 Aug 2021 15:40:58 -0700 Subject: [PATCH 6/8] Move src/ from tapeout to top level get rid of root --- build.sbt | 4 +- .../resources/barstools/iocell/vsrc/Analog.v | 0 .../resources/barstools/iocell/vsrc/IOCell.v | 0 .../barstools/iocell/chisel/Analog.scala | 0 .../barstools/iocell/chisel/IOCell.scala | 0 .../scala/barstools/macros/CostMetric.scala | 0 .../barstools/macros/MacroCompiler.scala | 0 .../scala/barstools/macros/SynFlops.scala | 0 .../main/scala/barstools/macros/Utils.scala | 0 .../transforms/AddSuffixToModuleNames.scala | 0 .../transforms/AvoidExtModuleCollisions.scala | 0 .../transforms/ConvertToExtModPass.scala | 0 .../tapeout/transforms/EnumerateModules.scala | 0 .../transforms/GenerateTopAndHarness.scala | 0 .../tapeout/transforms/ReParentCircuit.scala | 0 .../transforms/RemoveUnusedModules.scala | 0 .../tapeout/transforms/ResetInverter.scala | 0 .../tapeout/transforms/retime/Retime.scala | 0 .../transforms/stage/TapeoutStage.scala | 0 .../tapeout/transforms/utils/FileUtils.scala | 0 .../transforms/utils/LowerAnnotations.scala | 0 .../transforms/utils/ProgrammaticBundle.scala | 0 .../transforms/utils/YamlHelpers.scala | 0 .../main/scala/mdf/macrolib/ConfReader.scala | 0 .../scala/mdf/macrolib/FillerMacroBase.scala | 0 .../scala/mdf/macrolib/FlipChipMacro.scala | 0 .../main/scala/mdf/macrolib/IOMacro.scala | 0 .../main/scala/mdf/macrolib/MacroLib.scala | 0 .../main/scala/mdf/macrolib/SRAM.scala | 0 .../main/scala/mdf/macrolib/Utils.scala | 0 .../test/resources/PadAnnotationVerilogPart.v | 0 .../src => src}/test/resources/bumps.json | 0 .../test/resources/io_properties.json | 0 .../test/resources/lib-BOOMTest.json | 0 .../test/resources/lib-MaskPortTest.json | 0 .../test/resources/lib-WriteEnableTest.json | 0 .../scala/barstools/macros/CostFunction.scala | 0 .../scala/barstools/macros/Functional.scala | 0 .../barstools/macros/MacroCompilerSpec.scala | 0 .../test/scala/barstools/macros/Masks.scala | 0 .../scala/barstools/macros/MultiPort.scala | 0 .../scala/barstools/macros/SRAMCompiler.scala | 0 .../barstools/macros/SimpleSplitDepth.scala | 0 .../barstools/macros/SimpleSplitWidth.scala | 0 .../barstools/macros/SpecificExamples.scala | 0 .../scala/barstools/macros/SynFlops.scala | 0 .../tapeout/transforms/GenerateSpec.scala | 0 .../tapeout/transforms/GenerateTopSpec.scala | 0 .../tapeout/transforms/NoFileProblem.scala | 51 +++++++++++++++++++ .../transforms/ResetInverterSpec.scala | 0 .../transforms/retime/RetimeSpec.scala | 0 .../scala/mdf/macrolib/ConfReaderSpec.scala | 0 .../mdf/macrolib/FlipChipMacroSpec.scala | 0 .../test/scala/mdf/macrolib/IOMacroSpec.scala | 0 .../scala/mdf/macrolib/IOPropertiesSpec.scala | 0 .../scala/mdf/macrolib/MacroLibOutput.scala | 0 .../scala/mdf/macrolib/MacroLibSpec.scala | 0 57 files changed, 53 insertions(+), 2 deletions(-) rename {tapeout/src => src}/main/resources/barstools/iocell/vsrc/Analog.v (100%) rename {tapeout/src => src}/main/resources/barstools/iocell/vsrc/IOCell.v (100%) rename {tapeout/src => src}/main/scala/barstools/iocell/chisel/Analog.scala (100%) rename {tapeout/src => src}/main/scala/barstools/iocell/chisel/IOCell.scala (100%) rename {tapeout/src => src}/main/scala/barstools/macros/CostMetric.scala (100%) rename {tapeout/src => src}/main/scala/barstools/macros/MacroCompiler.scala (100%) rename {tapeout/src => src}/main/scala/barstools/macros/SynFlops.scala (100%) rename {tapeout/src => src}/main/scala/barstools/macros/Utils.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/EnumerateModules.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/ResetInverter.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/retime/Retime.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala (100%) rename {tapeout/src => src}/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/ConfReader.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/FillerMacroBase.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/FlipChipMacro.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/IOMacro.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/MacroLib.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/SRAM.scala (100%) rename {tapeout/src => src}/main/scala/mdf/macrolib/Utils.scala (100%) rename {tapeout/src => src}/test/resources/PadAnnotationVerilogPart.v (100%) rename {tapeout/src => src}/test/resources/bumps.json (100%) rename {tapeout/src => src}/test/resources/io_properties.json (100%) rename {tapeout/src => src}/test/resources/lib-BOOMTest.json (100%) rename {tapeout/src => src}/test/resources/lib-MaskPortTest.json (100%) rename {tapeout/src => src}/test/resources/lib-WriteEnableTest.json (100%) rename {tapeout/src => src}/test/scala/barstools/macros/CostFunction.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/Functional.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/MacroCompilerSpec.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/Masks.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/MultiPort.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/SRAMCompiler.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/SimpleSplitDepth.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/SimpleSplitWidth.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/SpecificExamples.scala (100%) rename {tapeout/src => src}/test/scala/barstools/macros/SynFlops.scala (100%) rename {tapeout/src => src}/test/scala/barstools/tapeout/transforms/GenerateSpec.scala (100%) rename {tapeout/src => src}/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala (100%) create mode 100644 src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala rename {tapeout/src => src}/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala (100%) rename {tapeout/src => src}/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/ConfReaderSpec.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/FlipChipMacroSpec.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/IOMacroSpec.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/IOPropertiesSpec.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/MacroLibOutput.scala (100%) rename {tapeout/src => src}/test/scala/mdf/macrolib/MacroLibSpec.scala (100%) diff --git a/build.sbt b/build.sbt index 47e450be..2b75dbc1 100644 --- a/build.sbt +++ b/build.sbt @@ -30,7 +30,7 @@ lazy val commonSettings = Seq( // //enablePlugins(sbtassembly.AssemblyPlugin) -lazy val tapeout = (project in file("tapeout")) +lazy val tapeout = (project in file(".")) .settings(commonSettings) .settings(scalacOptions in Test ++= Seq("-language:reflectiveCalls")) .settings(fork := true) @@ -39,4 +39,4 @@ lazy val tapeout = (project in file("tapeout")) ) .enablePlugins(sbtassembly.AssemblyPlugin) -lazy val root = (project in file(".")).aggregate(tapeout) +//lazy val root = (project in file(".")).aggregate(tapeout) diff --git a/tapeout/src/main/resources/barstools/iocell/vsrc/Analog.v b/src/main/resources/barstools/iocell/vsrc/Analog.v similarity index 100% rename from tapeout/src/main/resources/barstools/iocell/vsrc/Analog.v rename to src/main/resources/barstools/iocell/vsrc/Analog.v diff --git a/tapeout/src/main/resources/barstools/iocell/vsrc/IOCell.v b/src/main/resources/barstools/iocell/vsrc/IOCell.v similarity index 100% rename from tapeout/src/main/resources/barstools/iocell/vsrc/IOCell.v rename to src/main/resources/barstools/iocell/vsrc/IOCell.v diff --git a/tapeout/src/main/scala/barstools/iocell/chisel/Analog.scala b/src/main/scala/barstools/iocell/chisel/Analog.scala similarity index 100% rename from tapeout/src/main/scala/barstools/iocell/chisel/Analog.scala rename to src/main/scala/barstools/iocell/chisel/Analog.scala diff --git a/tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala b/src/main/scala/barstools/iocell/chisel/IOCell.scala similarity index 100% rename from tapeout/src/main/scala/barstools/iocell/chisel/IOCell.scala rename to src/main/scala/barstools/iocell/chisel/IOCell.scala diff --git a/tapeout/src/main/scala/barstools/macros/CostMetric.scala b/src/main/scala/barstools/macros/CostMetric.scala similarity index 100% rename from tapeout/src/main/scala/barstools/macros/CostMetric.scala rename to src/main/scala/barstools/macros/CostMetric.scala diff --git a/tapeout/src/main/scala/barstools/macros/MacroCompiler.scala b/src/main/scala/barstools/macros/MacroCompiler.scala similarity index 100% rename from tapeout/src/main/scala/barstools/macros/MacroCompiler.scala rename to src/main/scala/barstools/macros/MacroCompiler.scala diff --git a/tapeout/src/main/scala/barstools/macros/SynFlops.scala b/src/main/scala/barstools/macros/SynFlops.scala similarity index 100% rename from tapeout/src/main/scala/barstools/macros/SynFlops.scala rename to src/main/scala/barstools/macros/SynFlops.scala diff --git a/tapeout/src/main/scala/barstools/macros/Utils.scala b/src/main/scala/barstools/macros/Utils.scala similarity index 100% rename from tapeout/src/main/scala/barstools/macros/Utils.scala rename to src/main/scala/barstools/macros/Utils.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala b/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala rename to src/main/scala/barstools/tapeout/transforms/AddSuffixToModuleNames.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala b/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala rename to src/main/scala/barstools/tapeout/transforms/AvoidExtModuleCollisions.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala b/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala rename to src/main/scala/barstools/tapeout/transforms/ConvertToExtModPass.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala b/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala rename to src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala rename to src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala b/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala rename to src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala b/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala rename to src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala b/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/ResetInverter.scala rename to src/main/scala/barstools/tapeout/transforms/ResetInverter.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala b/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/retime/Retime.scala rename to src/main/scala/barstools/tapeout/transforms/retime/Retime.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala b/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala rename to src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala b/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala rename to src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala b/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala rename to src/main/scala/barstools/tapeout/transforms/utils/LowerAnnotations.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala b/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala rename to src/main/scala/barstools/tapeout/transforms/utils/ProgrammaticBundle.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala b/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala similarity index 100% rename from tapeout/src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala rename to src/main/scala/barstools/tapeout/transforms/utils/YamlHelpers.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/ConfReader.scala b/src/main/scala/mdf/macrolib/ConfReader.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/ConfReader.scala rename to src/main/scala/mdf/macrolib/ConfReader.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala b/src/main/scala/mdf/macrolib/FillerMacroBase.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/FillerMacroBase.scala rename to src/main/scala/mdf/macrolib/FillerMacroBase.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala b/src/main/scala/mdf/macrolib/FlipChipMacro.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/FlipChipMacro.scala rename to src/main/scala/mdf/macrolib/FlipChipMacro.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/IOMacro.scala b/src/main/scala/mdf/macrolib/IOMacro.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/IOMacro.scala rename to src/main/scala/mdf/macrolib/IOMacro.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/MacroLib.scala b/src/main/scala/mdf/macrolib/MacroLib.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/MacroLib.scala rename to src/main/scala/mdf/macrolib/MacroLib.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/SRAM.scala b/src/main/scala/mdf/macrolib/SRAM.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/SRAM.scala rename to src/main/scala/mdf/macrolib/SRAM.scala diff --git a/tapeout/src/main/scala/mdf/macrolib/Utils.scala b/src/main/scala/mdf/macrolib/Utils.scala similarity index 100% rename from tapeout/src/main/scala/mdf/macrolib/Utils.scala rename to src/main/scala/mdf/macrolib/Utils.scala diff --git a/tapeout/src/test/resources/PadAnnotationVerilogPart.v b/src/test/resources/PadAnnotationVerilogPart.v similarity index 100% rename from tapeout/src/test/resources/PadAnnotationVerilogPart.v rename to src/test/resources/PadAnnotationVerilogPart.v diff --git a/tapeout/src/test/resources/bumps.json b/src/test/resources/bumps.json similarity index 100% rename from tapeout/src/test/resources/bumps.json rename to src/test/resources/bumps.json diff --git a/tapeout/src/test/resources/io_properties.json b/src/test/resources/io_properties.json similarity index 100% rename from tapeout/src/test/resources/io_properties.json rename to src/test/resources/io_properties.json diff --git a/tapeout/src/test/resources/lib-BOOMTest.json b/src/test/resources/lib-BOOMTest.json similarity index 100% rename from tapeout/src/test/resources/lib-BOOMTest.json rename to src/test/resources/lib-BOOMTest.json diff --git a/tapeout/src/test/resources/lib-MaskPortTest.json b/src/test/resources/lib-MaskPortTest.json similarity index 100% rename from tapeout/src/test/resources/lib-MaskPortTest.json rename to src/test/resources/lib-MaskPortTest.json diff --git a/tapeout/src/test/resources/lib-WriteEnableTest.json b/src/test/resources/lib-WriteEnableTest.json similarity index 100% rename from tapeout/src/test/resources/lib-WriteEnableTest.json rename to src/test/resources/lib-WriteEnableTest.json diff --git a/tapeout/src/test/scala/barstools/macros/CostFunction.scala b/src/test/scala/barstools/macros/CostFunction.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/CostFunction.scala rename to src/test/scala/barstools/macros/CostFunction.scala diff --git a/tapeout/src/test/scala/barstools/macros/Functional.scala b/src/test/scala/barstools/macros/Functional.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/Functional.scala rename to src/test/scala/barstools/macros/Functional.scala diff --git a/tapeout/src/test/scala/barstools/macros/MacroCompilerSpec.scala b/src/test/scala/barstools/macros/MacroCompilerSpec.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/MacroCompilerSpec.scala rename to src/test/scala/barstools/macros/MacroCompilerSpec.scala diff --git a/tapeout/src/test/scala/barstools/macros/Masks.scala b/src/test/scala/barstools/macros/Masks.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/Masks.scala rename to src/test/scala/barstools/macros/Masks.scala diff --git a/tapeout/src/test/scala/barstools/macros/MultiPort.scala b/src/test/scala/barstools/macros/MultiPort.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/MultiPort.scala rename to src/test/scala/barstools/macros/MultiPort.scala diff --git a/tapeout/src/test/scala/barstools/macros/SRAMCompiler.scala b/src/test/scala/barstools/macros/SRAMCompiler.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/SRAMCompiler.scala rename to src/test/scala/barstools/macros/SRAMCompiler.scala diff --git a/tapeout/src/test/scala/barstools/macros/SimpleSplitDepth.scala b/src/test/scala/barstools/macros/SimpleSplitDepth.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/SimpleSplitDepth.scala rename to src/test/scala/barstools/macros/SimpleSplitDepth.scala diff --git a/tapeout/src/test/scala/barstools/macros/SimpleSplitWidth.scala b/src/test/scala/barstools/macros/SimpleSplitWidth.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/SimpleSplitWidth.scala rename to src/test/scala/barstools/macros/SimpleSplitWidth.scala diff --git a/tapeout/src/test/scala/barstools/macros/SpecificExamples.scala b/src/test/scala/barstools/macros/SpecificExamples.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/SpecificExamples.scala rename to src/test/scala/barstools/macros/SpecificExamples.scala diff --git a/tapeout/src/test/scala/barstools/macros/SynFlops.scala b/src/test/scala/barstools/macros/SynFlops.scala similarity index 100% rename from tapeout/src/test/scala/barstools/macros/SynFlops.scala rename to src/test/scala/barstools/macros/SynFlops.scala diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala similarity index 100% rename from tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala rename to src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala similarity index 100% rename from tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala rename to src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala diff --git a/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala b/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala new file mode 100644 index 00000000..da8e0acb --- /dev/null +++ b/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala @@ -0,0 +1,51 @@ +//// SPDX-License-Identifier: Apache-2.0 +// +//package barstools.tapeout.transforms +// +//import firrtl.AnnotationSeq +//import firrtl.options.{Shell, Stage, StageMain} +//import firrtl.stage.{FirrtlCli, FirrtlStage} +//import logger.Logger.OutputCaptor +//import logger.{LazyLogging, LogLevel, Logger} +//import org.scalatest.freespec.AnyFreeSpec +// +//import java.io.{ByteArrayOutputStream, PrintStream} +// +//class NoFileStage extends Stage { +// override val shell: Shell = new Shell(applicationName = "tapeout") with FirrtlCli +// +// override def run(annotations: AnnotationSeq): AnnotationSeq = { +// Logger.makeScope(annotations) { +// val annos = new FirrtlStage().execute(Array.empty, annotations) +// } +// annotations +// } +//} +// +//class NoFileGenerator(annotationSeq: AnnotationSeq) extends LazyLogging { +// +//} +// +//object NoFileGenerator extends StageMain(new NoFileStage) +// +//class NoFileProblem extends AnyFreeSpec { +// // "should fail in a way that discloses missing file" - { +// // (new NoFileStage).execute(Array("-i", "jackalope"), Seq.empty) +// // } +// +// "should fail in a way that discloses missing file with output capture" in { +// val buffer = new ByteArrayOutputStream() +// Console.withOut(new PrintStream(buffer)) { +// NoFileGenerator.main(Array("-i", "jackalope", "-ll", "info")) +// } +// println(buffer.toString) +// } +// +// "don't uses Console.withOut" in { +// val captor = new OutputCaptor +// Logger.setOutput(captor.printStream) +// Logger.setLevel(getClass.getName, LogLevel.Info) +// NoFileGenerator.main(Array("-i", "jackalope", "-ll", "info")) +// println(captor.getOutputAsString) +// } +//} diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala b/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala similarity index 100% rename from tapeout/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala rename to src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala b/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala similarity index 100% rename from tapeout/src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala rename to src/test/scala/barstools/tapeout/transforms/retime/RetimeSpec.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala b/src/test/scala/mdf/macrolib/ConfReaderSpec.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/ConfReaderSpec.scala rename to src/test/scala/mdf/macrolib/ConfReaderSpec.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala b/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala rename to src/test/scala/mdf/macrolib/FlipChipMacroSpec.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala b/src/test/scala/mdf/macrolib/IOMacroSpec.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/IOMacroSpec.scala rename to src/test/scala/mdf/macrolib/IOMacroSpec.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala b/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/IOPropertiesSpec.scala rename to src/test/scala/mdf/macrolib/IOPropertiesSpec.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala b/src/test/scala/mdf/macrolib/MacroLibOutput.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/MacroLibOutput.scala rename to src/test/scala/mdf/macrolib/MacroLibOutput.scala diff --git a/tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala b/src/test/scala/mdf/macrolib/MacroLibSpec.scala similarity index 100% rename from tapeout/src/test/scala/mdf/macrolib/MacroLibSpec.scala rename to src/test/scala/mdf/macrolib/MacroLibSpec.scala From 08eba27126af44f1cc431b8d6ec9bff086314b7b Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 10 Aug 2021 16:26:11 -0700 Subject: [PATCH 7/8] MultiPort remove random println GenerateSpec fix so "generate top test" does not rely on side-effects of previous test GenerateTopSpec fix so it creates needed input file itself, does not rely on other tests to do that --- .../scala/barstools/macros/MultiPort.scala | 1 - .../tapeout/transforms/GenerateSpec.scala | 35 +++++++++++-------- .../tapeout/transforms/GenerateTopSpec.scala | 12 ++++++- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/test/scala/barstools/macros/MultiPort.scala b/src/test/scala/barstools/macros/MultiPort.scala index 1968f6aa..75eb20d7 100644 --- a/src/test/scala/barstools/macros/MultiPort.scala +++ b/src/test/scala/barstools/macros/MultiPort.scala @@ -316,7 +316,6 @@ class SplitWidth_2rw_differentMasks extends MacroCompilerSpec with HasSRAMGenera lazy val memMaskGranB = 8 // these generators are run at constructor time override def generateMemSRAM() = { - println(memMaskGranB) SRAMMacro( name = mem_name, width = memWidth, diff --git a/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala index 5c7d53f1..b5c03c44 100644 --- a/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala @@ -8,7 +8,6 @@ import chisel3.stage.ChiselStage import firrtl.FileUtils import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.must.Matchers.be -import org.scalatest.matchers.should.Matchers import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper import java.io.{File, PrintWriter} @@ -60,34 +59,40 @@ class GenerateExampleTester extends MultiIOModule { } class GenerateSpec extends AnyFreeSpec { - "generate test data" in { - val targetDir = "test_run_dir/generate_spec_source" + + def generateTestData(targetDir: String): Unit = { FileUtils.makeDirectory(targetDir) - (new ChiselStage()).emitFirrtl(new GenerateExampleTester, Array("--target-dir", targetDir)) + new ChiselStage().emitFirrtl(new GenerateExampleTester, Array("--target-dir", targetDir)) - val blackBoxInverterText = """ - |module BlackBoxInverter( - | input [0:0] in, - | output [0:0] out - |); - | assign out = !in; - |endmodule - |""".stripMargin + val blackBoxInverterText = + """ + |module BlackBoxInverter( + | input [0:0] in, + | output [0:0] out + |); + | assign out = !in; + |endmodule + |""".stripMargin val printWriter2 = new PrintWriter(new File(s"$targetDir/BlackBoxInverter.v")) printWriter2.write(blackBoxInverterText) printWriter2.close() + } - new File(s"$targetDir/GenerateExampleTester.fir").exists() should be (true) + "generate test data" in { + val targetDir = "test_run_dir/generate_spec_source" + generateTestData(targetDir) + + new File(s"$targetDir/GenerateExampleTester.fir").exists() should be(true) } "generate top test" in { - val sourceDir = "test_run_dir/generate_spec_source" val targetDir = "test_run_dir/generate_spec" + generateTestData(targetDir) GenerateTop.main(Array( - "-i", s"$sourceDir/GenerateExampleTester.fir", + "-i", s"$targetDir/GenerateExampleTester.fir", "-o", s"$targetDir/GenerateExampleTester.v" )) new File(s"$targetDir/GenerateExampleTester.v").exists() should be (true) diff --git a/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala index e4824c4c..c9de4378 100644 --- a/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -2,6 +2,7 @@ package barstools.tapeout.transforms +import chisel3.stage.ChiselStage import firrtl.FileUtils import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers @@ -11,9 +12,18 @@ import java.io.{ByteArrayOutputStream, File, PrintStream, PrintWriter} class GenerateTopSpec extends AnyFreeSpec with Matchers { "Generate top and harness" - { "should include the following transforms" in { + val targetDir = "test_run_dir/generate_top_and_harness" + FileUtils.makeDirectory(targetDir) + (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted, Array("--target-dir", targetDir)) + val buffer = new ByteArrayOutputStream() Console.withOut(new PrintStream(buffer)) { - GenerateTopAndHarness.main(Array("-i", "ExampleModuleNeedsResetInverted.fir", "-ll", "info")) + GenerateTopAndHarness.main( + Array( + "-i", s"$targetDir/ExampleModuleNeedsResetInverted.fir", + "-ll", "info" + ) + ) } val output = buffer.toString output should include("barstools.tapeout.transforms.AddSuffixToModuleNames") From b2cee7ccb8ba119f27e0bdb22e66fcf0c806377a Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 10 Aug 2021 18:04:49 -0700 Subject: [PATCH 8/8] GenerateTopSpec get rid of `Console.withOut` --- .../tapeout/transforms/GenerateTopSpec.scala | 79 +++++++++---------- .../tapeout/transforms/NoFileProblem.scala | 51 ------------ 2 files changed, 39 insertions(+), 91 deletions(-) delete mode 100644 src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala diff --git a/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala index c9de4378..a7a165a4 100644 --- a/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -7,25 +7,25 @@ import firrtl.FileUtils import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers -import java.io.{ByteArrayOutputStream, File, PrintStream, PrintWriter} +import java.io.{File, PrintWriter} class GenerateTopSpec extends AnyFreeSpec with Matchers { "Generate top and harness" - { "should include the following transforms" in { val targetDir = "test_run_dir/generate_top_and_harness" + val transformListName = s"$targetDir/ExampleModuleNeesResetInvertTransforms.log" FileUtils.makeDirectory(targetDir) (new ChiselStage).emitChirrtl(new ExampleModuleNeedsResetInverted, Array("--target-dir", targetDir)) - val buffer = new ByteArrayOutputStream() - Console.withOut(new PrintStream(buffer)) { - GenerateTopAndHarness.main( - Array( - "-i", s"$targetDir/ExampleModuleNeedsResetInverted.fir", - "-ll", "info" - ) + GenerateTopAndHarness.main( + Array( + "-i", s"$targetDir/ExampleModuleNeedsResetInverted.fir", + "-ll", "info", + "--log-file", transformListName ) - } - val output = buffer.toString + ) + + val output = FileUtils.getText(transformListName) output should include("barstools.tapeout.transforms.AddSuffixToModuleNames") output should include("barstools.tapeout.transforms.ConvertToExtMod") output should include("barstools.tapeout.transforms.RemoveUnusedModules") @@ -33,8 +33,9 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { } } - "generate harness should " ignore { + "generate harness should be generated" ignore { val targetDir = "test_run_dir/generate_top_spec" + val logOutputName = s"$targetDir/top_spec_output.log" FileUtils.makeDirectory(targetDir) val input = FileUtils.getLinesResource("/BlackBoxFloatTester.fir") @@ -44,34 +45,32 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { println(s"""Resource: ${input.mkString("\n")}""") - -// val buffer = new ByteArrayOutputStream() -// Console.withOut(new PrintStream(buffer)) { - GenerateTopAndHarness.main( - Array( - "--target-dir", "test_run_dir/generate_top_spec", - "-i", s"$targetDir/BlackBoxFloatTester.fir", - "-o", - "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.v", - "-tho", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.v", - "-i", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.fir", - "--syn-top", "UnitTestSuite", - "--harness-top", "TestHarness", - "-faf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.anno.json", - "-tsaof", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.anno.json", - "-tdf", "firrtl_black_box_resource_files.top.f", - "-tsf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.fir", - "-thaof", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.anno.json", - "-hdf", "firrtl_black_box_resource_files.harness.f", - "-thf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.fir", - "--infer-rw", - "--repl-seq-mem", "-c:TestHarness:-o:chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.mems.conf", - "-thconf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.mems.conf", - "-td", "test_run_dir/from-ci", - "-ll", "info" - ) + GenerateTopAndHarness.main( + Array( + "--target-dir", "test_run_dir/generate_top_spec", + "-i", s"$targetDir/BlackBoxFloatTester.fir", + "-o", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.v", + "-tho", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.v", + "-i", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.fir", + "--syn-top", "UnitTestSuite", + "--harness-top", "TestHarness", + "-faf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.anno.json", + "-tsaof", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.anno.json", + "-tdf", "firrtl_black_box_resource_files.top.f", + "-tsf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.fir", + "-thaof", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.anno.json", + "-hdf", "firrtl_black_box_resource_files.harness.f", + "-thf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.fir", + "--infer-rw", + "--repl-seq-mem", "-c:TestHarness:-o:chipyard.unittest.TestHarness.IceNetUnitTestConfig.top.mems.conf", + "-thconf", "chipyard.unittest.TestHarness.IceNetUnitTestConfig.harness.mems.conf", + "-td", "test_run_dir/from-ci", + "-ll", "info", + "--log-file", logOutputName ) - } -// val output = buffer.toString -// println(output) + ) + + val output = FileUtils.getText(logOutputName) + println(output) + } } diff --git a/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala b/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala deleted file mode 100644 index da8e0acb..00000000 --- a/src/test/scala/barstools/tapeout/transforms/NoFileProblem.scala +++ /dev/null @@ -1,51 +0,0 @@ -//// SPDX-License-Identifier: Apache-2.0 -// -//package barstools.tapeout.transforms -// -//import firrtl.AnnotationSeq -//import firrtl.options.{Shell, Stage, StageMain} -//import firrtl.stage.{FirrtlCli, FirrtlStage} -//import logger.Logger.OutputCaptor -//import logger.{LazyLogging, LogLevel, Logger} -//import org.scalatest.freespec.AnyFreeSpec -// -//import java.io.{ByteArrayOutputStream, PrintStream} -// -//class NoFileStage extends Stage { -// override val shell: Shell = new Shell(applicationName = "tapeout") with FirrtlCli -// -// override def run(annotations: AnnotationSeq): AnnotationSeq = { -// Logger.makeScope(annotations) { -// val annos = new FirrtlStage().execute(Array.empty, annotations) -// } -// annotations -// } -//} -// -//class NoFileGenerator(annotationSeq: AnnotationSeq) extends LazyLogging { -// -//} -// -//object NoFileGenerator extends StageMain(new NoFileStage) -// -//class NoFileProblem extends AnyFreeSpec { -// // "should fail in a way that discloses missing file" - { -// // (new NoFileStage).execute(Array("-i", "jackalope"), Seq.empty) -// // } -// -// "should fail in a way that discloses missing file with output capture" in { -// val buffer = new ByteArrayOutputStream() -// Console.withOut(new PrintStream(buffer)) { -// NoFileGenerator.main(Array("-i", "jackalope", "-ll", "info")) -// } -// println(buffer.toString) -// } -// -// "don't uses Console.withOut" in { -// val captor = new OutputCaptor -// Logger.setOutput(captor.printStream) -// Logger.setLevel(getClass.getName, LogLevel.Info) -// NoFileGenerator.main(Array("-i", "jackalope", "-ll", "info")) -// println(captor.getOutputAsString) -// } -//}