From afcdcc6c2d3a1fdf23a339c7ff6406457270175b Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 9 Feb 2021 14:04:24 -0800 Subject: [PATCH 1/9] Modernize deprecated Chisel/Firrtl constructs - Build out a stage for tapeout - Refactor annotation construction - Create a CLI handler - create a TapeOutStage - Remove outputForm reference from EnumerateModules - New GenerateTopAndHarness is fresh implmentation of Generate.scala - GenerateTopSpec is a work in progress --- .../tapeout/transforms/EnumerateModules.scala | 3 +- .../tapeout/transforms/Generate.scala | 548 +++++++++--------- .../transforms/GenerateTopAndHarness.scala | 127 ++++ .../transforms/RemoveUnusedModules.scala | 2 +- .../transforms/stage/TapeoutStage.scala | 181 ++++++ .../tapeout/transforms/GenerateTopSpec.scala | 42 ++ 6 files changed, 626 insertions(+), 277 deletions(-) create mode 100644 tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala create mode 100644 tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala create mode 100644 tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala index 182b0071..47dae82c 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/EnumerateModules.scala @@ -35,7 +35,6 @@ class EnumerateModules(enumerate: (Module) => Unit) def transforms: Seq[Transform] = Seq(new EnumerateModulesPass(enumerate)) def execute(state: CircuitState): CircuitState = { - val ret = runTransforms(state) - CircuitState(ret.circuit, outputForm, ret.annotations, ret.renames) + runTransforms(state) } } diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala index 01ea56e0..e20f72e5 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala @@ -1,274 +1,274 @@ -package barstools.tapeout.transforms - -import firrtl._ -import firrtl.annotations._ -import firrtl.ir._ -import firrtl.passes.memlib.ReplSeqMemAnnotation -import firrtl.stage.FirrtlCircuitAnnotation -import firrtl.transforms.BlackBoxResourceFileNameAnno -import logger.LazyLogging - -trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions => - var tapeoutOptions = TapeoutOptions() - - parser.note("tapeout options") - - parser - .opt[String]("harness-o") - .abbr("tho") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessOutput = Some(x) - ) - } - .text { - "use this to generate a harness at " - } - - parser - .opt[String]("syn-top") - .abbr("tst") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - synTop = Some(x) - ) - } - .text { - "use this to set synTop" - } - - parser - .opt[String]("top-fir") - .abbr("tsf") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - topFir = Some(x) - ) - } - .text { - "use this to set topFir" - } - - parser - .opt[String]("top-anno-out") - .abbr("tsaof") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - topAnnoOut = Some(x) - ) - } - .text { - "use this to set topAnnoOut" - } - - parser - .opt[String]("top-dotf-out") - .abbr("tdf") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - topDotfOut = Some(x) - ) - } - .text { - "use this to set the filename for the top resource .f file" - } - - parser - .opt[String]("harness-top") - .abbr("tht") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessTop = Some(x) - ) - } - .text { - "use this to set harnessTop" - } - - parser - .opt[String]("harness-fir") - .abbr("thf") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessFir = Some(x) - ) - } - .text { - "use this to set harnessFir" - } - - parser - .opt[String]("harness-anno-out") - .abbr("thaof") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessAnnoOut = Some(x) - ) - } - .text { - "use this to set harnessAnnoOut" - } - - parser - .opt[String]("harness-dotf-out") - .abbr("hdf") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessDotfOut = Some(x) - ) - } - .text { - "use this to set the filename for the harness resource .f file" - } - - parser - .opt[String]("harness-conf") - .abbr("thconf") - .valueName("") - .foreach { x => - tapeoutOptions = tapeoutOptions.copy( - harnessConf = Some(x) - ) - } - .text { - "use this to set the harness conf file location" - } - -} - -case class TapeoutOptions( - harnessOutput: Option[String] = None, - synTop: Option[String] = None, - topFir: Option[String] = None, - topAnnoOut: Option[String] = None, - topDotfOut: Option[String] = None, - harnessTop: Option[String] = None, - harnessFir: Option[String] = None, - harnessAnnoOut: Option[String] = None, - harnessDotfOut: Option[String] = None, - harnessConf: Option[String] = None) - extends LazyLogging - -// Requires two phases, one to collect modules below synTop in the hierarchy -// and a second to remove those modules to generate the test harness -sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => - lazy val optionsManager = { - val optionsManager = new ExecutionOptionsManager("tapeout") with HasFirrtlOptions with HasTapeoutOptions - if (!optionsManager.parse(args)) { - throw new Exception("Error parsing options!") - } - optionsManager - } - lazy val tapeoutOptions = optionsManager.tapeoutOptions - // Tapeout options - lazy val synTop = tapeoutOptions.synTop - lazy val harnessTop = tapeoutOptions.harnessTop - lazy val firrtlOptions = optionsManager.firrtlOptions - // FIRRTL options - lazy val annoFiles = firrtlOptions.annotationFileNames - - // order is determined by DependencyAPIMigration - val topTransforms = Seq( - new ReParentCircuit, - new RemoveUnusedModules - ) - - lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) - - lazy val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ - tapeoutOptions.topDotfOut.map(BlackBoxResourceFileNameAnno(_)) - - lazy val topOptions = firrtlOptions.copy( - customTransforms = firrtlOptions.customTransforms ++ topTransforms, - annotations = firrtlOptions.annotations ++ topAnnos - ) - - // order is determined by DependencyAPIMigration - val harnessTransforms = Seq( - new ConvertToExtMod, - new RemoveUnusedModules, - new AvoidExtModuleCollisions, - new AddSuffixToModuleNames - ) - - // Dump firrtl and annotation files - protected def dump(res: FirrtlExecutionSuccess, firFile: Option[String], annoFile: Option[String]): Unit = { - firFile.foreach { firPath => - val outputFile = new java.io.PrintWriter(firPath) - outputFile.write(res.circuitState.circuit.serialize) - outputFile.close() - } - annoFile.foreach { annoPath => - val outputFile = new java.io.PrintWriter(annoPath) - outputFile.write(JsonProtocol.serialize(res.circuitState.annotations.filter(_ match { - case da: DeletedAnnotation => false - case ec: EmittedComponent => false - case ea: EmittedAnnotation[_] => false - case fca: FirrtlCircuitAnnotation => false - case _ => true - }))) - outputFile.close() - } - } - - // Top Generation - protected def executeTop(): Seq[ExtModule] = { - optionsManager.firrtlOptions = topOptions - val result = firrtl.Driver.execute(optionsManager) - result match { - case x: FirrtlExecutionSuccess => - dump(x, tapeoutOptions.topFir, tapeoutOptions.topAnnoOut) - x.circuitState.circuit.modules.collect { case e: ExtModule => e } - case x => - throw new Exception(s"executeTop failed while executing FIRRTL!\n${x}") - } - } - - // Top and harness generation - protected def executeTopAndHarness(): Unit = { - // Execute top and get list of ExtModules to avoid collisions - val topExtModules = executeTop() - - val harnessAnnos = - tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++ - harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ - synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+ - LinkExtModulesAnnotation(topExtModules) - - // For harness run, change some firrtlOptions (below) for harness phase - // customTransforms: setup harness transforms, add AvoidExtModuleCollisions - // outputFileNameOverride: change to harnessOutput - // conf file must change to harnessConf by mapping annotations - optionsManager.firrtlOptions = firrtlOptions.copy( - customTransforms = firrtlOptions.customTransforms ++ harnessTransforms, - outputFileNameOverride = tapeoutOptions.harnessOutput.get, - annotations = firrtlOptions.annotations.map({ - case ReplSeqMemAnnotation(i, o) => ReplSeqMemAnnotation(i, tapeoutOptions.harnessConf.get) - case a => a - }) ++ harnessAnnos - ) - val harnessResult = firrtl.Driver.execute(optionsManager) - harnessResult match { - case x: FirrtlExecutionSuccess => dump(x, tapeoutOptions.harnessFir, tapeoutOptions.harnessAnnoOut) - case x => throw new Exception(s"executeHarness failed while executing FIRRTL!\n${x}") - } - } -} - -object GenerateTop extends App with GenerateTopAndHarnessApp { - // Only need a single phase to generate the top module - executeTop() -} - -object GenerateTopAndHarness extends App with GenerateTopAndHarnessApp { - executeTopAndHarness() -} +//package barstools.tapeout.transforms +// +//import firrtl._ +//import firrtl.annotations._ +//import firrtl.ir._ +//import firrtl.passes.memlib.ReplSeqMemAnnotation +//import firrtl.stage.FirrtlCircuitAnnotation +//import firrtl.transforms.BlackBoxResourceFileNameAnno +//import logger.LazyLogging +// +//trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions => +// var tapeoutOptions = TapeoutOptions() +// +// parser.note("tapeout options") +// +// parser +// .opt[String]("harness-o") +// .abbr("tho") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessOutput = Some(x) +// ) +// } +// .text { +// "use this to generate a harness at " +// } +// +// parser +// .opt[String]("syn-top") +// .abbr("tst") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// synTop = Some(x) +// ) +// } +// .text { +// "use this to set synTop" +// } +// +// parser +// .opt[String]("top-fir") +// .abbr("tsf") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// topFir = Some(x) +// ) +// } +// .text { +// "use this to set topFir" +// } +// +// parser +// .opt[String]("top-anno-out") +// .abbr("tsaof") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// topAnnoOut = Some(x) +// ) +// } +// .text { +// "use this to set topAnnoOut" +// } +// +// parser +// .opt[String]("top-dotf-out") +// .abbr("tdf") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// topDotfOut = Some(x) +// ) +// } +// .text { +// "use this to set the filename for the top resource .f file" +// } +// +// parser +// .opt[String]("harness-top") +// .abbr("tht") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessTop = Some(x) +// ) +// } +// .text { +// "use this to set harnessTop" +// } +// +// parser +// .opt[String]("harness-fir") +// .abbr("thf") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessFir = Some(x) +// ) +// } +// .text { +// "use this to set harnessFir" +// } +// +// parser +// .opt[String]("harness-anno-out") +// .abbr("thaof") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessAnnoOut = Some(x) +// ) +// } +// .text { +// "use this to set harnessAnnoOut" +// } +// +// parser +// .opt[String]("harness-dotf-out") +// .abbr("hdf") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessDotfOut = Some(x) +// ) +// } +// .text { +// "use this to set the filename for the harness resource .f file" +// } +// +// parser +// .opt[String]("harness-conf") +// .abbr("thconf") +// .valueName("") +// .foreach { x => +// tapeoutOptions = tapeoutOptions.copy( +// harnessConf = Some(x) +// ) +// } +// .text { +// "use this to set the harness conf file location" +// } +// +//} +// +//case class TapeoutOptions( +// harnessOutput: Option[String] = None, +// synTop: Option[String] = None, +// topFir: Option[String] = None, +// topAnnoOut: Option[String] = None, +// topDotfOut: Option[String] = None, +// harnessTop: Option[String] = None, +// harnessFir: Option[String] = None, +// harnessAnnoOut: Option[String] = None, +// harnessDotfOut: Option[String] = None, +// harnessConf: Option[String] = None) +// extends LazyLogging +// +//// Requires two phases, one to collect modules below synTop in the hierarchy +//// and a second to remove those modules to generate the test harness +//sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => +// lazy val optionsManager = { +// val optionsManager = new ExecutionOptionsManager("tapeout") with HasFirrtlOptions with HasTapeoutOptions +// if (!optionsManager.parse(args)) { +// throw new Exception("Error parsing options!") +// } +// optionsManager +// } +// lazy val tapeoutOptions = optionsManager.tapeoutOptions +// // Tapeout options +// lazy val synTop = tapeoutOptions.synTop +// lazy val harnessTop = tapeoutOptions.harnessTop +// lazy val firrtlOptions = optionsManager.firrtlOptions +// // FIRRTL options +// lazy val annoFiles = firrtlOptions.annotationFileNames +// +// // order is determined by DependencyAPIMigration +// val topTransforms = Seq( +// new ReParentCircuit, +// new RemoveUnusedModules +// ) +// +// lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) +// +// lazy val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ +// tapeoutOptions.topDotfOut.map(BlackBoxResourceFileNameAnno(_)) +// +// lazy val topOptions = firrtlOptions.copy( +// customTransforms = firrtlOptions.customTransforms ++ topTransforms, +// annotations = firrtlOptions.annotations ++ topAnnos +// ) +// +// // order is determined by DependencyAPIMigration +// val harnessTransforms = Seq( +// new ConvertToExtMod, +// new RemoveUnusedModules, +// new AvoidExtModuleCollisions, +// new AddSuffixToModuleNames +// ) +// +// // Dump firrtl and annotation files +// protected def dump(res: FirrtlExecutionSuccess, firFile: Option[String], annoFile: Option[String]): Unit = { +// firFile.foreach { firPath => +// val outputFile = new java.io.PrintWriter(firPath) +// outputFile.write(res.circuitState.circuit.serialize) +// outputFile.close() +// } +// annoFile.foreach { annoPath => +// val outputFile = new java.io.PrintWriter(annoPath) +// outputFile.write(JsonProtocol.serialize(res.circuitState.annotations.filter(_ match { +// case da: DeletedAnnotation => false +// case ec: EmittedComponent => false +// case ea: EmittedAnnotation[_] => false +// case fca: FirrtlCircuitAnnotation => false +// case _ => true +// }))) +// outputFile.close() +// } +// } +// +// // Top Generation +// protected def executeTop(): Seq[ExtModule] = { +// optionsManager.firrtlOptions = topOptions +// val result = firrtl.Driver.execute(optionsManager) +// result match { +// case x: FirrtlExecutionSuccess => +// dump(x, tapeoutOptions.topFir, tapeoutOptions.topAnnoOut) +// x.circuitState.circuit.modules.collect { case e: ExtModule => e } +// case x => +// throw new Exception(s"executeTop failed while executing FIRRTL!\n${x}") +// } +// } +// +// // Top and harness generation +// protected def executeTopAndHarness(): Unit = { +// // Execute top and get list of ExtModules to avoid collisions +// val topExtModules = executeTop() +// +// val harnessAnnos = +// tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++ +// harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ +// synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+ +// LinkExtModulesAnnotation(topExtModules) +// +// // For harness run, change some firrtlOptions (below) for harness phase +// // customTransforms: setup harness transforms, add AvoidExtModuleCollisions +// // outputFileNameOverride: change to harnessOutput +// // conf file must change to harnessConf by mapping annotations +// optionsManager.firrtlOptions = firrtlOptions.copy( +// customTransforms = firrtlOptions.customTransforms ++ harnessTransforms, +// outputFileNameOverride = tapeoutOptions.harnessOutput.get, +// annotations = firrtlOptions.annotations.map({ +// case ReplSeqMemAnnotation(i, o) => ReplSeqMemAnnotation(i, tapeoutOptions.harnessConf.get) +// case a => a +// }) ++ harnessAnnos +// ) +// val harnessResult = firrtl.Driver.execute(optionsManager) +// harnessResult match { +// case x: FirrtlExecutionSuccess => dump(x, tapeoutOptions.harnessFir, tapeoutOptions.harnessAnnoOut) +// case x => throw new Exception(s"executeHarness failed while executing FIRRTL!\n${x}") +// } +// } +//} +// +////object GenerateTop extends App with GenerateTopAndHarnessApp { +//// // Only need a single phase to generate the top module +//// executeTop() +////} +//// +////object GenerateTopAndHarness extends App with GenerateTopAndHarnessApp { +//// executeTopAndHarness() +////} diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala new file mode 100644 index 00000000..108d3c13 --- /dev/null +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -0,0 +1,127 @@ +package barstools.tapeout.transforms + +import barstools.tapeout.transforms.stage._ +import firrtl._ +import firrtl.annotations._ +import firrtl.ir._ +import firrtl.options.{Dependency, InputAnnotationFileAnnotation, StageMain} +import firrtl.passes.memlib.ReplSeqMemAnnotation +import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage, OutputFileAnnotation, RunFirrtlTransformAnnotation} +import firrtl.transforms.BlackBoxResourceFileNameAnno +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 topAnnoOut: Option[String] = annotations.collectFirst { case TopAnnoOutAnnotation(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 harnessDotfOut: Option[String] = annotations.collectFirst { case HarnessDotfOutAnnotation(h) => h } + + val annoFiles: List[String] = annotations.flatMap { + case InputAnnotationFileAnnotation(f) => Some(f) + case _ => None + }.toList + + // order is determined by DependencyAPIMigration + val topTransforms = Seq( + new ReParentCircuit, + new RemoveUnusedModules + ) + + lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) + + val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ + topDotfOut.map(BlackBoxResourceFileNameAnno) + + // order is determined by DependencyAPIMigration + val harnessTransforms = Seq( + new ConvertToExtMod, + new RemoveUnusedModules, + new AvoidExtModuleCollisions, + new AddSuffixToModuleNames + ) + + // Dump firrtl and annotation files + protected def dump( + 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) + outputFile.close() + } + 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 _: FirrtlCircuitAnnotation => false + case _ => true + }))) + outputFile.close() + } + } + + // Top Generation + def executeTop(): Seq[ExtModule] = { + val annos = new FirrtlStage().execute(Array.empty, annotations) + annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match { + case Some(circuit) => + dump(circuit, annos, topFir, topAnnoOut) + circuit.modules.collect { case e: ExtModule => e } + case _ => + throw new Exception(s"executeTop failed while executing FIRRTL!\n") + } + } + + // Top and harness generation + def executeTopAndHarness(): Unit = { + // Execute top and get list of ExtModules to avoid collisions + val topExtModules = executeTop() + + val harnessAnnos = + harnessDotfOut.map(BlackBoxResourceFileNameAnno).toSeq ++ + harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ + synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) ++ + Seq( + LinkExtModulesAnnotation(topExtModules), + RunFirrtlTransformAnnotation(Dependency[ConvertToExtMod]), + RunFirrtlTransformAnnotation(Dependency[RemoveUnusedModules]), + RunFirrtlTransformAnnotation(Dependency[AvoidExtModuleCollisions]), + RunFirrtlTransformAnnotation(Dependency[AddSuffixToModuleNames]) + ) + + // For harness run, change some firrtlOptions (below) for harness phase + // customTransforms: setup harness transforms, add AvoidExtModuleCollisions + // outputFileNameOverride: change to harnessOutput + // conf file must change to harnessConf by mapping annotations + + val generatorAnnotations = annotations.map { + 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 { + case Some(circuit) => + dump(circuit, annos, topFir, topAnnoOut) + case _ => + throw new Exception(s"executeTop failed while executing FIRRTL!\n") + } + } +} + + +object GenerateTop extends StageMain(new TapeoutStage(doHarness = false)) + +object GenerateTopAndHarness extends StageMain(new TapeoutStage(doHarness = true)) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala index 5d1cbc6c..d6d7b80d 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/RemoveUnusedModules.scala +++ b/tapeout/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/tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala new file mode 100644 index 00000000..1c50a82e --- /dev/null +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala @@ -0,0 +1,181 @@ +// See LICENSE for license details. + +package barstools.tapeout.transforms.stage + +import barstools.tapeout.transforms.GenerateTopAndHarness +import chisel3.stage.ChiselCli +import firrtl.AnnotationSeq +import firrtl.annotations.{Annotation, NoTargetAnnotation} +import firrtl.options.{HasShellOptions, Shell, ShellOption, Stage, Unserializable} +import firrtl.stage.FirrtlCli +import logger.Logger + +sealed trait TapeoutOption extends Unserializable { + this: Annotation => +} + +case class HarnessOutputAnnotation(harnessOutput: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessOutputAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-o", + shortOption = Some("tho"), + toAnnotationSeq = (s: String) => Seq(HarnessOutputAnnotation(s)), + helpText = "use this to generate a harness at " + ) + ) +} + +case class SynTopAnnotation(synTop: String) extends NoTargetAnnotation with TapeoutOption + +object SynTopAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "syn-top", + shortOption = Some("tst"), + toAnnotationSeq = (s: String) => Seq(SynTopAnnotation(s)), + helpText = "use this to set synTop" + ) + ) +} + +case class TopFirAnnotation(topFir: String) extends NoTargetAnnotation with TapeoutOption + +object TopFirAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "top-fir", + shortOption = Some("tsf"), + toAnnotationSeq = (s: String) => Seq(TopFirAnnotation(s)), + helpText = "use this to set topFir" + ) + ) +} + +case class TopAnnoOutAnnotation(topAnnoOut: String) extends NoTargetAnnotation with TapeoutOption + +object TopAnnoOutAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "top-anno-out", + shortOption = Some("tsaof"), + toAnnotationSeq = (s: String) => Seq(TopAnnoOutAnnotation(s)), + helpText = "use this to set topAnnoOut" + ) + ) +} + +case class TopDotfOutAnnotation(topDotfOut: String) extends NoTargetAnnotation with TapeoutOption + +object TopDotfOutAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "top-dotf-out", + shortOption = Some("tdf"), + toAnnotationSeq = (s: String) => Seq(TopDotfOutAnnotation(s)), + helpText = "use this to set the filename for the top resource .f file" + ) + ) +} + +case class HarnessTopAnnotation(harnessTop: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessTopAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-top", + shortOption = Some("tht"), + toAnnotationSeq = (s: String) => Seq(HarnessTopAnnotation(s)), + helpText = "use this to set harnessTop" + ) + ) +} + +case class HarnessFirAnnotation(harnessFir: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessFirAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-fir", + shortOption = Some("thf"), + toAnnotationSeq = (s: String) => Seq(HarnessFirAnnotation(s)), + helpText = "use this to set harnessFir" + ) + ) +} + +case class HarnessAnnoOutAnnotation(harnessAnnoOut: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessAnnoOutAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-anno-out", + shortOption = Some("thaof"), + toAnnotationSeq = (s: String) => Seq(HarnessAnnoOutAnnotation(s)), + helpText = "use this to set harnessAnnoOut" + ) + ) +} + +case class HarnessDotfOutAnnotation(harnessDotfOut: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessDotfOutAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-dotf-out", + shortOption = Some("hdf"), + toAnnotationSeq = (s: String) => Seq(HarnessDotfOutAnnotation(s)), + helpText = "use this to set the filename for the harness resource .f file" + ) + ) +} + +case class HarnessConfAnnotation(harnessConf: String) extends NoTargetAnnotation with TapeoutOption + +object HarnessConfAnnotation extends HasShellOptions { + val options: Seq[ShellOption[_]] = Seq( + new ShellOption[String]( + longOption = "harness-conf", + shortOption = Some("thconf"), + toAnnotationSeq = (s: String) => Seq(HarnessConfAnnotation(s)), + helpText = "use this to set the harness conf file location" + ) + ) +} + +trait TapeoutCli { + this: Shell => + parser.note("Tapeout specific options") + + Seq( + HarnessOutputAnnotation, + SynTopAnnotation, + TopFirAnnotation, + TopAnnoOutAnnotation, + TopDotfOutAnnotation, + HarnessTopAnnotation, + HarnessFirAnnotation, + HarnessAnnoOutAnnotation, + HarnessDotfOutAnnotation, + HarnessConfAnnotation + ).foreach(_.addOptions(parser)) +} + +class TapeoutStage(doHarness: Boolean) extends Stage { + override val shell: Shell = new Shell(applicationName = "tapeout") with TapeoutCli with ChiselCli with FirrtlCli + + override def run(annotations: AnnotationSeq): AnnotationSeq = { + Logger.makeScope(annotations) { + val generator = new GenerateTopAndHarness(annotations) + + if (doHarness) { + generator.executeTopAndHarness() + } else { + generator.executeTop() + } + } + annotations + } +} + diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala new file mode 100644 index 00000000..db84230d --- /dev/null +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 + +package barstools.tapeout.transforms + +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +import java.io.{ByteArrayOutputStream, PrintStream} + +class GenerateTopSpec extends AnyFreeSpec with Matchers { + "Generate top and harness" - { + "should include the following transforms" in { + val buffer = new ByteArrayOutputStream() + Console.withOut(new PrintStream(buffer)) { + GenerateTopAndHarness.main(Array("-i", "ExampleModuleNeedsResetInverted.fir", "-ll", "info")) + } + val output = buffer.toString + output should include("barstools.tapeout.transforms.AddSuffixToModuleNames") + output should include("barstools.tapeout.transforms.ConvertToExtMod") + output should include("barstools.tapeout.transforms.RemoveUnusedModules") + output should include("barstools.tapeout.transforms.AvoidExtModuleCollisions") + println(output) + } + } + + "generate harness should " in { + val buffer = new ByteArrayOutputStream() + Console.withOut(new PrintStream(buffer)) { + GenerateTopAndHarness.main( + Array( + "--target-dir", "test_run_dir/generate_top_spec", + "-i", "/Users/chick/Adept/dev/masters/barstools/tapeout/src/test/resources/BlackBoxFloatTester.fir", +// "-X", "low", +// "-ll", "info", +// "--help" + ) + ) + } + val output = buffer.toString + println(output) + } +} From 5616b9d68fe6579b93bc7dae5d4dc2bb6ecc19a7 Mon Sep 17 00:00:00 2001 From: chick Date: Sun, 14 Feb 2021 13:25:16 -0800 Subject: [PATCH 2/9] - remove unused harnessTransforms - --- .../transforms/GenerateTopAndHarness.scala | 9 +- .../tapeout/transforms/GenerateSpec.scala | 93 +++++++++++++++++++ .../tapeout/transforms/GenerateTopSpec.scala | 47 ++++++++-- 3 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index 108d3c13..35e364c0 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -38,14 +38,6 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ topDotfOut.map(BlackBoxResourceFileNameAnno) - // order is determined by DependencyAPIMigration - val harnessTransforms = Seq( - new ConvertToExtMod, - new RemoveUnusedModules, - new AvoidExtModuleCollisions, - new AddSuffixToModuleNames - ) - // Dump firrtl and annotation files protected def dump( circuit: Circuit, @@ -88,6 +80,7 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg // Execute top and get list of ExtModules to avoid collisions val topExtModules = executeTop() + // order is determined by DependencyAPIMigration val harnessAnnos = harnessDotfOut.map(BlackBoxResourceFileNameAnno).toSeq ++ harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala new file mode 100644 index 00000000..cefd9759 --- /dev/null +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateSpec.scala @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 + +package barstools.tapeout.transforms + +import chisel3._ +import chisel3.experimental.ExtModule +import chisel3.stage.ChiselStage +import firrtl.FileUtils +import org.scalatest.freespec.AnyFreeSpec + +import java.io.{File, PrintWriter} + +class BlackBoxInverter extends ExtModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) +} + +class GenerateExampleModule extends MultiIOModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + + val inverter = Module(new BlackBoxInverter) + inverter.in := in + val inverted = inverter.out + + val reg = RegInit(0.U(8.W)) + reg := reg + inverted.asUInt + out := reg +} + +class ToBeMadeExternal extends MultiIOModule { + val in = IO(Input(Bool())) + val out = IO(Output(Bool())) + + val reg = RegInit(0.U(8.W)) + reg := reg + in.asUInt + 2.U + out := reg +} + +class GenerateExampleTester extends MultiIOModule { + val success = IO(Output(Bool())) + + val mod = Module(new GenerateExampleModule) + mod.in := 1.U + + val mod2 = Module(new ToBeMadeExternal) + mod2.in := 1.U + + val reg = RegInit(0.U(8.W)) + reg := reg + mod.out + mod2.out + + success := reg === 100.U + + when(reg === 100.U) { + stop() + } +} + +class GenerateSpec extends AnyFreeSpec { + "generate test data" in { + 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)) + printWriter.close() + + 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() + + + } + + "generate top test" in { + val sourceDir = "test_run_dir/generate_spec_source" + val targetDir = "test_run_dir/generate_spec" + + GenerateTop.main(Array( + "-i", s"$sourceDir/GenerateExampleTester.fir", + "-o", s"$targetDir/GenerateExampleTester.v" + )) + } +} diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala index db84230d..25ddbd9b 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -2,10 +2,11 @@ package barstools.tapeout.transforms +import firrtl.FileUtils import org.scalatest.freespec.AnyFreeSpec import org.scalatest.matchers.should.Matchers -import java.io.{ByteArrayOutputStream, PrintStream} +import java.io.{ByteArrayOutputStream, File, PrintStream, PrintWriter} class GenerateTopSpec extends AnyFreeSpec with Matchers { "Generate top and harness" - { @@ -24,19 +25,45 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { } "generate harness should " in { - val buffer = new ByteArrayOutputStream() - Console.withOut(new PrintStream(buffer)) { + 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 printWriter = new PrintWriter(new File(s"$targetDir/BlackBoxFloatTester.fir")) + printWriter.write(input.mkString("\n")) + printWriter.close() + + 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", "/Users/chick/Adept/dev/masters/barstools/tapeout/src/test/resources/BlackBoxFloatTester.fir", -// "-X", "low", -// "-ll", "info", -// "--help" + "-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" ) ) } - val output = buffer.toString - println(output) - } +// val output = buffer.toString +// println(output) } From c052f793927923943e98748cd3ad2ed3e9dcbe69 Mon Sep 17 00:00:00 2001 From: chick Date: Sun, 14 Feb 2021 14:44:36 -0800 Subject: [PATCH 3/9] - Add rocketchip dependency to try and fix run problem in chipyard sims/vcs --- build.sbt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index d8840865..c78e638c 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,8 @@ val defaultVersions = Map( "chisel3" -> "3.4.+", - "chisel-iotesters" -> "1.5.+" + "chisel-iotesters" -> "1.5.+", + "rocketchip" -> "1.2.+" ) lazy val commonSettings = Seq( @@ -10,7 +11,7 @@ lazy val commonSettings = Seq( version := "0.4-SNAPSHOT", scalaVersion := "2.12.10", scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Xsource:2.11"), - libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { + libraryDependencies ++= Seq("chisel3","chisel-iotesters", "rocketchip").map { dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }, libraryDependencies ++= Seq( From 055800898de2fbebcd5751d071492f49c5a41a9b Mon Sep 17 00:00:00 2001 From: chick Date: Sun, 14 Feb 2021 16:18:04 -0800 Subject: [PATCH 4/9] - Don't carry over OutputFileAnnotaton to the harness phase of GenerateTopAndHarness --- .../barstools/tapeout/transforms/GenerateTopAndHarness.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index 35e364c0..dd9a5ac1 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -98,7 +98,9 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg // outputFileNameOverride: change to harnessOutput // conf file must change to harnessConf by mapping annotations - val generatorAnnotations = annotations.map { + val generatorAnnotations = annotations + .filterNot(_.isInstanceOf[OutputFileAnnotation]) + .map { case ReplSeqMemAnnotation(i, _) => ReplSeqMemAnnotation(i, harnessConf.get) case HarnessOutputAnnotation(s) => OutputFileAnnotation(s) case anno => anno From 5040e0dcbfce7d274f3b6407aa188fa7efdf75b1 Mon Sep 17 00:00:00 2001 From: chick Date: Sun, 14 Feb 2021 16:54:25 -0800 Subject: [PATCH 5/9] - Pull rocket dependency back out --- build.sbt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c78e638c..d8840865 100644 --- a/build.sbt +++ b/build.sbt @@ -2,8 +2,7 @@ val defaultVersions = Map( "chisel3" -> "3.4.+", - "chisel-iotesters" -> "1.5.+", - "rocketchip" -> "1.2.+" + "chisel-iotesters" -> "1.5.+" ) lazy val commonSettings = Seq( @@ -11,7 +10,7 @@ lazy val commonSettings = Seq( version := "0.4-SNAPSHOT", scalaVersion := "2.12.10", scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Xsource:2.11"), - libraryDependencies ++= Seq("chisel3","chisel-iotesters", "rocketchip").map { + libraryDependencies ++= Seq("chisel3","chisel-iotesters").map { dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }, libraryDependencies ++= Seq( From 7c2d7abbe1cd30ec3a97da0961ea5800abf91143 Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 16 Feb 2021 14:43:58 -0800 Subject: [PATCH 6/9] Add in missing transforms --- .../barstools/tapeout/transforms/GenerateTopAndHarness.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index dd9a5ac1..7a35c4d9 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -65,7 +65,10 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg // Top Generation def executeTop(): Seq[ExtModule] = { - val annos = new FirrtlStage().execute(Array.empty, annotations) + val annos = new FirrtlStage().execute(Array.empty, annotations ++ Seq( + RunFirrtlTransformAnnotation(Dependency[ReParentCircuit]), + RunFirrtlTransformAnnotation(Dependency[RemoveUnusedModules]) + )) annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match { case Some(circuit) => dump(circuit, annos, topFir, topAnnoOut) From bbc8800840b32a4fb53487519a0f9223a198a352 Mon Sep 17 00:00:00 2001 From: chick Date: Tue, 16 Feb 2021 16:29:41 -0800 Subject: [PATCH 7/9] Get topAnnos into the mix --- .../transforms/GenerateTopAndHarness.scala | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index 7a35c4d9..4cb19592 100644 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/tapeout/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -27,12 +27,6 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg case _ => None }.toList - // order is determined by DependencyAPIMigration - val topTransforms = Seq( - new ReParentCircuit, - new RemoveUnusedModules - ) - lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ @@ -65,10 +59,14 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg // Top Generation def executeTop(): Seq[ExtModule] = { - val annos = new FirrtlStage().execute(Array.empty, annotations ++ Seq( - RunFirrtlTransformAnnotation(Dependency[ReParentCircuit]), - RunFirrtlTransformAnnotation(Dependency[RemoveUnusedModules]) - )) + val annos = new FirrtlStage().execute( + Array.empty, + annotations ++ Seq( + RunFirrtlTransformAnnotation(Dependency[ReParentCircuit]), + RunFirrtlTransformAnnotation(Dependency[RemoveUnusedModules]) + ) ++ + topAnnos + ) annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match { case Some(circuit) => dump(circuit, annos, topFir, topAnnoOut) From 8a93d8b2d7cd29f113b903bf2bd4094cd69acf2b Mon Sep 17 00:00:00 2001 From: chick Date: Fri, 19 Feb 2021 14:48:48 -0800 Subject: [PATCH 8/9] Ignore GenerateTopAndHarness test for now --- .../scala/barstools/tapeout/transforms/GenerateTopSpec.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala index 25ddbd9b..02afa79a 100644 --- a/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala +++ b/tapeout/src/test/scala/barstools/tapeout/transforms/GenerateTopSpec.scala @@ -20,11 +20,10 @@ class GenerateTopSpec extends AnyFreeSpec with Matchers { output should include("barstools.tapeout.transforms.ConvertToExtMod") output should include("barstools.tapeout.transforms.RemoveUnusedModules") output should include("barstools.tapeout.transforms.AvoidExtModuleCollisions") - println(output) } } - "generate harness should " in { + "generate harness should " ignore { val targetDir = "test_run_dir/generate_top_spec" FileUtils.makeDirectory(targetDir) From a3711c4e19911b57b21bdcf8d459d19795f3201d Mon Sep 17 00:00:00 2001 From: chick Date: Mon, 22 Feb 2021 11:39:47 -0800 Subject: [PATCH 9/9] Remove fully commented out original file Generate.scala --- .../tapeout/transforms/Generate.scala | 274 ------------------ 1 file changed, 274 deletions(-) delete mode 100644 tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala diff --git a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala b/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala deleted file mode 100644 index e20f72e5..00000000 --- a/tapeout/src/main/scala/barstools/tapeout/transforms/Generate.scala +++ /dev/null @@ -1,274 +0,0 @@ -//package barstools.tapeout.transforms -// -//import firrtl._ -//import firrtl.annotations._ -//import firrtl.ir._ -//import firrtl.passes.memlib.ReplSeqMemAnnotation -//import firrtl.stage.FirrtlCircuitAnnotation -//import firrtl.transforms.BlackBoxResourceFileNameAnno -//import logger.LazyLogging -// -//trait HasTapeoutOptions { self: ExecutionOptionsManager with HasFirrtlOptions => -// var tapeoutOptions = TapeoutOptions() -// -// parser.note("tapeout options") -// -// parser -// .opt[String]("harness-o") -// .abbr("tho") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessOutput = Some(x) -// ) -// } -// .text { -// "use this to generate a harness at " -// } -// -// parser -// .opt[String]("syn-top") -// .abbr("tst") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// synTop = Some(x) -// ) -// } -// .text { -// "use this to set synTop" -// } -// -// parser -// .opt[String]("top-fir") -// .abbr("tsf") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// topFir = Some(x) -// ) -// } -// .text { -// "use this to set topFir" -// } -// -// parser -// .opt[String]("top-anno-out") -// .abbr("tsaof") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// topAnnoOut = Some(x) -// ) -// } -// .text { -// "use this to set topAnnoOut" -// } -// -// parser -// .opt[String]("top-dotf-out") -// .abbr("tdf") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// topDotfOut = Some(x) -// ) -// } -// .text { -// "use this to set the filename for the top resource .f file" -// } -// -// parser -// .opt[String]("harness-top") -// .abbr("tht") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessTop = Some(x) -// ) -// } -// .text { -// "use this to set harnessTop" -// } -// -// parser -// .opt[String]("harness-fir") -// .abbr("thf") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessFir = Some(x) -// ) -// } -// .text { -// "use this to set harnessFir" -// } -// -// parser -// .opt[String]("harness-anno-out") -// .abbr("thaof") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessAnnoOut = Some(x) -// ) -// } -// .text { -// "use this to set harnessAnnoOut" -// } -// -// parser -// .opt[String]("harness-dotf-out") -// .abbr("hdf") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessDotfOut = Some(x) -// ) -// } -// .text { -// "use this to set the filename for the harness resource .f file" -// } -// -// parser -// .opt[String]("harness-conf") -// .abbr("thconf") -// .valueName("") -// .foreach { x => -// tapeoutOptions = tapeoutOptions.copy( -// harnessConf = Some(x) -// ) -// } -// .text { -// "use this to set the harness conf file location" -// } -// -//} -// -//case class TapeoutOptions( -// harnessOutput: Option[String] = None, -// synTop: Option[String] = None, -// topFir: Option[String] = None, -// topAnnoOut: Option[String] = None, -// topDotfOut: Option[String] = None, -// harnessTop: Option[String] = None, -// harnessFir: Option[String] = None, -// harnessAnnoOut: Option[String] = None, -// harnessDotfOut: Option[String] = None, -// harnessConf: Option[String] = None) -// extends LazyLogging -// -//// Requires two phases, one to collect modules below synTop in the hierarchy -//// and a second to remove those modules to generate the test harness -//sealed trait GenerateTopAndHarnessApp extends LazyLogging { this: App => -// lazy val optionsManager = { -// val optionsManager = new ExecutionOptionsManager("tapeout") with HasFirrtlOptions with HasTapeoutOptions -// if (!optionsManager.parse(args)) { -// throw new Exception("Error parsing options!") -// } -// optionsManager -// } -// lazy val tapeoutOptions = optionsManager.tapeoutOptions -// // Tapeout options -// lazy val synTop = tapeoutOptions.synTop -// lazy val harnessTop = tapeoutOptions.harnessTop -// lazy val firrtlOptions = optionsManager.firrtlOptions -// // FIRRTL options -// lazy val annoFiles = firrtlOptions.annotationFileNames -// -// // order is determined by DependencyAPIMigration -// val topTransforms = Seq( -// new ReParentCircuit, -// new RemoveUnusedModules -// ) -// -// lazy val rootCircuitTarget = CircuitTarget(harnessTop.get) -// -// lazy val topAnnos = synTop.map(st => ReParentCircuitAnnotation(rootCircuitTarget.module(st))) ++ -// tapeoutOptions.topDotfOut.map(BlackBoxResourceFileNameAnno(_)) -// -// lazy val topOptions = firrtlOptions.copy( -// customTransforms = firrtlOptions.customTransforms ++ topTransforms, -// annotations = firrtlOptions.annotations ++ topAnnos -// ) -// -// // order is determined by DependencyAPIMigration -// val harnessTransforms = Seq( -// new ConvertToExtMod, -// new RemoveUnusedModules, -// new AvoidExtModuleCollisions, -// new AddSuffixToModuleNames -// ) -// -// // Dump firrtl and annotation files -// protected def dump(res: FirrtlExecutionSuccess, firFile: Option[String], annoFile: Option[String]): Unit = { -// firFile.foreach { firPath => -// val outputFile = new java.io.PrintWriter(firPath) -// outputFile.write(res.circuitState.circuit.serialize) -// outputFile.close() -// } -// annoFile.foreach { annoPath => -// val outputFile = new java.io.PrintWriter(annoPath) -// outputFile.write(JsonProtocol.serialize(res.circuitState.annotations.filter(_ match { -// case da: DeletedAnnotation => false -// case ec: EmittedComponent => false -// case ea: EmittedAnnotation[_] => false -// case fca: FirrtlCircuitAnnotation => false -// case _ => true -// }))) -// outputFile.close() -// } -// } -// -// // Top Generation -// protected def executeTop(): Seq[ExtModule] = { -// optionsManager.firrtlOptions = topOptions -// val result = firrtl.Driver.execute(optionsManager) -// result match { -// case x: FirrtlExecutionSuccess => -// dump(x, tapeoutOptions.topFir, tapeoutOptions.topAnnoOut) -// x.circuitState.circuit.modules.collect { case e: ExtModule => e } -// case x => -// throw new Exception(s"executeTop failed while executing FIRRTL!\n${x}") -// } -// } -// -// // Top and harness generation -// protected def executeTopAndHarness(): Unit = { -// // Execute top and get list of ExtModules to avoid collisions -// val topExtModules = executeTop() -// -// val harnessAnnos = -// tapeoutOptions.harnessDotfOut.map(BlackBoxResourceFileNameAnno(_)).toSeq ++ -// harnessTop.map(ht => ModuleNameSuffixAnnotation(rootCircuitTarget, s"_in${ht}")) ++ -// synTop.map(st => ConvertToExtModAnnotation(rootCircuitTarget.module(st))) :+ -// LinkExtModulesAnnotation(topExtModules) -// -// // For harness run, change some firrtlOptions (below) for harness phase -// // customTransforms: setup harness transforms, add AvoidExtModuleCollisions -// // outputFileNameOverride: change to harnessOutput -// // conf file must change to harnessConf by mapping annotations -// optionsManager.firrtlOptions = firrtlOptions.copy( -// customTransforms = firrtlOptions.customTransforms ++ harnessTransforms, -// outputFileNameOverride = tapeoutOptions.harnessOutput.get, -// annotations = firrtlOptions.annotations.map({ -// case ReplSeqMemAnnotation(i, o) => ReplSeqMemAnnotation(i, tapeoutOptions.harnessConf.get) -// case a => a -// }) ++ harnessAnnos -// ) -// val harnessResult = firrtl.Driver.execute(optionsManager) -// harnessResult match { -// case x: FirrtlExecutionSuccess => dump(x, tapeoutOptions.harnessFir, tapeoutOptions.harnessAnnoOut) -// case x => throw new Exception(s"executeHarness failed while executing FIRRTL!\n${x}") -// } -// } -//} -// -////object GenerateTop extends App with GenerateTopAndHarnessApp { -//// // Only need a single phase to generate the top module -//// executeTop() -////} -//// -////object GenerateTopAndHarness extends App with GenerateTopAndHarnessApp { -//// executeTopAndHarness() -////}