diff --git a/.github/workflows/run-ci.yml b/.github/workflows/run-ci.yml index 492f417a..78b6b9e6 100644 --- a/.github/workflows/run-ci.yml +++ b/.github/workflows/run-ci.yml @@ -24,3 +24,16 @@ jobs: run: git submodule update --init - name: Test run: sbt test + + doc: + name: Documentation and formatting + runs-on: ubuntu-latest + steps: + - name: Check Formatting + run: sbt scalafmtCheckAll + + all_test_passed: + name: "all tests passed" + runs-on: ubuntu-latest + steps: + - run: echo Success diff --git a/src/main/scala/barstools/macros/CostMetric.scala b/src/main/scala/barstools/macros/CostMetric.scala index a6111d2e..8b0d0413 100644 --- a/src/main/scala/barstools/macros/CostMetric.scala +++ b/src/main/scala/barstools/macros/CostMetric.scala @@ -128,7 +128,7 @@ object DefaultMetric extends CostMetric with CostMetricCompanion { } val maskPenalty = (memMask, libMask) match { case (None, Some(m)) => 0.001 - case (_, _) => 0 + case (_, _) => 0 } val depthCost = math.ceil(mem.src.depth.toDouble / lib.src.depth.toDouble) val widthCost = math.ceil(memWidth.toDouble / lib.src.width.toDouble) diff --git a/src/main/scala/barstools/macros/MacroCompiler.scala b/src/main/scala/barstools/macros/MacroCompiler.scala index ff75d645..5a5804b7 100644 --- a/src/main/scala/barstools/macros/MacroCompiler.scala +++ b/src/main/scala/barstools/macros/MacroCompiler.scala @@ -8,7 +8,7 @@ package barstools.macros import barstools.macros.Utils._ -import firrtl.Utils.{BoolType, one, zero} +import firrtl.Utils.{one, zero, BoolType} import firrtl.annotations._ import firrtl.ir._ import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, Forms, OutputFileAnnotation, RunFirrtlTransformAnnotation} @@ -109,16 +109,16 @@ object MacroCompilerAnnotation { * @param forceSynflops Set of memories to force compiling as flops regardless of the mode */ case class Params( - mem: String, - memFormat: Option[String], - lib: Option[String], - hammerIR: Option[String], - costMetric: CostMetric, - mode: CompilerMode, - useCompiler: Boolean, - forceCompile: Set[String], - forceSynflops: Set[String] - ) extends Serializable + mem: String, + memFormat: Option[String], + lib: Option[String], + hammerIR: Option[String], + costMetric: CostMetric, + mode: CompilerMode, + useCompiler: Boolean, + forceCompile: Set[String], + forceSynflops: Set[String]) + extends Serializable /** Create a MacroCompilerAnnotation. * @param c Top-level circuit name (see class description) @@ -869,8 +869,7 @@ object MacroCompiler extends App { case Some("conf") => filterForSRAM(readConfFromPath(params.get(Macros))).get.map(x => (new Macro(x)).blackbox) case _ => - filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))) - .get + filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get .map(x => (new Macro(x)).blackbox) } diff --git a/src/main/scala/barstools/macros/SynFlops.scala b/src/main/scala/barstools/macros/SynFlops.scala index a6fe32a4..f7245144 100644 --- a/src/main/scala/barstools/macros/SynFlops.scala +++ b/src/main/scala/barstools/macros/SynFlops.scala @@ -3,7 +3,7 @@ package barstools.macros import barstools.macros.Utils._ -import firrtl.Utils.{zero, one} +import firrtl.Utils.{one, zero} import firrtl._ import firrtl.ir._ import firrtl.passes.MemPortUtils.memPortField diff --git a/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index b30d9d41..ef9c5408 100644 --- a/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -13,20 +13,20 @@ import logger.LazyLogging // Requires two phases, one to collect modules below synTop in the hierarchy // and a second to remove those modules to generate the test harness private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogging { - val synTop: Option[String] = annotations.collectFirst { case SynTopAnnotation(s) => s } - val topFir: Option[String] = annotations.collectFirst { case TopFirAnnotation(s) => s } - val harnessFir: Option[String] = annotations.collectFirst { case HarnessFirAnnotation(s) => s } - val topAnnoOut: Option[String] = annotations.collectFirst { case TopAnnoOutAnnotation(s) => s } + val synTop: Option[String] = annotations.collectFirst { case SynTopAnnotation(s) => s } + val topFir: Option[String] = annotations.collectFirst { case TopFirAnnotation(s) => s } + val harnessFir: Option[String] = annotations.collectFirst { case HarnessFirAnnotation(s) => s } + val topAnnoOut: Option[String] = annotations.collectFirst { case TopAnnoOutAnnotation(s) => s } val harnessAnnoOut: Option[String] = annotations.collectFirst { case HarnessAnnoOutAnnotation(s) => s } - val harnessTop: Option[String] = annotations.collectFirst { case HarnessTopAnnotation(h) => h } - val harnessConf: Option[String] = annotations.collectFirst { case HarnessConfAnnotation(h) => h } - val harnessOutput: Option[String] = annotations.collectFirst { case HarnessOutputAnnotation(h) => h } - val topDotfOut: Option[String] = annotations.collectFirst { case TopDotfOutAnnotation(h) => h } + val harnessTop: Option[String] = annotations.collectFirst { case HarnessTopAnnotation(h) => h } + val harnessConf: Option[String] = annotations.collectFirst { case HarnessConfAnnotation(h) => h } + val harnessOutput: Option[String] = annotations.collectFirst { case HarnessOutputAnnotation(h) => h } + val topDotfOut: Option[String] = annotations.collectFirst { case TopDotfOutAnnotation(h) => h } val harnessDotfOut: Option[String] = annotations.collectFirst { case HarnessDotfOutAnnotation(h) => h } val annoFiles: List[String] = annotations.flatMap { case InputAnnotationFileAnnotation(f) => Some(f) - case _ => None + case _ => None }.toList lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) @@ -36,11 +36,11 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg // Dump firrtl and annotation files protected def dump( - circuit: Circuit, - annotations: AnnotationSeq, - firFile: Option[String], - annoFile: Option[String] - ): Unit = { + circuit: Circuit, + annotations: AnnotationSeq, + firFile: Option[String], + annoFile: Option[String] + ): Unit = { firFile.foreach { firPath => val outputFile = new java.io.PrintWriter(firPath) outputFile.write(circuit.serialize) @@ -49,9 +49,9 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg annoFile.foreach { annoPath => val outputFile = new java.io.PrintWriter(annoPath) outputFile.write(JsonProtocol.serialize(annotations.filter(_ match { - case _: DeletedAnnotation => false - case _: EmittedComponent => false - case _: EmittedAnnotation[_] => false + case _: DeletedAnnotation => false + case _: EmittedComponent => false + case _: EmittedAnnotation[_] => false case _: FirrtlCircuitAnnotation => false case _ => true }))) @@ -104,10 +104,10 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg val generatorAnnotations = annotations .filterNot(_.isInstanceOf[OutputFileAnnotation]) .map { - case ReplSeqMemAnnotation(i, _) => ReplSeqMemAnnotation(i, harnessConf.get) - case HarnessOutputAnnotation(s) => OutputFileAnnotation(s) - case anno => anno - } ++ harnessAnnos + case ReplSeqMemAnnotation(i, _) => ReplSeqMemAnnotation(i, harnessConf.get) + case HarnessOutputAnnotation(s) => OutputFileAnnotation(s) + case anno => anno + } ++ harnessAnnos val annos = new FirrtlStage().execute(Array.empty, generatorAnnotations) annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match { @@ -119,7 +119,6 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg } } - object GenerateTop extends StageMain(new TapeoutStage(doHarness = false)) object GenerateTopAndHarness extends StageMain(new TapeoutStage(doHarness = true)) diff --git a/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala b/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala index 82484cce..b027a782 100644 --- a/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala +++ b/src/main/scala/barstools/tapeout/transforms/ReParentCircuit.scala @@ -34,33 +34,42 @@ class ReParentCircuit extends Transform with DependencyAPIMigration { rmap } - val newAnnotations = newTopName.map({ topName => - // Update InstanceTargets and ReferenceTargets - // Yes, these are identical functions, but the copy methods force separate implementations - def updateInstance(t: InstanceTarget): Option[InstanceTarget] = { - val idx = t.path.lastIndexWhere(_._2.value == topName) - if (idx == -1) Some(t.copy(circuit=topName)) else Some(t.copy(circuit=topName, module=topName, path=t.path.drop(idx+1))) - } - def updateReference(t: ReferenceTarget): Option[ReferenceTarget] = { - val idx = t.path.lastIndexWhere(_._2.value == topName) - if (idx == -1) Some(t.copy(circuit=topName)) else Some(t.copy(circuit=topName, module=topName, path=t.path.drop(idx+1))) - } + val newAnnotations = newTopName + .map({ topName => + // Update InstanceTargets and ReferenceTargets + // Yes, these are identical functions, but the copy methods force separate implementations + def updateInstance(t: InstanceTarget): Option[InstanceTarget] = { + val idx = t.path.lastIndexWhere(_._2.value == topName) + if (idx == -1) Some(t.copy(circuit = topName)) + else Some(t.copy(circuit = topName, module = topName, path = t.path.drop(idx + 1))) + } + def updateReference(t: ReferenceTarget): Option[ReferenceTarget] = { + val idx = t.path.lastIndexWhere(_._2.value == topName) + if (idx == -1) Some(t.copy(circuit = topName)) + else Some(t.copy(circuit = topName, module = topName, path = t.path.drop(idx + 1))) + } - AnnotationSeq(state.annotations.toSeq.map({ - case x: SingleTargetAnnotation[InstanceTarget] if x.target.isInstanceOf[InstanceTarget] => - updateInstance(x.target).map(y => x.duplicate(y)) - case x: SingleTargetAnnotation[ReferenceTarget] if x.target.isInstanceOf[ReferenceTarget] => - updateReference(x.target).map(y => x.duplicate(y)) - case x: MultiTargetAnnotation => - val newTargets: Seq[Seq[Option[Target]]] = x.targets.map(_.map({ - case y: InstanceTarget => updateInstance(y) - case y: ReferenceTarget => updateReference(y) - case y => Some(y) - })) - if (newTargets.flatten.forall(_.isDefined)) Some(x.duplicate(newTargets.map(_.map(_.get)))) else None - case x => Some(x) - }).filter(_.isDefined).map(_.get)) - }).getOrElse(state.annotations) + AnnotationSeq( + state.annotations.toSeq + .map({ + case x: SingleTargetAnnotation[InstanceTarget] if x.target.isInstanceOf[InstanceTarget] => + updateInstance(x.target).map(y => x.duplicate(y)) + case x: SingleTargetAnnotation[ReferenceTarget] if x.target.isInstanceOf[ReferenceTarget] => + updateReference(x.target).map(y => x.duplicate(y)) + case x: MultiTargetAnnotation => + val newTargets: Seq[Seq[Option[Target]]] = x.targets.map(_.map({ + case y: InstanceTarget => updateInstance(y) + case y: ReferenceTarget => updateReference(y) + case y => Some(y) + })) + if (newTargets.flatten.forall(_.isDefined)) Some(x.duplicate(newTargets.map(_.map(_.get)))) else None + case x => Some(x) + }) + .filter(_.isDefined) + .map(_.get) + ) + }) + .getOrElse(state.annotations) state.copy(circuit = newCircuit, renames = mainRename, annotations = newAnnotations) } diff --git a/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala b/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala index d6d7b80d..5d1cbc6c 100644 --- a/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala +++ b/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala @@ -23,7 +23,7 @@ class RemoveUnusedModules extends Transform with DependencyAPIMigration { def execute(state: CircuitState): CircuitState = { val modulesByName = state.circuit.modules.map { - case m: Module => (m.name, Some(m)) + case m: Module => (m.name, Some(m)) case m: ExtModule => (m.name, None) }.toMap diff --git a/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala b/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala index 1c50a82e..7bbb046a 100644 --- a/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala +++ b/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala @@ -178,4 +178,3 @@ class TapeoutStage(doHarness: Boolean) extends Stage { annotations } } - diff --git a/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala b/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala index 86bf43de..78d33e10 100644 --- a/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala +++ b/src/main/scala/barstools/tapeout/transforms/utils/FileUtils.scala @@ -2,7 +2,7 @@ package barstools.tapeout.transforms.utils -import chisel3.experimental.{ChiselAnnotation, annotate} +import chisel3.experimental.{annotate, ChiselAnnotation} import firrtl._ import firrtl.annotations._ import firrtl.stage.Forms diff --git a/src/main/scala/mdf/macrolib/Utils.scala b/src/main/scala/mdf/macrolib/Utils.scala index 86d78a24..547f910c 100644 --- a/src/main/scala/mdf/macrolib/Utils.scala +++ b/src/main/scala/mdf/macrolib/Utils.scala @@ -45,7 +45,7 @@ object Utils { } catch { case f: FileNotFoundException => println(s"FILE NOT FOUND $p in dir ${os.pwd}") - throw f + throw f } } } diff --git a/src/test/scala/barstools/macros/CostFunction.scala b/src/test/scala/barstools/macros/CostFunction.scala index ee6c557f..b3d5b46e 100644 --- a/src/test/scala/barstools/macros/CostFunction.scala +++ b/src/test/scala/barstools/macros/CostFunction.scala @@ -2,7 +2,6 @@ package barstools.macros import mdf.macrolib.SRAMMacro - /** Tests to check that the cost function mechanism is working properly. */ /** A test metric that simply favours memories with smaller widths, to test that diff --git a/src/test/scala/barstools/macros/SpecificExamples.scala b/src/test/scala/barstools/macros/SpecificExamples.scala index 1a957199..01d08de7 100644 --- a/src/test/scala/barstools/macros/SpecificExamples.scala +++ b/src/test/scala/barstools/macros/SpecificExamples.scala @@ -187,7 +187,8 @@ class BOOMTest extends MacroCompilerSpec with HasSRAMGenerator { override val libPrefix = "src/test/resources" - val memSRAMs = mdf.macrolib.Utils.readMDFFromString(""" + val memSRAMs = mdf.macrolib.Utils + .readMDFFromString(""" [ { "type" : "sram", "name" : "_T_182_ext", diff --git a/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala index b5c03c44..b953d170 100644 --- a/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala @@ -42,10 +42,10 @@ class ToBeMadeExternal extends MultiIOModule { class GenerateExampleTester extends MultiIOModule { val success = IO(Output(Bool())) - val mod = Module(new GenerateExampleModule) + val mod = Module(new GenerateExampleModule) mod.in := 1.U - val mod2 = Module(new ToBeMadeExternal) + val mod2 = Module(new ToBeMadeExternal) mod2.in := 1.U val reg = RegInit(0.U(8.W)) @@ -91,10 +91,14 @@ class GenerateSpec extends AnyFreeSpec { val targetDir = "test_run_dir/generate_spec" generateTestData(targetDir) - GenerateTop.main(Array( - "-i", s"$targetDir/GenerateExampleTester.fir", - "-o", s"$targetDir/GenerateExampleTester.v" - )) - new File(s"$targetDir/GenerateExampleTester.v").exists() should be (true) + GenerateTop.main( + Array( + "-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 a7a165a4..d967c8df 100644 --- a/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -19,9 +19,12 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { GenerateTopAndHarness.main( Array( - "-i", s"$targetDir/ExampleModuleNeedsResetInverted.fir", - "-ll", "info", - "--log-file", transformListName + "-i", + s"$targetDir/ExampleModuleNeedsResetInverted.fir", + "-ll", + "info", + "--log-file", + transformListName ) ) @@ -47,26 +50,45 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { 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", + "--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 + "--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 ) ) diff --git a/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala b/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala index d18053f0..5d4c4ab3 100644 --- a/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala +++ b/src/test/scala/barstools/tapeout/transforms/ResetInverterSpec.scala @@ -22,7 +22,8 @@ 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, Array("--target-dir", "test_run_dir/reset_n_spec")) + 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)")