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

git-subtree add sifive/chisel-circt #2477

Merged
merged 36 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c136d11
Initial Commit
seldridge Jan 14, 2021
2460754
Add documentation
seldridge Jan 14, 2021
1046d8c
Add CI
seldridge Jan 15, 2021
2f3c5cb
Merge pull request #1 from sifive/dev/seldridge/ci
seldridge Jan 15, 2021
a043bb3
Add --handover option to lower partially using SFC
seldridge Jan 16, 2021
dfaed69
Merge pull request #2 from sifive/dev/seldridge/configurable-handover
seldridge Jan 16, 2021
042a276
Add publishing to sonatype
seldridge Jan 26, 2021
92041a5
Merge pull request #3 from sifive/dev/seldridge/sonatype-publish
seldridge Jan 26, 2021
80fa20c
Add description, SiFive homepage to build.sbt
seldridge Jan 27, 2021
13b9a9e
Update README.md
seldridge Jan 27, 2021
493988e
Bump project dependencies
seldridge Apr 22, 2021
17c9d39
Add "--target verilog" option for "*.v" output
seldridge Apr 22, 2021
26bc35c
Fix bug where -enable-lower-types was always used
seldridge Apr 22, 2021
0c21356
Switch to -lower-types
seldridge Apr 22, 2021
cf2993b
Switch from FlatSpec to FunSpec
seldridge Apr 22, 2021
caeb131
Change "RTL" to "HW"
seldridge Jun 22, 2021
ef09fa0
Merge pull request #5 from sifive/dev/seldridge/rtl-to-hw
seldridge Jun 22, 2021
bdc5ae4
Update CIRCT Phase to use newer CIRCT CLI (#8)
seldridge Jan 16, 2022
f1bdfe4
Add Mill build and Bump to Chisel 3.5 (#7)
sequencer Jan 16, 2022
b333604
Add Scala 2.13, enable 2.13 CI
seldridge Feb 18, 2022
3e95ad7
Merge pull request #10 from sifive/dev/seldridge/scala-2.13
seldridge Feb 18, 2022
54f881d
Change default handover to CHIRRTL
seldridge Feb 19, 2022
beb37c2
Add Annotation passing support, set firtool CLI
seldridge Jun 22, 2021
f73c720
Add test of annotation passing/handling
seldridge Jun 22, 2021
8ff8aab
Merge pull request #6 from sifive/dev/seldridge/issue-4
seldridge Feb 19, 2022
72bd6af
Update README badges to 2.13, README updates, NFC
seldridge Feb 19, 2022
6bcb704
Add ability to pass options to firtool
seldridge Mar 24, 2022
58d933f
Change disableLowerTypes to preserveAggregate option
uenoku Apr 11, 2022
5554b38
Add scalafmt Formatting and CI Checks [NFC] (#16)
mwachs5 Jul 7, 2022
e1f8778
Add support for new preserve-aggregate options (#17)
seldridge Jul 21, 2022
d89b2c1
Change CI to use published CIRCT binary (#18)
seldridge Aug 4, 2022
b2b740f
Handle EmitAllModulesAnnotation and Better grabbing of stderr from fi…
mwachs5 Aug 4, 2022
7dd9f0e
Fix scala-fmt
seldridge Aug 4, 2022
73551f0
Add 'circt/' from commit '7dd9f0e9e05b0b2cf1ff5c8cab8b0c490836d021'
seldridge Aug 4, 2022
e8b5b03
Refactor circt into src/main/scala/circt, NFC
seldridge Aug 4, 2022
abab0dd
Add chisel-circt to CI
seldridge Aug 4, 2022
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: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ jobs:
uses: olafurpg/setup-scala@v10
with:
java-version: ${{ matrix.jvm }}
- name: Install CIRCT
run: |
mkdir usr
wget https://github.com/llvm/circt/releases/download/sifive%2F1%2F11%2F0/circt-bin-ubuntu-20.04.tar.gz -O - | tar -zx -C usr/
echo "$(pwd)/usr/bin" >> $GITHUB_PATH
Comment on lines +45 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope we can have a better way to install CIRCT in the system.

- name: Cache Scala
uses: coursier/cache-action@v5
- name: Check Formatting (Scala 2.12 only)
Expand Down
19 changes: 19 additions & 0 deletions src/main/scala/circt/Implicits.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: Apache-2.0

package circt

/** A collection of implicit classes to provide additional methods to existing types */
object Implicits {

/** Helpers for working with Boolean */
implicit class BooleanImplicits(a: Boolean) {

/** Construct an Option from a Boolean. */
def option[A](b: => A): Option[A] =
if (a)
Some(b)
else
None
}

}
Comment on lines +6 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought these APIs may not be public?

Comment on lines +6 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay review:
Should we private these to avoid introducing more public APIs?

129 changes: 129 additions & 0 deletions src/main/scala/circt/stage/Annotations.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// SPDX-License-Identifier: Apache-2.0

package circt.stage

import firrtl.AnnotationSeq
import firrtl.annotations.{Annotation, NoTargetAnnotation}
import firrtl.options.{CustomFileEmission, HasShellOptions, OptionsException, ShellOption, Unserializable}
import firrtl.options.Viewer.view
import firrtl.stage.FirrtlOptions

/** An option consumed by [[circt.stage.CIRCTStage CIRCTStage]] */
sealed trait CIRCTOption extends Unserializable { this: Annotation => }

object PreserveAggregate extends HasShellOptions {
sealed trait Type
object OneDimVec extends Type
object Vec extends Type
object All extends Type

override def options = Seq(
new ShellOption[String](
longOption = "preserve-aggregate",
toAnnotationSeq = _ match {
case "none" => Seq.empty
case "1d-vec" => Seq(PreserveAggregate(PreserveAggregate.OneDimVec))
case "vec" => Seq(PreserveAggregate(PreserveAggregate.Vec))
case "all" => Seq(PreserveAggregate(PreserveAggregate.All))
},
helpText = "Do not lower aggregate types to ground types"
)
)

}

/** Preserve passive aggregate types in CIRCT.
*/
case class PreserveAggregate(mode: PreserveAggregate.Type) extends NoTargetAnnotation with CIRCTOption

/** Object storing types associated with different CIRCT target languages, e.g., RTL or SystemVerilog */
object CIRCTTarget {

/** The parent type of all CIRCT targets */
sealed trait Type

/** The FIRRTL dialect */
case object FIRRTL extends Type

/** The HW dialect */
case object HW extends Type

/** The Verilog language */
case object Verilog extends Type

/** The SystemVerilog language */
case object SystemVerilog extends Type

}

/** Annotation that tells [[circt.stage.phases.CIRCT CIRCT]] what target to compile to */
case class CIRCTTargetAnnotation(target: CIRCTTarget.Type) extends NoTargetAnnotation with CIRCTOption

object CIRCTTargetAnnotation extends HasShellOptions {

override def options = Seq(
new ShellOption[String](
longOption = "target",
toAnnotationSeq = _ match {
case "firrtl" => Seq(CIRCTTargetAnnotation(CIRCTTarget.FIRRTL))
case "hw" => Seq(CIRCTTargetAnnotation(CIRCTTarget.HW))
case "verilog" => Seq(CIRCTTargetAnnotation(CIRCTTarget.Verilog))
case "systemverilog" => Seq(CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog))
case a => throw new OptionsException(s"Unknown target name '$a'! (Did you misspell it?)")
},
helpText = "The CIRCT",
helpValueName = Some("{firrtl|rtl|systemverilog}")
)
)

}

/** Annotation holding an emitted MLIR string
*
* @param filename the name of the file where this should be written
* @param value a string of MLIR
* @param suffix an optional suffix added to the filename when this is written to disk
*/
case class EmittedMLIR(
filename: String,
value: String,
suffix: Option[String])
extends NoTargetAnnotation
with CustomFileEmission {

override protected def baseFileName(annotations: AnnotationSeq): String = filename

override def getBytes = value.getBytes

}

object CIRCTHandover extends HasShellOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we might eventually get rid of the Handover behavior. Am I right?


sealed trait Type

case object CHIRRTL extends Type
case object HighFIRRTL extends Type
case object MiddleFIRRTL extends Type
case object LowFIRRTL extends Type
case object LowOptimizedFIRRTL extends Type

override def options = Seq(
new ShellOption[String](
longOption = "handover",
toAnnotationSeq = _ match {
case "chirrtl" => Seq(CIRCTHandover(CHIRRTL))
case "high" => Seq(CIRCTHandover(HighFIRRTL))
case "middle" => Seq(CIRCTHandover(MiddleFIRRTL))
case "low" => Seq(CIRCTHandover(LowFIRRTL))
case "lowopt" => Seq(CIRCTHandover(LowOptimizedFIRRTL))
case a => throw new OptionsException(s"Unknown handover point '$a'! (Did you misspell it?)")
},
helpText = "Switch to the CIRCT compiler at this point, using the Scala FIRRTL Compiler if needed",
helpValueName = Some("{chirrtl|high|middle|low|lowopt}")
)
)
}

case class CIRCTHandover(handover: CIRCTHandover.Type) extends NoTargetAnnotation with CIRCTOption

case class FirtoolOption(option: String) extends NoTargetAnnotation with CIRCTOption
31 changes: 31 additions & 0 deletions src/main/scala/circt/stage/CIRCTOptions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: Apache-2.0

package circt.stage

import java.io.File

/** Options associated with CIRCT
*
* @param inputFile the name of an input FIRRTL IR file
* @param outputFile the name of the file where the result will be written, if not split
* @param preserveAggregate causes CIRCT to not lower aggregate FIRRTL IR types
* @param target the specific IR or language target that CIRCT should compile to
*/
class CIRCTOptions private[stage] (
val inputFile: Option[File] = None,
val outputFile: Option[File] = None,
val preserveAggregate: Option[PreserveAggregate.Type] = None,
val target: Option[CIRCTTarget.Type] = None,
val handover: Option[CIRCTHandover.Type] = None,
val firtoolOptions: Seq[String] = Seq.empty) {

private[stage] def copy(
inputFile: Option[File] = inputFile,
outputFile: Option[File] = outputFile,
preserveAggregate: Option[PreserveAggregate.Type] = preserveAggregate,
target: Option[CIRCTTarget.Type] = target,
handover: Option[CIRCTHandover.Type] = handover,
firtoolOptions: Seq[String] = firtoolOptions
): CIRCTOptions = new CIRCTOptions(inputFile, outputFile, preserveAggregate, target, handover, firtoolOptions)

}
49 changes: 49 additions & 0 deletions src/main/scala/circt/stage/CIRCTStage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: Apache-2.0

package circt.stage

import chisel3.stage.ChiselGeneratorAnnotation

import firrtl.AnnotationSeq
import firrtl.options.{Dependency, Phase, PhaseManager, Shell, Stage, StageMain}
import firrtl.stage.FirrtlCli

trait CLI { this: Shell =>
parser.note("CIRCT (MLIR FIRRTL Compiler) options")
Seq(
CIRCTTargetAnnotation,
PreserveAggregate,
ChiselGeneratorAnnotation,
CIRCTHandover
).foreach(_.addOptions(parser))
}

/** A [[firrtl.options.Stage Stage]] used to compile FIRRTL IR using CIRCT. This is a drop-in replacement for
* [[firrtl.stage.FirrtlStage]].
*
* @see [[https://github.com/llvm/circt llvm/circt]]
*/
class CIRCTStage extends Stage {

override def prerequisites = Seq.empty
override def optionalPrerequisites = Seq(Dependency[firrtl.stage.phases.Compiler])
override def optionalPrerequisiteOf = Seq.empty
override def invalidates(a: Phase) = false

override val shell: Shell = new Shell("circt") with CLI with FirrtlCli

final val phaseManager = new PhaseManager(
targets = Seq(
Dependency[circt.stage.phases.CIRCT]
),
currentState = Seq(
Dependency[firrtl.stage.phases.AddImplicitEmitter]
)
)

override def run(annotations: AnnotationSeq): AnnotationSeq = phaseManager.transform(annotations)

}

/** Command line utility for [[CIRCTStage]]. */
object CIRCTMain extends StageMain(new CIRCTStage)
114 changes: 114 additions & 0 deletions src/main/scala/circt/stage/ChiselStage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: Apache-2.0

package circt.stage

import chisel3.RawModule
import chisel3.stage.{ChiselGeneratorAnnotation, NoRunFirrtlCompilerAnnotation}

import firrtl.{AnnotationSeq, EmittedVerilogCircuitAnnotation}
import firrtl.options.{Dependency, Phase, PhaseManager, Shell, Stage, StageMain}
import firrtl.options.Viewer.view
import firrtl.stage.{Forms, RunFirrtlTransformAnnotation}

/** Entry point for running Chisel with the CIRCT compiler.
*
* This is intended to be a replacement for [[chisel3.stage.ChiselStage]].
*
* @note The companion object, [[ChiselStage$]], has a cleaner API for compiling and returning a string.
*/
class ChiselStage extends Stage {

override def prerequisites = Seq.empty
override def optionalPrerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq.empty
override def invalidates(a: Phase) = false

override val shell = new Shell("circt") with CLI

override def run(annotations: AnnotationSeq): AnnotationSeq = {

val pm = new PhaseManager(
targets = Seq(
Dependency[chisel3.stage.ChiselStage],
Dependency[firrtl.stage.phases.AddImplicitOutputFile],
Dependency[circt.stage.phases.AddDefaults],
Dependency[circt.stage.phases.Checks],
Dependency[circt.stage.phases.MaybeSFC],
Dependency[circt.stage.CIRCTStage]
),
currentState = Seq(
Dependency[firrtl.stage.phases.AddDefaults],
Dependency[firrtl.stage.phases.Checks]
)
)
pm.transform(NoRunFirrtlCompilerAnnotation +: annotations)
}

}

/** Utilities for compiling Chisel */
object ChiselStage {

/** Elaborate a Chisel circuit into a CHIRRTL string */
def emitCHIRRTL(gen: => RawModule): String = chisel3.stage.ChiselStage.emitChirrtl(gen)

/** A phase shared by all the CIRCT backends */
private def phase = new PhaseManager(
Seq(
Dependency[chisel3.stage.phases.Checks],
Dependency[chisel3.stage.phases.Elaborate],
Dependency[chisel3.stage.phases.Convert],
Dependency[firrtl.stage.phases.AddImplicitOutputFile],
Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
Dependency[circt.stage.phases.Checks],
Dependency[circt.stage.phases.CIRCT]
)
)

/** Compile a Chisel circuit to FIRRTL dialect */
def emitFIRRTLDialect(gen: => RawModule): String = phase
.transform(
Seq(
ChiselGeneratorAnnotation(() => gen),
CIRCTTargetAnnotation(CIRCTTarget.FIRRTL),
CIRCTHandover(CIRCTHandover.CHIRRTL)
)
)
.collectFirst {
case EmittedMLIR(_, a, _) => a
}
.get

/** Compile a Chisel circuit to HWS dialect */
def emitHWDialect(gen: => RawModule): String = phase
.transform(
Seq(
ChiselGeneratorAnnotation(() => gen),
CIRCTTargetAnnotation(CIRCTTarget.HW),
CIRCTHandover(CIRCTHandover.CHIRRTL)
)
)
.collectFirst {
case EmittedMLIR(_, a, _) => a
}
.get

/** Compile a Chisel circuit to SystemVerilog */
def emitSystemVerilog(gen: => RawModule): String = phase
.transform(
Seq(
ChiselGeneratorAnnotation(() => gen),
CIRCTTargetAnnotation(CIRCTTarget.SystemVerilog),
CIRCTHandover(CIRCTHandover.CHIRRTL)
)
)
.collectFirst {
case EmittedVerilogCircuitAnnotation(a) => a
}
.get
.value

}

/** Command line entry point to [[ChiselStage]] */
object ChiselMain extends StageMain(new ChiselStage)
37 changes: 37 additions & 0 deletions src/main/scala/circt/stage/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: Apache-2.0

package circt

import circt.stage.{CIRCTOption, CIRCTTargetAnnotation, PreserveAggregate}

import firrtl.AnnotationSeq
import firrtl.options.OptionsView
import firrtl.stage.{FirrtlFileAnnotation, FirrtlOption, OutputFileAnnotation}

import java.io.File

package object stage {

implicit object CIRCTOptionsView extends OptionsView[CIRCTOptions] {

def view(annotations: AnnotationSeq): CIRCTOptions =
annotations.collect {
case a: CIRCTOption => a
case a: FirrtlOption => a
case a: FirrtlFileAnnotation => a
}
.foldLeft(new CIRCTOptions()) { (acc, c) =>
c match {
case FirrtlFileAnnotation(a) => acc.copy(inputFile = Some(new File(a)))
case OutputFileAnnotation(a) => acc.copy(outputFile = Some(new File(a)))
case CIRCTTargetAnnotation(a) => acc.copy(target = Some(a))
case PreserveAggregate(a) => acc.copy(preserveAggregate = Some(a))
case CIRCTHandover(a) => acc.copy(handover = Some(a))
case FirtoolOption(a) => acc.copy(firtoolOptions = acc.firtoolOptions :+ a)
case _ => acc
}
}

}

}
Loading