Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixing aspect generation #2309

Merged
merged 3 commits into from
Feb 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// See LICENSE.Berkeley for license details.

import sbt.complete._
import sbt.complete.DefaultParsers._
import xerial.sbt.pack._
import sys.process._
import scala.sys.process._

enablePlugins(PackPlugin)

Expand All @@ -16,6 +14,7 @@ lazy val commonSettings = Seq(
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
libraryDependencies ++= Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value),
libraryDependencies ++= Seq("org.json4s" %% "json4s-jackson" % "3.6.1"),
libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.0.8" % "test"),
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Expand Down
33 changes: 0 additions & 33 deletions src/main/scala/stage/phases/GenerateFirrtl.scala

This file was deleted.

33 changes: 20 additions & 13 deletions src/main/scala/stage/phases/GenerateFirrtlAnnos.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,41 @@

package freechips.rocketchip.stage.phases

import java.io.{File, FileWriter}

import chisel3.stage.ChiselCircuitAnnotation
import chisel3.stage.phases.Elaborate
import chisel3.stage.phases.{Convert, Elaborate, MaybeAspectPhase}
import firrtl.AnnotationSeq
import firrtl.annotations.JsonProtocol
import firrtl.annotations.{Annotation, DeletedAnnotation, JsonProtocol}
import firrtl.options.Viewer.view
import firrtl.options.{Phase, PreservesAll, StageOptions}
import firrtl.options.{Phase, PreservesAll, StageOptions, TargetDirAnnotation, Unserializable}
import freechips.rocketchip.stage.RocketChipOptions
import freechips.rocketchip.util.HasRocketChipStageUtils

/** Writes FIRRTL annotations into a file */
class GenerateFirrtlAnnos extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {

override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
override val prerequisites = Seq(classOf[Checks], classOf[Elaborate], classOf[Convert], classOf[MaybeAspectPhase])

override def transform(annotations: AnnotationSeq): AnnotationSeq = {
val targetDir = view[StageOptions](annotations).targetDir
val file = new File(targetDir, s"${view[RocketChipOptions](annotations).longName.get}.anno.json")
val fileName = s"${view[RocketChipOptions](annotations).longName.get}.anno.json"

val annos = scala.collection.mutable.Buffer[Annotation]()
annotations.flatMap {
case a: ChiselCircuitAnnotation =>
val af = new FileWriter(file)
af.write(JsonProtocol.serialize(a.circuit.annotations.map(_.toFirrtl)))
af.close()
case a: Unserializable =>
Some(a)
case a: TargetDirAnnotation =>
/** Don't serialize, in case of downstream FIRRTL call */
Some(a)
case a @ DeletedAnnotation(_, _: Unserializable) =>
/** [[DeletedAnnotation]]s of unserializable annotations cannot be serialized */
Some(a)
case a =>
annos += a
Some(a)
case a => Some(a)
}

writeOutputFile(targetDir, fileName, JsonProtocol.serialize(annos))

annotations
}

}
3 changes: 2 additions & 1 deletion src/main/scala/stage/phases/GenerateROMs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package freechips.rocketchip.stage.phases

import chisel3.stage.ChiselCircuitAnnotation
import chisel3.stage.phases.Elaborate
import chisel3.stage.phases.{Convert, Elaborate}
import firrtl.AnnotationSeq
import firrtl.options.{Phase, PreservesAll, StageOptions}
import firrtl.options.Viewer.view
Expand All @@ -14,6 +14,7 @@ import freechips.rocketchip.util.HasRocketChipStageUtils
class GenerateROMs extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {

override val prerequisites = Seq(classOf[Checks], classOf[Elaborate])
override val dependents = Seq(classOf[Convert])

override def transform(annotations: AnnotationSeq): AnnotationSeq = {
val targetDir = view[StageOptions](annotations).targetDir
Expand Down
23 changes: 23 additions & 0 deletions src/main/scala/stage/phases/TransformAnnotations.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// See LICENSE.SiFive for license details.

package freechips.rocketchip.stage.phases

import chisel3.stage.ChiselOutputFileAnnotation
import chisel3.stage.phases.Emitter
import firrtl.AnnotationSeq
import firrtl.options.Viewer.view
import firrtl.options.{Phase, PreservesAll}
import freechips.rocketchip.stage.RocketChipOptions
import freechips.rocketchip.util.HasRocketChipStageUtils

/** Transforms RocketChipAnnotations into those used by other stages */
class TransformAnnotations extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {

override val prerequisites = Seq(classOf[Checks])
override val dependents = Seq(classOf[Emitter])

override def transform(annotations: AnnotationSeq): AnnotationSeq = {
/** Construct output file annotation for emission */
new ChiselOutputFileAnnotation(view[RocketChipOptions](annotations).longName.get) +: annotations
}
}
8 changes: 6 additions & 2 deletions src/main/scala/system/RocketChipStageGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ class RocketChipStage extends ChiselStage with PreservesAll[Phase] {
override val shell = new Shell("rocket-chip") with RocketChipCli with ChiselCli with FirrtlCli
override val targets: Seq[PhaseDependency] = Seq(
classOf[freechips.rocketchip.stage.phases.Checks],
classOf[freechips.rocketchip.stage.phases.TransformAnnotations],
classOf[freechips.rocketchip.stage.phases.PreElaboration],
classOf[chisel3.stage.phases.Checks],
classOf[chisel3.stage.phases.Elaborate],
classOf[freechips.rocketchip.stage.phases.GenerateROMs],
classOf[chisel3.stage.phases.AddImplicitOutputFile],
classOf[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
classOf[chisel3.stage.phases.MaybeAspectPhase],
classOf[freechips.rocketchip.stage.phases.GenerateFirrtl],
classOf[chisel3.stage.phases.Emitter],
classOf[chisel3.stage.phases.Convert],
classOf[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos],
classOf[freechips.rocketchip.stage.phases.AddDefaultTests],
classOf[freechips.rocketchip.stage.phases.GenerateTestSuiteMakefrags],
classOf[freechips.rocketchip.stage.phases.GenerateROMs],
classOf[freechips.rocketchip.stage.phases.GenerateArtefacts],
)

Expand Down
44 changes: 44 additions & 0 deletions src/test/scala/generatorTests/StageGeneratorSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// See LICENSE.SiFive for license details.

package generatorTests

import java.io.File

import chisel3.aop.injecting.InjectingAspect
import chisel3._
import firrtl.options.TargetDirAnnotation
import freechips.rocketchip.stage.{ConfigsAnnotation, TopModuleAnnotation}
import freechips.rocketchip.system.{RocketChipStage, TestHarness}
import org.scalatest.FlatSpec

/** run via SBT with
* > testOnly generatorTests.StageGeneratorSpec
*
* Output can be viewed in the testbuild directory. The wire named "hello" should show up in the generated
* *.anno.json file.
*/
class StageGeneratorSpec extends FlatSpec {

val dummyAspect = InjectingAspect(
{dut: TestHarness => Seq(dut.dut)},
{dut: freechips.rocketchip.system.ExampleRocketSystemModuleImp[freechips.rocketchip.system.ExampleRocketSystem] =>
val dummyWire = Wire(UInt(3.W)).suggestName("hello")
dummyWire := 5.U
dontTouch(dummyWire)
}
)

"Test" should "pass" in {
val dirName = System.getProperty("user.dir") + "/testbuild"
val dir = new File(dirName)
if (!dir.exists()) dir.mkdirs()

new RocketChipStage().run(Seq(
new TargetDirAnnotation(dirName),
new TopModuleAnnotation(Class.forName("freechips.rocketchip.system.TestHarness")),
new ConfigsAnnotation(Seq("freechips.rocketchip.system.DefaultConfig")),
dummyAspect
))
}

}