summaryrefslogtreecommitdiff
path: root/integration-tests
diff options
context:
space:
mode:
authorJack Koenig2021-09-17 21:01:26 -0700
committerJack Koenig2021-09-17 21:01:26 -0700
commit5c8c19345e6711279594cf1f9ddab33623c8eba7 (patch)
treed9d6ced3934aa4a8be3dec19ddcefe50a7a93d5a /integration-tests
parente63b9667d89768e0ec6dc8a9153335cb48a213a7 (diff)
parent958904cb2f2f65d02b2ab3ec6d9ec2e06d04e482 (diff)
Merge branch 'master' into 3.5-release
Diffstat (limited to 'integration-tests')
-rw-r--r--integration-tests/src/test/scala/chiselTest/MemFormalSpec.scala81
-rw-r--r--integration-tests/src/test/scala/chiselTests/util/experimental/DecoderSpec.scala53
-rw-r--r--integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/EspressoSpec.scala9
-rw-r--r--integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/MinimizerSpec.scala275
-rw-r--r--integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/QMCSpec.scala9
5 files changed, 427 insertions, 0 deletions
diff --git a/integration-tests/src/test/scala/chiselTest/MemFormalSpec.scala b/integration-tests/src/test/scala/chiselTest/MemFormalSpec.scala
new file mode 100644
index 00000000..35d1a299
--- /dev/null
+++ b/integration-tests/src/test/scala/chiselTest/MemFormalSpec.scala
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTest
+
+import chisel3._
+import chisel3.experimental._
+import chiseltest._
+import chiseltest.formal._
+import firrtl.annotations.MemoryArrayInitAnnotation
+import org.scalatest.flatspec.AnyFlatSpec
+
+class MemFormalSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
+ behavior of "SyncReadMem read enable"
+
+ private def check(mod: Boolean => ReadEnTestModule, alwaysEnabeld: Boolean = false): Unit = {
+ // we first check that the read is enabled when it should be
+ verify(mod(true), Seq(BoundedCheck(4)))
+ if(!alwaysEnabeld) {
+ // now we check that it is disabled, when it should be
+ // however, note that this check is not exhaustive/complete!
+ assertThrows[FailedBoundedCheckException] {
+ verify(mod(false), Seq(BoundedCheck(4)))
+ }
+ }
+ }
+
+ it should "always be true when calling read(addr)" in {
+ check(new ReadEnTestModule(_) { out := mem.read(addr) }, true)
+ }
+
+ it should "always be true when calling read(addr, true.B)" in {
+ check(new ReadEnTestModule(_) { out := mem.read(addr, true.B) }, true)
+ }
+
+ it should "always be false when calling read(addr, false.B)" in {
+ check(new ReadEnTestModule(_) {
+ out := mem.read(addr, false.B)
+ shouldRead := false.B
+ shouldNotRead := true.B
+ })
+ }
+
+ it should "be enabled by iff en=1 when calling read(addr, en)" in {
+ check(new ReadEnTestModule(_) {
+ val en = IO(Input(Bool()))
+ out := mem.read(addr, en)
+ shouldRead := en
+ shouldNotRead := !en
+ })
+ }
+}
+
+abstract class ReadEnTestModule(testShouldRead: Boolean) extends Module {
+ val addr = IO(Input(UInt(5.W)))
+ val out = IO(Output(UInt(8.W)))
+ out := DontCare
+ // these can be overwritten by the concrete test
+ val shouldRead = WireInit(true.B)
+ val shouldNotRead = WireInit(false.B)
+
+ // we initialize the memory, so that the output should always equivalent to the read address
+ val mem = SyncReadMem(32, chiselTypeOf(out))
+ annotate(new ChiselAnnotation {
+ override def toFirrtl = MemoryArrayInitAnnotation(mem.toTarget, values = Seq.tabulate(32)(BigInt(_)))
+ })
+
+ // the first cycle after reset, the data will be arbitrary
+ val firstCycle = RegNext(false.B, init=true.B)
+
+ if(testShouldRead) {
+ when(!firstCycle && RegNext(shouldRead)) {
+ verification.assert(out === RegNext(addr))
+ }
+ } else {
+ when(!firstCycle && RegNext(shouldNotRead)) {
+ // this can only fail if the read enable is false and an arbitrary value is provided
+ // note that this test is not complete!!
+ verification.assert(out === 200.U)
+ }
+ }
+}
diff --git a/integration-tests/src/test/scala/chiselTests/util/experimental/DecoderSpec.scala b/integration-tests/src/test/scala/chiselTests/util/experimental/DecoderSpec.scala
new file mode 100644
index 00000000..c31fdee0
--- /dev/null
+++ b/integration-tests/src/test/scala/chiselTests/util/experimental/DecoderSpec.scala
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTests.util.experimental
+
+import chisel3.util.experimental.decode.{DecodeTableAnnotation, Minimizer, QMCMinimizer, TruthTable}
+import chiselTests.util.experimental.minimizer.DecodeTestModule
+import firrtl.annotations.ReferenceTarget
+import org.scalatest.flatspec.AnyFlatSpec
+import chiseltest._
+import chiseltest.formal._
+
+class DecoderSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
+ val xor = TruthTable(
+ """10->1
+ |01->1
+ | 0""".stripMargin)
+
+ def minimizer: Minimizer = QMCMinimizer
+
+ "decoder" should "pass without DecodeTableAnnotation" in {
+ verify(new DecodeTestModule(minimizer, table = xor), Seq(BoundedCheck(1)))
+ }
+
+ "decoder" should "fail with a incorrect DecodeTableAnnotation" in {
+ val annos = Seq(
+ DecodeTableAnnotation(ReferenceTarget("", "", Nil, "", Nil),
+ """10->1
+ |01->1
+ | 0""".stripMargin,
+ """10->1
+ | 0""".stripMargin
+ )
+ )
+ assertThrows[FailedBoundedCheckException] {
+ verify(new DecodeTestModule(minimizer, table = xor), BoundedCheck(1) +: annos)
+ }
+ }
+
+ "decoder" should "success with a correct DecodeTableAnnotation" in {
+ val annos = Seq(
+ DecodeTableAnnotation(ReferenceTarget("", "", Nil, "", Nil),
+ """10->1
+ |01->1
+ | 0""".stripMargin,
+ QMCMinimizer.minimize(TruthTable(
+ """10->1
+ |01->1
+ | 0""".stripMargin)).toString
+ )
+ )
+ verify(new DecodeTestModule(minimizer, table = xor), BoundedCheck(1) +: annos)
+ }
+}
diff --git a/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/EspressoSpec.scala b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/EspressoSpec.scala
new file mode 100644
index 00000000..f3270cae
--- /dev/null
+++ b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/EspressoSpec.scala
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTests.util.experimental.minimizer
+import chisel3.util.experimental.decode.EspressoMinimizer
+import chisel3.util.experimental.decode.Minimizer
+
+class EspressoSpec extends MinimizerSpec {
+ override def minimizer: Minimizer = EspressoMinimizer
+}
diff --git a/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/MinimizerSpec.scala b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/MinimizerSpec.scala
new file mode 100644
index 00000000..a932eb77
--- /dev/null
+++ b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/MinimizerSpec.scala
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTests.util.experimental.minimizer
+
+import chisel3._
+import chisel3.util._
+import chisel3.util.experimental.decode._
+import chisel3.util.pla
+import chiseltest._
+import chiseltest.formal._
+import org.scalatest.flatspec.AnyFlatSpec
+
+class DecodeTestModule(minimizer: Minimizer, table: TruthTable) extends Module {
+ val i = IO(Input(UInt(table.table.head._1.getWidth.W)))
+ val (unminimizedI, unminimizedO) = pla(table.table.toSeq)
+ unminimizedI := i
+ val minimizedO: UInt = decoder(minimizer, i, table)
+
+ chisel3.experimental.verification.assert(
+ // for each instruction, if input matches, output should match, not no matched, fallback to default
+ (table.table.map { case (key, value) => (i === key) && (minimizedO === value) } ++
+ Seq(table.table.keys.map(i =/= _).reduce(_ && _) && minimizedO === table.default)).reduce(_ || _)
+ )
+}
+
+trait MinimizerSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
+ def minimizer: Minimizer
+
+ def minimizerTest(testcase: TruthTable) = {
+ verify(new DecodeTestModule(minimizer, table = testcase), Seq(BoundedCheck(1)))
+ }
+
+ // Term that being commented out is the result of which is same as default,
+ // making optimization opportunities to decoder algorithms
+
+ "case0" should "pass" in {
+ minimizerTest(TruthTable(
+ Map(
+ // BitPat("b000") -> BitPat("b0"),
+ BitPat("b001") -> BitPat("b?"),
+ BitPat("b010") -> BitPat("b?"),
+ // BitPat("b011") -> BitPat("b0"),
+ BitPat("b100") -> BitPat("b1"),
+ BitPat("b101") -> BitPat("b1"),
+ // BitPat("b110") -> BitPat("b0"),
+ BitPat("b111") -> BitPat("b1")
+ ),
+ BitPat("b0")
+ ))
+ }
+
+ "case1" should "pass" in {
+ minimizerTest(TruthTable(
+ Map(
+ BitPat("b000") -> BitPat("b0"),
+ BitPat("b001") -> BitPat("b?"),
+ BitPat("b010") -> BitPat("b?"),
+ BitPat("b011") -> BitPat("b0"),
+ // BitPat("b100") -> BitPat("b1"),
+ // BitPat("b101") -> BitPat("b1"),
+ BitPat("b110") -> BitPat("b0"),
+ // BitPat("b111") -> BitPat("b1")
+ ),
+ BitPat("b1")
+ ))
+ }
+
+ "caseX" should "pass" in {
+ minimizerTest(TruthTable(
+ Map(
+ BitPat("b000") -> BitPat("b0"),
+ // BitPat("b001") -> BitPat("b?"),
+ // BitPat("b010") -> BitPat("b?"),
+ BitPat("b011") -> BitPat("b0"),
+ BitPat("b100") -> BitPat("b1"),
+ BitPat("b101") -> BitPat("b1"),
+ BitPat("b110") -> BitPat("b0"),
+ BitPat("b111") -> BitPat("b1")
+ ),
+ BitPat("b?")
+ ))
+ }
+
+ "caseMultiDefault" should "pass" in {
+ minimizerTest(TruthTable(
+ Map(
+ BitPat("b000") -> BitPat("b0100"),
+ BitPat("b001") -> BitPat("b?111"),
+ BitPat("b010") -> BitPat("b?000"),
+ BitPat("b011") -> BitPat("b0101"),
+ BitPat("b111") -> BitPat("b1101")
+ ),
+ BitPat("b?100")
+ ))
+ }
+
+ "case7SegDecoder" should "pass" in {
+ minimizerTest(TruthTable(
+ Map(
+ BitPat("b0000") -> BitPat("b111111001"),
+ BitPat("b0001") -> BitPat("b011000001"),
+ BitPat("b0010") -> BitPat("b110110101"),
+ BitPat("b0011") -> BitPat("b111100101"),
+ BitPat("b0100") -> BitPat("b011001101"),
+ BitPat("b0101") -> BitPat("b101101101"),
+ BitPat("b0110") -> BitPat("b101111101"),
+ BitPat("b0111") -> BitPat("b111000001"),
+ BitPat("b1000") -> BitPat("b111111101"),
+ BitPat("b1001") -> BitPat("b111101101"),
+ ),
+ BitPat("b???????10")
+ ))
+ }
+
+ // A simple RV32I decode table example
+ "caseRV32I" should "pass" in {
+ val BEQ = "?????????????????000?????1100011"
+ val BNE = "?????????????????001?????1100011"
+ val BLT = "?????????????????100?????1100011"
+ val BGE = "?????????????????101?????1100011"
+ val BLTU = "?????????????????110?????1100011"
+ val BGEU = "?????????????????111?????1100011"
+ val JALR = "?????????????????000?????1100111"
+ val JAL = "?????????????????????????1101111"
+ val LUI = "?????????????????????????0110111"
+ val AUIPC = "?????????????????????????0010111"
+ val ADDI = "?????????????????000?????0010011"
+ val SLTI = "?????????????????010?????0010011"
+ val SLTIU = "?????????????????011?????0010011"
+ val XORI = "?????????????????100?????0010011"
+ val ORI = "?????????????????110?????0010011"
+ val ANDI = "?????????????????111?????0010011"
+ val ADD = "0000000??????????000?????0110011"
+ val SUB = "0100000??????????000?????0110011"
+ val SLL = "0000000??????????001?????0110011"
+ val SLT = "0000000??????????010?????0110011"
+ val SLTU = "0000000??????????011?????0110011"
+ val XOR = "0000000??????????100?????0110011"
+ val SRL = "0000000??????????101?????0110011"
+ val SRA = "0100000??????????101?????0110011"
+ val OR = "0000000??????????110?????0110011"
+ val AND = "0000000??????????111?????0110011"
+ val LB = "?????????????????000?????0000011"
+ val LH = "?????????????????001?????0000011"
+ val LW = "?????????????????010?????0000011"
+ val LBU = "?????????????????100?????0000011"
+ val LHU = "?????????????????101?????0000011"
+ val SB = "?????????????????000?????0100011"
+ val SH = "?????????????????001?????0100011"
+ val SW = "?????????????????010?????0100011"
+ val FENCE = "?????????????????000?????0001111"
+ val MRET = "00110000001000000000000001110011"
+ val WFI = "00010000010100000000000001110011"
+ val CEASE = "00110000010100000000000001110011"
+ val CSRRW = "?????????????????001?????1110011"
+ val CSRRS = "?????????????????010?????1110011"
+ val CSRRC = "?????????????????011?????1110011"
+ val CSRRWI = "?????????????????101?????1110011"
+ val CSRRSI = "?????????????????110?????1110011"
+ val CSRRCI = "?????????????????111?????1110011"
+ val SCALL = "00000000000000000000000001110011"
+ val SBREAK = "00000000000100000000000001110011"
+ val SLLI_RV32 = "0000000??????????001?????0010011"
+ val SRLI_RV32 = "0000000??????????101?????0010011"
+ val SRAI_RV32 = "0100000??????????101?????0010011"
+
+ val A1_X = "??"
+ val A1_ZERO = "00"
+ val A1_RS1 = "01"
+ val A1_PC = "10"
+
+ val IMM_X = "???"
+ val IMM_S = "000"
+ val IMM_SB = "001"
+ val IMM_U = "010"
+ val IMM_UJ = "011"
+ val IMM_I = "100"
+ val IMM_Z = "101"
+
+ val A2_X = "??"
+ val A2_ZERO = "00"
+ val A2_SIZE = "01"
+ val A2_RS2 = "10"
+ val A2_IMM = "11"
+
+ val X = "?"
+ val N = "0"
+ val Y = "1"
+
+ val DW_X = X
+ val DW_XPR = Y
+
+ val M_X = "?????"
+ val M_XRD = "00000"
+ val M_XWR = "00001"
+
+ val CSR_X = "???"
+ val CSR_N = "000"
+ val CSR_I = "100"
+ val CSR_W = "101"
+ val CSR_S = "110"
+ val CSR_C = "111"
+
+ val FN_X = "????"
+ val FN_ADD = "0000"
+ val FN_SL = "0001"
+ val FN_SEQ = "0010"
+ val FN_SNE = "0011"
+ val FN_XOR = "0100"
+ val FN_SR = "0101"
+ val FN_OR = "0110"
+ val FN_AND = "0111"
+ val FN_SUB = "1010"
+ val FN_SRA = "1011"
+ val FN_SLT = "1100"
+ val FN_SGE = "1101"
+ val FN_SLTU = "1110"
+ val FN_SGEU = "1111"
+
+ minimizerTest(TruthTable(
+ Map(
+ BNE -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SNE, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ BEQ -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SEQ, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ BLT -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SLT, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ BLTU -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SLTU, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ BGE -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SGE, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ BGEU -> Seq(Y, N, N, Y, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_SB, DW_X, FN_SGEU, N, M_X, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ JAL -> Seq(Y, N, N, N, Y, N, N, N, N, A2_SIZE, A1_PC, IMM_UJ, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ JALR -> Seq(Y, N, N, N, N, Y, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ AUIPC -> Seq(Y, N, N, N, N, N, N, N, N, A2_IMM, A1_PC, IMM_U, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ LB -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y, M_XRD, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ LH -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y, M_XRD, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ LW -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y, M_XRD, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ LBU -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y, M_XRD, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ LHU -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, Y, M_XRD, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SB -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_IMM, A1_RS1, IMM_S, DW_XPR, FN_ADD, Y, M_XWR, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ SH -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_IMM, A1_RS1, IMM_S, DW_XPR, FN_ADD, Y, M_XWR, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ SW -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_IMM, A1_RS1, IMM_S, DW_XPR, FN_ADD, Y, M_XWR, N, N, N, N, N, N, N, CSR_N, N, N, N, N),
+ LUI -> Seq(Y, N, N, N, N, N, N, N, N, A2_IMM, A1_ZERO, IMM_U, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ ADDI -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SLTI -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_SLT, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SLTIU -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_SLTU, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ ANDI -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_AND, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ ORI -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_OR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ XORI -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_XOR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ ADD -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SUB -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SUB, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SLT -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SLT, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SLTU -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SLTU, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ AND -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_AND, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ OR -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_OR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ XOR -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_XOR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SLL -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SL, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SRL -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SRA -> Seq(Y, N, N, N, N, N, Y, Y, N, A2_RS2, A1_RS1, IMM_X, DW_XPR, FN_SRA, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ FENCE -> Seq(Y, N, N, N, N, N, N, N, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_N, N, Y, N, N),
+ SCALL -> Seq(Y, N, N, N, N, N, N, X, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_I, N, N, N, N),
+ SBREAK -> Seq(Y, N, N, N, N, N, N, X, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_I, N, N, N, N),
+ MRET -> Seq(Y, N, N, N, N, N, N, X, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_I, N, N, N, N),
+ WFI -> Seq(Y, N, N, N, N, N, N, X, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_I, N, N, N, N),
+ CEASE -> Seq(Y, N, N, N, N, N, N, X, N, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, N, N, N, N, N, N, N, CSR_I, N, N, N, N),
+ CSRRW -> Seq(Y, N, N, N, N, N, N, Y, N, A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_W, N, N, N, N),
+ CSRRS -> Seq(Y, N, N, N, N, N, N, Y, N, A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_S, N, N, N, N),
+ CSRRC -> Seq(Y, N, N, N, N, N, N, Y, N, A2_ZERO, A1_RS1, IMM_X, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_C, N, N, N, N),
+ CSRRWI -> Seq(Y, N, N, N, N, N, N, N, N, A2_IMM, A1_ZERO, IMM_Z, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_W, N, N, N, N),
+ CSRRSI -> Seq(Y, N, N, N, N, N, N, N, N, A2_IMM, A1_ZERO, IMM_Z, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_S, N, N, N, N),
+ CSRRCI -> Seq(Y, N, N, N, N, N, N, N, N, A2_IMM, A1_ZERO, IMM_Z, DW_XPR, FN_ADD, N, M_X, N, N, N, N, N, N, Y, CSR_C, N, N, N, N),
+ SLLI_RV32 -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_SL, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SRLI_RV32 -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_SR, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ SRAI_RV32 -> Seq(Y, N, N, N, N, N, N, Y, N, A2_IMM, A1_RS1, IMM_I, DW_XPR, FN_SRA, N, M_X, N, N, N, N, N, N, Y, CSR_N, N, N, N, N),
+ ).map { case (k, v) => BitPat(s"b$k") -> BitPat(s"b${v.reduce(_ + _)}") },
+ BitPat(s"b${Seq(N, X, X, X, X, X, X, X, X, A2_X, A1_X, IMM_X, DW_X, FN_X, N, M_X, X, X, X, X, X, X, X, CSR_X, X, X, X, X).reduce(_ + _)}")
+ ))
+ }
+}
diff --git a/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/QMCSpec.scala b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/QMCSpec.scala
new file mode 100644
index 00000000..fc770202
--- /dev/null
+++ b/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/QMCSpec.scala
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chiselTests.util.experimental.minimizer
+import chisel3.util.experimental.decode.Minimizer
+import chisel3.util.experimental.decode.QMCMinimizer
+
+class QMCSpec extends MinimizerSpec {
+ override def minimizer: Minimizer = QMCMinimizer
+}