diff --git a/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala b/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala index 44aa37cf3b..448d6b1a00 100644 --- a/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala +++ b/src/main/scala/barstools/tapeout/transforms/GenerateTopAndHarness.scala @@ -15,6 +15,12 @@ import logger.LazyLogging // and a second to remove those modules to generate the test harness private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogging { val outAnno: Option[String] = annotations.collectFirst { case OutAnnoAnnotation(s) => s } + val harnessConf: Option[String] = annotations.collectFirst { case HarnessConfAnnotation(h) => h } + + val annoFiles: List[String] = annotations.flatMap { + case InputAnnotationFileAnnotation(f) => Some(f) + case _ => None + }.toList // Dump firrtl and annotation files protected def dump( @@ -49,6 +55,31 @@ private class GenerateTopAndHarness(annotations: AnnotationSeq) extends LazyLogg throw new Exception(s"executeTop failed while executing FIRRTL!\n") } } + + // Top and harness generation + def executeTopAndHarness(): Unit = { + executeTop() + + // 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 + .filterNot(_.isInstanceOf[OutputFileAnnotation]) + .map { + case ReplSeqMemAnnotation(i, _) => ReplSeqMemAnnotation(i, harnessConf.get) + case anno => anno + } + + val annos = new FirrtlStage().execute(Array.empty, generatorAnnotations) + annos.collectFirst { case FirrtlCircuitAnnotation(circuit) => circuit } match { + case Some(circuit) => + dump(circuit, annos) + case _ => + throw new Exception(s"executeTop failed while executing FIRRTL!\n") + } + } } -object GenerateTop extends StageMain(new TapeoutStage) +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/stage/TapeoutStage.scala b/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala index 2ba0bdb892..9de5e04f56 100644 --- a/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala +++ b/src/main/scala/barstools/tapeout/transforms/stage/TapeoutStage.scala @@ -27,23 +27,41 @@ object OutAnnoAnnotation extends HasShellOptions { ) } +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( OutAnnoAnnotation, + HarnessConfAnnotation, ).foreach(_.addOptions(parser)) } -class TapeoutStage extends Stage { +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) - generator.executeTop() + if (doHarness) { + generator.executeTopAndHarness() + } else { + generator.executeTop() + } } annotations }