Skip to content

Commit

Permalink
[plugin] Disable BundleComponent by default, add option to enable
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkoenig committed Mar 13, 2021
1 parent a8d3238 commit 3bea616
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
2 changes: 2 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ lazy val chisel = (project in file(".")).
mimaPreviousArtifacts := Set(),
libraryDependencies += defaultVersions("treadle") % "test",
scalacOptions in Test ++= Seq("-language:reflectiveCalls"),
// Only used in Test for 3.4.x, used in Compile in 3.5
scalacOptions in Test += "-P:chiselplugin:useBundlePlugin",
scalacOptions in Compile in doc ++= Seq(
"-diagrams",
"-groups",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import scala.tools.nsc.symtab.Flags
import scala.tools.nsc.transform.TypingTransformers

// TODO This component could also implement val elements in Bundles
private[plugin] class BundleComponent(val global: Global) extends PluginComponent with TypingTransformers {
private[plugin] class BundleComponent(val global: Global, arguments: ChiselPluginArguments)
extends PluginComponent
with TypingTransformers {
import global._

val phaseName: String = "chiselbundlephase"
Expand All @@ -23,8 +25,17 @@ private[plugin] class BundleComponent(val global: Global) extends PluginComponen
// This plugin doesn't work on Scala 2.11 nor Scala 3. Rather than complicate the sbt build flow,
// instead we just check the version and if its an early Scala version, the plugin does nothing
val scalaVersion = scala.util.Properties.versionNumberString.split('.')
if (scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12) {
val scalaVersionOk = scalaVersion(0).toInt == 2 && scalaVersion(1).toInt >= 12
if (scalaVersionOk && arguments.useBundlePlugin) {
unit.body = new MyTypingTransformer(unit).transform(unit.body)
} else {
val reason = if (!scalaVersionOk) {
s"invalid Scala version '${scala.util.Properties.versionNumberString}'"
} else {
s"not enabled via '${arguments.useBundlePluginFullOpt}'"
}
// Enable this with scalacOption '-Ylog:chiselbundlephase'
global.log(s"Skipping BundleComponent on account of $reason.")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,32 @@ import scala.tools.nsc
import nsc.Global
import nsc.plugins.{Plugin, PluginComponent}

private[plugin] case class ChiselPluginArguments(var useBundlePlugin: Boolean = false) {
def useBundlePluginOpt = "useBundlePlugin"
def useBundlePluginFullOpt = s"-P:chiselplugin:$useBundlePluginOpt"
}

// The plugin to be run by the Scala compiler during compilation of Chisel code
class ChiselPlugin(val global: Global) extends Plugin {
val name = "chiselplugin"
val description = "Plugin for Chisel 3 Hardware Description Language"
private val arguments = ChiselPluginArguments()
val components: List[PluginComponent] = List[PluginComponent](
new ChiselComponent(global),
new BundleComponent(global)
new BundleComponent(global, arguments)
)

override def init(options: List[String], error: String => Unit): Boolean = {
for (option <- options) {
if (option == arguments.useBundlePluginOpt) {
arguments.useBundlePlugin = true
} else {
error(s"Option not understood: '$option'")
}
}
true
}


}

21 changes: 19 additions & 2 deletions src/test/scala/chiselTests/AutoClonetypeSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package chiselTests

import chisel3._
import chisel3.testers.TestUtils
import chisel3.util.QueueIO

class BundleWithIntArg(val i: Int) extends Bundle {
val out = UInt(i.W)
Expand Down Expand Up @@ -65,6 +66,11 @@ class NestedAnonymousBundle extends Bundle {
// Not necessarily good style (and not necessarily recommended), but allowed to preserve compatibility.
class BundleWithArgumentField(val x: Data, val y: Data) extends Bundle

// Needs to be top-level so that reflective autoclonetype works
class InheritingBundle extends QueueIO(UInt(8.W), 8) {
val error = Output(Bool())
}

// TODO all `.suggestNames` are due to https://github.com/chipsalliance/chisel3/issues/1802
class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
val usingPlugin: Boolean = TestUtils.usingPlugin
Expand Down Expand Up @@ -253,10 +259,21 @@ class AutoClonetypeSpec extends ChiselFlatSpec with Utils {
elaborate(new MyModule(3))
}

behavior of "Compiler Plugin Autoclonetype"

// Necessary test for 3.4.x, but we will break this (for non-plugin users) in 3.5
it should "NOT break code that extends chisel3.util Bundles (whether they use the plugin or not)" in {
class MyModule extends MultiIOModule {
val io = IO(new InheritingBundle)
io.deq <> io.enq
io.count := 0.U
io.error := true.B
}
elaborate(new MyModule)
}

// New tests from the plugin
if (usingPlugin) {
behavior of "Compiler Plugin Autoclonetype"

it should "support Bundles with non-val parameters" in {
class MyBundle(i: Int) extends Bundle {
val foo = UInt(i.W)
Expand Down

0 comments on commit 3bea616

Please sign in to comment.