Add BSwitch macro and update gtkwave config

This commit is contained in:
2025-11-11 19:12:12 +01:00
parent 4c967431ed
commit f9cbcaf20f
3 changed files with 90 additions and 1 deletions

View File

@@ -13,6 +13,17 @@ import mill.bsp._
// to properly generate and handle test directories and output files.
// See: https://github.com/com-lihaoyi/mill/issues/3840
object macros extends ScalaModule {
def scalaVersion = "2.13.16"
def scalacOptions = Seq[String]()
override def ivyDeps = Agg(
ivy"org.chipsalliance::chisel:7.2.0"
)
override def scalacPluginIvyDeps = Agg(
ivy"org.chipsalliance:::chisel-plugin:7.2.0"
)
}
object `TPchisel` extends SbtModule { m =>
override def millSourcePath = super.millSourcePath / os.up
override def scalaVersion = "2.13.16"
@@ -27,6 +38,7 @@ object `TPchisel` extends SbtModule { m =>
"-Ywarn-dead-code",
"-Ywarn-unused"
)
override def moduleDeps = Seq(macros)
override def ivyDeps = Agg(
ivy"org.chipsalliance::chisel:7.2.0"
)

View File

@@ -17,7 +17,7 @@ TOP.svsimTestbench.dut.core.wbVal[31:0]
TOP.svsimTestbench.dut.core.clock
TOP.svsimTestbench.dut.core.reset
@22
TOP.svsimTestbench.dut.io_x31[31:0]
TOP.svsimTestbench.dut.io_x31[63:0]
@28
TOP.svsimTestbench.dut.io_valid_x31
TOP.svsimTestbench.dut.core.rdValid

View File

@@ -0,0 +1,77 @@
package macros.utils
import scala.language.experimental.macros
import scala.reflect.macros.blackbox._
import chisel3._
import chisel3.experimental.SourceInfo
import chisel3.util.BitPat
object bis {
/** Executes `block` if the bswitch condition matchs `v`.
*/
def apply(v: BitPat)(block: => Any): Unit = {
locally((v, block))
require(
false,
"The 'bis' keyword may not be used outside of a bswitch."
)
}
}
class BSwitchContext(
cond: UInt,
whenContext: Option[WhenContext],
lits: Set[BitPat]
) {
def bis(
pat: BitPat
)(block: => Any)(implicit
sourceInfo: SourceInfo
): BSwitchContext = {
require(
!lits.exists(w => {
w.overlap(pat)
}),
"all bis conditions must be mutually exclusive!"
)
// def instead of val so that logic ends up in legal place
def p = (cond === pat)
whenContext match {
case Some(w) =>
new BSwitchContext(
cond,
Some(w.elsewhen(p)(block)),
lits + pat
)
case None =>
new BSwitchContext(
cond,
Some(when(p)(block)),
lits + pat
)
}
}
}
object bswitch {
def apply[T <: Element](cond: T)(x: => Any): Unit = macro impl
def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = {
import c.universe._
val q"..$body" = x
val res = body.foldLeft(
q"""new macros.utils.BSwitchContext($cond, None, Set.empty)"""
) { case (acc, tree) =>
tree match {
case q"macros.utils.bis.apply( ..$params )( ..$body )" =>
q"$acc.bis( ..$params )( ..$body )"
case _ =>
throw new Exception(
s"Cannot include blocks that do not begin with bis() in bswitch."
)
}
}
q"""{ $res }"""
}
}