Skip to content

Commit

Permalink
Merge branch '3.3.x' into 3.3-release
Browse files Browse the repository at this point in the history
  • Loading branch information
chick committed Jun 25, 2020
2 parents 3a67a02 + cc2971f commit 2f9f12a
Show file tree
Hide file tree
Showing 78 changed files with 1,081 additions and 672 deletions.
2 changes: 1 addition & 1 deletion SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Note that both [PeekPokeTester](https://github.com/freechipsproject/chisel-teste
3. In the Verilator repository directory, check out a known good version:
```
git pull
git checkout verilator_4_016
git checkout v4.016
```

4. In the Verilator repository directory, build and install:
Expand Down
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ lazy val macros = (project in file("macros")).
settings(name := "chisel3-macros").
settings(commonSettings: _*).
settings(publishSettings: _*).
settings(mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-macros" % "3.3.0"))
settings(mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-macros" % "3.3.1"))

lazy val core = (project in file("core")).
settings(commonSettings: _*).
Expand All @@ -143,7 +143,7 @@ lazy val core = (project in file("core")).
"-Xlint:infer-any"
// "-Xlint:missing-interpolator"
),
mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-core" % "3.3.0")
mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3-core" % "3.3.1")
).
dependsOn(macros)

Expand All @@ -165,7 +165,7 @@ lazy val chisel = (project in file(".")).
dependsOn(core).
aggregate(macros, core).
settings(
mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3" % "3.3.0"),
mimaPreviousArtifacts := Set("edu.berkeley.cs" %% "chisel3" % "3.3.1"),
scalacOptions in Test ++= Seq("-language:reflectiveCalls"),
scalacOptions in Compile in doc ++= Seq(
"-diagrams",
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/scala/chisel3/core/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ package object core {

// These provide temporary compatibility for those who foolishly imported from chisel3.core
@deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
" Use chisel3.RawModule instead. This alias will be removed in 3.3.", "since the beginning of time")
" Use chisel3.RawModule instead. This alias will be removed in 3.4.", "since the beginning of time")
type RawModule = chisel3.RawModule
@deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
"Use chisel3.MultiIOModule instead. This alias will be removed in 3.3.", "since the beginning of time")
"Use chisel3.MultiIOModule instead. This alias will be removed in 3.4.", "since the beginning of time")
type MultiIOModule = chisel3.MultiIOModule
@deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
" Use chisel3.RawModule instead. This alias will be removed in 3.3.", "since the beginning of time")
" Use chisel3.RawModule instead. This alias will be removed in 3.4.", "since the beginning of time")
type UserModule = chisel3.RawModule
@deprecated("Avoid importing from chisel3.core, these are not public APIs and may change at any time. " +
"Use chisel3.MultiIOModule instead. This alias will be removed in 3.3.", "since the beginning of time")
"Use chisel3.MultiIOModule instead. This alias will be removed in 3.4.", "since the beginning of time")
type ImplicitModule = chisel3.MultiIOModule

@deprecated("Use the version in chisel3._", "3.2")
Expand Down
8 changes: 7 additions & 1 deletion core/src/main/scala/chisel3/internal/Builder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,13 @@ private[chisel3] object Builder {
}

def errors: ErrorLog = dynamicContext.errors
def error(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.error(m)
def error(m: => String): Unit = {
if (dynamicContextVar.value.isDefined) {
errors.error(m)
} else {
throwException(m)
}
}
def warning(m: => String): Unit = if (dynamicContextVar.value.isDefined) errors.warning(m)
def deprecated(m: => String, location: Option[String] = None): Unit =
if (dynamicContextVar.value.isDefined) errors.deprecated(m, location)
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/chisel3/Driver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ trait BackendCompilationUtilities extends FirrtlBackendCompilationUtilities {
/**
* This family provides return values from the chisel3 and possibly firrtl compile steps
*/
@deprecated("This will be removed in Chisel 3.5", "Chisel3 3.4")
trait ChiselExecutionResult

/**
Expand All @@ -69,6 +70,7 @@ trait ChiselExecutionResult
* @param emitted The emitted Chirrrl text
* @param firrtlResultOption Optional Firrtl result, @see freechipsproject/firrtl for details
*/
@deprecated("This will be removed in Chisel 3.5", "Chisel 3.4")
case class ChiselExecutionSuccess(
circuitOption: Option[Circuit],
emitted: String,
Expand All @@ -80,6 +82,7 @@ case class ChiselExecutionSuccess(
*
* @param message A clue might be provided here.
*/
@deprecated("This will be removed in Chisel 3.5", "Chisel 3.4")
case class ChiselExecutionFailure(message: String) extends ChiselExecutionResult

@deprecated("Please switch to chisel3.stage.ChiselStage. Driver will be removed in 3.4.", "3.2.4")
Expand Down
21 changes: 17 additions & 4 deletions src/main/scala/chisel3/compatibility.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* while moving to the more standard package naming convention `chisel3` (lowercase c).
*/
import chisel3._ // required for implicit conversions.
import chisel3.stage.{ChiselCircuitAnnotation, ChiselOutputFileAnnotation, ChiselStage, phases}

package object Chisel { // scalastyle:ignore package.object.name number.of.types number.of.methods
import chisel3.internal.firrtl.Width
Expand Down Expand Up @@ -400,14 +401,26 @@ package object Chisel { // scalastyle:ignore package.object.name number.of.t
object chiselMain {
import java.io.File

private var target_dir: Option[String] = None

private def parseArgs(args: Array[String]): Unit = {
for (i <- args.indices) {
if (args(i) == "--targetDir") {
target_dir = Some(args(i + 1))
}
}
}

def apply[T <: Module](args: Array[String], gen: () => T): Unit =
Predef.assert(false, "No more chiselMain in Chisel3")

def run[T <: Module] (args: Array[String], gen: () => T): Unit = {
val circuit = Driver.elaborate(gen)
Driver.parseArgs(args)
val output_file = new File(Driver.targetDir + "/" + circuit.name + ".fir")
Driver.dumpFirrtl(circuit, Option(output_file))
val circuit = ChiselStage.elaborate(gen())
parseArgs(args)
val output_file = new File(target_dir.getOrElse(new File(".").getCanonicalPath) + "/" + circuit.name + ".fir")

(new phases.Emitter).transform(Seq(ChiselCircuitAnnotation(circuit),
ChiselOutputFileAnnotation(output_file.toString)))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/chisel3/internal/firrtl/Emitter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ private class Emitter(circuit: Circuit) {
private def withIndent(f: => Unit) { indent(); f; unindent() }

private val res = new StringBuilder()
res ++= s";${Driver.chiselVersionString}\n"
res ++= s";${BuildInfo.toString}\n"
res ++= s"circuit ${circuit.name} : "
withIndent { circuit.components.foreach(c => res ++= emit(c)) }
res ++= newline
Expand Down
7 changes: 6 additions & 1 deletion src/main/scala/chisel3/stage/ChiselAnnotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,12 @@ object ChiselGeneratorAnnotation extends HasShellOptions {
/** Stores a Chisel Circuit
* @param circuit a Chisel Circuit
*/
case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption
case class ChiselCircuitAnnotation(circuit: Circuit) extends NoTargetAnnotation with ChiselOption {
/* Caching the hashCode for a large circuit is necessary due to repeated queries.
* Not caching the hashCode will cause severe performance degredations for large [[Circuit]]s.
*/
override lazy val hashCode: Int = circuit.hashCode
}

case class ChiselOutputFileAnnotation(file: String) extends NoTargetAnnotation with ChiselOption

Expand Down
68 changes: 35 additions & 33 deletions src/main/scala/chisel3/testers/TesterDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,53 @@ import java.io._

import chisel3.aop.Aspect
import chisel3.experimental.RunFirrtlTransform
import chisel3.stage.phases.AspectPhase
import chisel3.stage.{ChiselCircuitAnnotation, ChiselStage, DesignAnnotation}
import chisel3.stage.phases.{AspectPhase, Convert, Elaborate, Emitter}
import chisel3.stage.{
ChiselCircuitAnnotation,
ChiselGeneratorAnnotation,
ChiselOutputFileAnnotation,
ChiselStage,
DesignAnnotation
}
import firrtl.{Driver => _, _}
import firrtl.options.{Dependency, Phase, PhaseManager}
import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlStage}
import firrtl.transforms.BlackBoxSourceHelper.writeResourceToDirectory

object TesterDriver extends BackendCompilationUtilities {

/** Set the target directory to the name of the top module after elaboration */
final class AddImplicitTesterDirectory extends Phase {
override def prerequisites = Seq(Dependency[Elaborate])
override def optionalPrerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq(Dependency[Emitter])
override def invalidates(a: Phase) = false

override def transform(a: AnnotationSeq) = a.flatMap {
case a@ ChiselCircuitAnnotation(circuit) =>
Seq(a, TargetDirAnnotation(
firrtl.util.BackendCompilationUtilities.createTestDirectory(circuit.name)
.getAbsolutePath
.toString))
case a => Seq(a)
}
}

/** For use with modules that should successfully be elaborated by the
* frontend, and which can be turned into executables with assertions. */
def execute(t: () => BasicTester,
additionalVResources: Seq[String] = Seq(),
annotations: AnnotationSeq = Seq()
): Boolean = {
// Invoke the chisel compiler to get the circuit's IR
val (circuit, dut) = new chisel3.stage.ChiselGeneratorAnnotation(finishWrapper(t)).elaborate.toSeq match {
case Seq(ChiselCircuitAnnotation(cir), d:DesignAnnotation[_]) => (cir, d)
}

// Set up a bunch of file handlers based on a random temp filename,
// plus the quirks of Verilator's naming conventions
val target = circuit.name
val pm = new PhaseManager(
targets = Seq(Dependency[AddImplicitTesterDirectory],
Dependency[Emitter],
Dependency[Convert]))

val path = createTestDirectory(target)
val fname = new File(path, target)
val annotationsx = pm.transform(ChiselGeneratorAnnotation(finishWrapper(t)) +: annotations)

// For now, dump the IR out to a file
Driver.dumpFirrtl(circuit, Some(new File(fname.toString + ".fir")))
val firrtlCircuit = Driver.toFirrtl(circuit)
val target: String = annotationsx.collectFirst { case FirrtlCircuitAnnotation(cir) => cir.main }.get
val path = annotationsx.collectFirst { case TargetDirAnnotation(dir) => dir }.map(new File(_)).get

// Copy CPP harness and other Verilog sources from resources into files
val cppHarness = new File(path, "top.cpp")
Expand All @@ -47,24 +66,7 @@ object TesterDriver extends BackendCompilationUtilities {
writeResourceToDirectory(name, path)
})

// Compile firrtl
val transforms = circuit.annotations.collect {
case anno: RunFirrtlTransform => anno.transformClass
}.distinct
.filterNot(_ == classOf[Transform])
.map { transformClass: Class[_ <: Transform] => transformClass.newInstance() }
val newAnnotations = circuit.annotations.map(_.toFirrtl).toList ++ annotations ++ Seq(dut)
val resolvedAnnotations = new AspectPhase().transform(newAnnotations).toList
val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions {
commonOptions = CommonOptions(topName = target, targetDirName = path.getAbsolutePath)
firrtlOptions = FirrtlExecutionOptions(compilerName = "verilog", annotations = resolvedAnnotations,
customTransforms = transforms,
firrtlCircuit = Some(firrtlCircuit))
}
firrtl.Driver.execute(optionsManager) match {
case _: FirrtlExecutionFailure => return false
case _ =>
}
(new FirrtlStage).execute(Array("--compiler", "verilog"), annotationsx)

// Use sys.Process to invoke a bunch of backend stuff, then run the resulting exe
if ((verilogToCpp(target, path, additionalVFiles, cppHarness) #&&
Expand Down
9 changes: 9 additions & 0 deletions src/main/scala/chisel3/util/Decoupled.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,15 @@ object Decoupled
/** Wraps some Data with a DecoupledIO interface. */
def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen)

// TODO: use a proper empty data type, this is a quick and dirty solution
private final class EmptyBundle extends Bundle

// Both of these methods return DecoupledIO parameterized by the most generic type: Data
/** Returns a [[DecoupledIO]] inteface with no payload */
def apply(): DecoupledIO[Data] = apply(new EmptyBundle)
/** Returns a [[DecoupledIO]] inteface with no payload */
def empty: DecoupledIO[Data] = Decoupled()

/** Downconverts an IrrevocableIO output to a DecoupledIO, dropping guarantees of irrevocability.
*
* @note unsafe (and will error) on the producer (input) side of an IrrevocableIO
Expand Down
67 changes: 67 additions & 0 deletions src/main/scala/chisel3/util/experimental/group.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// See LICENSE for license details.

package chisel3.util.experimental

import chisel3._
import chisel3.experimental.{ChiselAnnotation, RunFirrtlTransform, annotate}
import chisel3.internal.requireIsHardware
import firrtl.Transform
import firrtl.transforms.{GroupAnnotation, GroupComponents}

/** Marks that a module to be ignored in Dedup Transform in Firrtl pass
*
* @example {{{
* class MyModule extends Module {
* val io = IO(new Bundle{
* val a = Input(Bool())
* val b = Output(Bool())
* })
* val reg1 = RegInit(0.U)
* reg1 := io.a
* val reg2 = RegNext(reg1)
* io.b := reg2
* group(Seq(reg1, reg2), "DosRegisters", "doubleReg")
* }
* }}}
*
* @note Intermediate wires will get pulled into the new instance, but intermediate registers will not
* because they are also connected to their module's clock port. This means that if you want
* a register to be included in a group, it must be explicitly referred to in the input list.
*/
object group {

/** Marks a set of components (and their interconnected components) to be included in a new
* instance hierarchy.
*
* @note Intermediate wires will get pulled into the new instance, but intermediate registers will not
* because they are also connected to their module's clock port. This means that if you want
* a register to be included in a group, it must be explicitly referred to in the input list.
*
* @param components components in this group
* @param newModule suggested name of the new module
* @param newInstance suggested name of the instance of the new module
* @param outputSuffix suggested suffix of any output ports of the new module
* @param inputSuffix suggested suffix of any input ports of the new module
* @param compileOptions necessary for backwards compatibility
* @tparam T Parent type of input components
*/
def apply[T <: Data](
components: Seq[T],
newModule: String,
newInstance: String,
outputSuffix: Option[String] = None,
inputSuffix: Option[String] = None
)(implicit compileOptions: CompileOptions): Unit = {
if (compileOptions.checkSynthesizable) {
components.foreach { data =>
requireIsHardware(data, s"Component ${data.toString} is marked to group, but is not bound.")
}
}
annotate(new ChiselAnnotation with RunFirrtlTransform {
def toFirrtl = GroupAnnotation(components.map(_.toNamed), newModule, newInstance, outputSuffix, inputSuffix)

override def transformClass: Class[_ <: Transform] = classOf[GroupComponents]
})
}
}

Loading

0 comments on commit 2f9f12a

Please sign in to comment.