Skip to content
New issue

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

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

Already on GitHub? # to your account

Implement FirtoolOptions for PanamaBinding #3773

Merged
merged 4 commits into from
Feb 2, 2024
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
45 changes: 45 additions & 0 deletions lit/tests/FirtoolOptions.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// RUN: scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" --java-opt="--enable-native-access=ALL-UNNAMED" --java-opt="--enable-preview" --java-opt="-Djava.library.path=%JAVALIBRARYPATH" %s -- panama-verilog | FileCheck %s -check-prefix=VERILOG

import chisel3._
import chisel3.panamalib.option._

// println(lit.utility.panamaconverter.verilogString(???, Set(AddMuxPragmas(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(AddVivadoRAMAddressConflictSynthesisBugWorkaround(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(BlackBoxRootPath(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(BuildMode(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ChiselInterfaceOutDirectory(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CkgEnableName(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CkgInputName(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CkgModuleName(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CkgOutputName(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CkgTestEnableName(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(CompanionMode(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(DisableAggressiveMergeConnections(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(DisableAnnotationsClassless(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(DisableOptimization(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(DisableRandom(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(DisableUnknownAnnotations(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EmitChiselAssertsAsSVA(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EmitOmir(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EmitSeparateAlwaysBlocks(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EnableAnnotationWarning(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EtcDisableInstanceExtraction(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EtcDisableModuleInlining(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(EtcDisableRegisterExtraction(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ExportChiselInterface(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ExportModuleHierarchy(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ExtractTestCode(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(IgnoreReadEnableMem(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(LowerAnnotationsNoRefTypePorts(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(LowerMemories(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(NoDedup(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(OmirOutFile(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(OutputAnnotationFilename(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(OutputFilename(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(PreserveAggregate(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(PreserveValues(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ReplSeqMem(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(ReplSeqMemFile(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(StripDebugInfo(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(StripFirDebugInfo(???))))
// println(lit.utility.panamaconverter.verilogString(???, Set(VbToBv(???))))
11 changes: 11 additions & 0 deletions lit/tests/Property/Bad.sc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: not scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" %s -- 2>&1 | FileCheck %s

import chisel3.properties._

class MyLit
// CHECK: error: unsupported Property type Bad.MyLit
val badPropLiteral = Property(new MyLit)

// CHECK: error: unsupported Property type Bad.MyTpe
class MyTpe
val badPropType = Property[MyTpe]()
39 changes: 28 additions & 11 deletions lit/tests/OMTest.sc → lit/tests/Property/Good.sc
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
// RUN: scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" --java-opt="--enable-native-access=ALL-UNNAMED" --java-opt="--enable-preview" --java-opt="-Djava.library.path=%JAVALIBRARYPATH" %s -- panama-omstring | FileCheck %s
// RUN: scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" %s -- chirrtl | FileCheck %s -check-prefix=SFC-FIRRTL
// RUN: scala-cli --server=false --java-home=%JAVAHOME --extra-jars=%RUNCLASSPATH --scala-version=%SCALAVERSION --scala-option="-Xplugin:%SCALAPLUGINJARS" --java-opt="--enable-native-access=ALL-UNNAMED" --java-opt="--enable-preview" --java-opt="-Djava.library.path=%JAVALIBRARYPATH" %s -- panama-om | FileCheck %s -check-prefix=MFC-OM

import chisel3._
import chisel3.properties._
import chisel3.panamaom._
import chisel3.panamaconverter._
import lit.utility._

// SFC-FIRRTL-LABEL: circuit IntPropTest :
// SFC-FIRRTL-NEXT: module IntPropTest :
// SFC-FIRRTL-NEXT: output intProp : Integer

// MFC-OM-LABEL: circuit IntPropTest :
// MFC-OM-NEXT: module IntPropTest :
// MFC-OM-NEXT: output intProp : Integer
class IntPropTest extends RawModule {
val intProp = IO(Output(Property[Int]()))
intProp := Property(1)
}

args.head match {
case "chirrtl" =>
println(circt.stage.ChiselStage.emitCHIRRTL(new IntPropTest))
case "panama-om" =>
println(lit.utility.panamaconverter.firrtlString(new IntPropTest))
case _ =>
}

class PropertyTest extends RawModule {
val i = IO(Input(UInt(8.W)))
Expand All @@ -18,14 +39,9 @@ class PropertyTest extends RawModule {
}

args.head match {
case "panama-omstring" =>
val converter: PanamaCIRCTConverter = lit.utility.panamaconverter.getConverter(new PropertyTest)
val pm = converter.passManager()
assert(pm.populatePreprocessTransforms())
assert(pm.populateCHIRRTLToLowFIRRTL())
assert(pm.populateLowFIRRTLToHW())
assert(pm.populateFinalizeIR())
assert(pm.run())
case "panama-om" =>
val converter = lit.utility.panamaconverter.getConverter(new PropertyTest)
lit.utility.panamaconverter.runAllPass(converter)

val om = converter.om()
val evaluator = om.evaluator()
Expand All @@ -38,4 +54,5 @@ args.head match {
// CHECK-NEXT: .b => { [ [ prim{omInteger{456}} ] ] }
// CHECK-NEXT: .p => { path{OMReferenceTarget:~PropertyTest|PropertyTest>i} }
obj.foreachField((name, value) => println(s".$name => { ${value.display} }"))
}
case _ =>
}
19 changes: 15 additions & 4 deletions lit/utility/src/package.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import chisel3._
import chisel3.panamaconverter.PanamaCIRCTConverter
import chisel3.panamalib.option.FirtoolOptions
import chisel3.panamaom.PanamaCIRCTOMEvaluator

package object lit {
object utility {
object panamaconverter {
def getConverter(module: => RawModule): PanamaCIRCTConverter = Seq(
def getConverter(module: => RawModule, firtoolOptions: FirtoolOptions = FirtoolOptions(Set.empty)): PanamaCIRCTConverter = Seq(
new chisel3.stage.phases.Elaborate,
chisel3.panamaconverter.stage.Convert
).foldLeft(
Expand All @@ -14,16 +16,25 @@ package object lit {
converter
}.get

def streamString(module: => RawModule, stream: PanamaCIRCTConverter => geny.Writable): String = {
def runAllPass(converter: PanamaCIRCTConverter) = {
val pm = converter.passManager()
assert(pm.populatePreprocessTransforms())
assert(pm.populateCHIRRTLToLowFIRRTL())
assert(pm.populateLowFIRRTLToHW())
assert(pm.populateFinalizeIR())
assert(pm.run())
}

def streamString(module: => RawModule, firtoolOptions: FirtoolOptions = FirtoolOptions(Set.empty), stream: PanamaCIRCTConverter => geny.Writable): String = {
val converter = getConverter(module)
val string = new java.io.ByteArrayOutputStream
stream(converter).writeBytesTo(string)
new String(string.toByteArray)
}

def firrtlString(module: => RawModule): String = streamString(module, _.firrtlStream)
def firrtlString(module: => RawModule, firtoolOptions: FirtoolOptions = FirtoolOptions(Set.empty)): String = streamString(module, firtoolOptions, _.firrtlStream)

def verilogString(module: => RawModule): String = streamString(module, _.verilogStream)
def verilogString(module: => RawModule, firtoolOptions: FirtoolOptions = FirtoolOptions(Set.empty)): String = streamString(module, firtoolOptions, _.verilogStream)
}
}
}
6 changes: 5 additions & 1 deletion panamaconverter/src/Convert.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
package chisel3.panamaconverter.stage

import chisel3.panamaconverter.PanamaCIRCTConverter
import chisel3.panamalib.option.FirtoolOptions
import chisel3.stage.ChiselCircuitAnnotation
import chisel3.stage.phases.Elaborate
import firrtl.AnnotationSeq
import firrtl.annotations.NoTargetAnnotation
import firrtl.options.{Dependency, Phase}

case class PanamaCIRCTConverterAnnotation(converter: PanamaCIRCTConverter) extends NoTargetAnnotation
case class FirtoolOptionsAnnotation(firtoolOptions: FirtoolOptions) extends NoTargetAnnotation

object Convert extends Phase {
override def prerequisites = Seq(Dependency[Elaborate])
Expand All @@ -20,7 +22,9 @@ object Convert extends Phase {
def transform(annotations: AnnotationSeq): AnnotationSeq =
annotations.flatMap {
case c @ ChiselCircuitAnnotation(circuit) =>
Seq(c, PanamaCIRCTConverterAnnotation(PanamaCIRCTConverter.convert(circuit)))
Seq(c, PanamaCIRCTConverterAnnotation(PanamaCIRCTConverter.convert(circuit, annotations.collectFirst {
case FirtoolOptionsAnnotation(firtoolOptions) => firtoolOptions
})))
case a => Seq(a)
}
}
13 changes: 8 additions & 5 deletions panamaconverter/src/PanamaCIRCTConverter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import chisel3.internal.firrtl.Converter
import chisel3.assert.{Assert => VerifAssert}
import chisel3.assume.{Assume => VerifAssume}
import chisel3.cover.{Cover => VerifCover}
import chisel3.panamalib.option.FirtoolOptions
import chisel3.panamaom.PanamaCIRCTOM
import chisel3.printf.{Printf => VerifPrintf}
import chisel3.stop.{Stop => VerifStop}
Expand Down Expand Up @@ -120,8 +121,7 @@ class FirContext {
def rootWhen: Option[WhenContext] = Option.when(whenStack.nonEmpty)(whenStack.last)
}

class PanamaCIRCTConverter {
val circt = new PanamaCIRCT
class PanamaCIRCTConverter(val circt: PanamaCIRCT, fos: Option[FirtoolOptions]) {
val firCtx = new FirContext
val mlirRootModule = circt.mlirModuleCreateEmpty(circt.unkLoc)

Expand Down Expand Up @@ -880,7 +880,7 @@ class PanamaCIRCTConverter {
assertResult(circt.mlirPassManagerRunOnOp(pm, circt.mlirModuleGetOperation(mlirRootModule)))
}

def passManager(): PanamaCIRCTPassManager = new PanamaCIRCTPassManager(circt, mlirRootModule)
def passManager(): PanamaCIRCTPassManager = new PanamaCIRCTPassManager(circt, mlirRootModule, fos)
def om(): PanamaCIRCTOM = new PanamaCIRCTOM(circt, mlirRootModule)

def visitCircuit(name: String): Unit = {
Expand Down Expand Up @@ -1617,8 +1617,11 @@ class PanamaCIRCTConverter {
}

private[panamaconverter] object PanamaCIRCTConverter {
def convert(circuit: Circuit): PanamaCIRCTConverter = {
implicit val cvt = new PanamaCIRCTConverter
def convert(circuit: Circuit, firtoolOptions: Option[FirtoolOptions]): PanamaCIRCTConverter = {
// TODO: In the future, we need to split PanamaCIRCT creation into a different public API.
// It provides a possibility for parsing mlirbc(OM requries it).
val circt = new PanamaCIRCT
implicit val cvt = new PanamaCIRCTConverter(circt, firtoolOptions)
visitCircuit(circuit)
cvt
}
Expand Down
6 changes: 4 additions & 2 deletions panamaconverter/src/PanamaCIRCTPassManager.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
package chisel3.panamaconverter

import chisel3.panamalib._
import chisel3.panamalib.option.FirtoolOptions
import chisel3.panamalib.option.PanamaFirtoolOption.FirtoolOptionsToPanama

private[panamaconverter] class PanamaCIRCTPassManager (circt: PanamaCIRCT, mlirModule: MlirModule) {
private[panamaconverter] class PanamaCIRCTPassManager (circt: PanamaCIRCT, mlirModule: MlirModule, fos: Option[FirtoolOptions]) {
val pm = circt.mlirPassManagerCreate()
val options = circt.circtFirtoolOptionsCreateDefault() // TODO: Make it configurable from CIRCTPassManager
val options = fos.map(_.toPanama(circt)).getOrElse(circt.circtFirtoolOptionsCreateDefault())

private def isSuccess(result: MlirLogicalResult): Boolean = circt.mlirLogicalResultIsSuccess(result)

Expand Down
81 changes: 81 additions & 0 deletions panamalib/src/FirtoolOptions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: Apache-2.0

// This should be the Scala API for user to invoke Firtool
// I(jiuyang) may want to promote it into a global user API for type safety in the userspace.(e.g. circt.options)
// It only declares types, converting them to cli/panama need to import corresponding implicit class
package chisel3.panamalib.option

sealed trait FirtoolOption

// All Firtool Options
case class AddMuxPragmas(value: Boolean) extends FirtoolOption
case class AddVivadoRAMAddressConflictSynthesisBugWorkaround(value: Boolean) extends FirtoolOption
case class BlackBoxRootPath(value: String) extends FirtoolOption
case class BuildMode(value: BuildModeEnum) extends FirtoolOption
case class ChiselInterfaceOutDirectory(value: String) extends FirtoolOption
case class CkgEnableName(value: String) extends FirtoolOption
case class CkgInputName(value: String) extends FirtoolOption
case class CkgModuleName(value: String) extends FirtoolOption
case class CkgOutputName(value: String) extends FirtoolOption
case class CkgTestEnableName(value: String) extends FirtoolOption
case class CompanionMode(value: CompanionModeEnum) extends FirtoolOption
case class DisableAggressiveMergeConnections(value: Boolean) extends FirtoolOption
case class DisableAnnotationsClassless(value: Boolean) extends FirtoolOption
case class DisableOptimization(value: Boolean) extends FirtoolOption
case class DisableRandom(value: RandomKindEnum) extends FirtoolOption
case class DisableUnknownAnnotations(value: Boolean) extends FirtoolOption
case class EmitChiselAssertsAsSVA(value: Boolean) extends FirtoolOption
case class EmitOmir(value: Boolean) extends FirtoolOption
case class EmitSeparateAlwaysBlocks(value: Boolean) extends FirtoolOption
case class EnableAnnotationWarning(value: Boolean) extends FirtoolOption
case class EtcDisableInstanceExtraction(value: Boolean) extends FirtoolOption
case class EtcDisableModuleInlining(value: Boolean) extends FirtoolOption
case class EtcDisableRegisterExtraction(value: Boolean) extends FirtoolOption
case class ExportChiselInterface(value: Boolean) extends FirtoolOption
case class ExportModuleHierarchy(value: Boolean) extends FirtoolOption
case class ExtractTestCode(value: Boolean) extends FirtoolOption
case class IgnoreReadEnableMem(value: Boolean) extends FirtoolOption
case class LowerAnnotationsNoRefTypePorts(value: Boolean) extends FirtoolOption
case class LowerMemories(value: Boolean) extends FirtoolOption
case class NoDedup(value: Boolean) extends FirtoolOption
case class OmirOutFile(value: String) extends FirtoolOption
case class OutputAnnotationFilename(value: String) extends FirtoolOption
case class OutputFilename(value: String) extends FirtoolOption
case class PreserveAggregate(value: PreserveAggregateModeEnum) extends FirtoolOption
case class PreserveValues(value: PreserveValuesModeEnum) extends FirtoolOption
case class ReplSeqMem(value: Boolean) extends FirtoolOption
case class ReplSeqMemFile(value: String) extends FirtoolOption
case class StripDebugInfo(value: Boolean) extends FirtoolOption
case class StripFirDebugInfo(value: Boolean) extends FirtoolOption
case class VbToBv(value: Boolean) extends FirtoolOption

// All Enums
sealed trait BuildModeEnum
case object BuildModeDefault extends BuildModeEnum
case object BuildModeDebug extends BuildModeEnum
case object BuildModeRelease extends BuildModeEnum

sealed trait CompanionModeEnum
case object CompanionModeBind extends CompanionModeEnum
case object CompanionModeInstantiate extends CompanionModeEnum
case object CompanionModeDrop extends CompanionModeEnum

sealed trait RandomKindEnum
case object RandomKindNone extends RandomKindEnum
case object RandomKindMem extends RandomKindEnum
case object RandomKindReg extends RandomKindEnum
case object RandomKindAll extends RandomKindEnum

sealed trait PreserveAggregateModeEnum
case object PreserveAggregateModeNone extends PreserveAggregateModeEnum
case object PreserveAggregateModeOneDimVec extends PreserveAggregateModeEnum
case object PreserveAggregateModeVec extends PreserveAggregateModeEnum
case object PreserveAggregateModeAll extends PreserveAggregateModeEnum

sealed trait PreserveValuesModeEnum
case object PreserveValuesModeStrip extends PreserveValuesModeEnum
case object PreserveValuesModeNone extends PreserveValuesModeEnum
case object PreserveValuesModeNamed extends PreserveValuesModeEnum
case object PreserveValuesModeAll extends PreserveValuesModeEnum

case class FirtoolOptions(options: Set[FirtoolOption])
Loading
Loading