summaryrefslogtreecommitdiff
path: root/src/test/scala/chiselTests/BundleElementsSpec.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/scala/chiselTests/BundleElementsSpec.scala')
-rw-r--r--src/test/scala/chiselTests/BundleElementsSpec.scala564
1 files changed, 0 insertions, 564 deletions
diff --git a/src/test/scala/chiselTests/BundleElementsSpec.scala b/src/test/scala/chiselTests/BundleElementsSpec.scala
deleted file mode 100644
index afca3d81..00000000
--- a/src/test/scala/chiselTests/BundleElementsSpec.scala
+++ /dev/null
@@ -1,564 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-package chiselTests
-
-import chisel3._
-import chisel3.experimental.FixedPoint
-import chisel3.stage.ChiselStage
-import chisel3.util.Decoupled
-import org.scalatest.exceptions.TestFailedException
-import org.scalatest.freespec.AnyFreeSpec
-import org.scalatest.matchers.should.Matchers
-
-import scala.language.reflectiveCalls
-
-/* Rich and complicated bundle examples
- */
-trait BpipSuperTraitWithField {
- val bpipSuperTraitGood = SInt(17.W)
- def bpipSuperTraitBad = SInt(22.W)
-}
-
-trait BpipTraitWithField extends BpipSuperTraitWithField {
- val bpipTraitGood = SInt(17.W)
- def bpipTraitBad = SInt(22.W)
-}
-
-class BpipOneField extends Bundle with BpipTraitWithField {
- val bpipOneFieldOne = SInt(8.W)
- val bpipOneFieldTwo = SInt(8.W)
-}
-
-class BpipTwoField extends BpipOneField {
- val bpipTwoFieldOne = SInt(8.W)
- val bpipTwoFieldTwo = Vec(4, UInt(12.W))
- val myInt = 7
- val baz = Decoupled(UInt(16.W))
-}
-
-class BpipDecoupled extends BpipOneField {
- val bpipDecoupledSInt = SInt(8.W)
- val bpipDecoupledVec = Vec(4, UInt(12.W))
- val bpipDecoupledDecoupled = Decoupled(UInt(16.W))
-}
-
-class HasDecoupledBundleByInheritance extends Module {
- val out1 = IO(Output(new BpipDecoupled))
- assertElementsMatchExpected(out1)(
- "bpipDecoupledDecoupled" -> _.bpipDecoupledDecoupled,
- "bpipDecoupledVec" -> _.bpipDecoupledVec,
- "bpipDecoupledSInt" -> _.bpipDecoupledSInt,
- "bpipOneFieldTwo" -> _.bpipOneFieldTwo,
- "bpipOneFieldOne" -> _.bpipOneFieldOne,
- "bpipTraitGood" -> _.bpipTraitGood,
- "bpipSuperTraitGood" -> _.bpipSuperTraitGood
- )
-}
-
-/* plugin should not affect the seq detection */
-class DebugProblem3 extends Module {
- val out1 = IO(Output(new BpipTwoField))
- assertElementsMatchExpected(out1)(
- "baz" -> _.baz,
- "bpipTwoFieldTwo" -> _.bpipTwoFieldTwo,
- "bpipTwoFieldOne" -> _.bpipTwoFieldOne,
- "bpipOneFieldTwo" -> _.bpipOneFieldTwo,
- "bpipOneFieldOne" -> _.bpipOneFieldOne,
- "bpipTraitGood" -> _.bpipTraitGood,
- "bpipSuperTraitGood" -> _.bpipSuperTraitGood
- )
-}
-
-class BpipBadSeqBundle extends Bundle {
- val bpipBadSeqBundleGood = UInt(999.W)
- val bpipBadSeqBundleBad = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
-}
-
-class HasBadSeqBundle extends Module {
- val out1 = IO(Output(new BpipBadSeqBundle))
-}
-
-class BpipBadSeqBundleWithIgnore extends Bundle with IgnoreSeqInBundle {
- val goodFieldWithIgnore = UInt(999.W)
- val badSeqFieldWithIgnore = Seq(UInt(16.W), UInt(8.W), UInt(4.W))
-}
-
-class UsesIgnoreSeqInBundle extends Module {
- val out1 = IO(Output(new BpipBadSeqBundleWithIgnore))
-}
-
-/* This is mostly a test of the field order */
-class BpipP8_1 extends Bundle {
- val field_1_1 = UInt(11.W)
- val field_1_2 = UInt(12.W)
-}
-
-class BpipP8_2 extends BpipP8_1 {
- val field_2_1 = UInt(11.W)
- val field_2_2 = UInt(12.W)
-}
-
-class BpipP8_3 extends BpipP8_2 {
- val field_3_1 = UInt(11.W)
- val field_3_2 = UInt(12.W)
-}
-
-/* plugin should not affect the seq detection */
-class ForFieldOrderingTest extends Module {
- val out1 = IO(Output(new BpipP8_3))
- out1 := DontCare
- assertElementsMatchExpected(out1)(
- "field_3_2" -> _.field_3_2,
- "field_3_1" -> _.field_3_1,
- "field_2_2" -> _.field_2_2,
- "field_2_1" -> _.field_2_1,
- "field_1_2" -> _.field_1_2,
- "field_1_1" -> _.field_1_1
- )
-}
-
-/* plugin should allow parameter var fields */
-class HasValParamsToBundle extends Module {
- // The following block does not work, suggesting that ParamIsField is not a case we need to solve
- class BpipParamIsField0(val paramField0: UInt) extends Bundle
- class BpipParamIsField1(val paramField1: UInt) extends BpipParamIsField0(UInt(66.W))
-
- val out3 = IO(Output(new BpipParamIsField1(UInt(10.W))))
- val out4 = IO(Output(new BpipParamIsField1(UInt(10.W))))
- out3 := DontCare
- assertElementsMatchExpected(out3)("paramField0" -> _.paramField0, "paramField1" -> _.paramField1)
- assertElementsMatchExpected(out4)("paramField0" -> _.paramField0, "paramField1" -> _.paramField1)
-}
-
-class HasGenParamsPassedToSuperclasses extends Module {
-
- class OtherBundle extends Bundle {
- val otherField = UInt(55.W)
- }
-
- class BpipWithGen[T <: Data, TT <: Data](gen: T, gen2: => TT) extends Bundle {
- val superFoo = gen
- val superQux = gen2
- }
-
-// class BpipDemoBundle[T <: Data](gen: T, gen2: => T) extends BpipTwoField with BpipVarmint {
- class BpipUsesWithGen[T <: Data](gen: T, gen2: => T) extends BpipWithGen(gen, gen2) {
- // val foo = gen
- val bar = Bool()
- val qux = gen2
- val bad = 444
- val baz = Decoupled(UInt(16.W))
- }
-
- val out1 = IO(Output(new BpipUsesWithGen(UInt(4.W), new OtherBundle)))
- val out2 = IO(Output(new BpipUsesWithGen(UInt(4.W), FixedPoint(10.W, 4.BP))))
-
- out1 := DontCare
-
- assertElementsMatchExpected(out1)(
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "superQux" -> _.superQux,
- "superFoo" -> _.superFoo
- )
- assertElementsMatchExpected(out2)(
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "superQux" -> _.superQux,
- "superFoo" -> _.superFoo
- )
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class UsesGenFiedldsInSuperClass extends Module {
- class BpipWithGen[T <: Data](gen: T) extends Bundle {
- val superFoo = gen
- val superQux = gen
- }
-
- class BpipUsesWithGen[T <: Data](gen: T) extends BpipWithGen(gen) {}
-
- val out = IO(Output(new BpipUsesWithGen(UInt(4.W))))
-
- out := DontCare
-
- assertElementsMatchExpected(out)()
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class BpipBadBundleWithHardware extends Bundle {
- val bpipWithHardwareGood = UInt(8.W)
- val bpipWithHardwareBad = 244.U(16.W)
-}
-
-class HasHardwareFieldsInBundle extends Module {
- val out = IO(Output(new BpipBadBundleWithHardware))
- assertElementsMatchExpected(out)()
-}
-
-/* This is legal because of =>
- */
-class UsesBundleWithGeneratorField extends Module {
- class BpipWithGen[T <: Data](gen: => T) extends Bundle {
- val superFoo = gen
- val superQux = gen
- }
-
- class BpipUsesWithGen[T <: Data](gen: => T) extends BpipWithGen(gen)
-
- val out = IO(Output(new BpipUsesWithGen(UInt(4.W))))
-
- out := DontCare
-
- assertElementsMatchExpected(out)("superQux" -> _.superQux, "superFoo" -> _.superFoo)
-}
-
-/* Testing whether gen fields superFoo and superQux can be found when they are
- * declared in a superclass
- *
- */
-class BundleElementsSpec extends AnyFreeSpec with Matchers {
-
- /** Tests a whole bunch of different Bundle constructions
- */
- class BpipIsComplexBundle extends Module {
-
- trait BpipVarmint {
- val varmint = Bool()
-
- def vermin = Bool()
-
- private val puppy = Bool()
- }
-
- abstract class BpipAbstractBundle extends Bundle {
- def doNothing: Unit
-
- val fromAbstractBundle = UInt(22.W)
- }
-
- class BpipOneField extends Bundle {
- val fieldOne = SInt(8.W)
- }
-
- class BpipTwoField extends BpipOneField {
- val fieldTwo = SInt(8.W)
- val fieldThree = Vec(4, UInt(12.W))
- }
-
- class BpipAnimalBundle(w1: Int, w2: Int) extends Bundle {
- val dog = SInt(w1.W)
- val fox = UInt(w2.W)
- }
-
- class BpipDemoBundle[T <: Data](gen: T, gen2: => T) extends BpipTwoField with BpipVarmint {
- val foo = gen
- val bar = Bool()
- val qux = gen2
- val bad = 44
- val baz = Decoupled(UInt(16.W))
- val animals = new BpipAnimalBundle(4, 8)
- }
-
- val out = IO(Output(new BpipDemoBundle(UInt(4.W), FixedPoint(10.W, 4.BP))))
-
- val out2 = IO(Output(new BpipAbstractBundle {
- override def doNothing: Unit = ()
-
- val notAbstract: Bool = Bool()
- }))
-
- val out4 = IO(Output(new BpipAnimalBundle(99, 100)))
- val out5 = IO(Output(new BpipTwoField))
-
- out := DontCare
- out5 := DontCare
-
- assertElementsMatchExpected(out)(
- "animals" -> _.animals,
- "baz" -> _.baz,
- "qux" -> _.qux,
- "bar" -> _.bar,
- "varmint" -> _.varmint,
- "fieldThree" -> _.fieldThree,
- "fieldTwo" -> _.fieldTwo,
- "fieldOne" -> _.fieldOne,
- "foo" -> _.foo
- )
- assertElementsMatchExpected(out5)("fieldThree" -> _.fieldThree, "fieldTwo" -> _.fieldTwo, "fieldOne" -> _.fieldOne)
- assertElementsMatchExpected(out2)("notAbstract" -> _.notAbstract, "fromAbstractBundle" -> _.fromAbstractBundle)
- assertElementsMatchExpected(out4)("fox" -> _.fox, "dog" -> _.dog)
- }
-
- "Complex Bundle with inheritance, traits and params. DebugProblem1" in {
- ChiselStage.emitFirrtl(new BpipIsComplexBundle)
- }
-
- "Decoupled Bundle with inheritance" in {
- ChiselStage.emitFirrtl(new HasDecoupledBundleByInheritance)
- }
-
- "Simple bundle inheritance. DebugProblem3" in {
- ChiselStage.emitFirrtl(new DebugProblem3)
- }
-
- "Bundles containing Seq[Data] should be compile erorr. HasBadSeqBundle" in {
- intercept[ChiselException] {
- ChiselStage.emitFirrtl(new HasBadSeqBundle)
- }
- }
-
- "IgnoreSeqInBundle allows Seq[Data] in bundle" in {
- ChiselStage.emitFirrtl(new UsesIgnoreSeqInBundle)
- }
-
- "Simple field ordering test." in {
- ChiselStage.emitFirrtl(new ForFieldOrderingTest)
- }
-
- "Val params to Bundle should be an Exception." in {
- ChiselStage.emitFirrtl(new HasValParamsToBundle)
- }
-
- "Should handle gen params passed to superclasses" in {
- ChiselStage.emitFirrtl(new HasGenParamsPassedToSuperclasses)
- }
-
- "Aliased fields should be detected and throw an exception, because gen: Data, with no =>" in {
- intercept[AliasedAggregateFieldException] {
- ChiselStage.emitFirrtl(new UsesGenFiedldsInSuperClass)
- }
- }
-
- "Error when bundle fields are hardware, such as literal values. HasHardwareFieldsInBundle" in {
- val e = intercept[ExpectedChiselTypeException] {
- ChiselStage.emitFirrtl(new HasHardwareFieldsInBundle)
- }
- e.getMessage should include(
- "Bundle: BpipBadBundleWithHardware contains hardware fields: bpipWithHardwareBad: UInt<16>(244)"
- )
- }
-
- "Aliased fields not created when using gen: => Data" in {
- ChiselStage.emitFirrtl(new UsesBundleWithGeneratorField)
- }
-
- class OptionBundle(val hasIn: Boolean) extends Bundle {
- val in = if (hasIn) {
- Some(Input(Bool()))
- } else {
- None
- }
- val out = Output(Bool())
- }
-
- class UsesBundleWithOptionFields extends Module {
- val outTrue = IO(Output(new OptionBundle(hasIn = true)))
- val outFalse = IO(Output(new OptionBundle(hasIn = false)))
- //NOTE: The _.in.get _.in is an optional field
- assertElementsMatchExpected(outTrue)("out" -> _.out, "in" -> _.in.get)
- assertElementsMatchExpected(outFalse)("out" -> _.out)
- }
-
- "plugin should work with Bundles with Option fields" in {
- ChiselStage.emitFirrtl(new UsesBundleWithOptionFields)
- }
-
- "plugin should work with enums in bundles" in {
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- ChiselStage.emitFirrtl(new Module {
- val out = IO(Output(new Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }))
- assertElementsMatchExpected(out)("b" -> _.b, "a" -> _.a)
- })
- }
-
- "plugin will NOT see fields that are Data but declared in some way as Any" in {
- //This is not incompatible with chisel not using the plugin, but this code is considered bad practice
-
- ChiselStage.emitFirrtl(new Module {
- val out = IO(Output(new Bundle {
- val a = UInt(8.W)
- val b: Any = Bool()
- }))
-
- intercept[TestFailedException] {
- assert(out.elements.keys.exists(_ == "b"))
- }
- })
- }
-
- "plugin tests should fail properly in the following cases" - {
-
- class BundleAB extends Bundle {
- val a = Output(UInt(8.W))
- val b = Output(Bool())
- }
-
- def checkAssertion(checks: (BundleAB => (String, Data))*)(expectedMessage: String): Unit = {
- intercept[AssertionError] {
- ChiselStage.emitFirrtl(new Module {
- val out = IO(new BundleAB)
- assertElementsMatchExpected(out)(checks: _*)
- })
- }.getMessage should include(expectedMessage)
- }
-
- "one of the expected data values is wrong" in {
- checkAssertion("b" -> _.b, "a" -> _.b)("field 'a' data field BundleElementsSpec_Anon.out.a")
- }
-
- "one of the expected field names in wrong" in {
- checkAssertion("b" -> _.b, "z" -> _.a)("field: 'a' did not match expected 'z'")
- }
-
- "fields that are expected are not returned by the elements method" in {
- checkAssertion("b" -> _.b, "a" -> _.a, "c" -> _.a)("#elements is missing the 'c' field")
- }
-
- "fields returned by the element are not specified in the expected fields" in {
- checkAssertion("b" -> _.b)("expected fields did not include 'a' field found in #elements")
- }
-
- "multiple errors between elements method and expected fields are shown in the assertion error message" in {
- checkAssertion()(
- "expected fields did not include 'b' field found in #elements," +
- " expected fields did not include 'a' field found in #elements"
- )
- }
- }
-
- "plugin should error correctly when bundles contain only a Option field" in {
- ChiselStage.emitFirrtl(new Module {
- val io = IO(new Bundle {
- val foo = Input(UInt(8.W))
- val x = new Bundle {
- val y = if (false) Some(Input(UInt(8.W))) else None
- }
- })
- assertElementsMatchExpected(io)("x" -> _.x, "foo" -> _.foo)
- assertElementsMatchExpected(io.x)()
- })
- }
-
- "plugin should handle fields using the boolean to option construct" in {
- case class ALUConfig(
- xLen: Int,
- mul: Boolean,
- b: Boolean)
-
- class OptionalBundle extends Bundle {
- val optionBundleA = Input(UInt(3.W))
- val optionBundleB = Input(UInt(7.W))
- }
-
- class ALU(c: ALUConfig) extends Module {
-
- class BpipOptionBundle extends Bundle with IgnoreSeqInBundle {
- val bpipUIntVal = Input(UInt(8.W))
- lazy val bpipUIntLazyVal = Input(UInt(8.W))
- var bpipUIntVar = Input(UInt(8.W))
-
- def bpipUIntDef = Input(UInt(8.W))
-
- val bpipOptionUInt = Some(Input(UInt(16.W)))
- val bpipOptionOfBundle = if (c.b) Some(new OptionalBundle) else None
- val bpipSeqData = Seq(UInt(8.W), UInt(8.W))
- }
-
- val io = IO(new BpipOptionBundle)
- assertElementsMatchExpected(io)(
- "bpipUIntLazyVal" -> _.bpipUIntLazyVal,
- "bpipOptionUInt" -> _.bpipOptionUInt.get,
- "bpipUIntVar" -> _.bpipUIntVar,
- "bpipUIntVal" -> _.bpipUIntVal
- )
- }
-
- ChiselStage.emitFirrtl(new ALU(ALUConfig(10, mul = true, b = false)))
- }
-
- "TraceSpec test, different version found in TraceSpec.scala" in {
- class Bundle0 extends Bundle {
- val a = UInt(8.W)
- val b = Bool()
- val c = Enum0.Type
- }
-
- class Bundle1 extends Bundle {
- val a = new Bundle0
- val b = Vec(4, Vec(4, Bool()))
- }
-
- class Module0 extends Module {
- val i = IO(Input(new Bundle1))
- val o = IO(Output(new Bundle1))
- val r = Reg(new Bundle1)
- o := r
- r := i
-
- assertElementsMatchExpected(i)("b" -> _.b, "a" -> _.a)
- assertElementsMatchExpected(o)("b" -> _.b, "a" -> _.a)
- assertElementsMatchExpected(r)("b" -> _.b, "a" -> _.a)
- }
-
- class Module1 extends Module {
- val i = IO(Input(new Bundle1))
- val m0 = Module(new Module0)
- m0.i := i
- m0.o := DontCare
- assertElementsMatchExpected(i)("b" -> _.b, "a" -> _.a)
- }
-
- object Enum0 extends ChiselEnum {
- val s0, s1, s2 = Value
- }
-
- ChiselStage.emitFirrtl(new Module1)
- }
-}
-/* Checks that the elements method of a bundle matches the testers idea of what the bundle field names and their
- * associated data match and that they have the same number of fields in the same order
- */
-object assertElementsMatchExpected {
- def apply[T <: Bundle](bun: T)(checks: (T => (String, Data))*): Unit = {
- val expected = checks.map { fn => fn(bun) }
- val elements = bun.elements
- val missingMsg = "missing field in #elements"
- val extraMsg = "extra field in #elements"
- val paired = elements.toSeq.zipAll(expected, missingMsg -> UInt(1.W), extraMsg -> UInt(1.W))
- val errorsStrings = paired.flatMap {
- case (element, expected) =>
- val (elementName, elementData) = element
- val (expectedName, expectedData) = expected
- if (elementName == missingMsg) {
- Some(s"#elements is missing the '$expectedName' field")
- } else if (expectedName == extraMsg) {
- Some(s"expected fields did not include '$elementName' field found in #elements")
- } else if (elementName != expectedName) {
- Some(s"field: '$elementName' did not match expected '$expectedName'")
- } else if (elementData != expectedData) {
- Some(
- s"field '$elementName' data field ${elementData}(${elementData.hashCode}) did not match expected $expectedData(${expectedData.hashCode})"
- )
- } else {
- None
- }
- }
- assert(errorsStrings.isEmpty, s"Bundle: ${bun.getClass.getName}: " + errorsStrings.mkString(", "))
- }
-}