diff --git a/src/main/scala/chiseltest/internal/BackendExecutive.scala b/src/main/scala/chiseltest/internal/BackendExecutive.scala index 6a2937909..7e9e99d36 100644 --- a/src/main/scala/chiseltest/internal/BackendExecutive.scala +++ b/src/main/scala/chiseltest/internal/BackendExecutive.scala @@ -23,7 +23,7 @@ object BackendExecutive { val (highFirrtl, dut) = Compiler.elaborate(dutGen, testersAnnotationSeq, chiselAnnos) // extract port names - val portNames = DataMirror.modulePorts(dut).flatMap { case (name, data) => getDataNames(name, data).toList }.toMap + val portNames = DataMirror.fullModulePorts(dut).map(_.swap).toMap // compile to low firrtl val lowFirrtl = Compiler.toLowFirrtl(highFirrtl) @@ -55,15 +55,6 @@ object BackendExecutive { private def componentToName(component: ReferenceTarget): String = component.name - /** Returns a Seq of (data reference, fully qualified element names) for the input. - * name is the name of data - */ - private def getDataNames(name: String, data: Data): Seq[(Data, String)] = Seq(data -> name) ++ (data match { - case _: Element => Seq() - case b: Record => b.elements.toSeq.flatMap { case (n, e) => getDataNames(s"${name}_$n", e) } - case v: Vec[_] => v.zipWithIndex.flatMap { case (e, i) => getDataNames(s"${name}_$i", e) } - }) - /** This creates some kind of map of combinational paths between inputs and outputs. * * @param dut use this to figure out which paths involve top level iO diff --git a/src/main/scala/chiseltest/internal/PeekPokeTesterBackend.scala b/src/main/scala/chiseltest/internal/PeekPokeTesterBackend.scala index 2d97b5fd7..537e60127 100644 --- a/src/main/scala/chiseltest/internal/PeekPokeTesterBackend.scala +++ b/src/main/scala/chiseltest/internal/PeekPokeTesterBackend.scala @@ -28,7 +28,7 @@ object PeekPokeTesterBackend { ): AnnotationSeq = { val (sim, covAnnos, dut) = createTester(dutGen, defaults.addDefaultSimulator(annos), chiselAnnos) // extract port names - val portNames = DataMirror.modulePorts(dut).flatMap { case (name, data) => getDataNames(name, data).toList }.toMap + val portNames = DataMirror.fullModulePorts(dut).map(_.swap).toMap val localCtx = IOTestersContext(sim, portNames) // run tests @@ -48,13 +48,6 @@ object PeekPokeTesterBackend { finish(sim, covAnnos) } - /** Returns a Seq of (data reference, fully qualified element names) for the input. name is the name of data. */ - private def getDataNames(name: String, data: Data): Seq[(Data, String)] = Seq(data -> name) ++ (data match { - case _: Element => Seq() - case b: Record => b.elements.toSeq.flatMap { case (n, e) => getDataNames(s"${name}_$n", e) } - case v: Vec[_] => v.zipWithIndex.flatMap { case (e, i) => getDataNames(s"${name}_$i", e) } - }) - } private[chiseltest] case class IOTestersContext(backend: SimulatorContext, dataNames: Map[Data, String]) diff --git a/src/test/scala/chiseltest/tests/OpaqueTypeTest.scala b/src/test/scala/chiseltest/tests/OpaqueTypeTest.scala new file mode 100644 index 000000000..9b236d2bd --- /dev/null +++ b/src/test/scala/chiseltest/tests/OpaqueTypeTest.scala @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chiseltest.tests + +import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor +import chisel3.experimental.OpaqueType +import chisel3._ +import chiseltest._ +import chiseltest.iotesters.PeekPokeTester +import org.scalatest.flatspec.AnyFlatSpec + +import scala.collection.immutable.SeqMap + +class OpaqueTypeTest extends AnyFlatSpec with ChiselScalatestTester { + + class OpaqueRecord[T <: Data](val data: T) extends Record with OpaqueType { + val elements: SeqMap[String, T] = SeqMap("" -> data) + } + + class OpaquePassthrough[T <: Data](data: T) extends Module { + val in: OpaqueRecord[T] = IO(Input(new OpaqueRecord(data))) + val out: OpaqueRecord[T] = IO(Output(new OpaqueRecord(data))) + out := in + } + + def rec[T <: Data](_val: => T): OpaqueRecord[T] = new OpaqueRecord(_val.cloneType: T).Lit(_.data -> _val) + + def testPokeExpect[T <: Data](_val: => T): TestResult = + test(new OpaquePassthrough(_val.cloneType)) { dut => + dut.in.poke(rec(_val)) + dut.out.expect(rec(_val)) + } + + class PokeExpectTester[T <: Data](dut: OpaquePassthrough[T], _val: => T) extends PeekPokeTester(dut) { + poke(dut.in, IndexedSeq(_val.litValue)) + expect(dut.out, IndexedSeq(_val.litValue)) + } + + def testPokeExpectTester[T <: Data](_val: => T): Unit = + test(new OpaquePassthrough(_val.cloneType)) + .runPeekPoke(new PokeExpectTester(_, _val)) + + behavior of "OpaqueType" + + it should "poke and expect successfully" in { + testPokeExpect(4.U(6.W)) + testPokeExpect(-4.S(8.W)) + testPokeExpect(rec(5.U(3.W))) + } + + it should "poke and expect successfully using PeekPokeTester" in { + testPokeExpectTester(4.U(6.W)) + testPokeExpectTester(-4.S(8.W)) + testPokeExpectTester(rec(5.U(3.W))) + } + +} diff --git a/src/test/scala/treadle2/FailSpec.scala b/src/test/scala/treadle2/FailSpec.scala index 438f355a4..0b86f8bb2 100644 --- a/src/test/scala/treadle2/FailSpec.scala +++ b/src/test/scala/treadle2/FailSpec.scala @@ -9,7 +9,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers class FailSpec extends AnyFlatSpec with Matchers { - behavior.of("explict fail") + behavior.of("explicit fail") it should "fail a test with an explicit failure code" in { val input =