diff options
| -rw-r--r-- | core/src/main/scala/chisel3/Data.scala | 26 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/experimental/DataMirrorSpec.scala | 58 |
2 files changed, 84 insertions, 0 deletions
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala index 77ad66ef..cb8f4683 100644 --- a/core/src/main/scala/chisel3/Data.scala +++ b/core/src/main/scala/chisel3/Data.scala @@ -12,6 +12,7 @@ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{DeprecatedSourceInfo, SourceInfo, SourceInfoTransform, UnlocatableSourceInfo} import scala.collection.immutable.LazyList // Needed for 2.12 alias +import scala.reflect.ClassTag import scala.util.Try /** User-specified directions. @@ -157,6 +158,31 @@ package experimental { target.direction } + private def hasBinding[B <: ConstrainedBinding: ClassTag](target: Data) = { + target.topBindingOpt match { + case Some(b: B) => true + case _ => false + } + } + + /** Check if a given `Data` is an IO port + * @param x the `Data` to check + * @return `true` if x is an IO port, `false` otherwise + */ + def isIO(x: Data): Boolean = hasBinding[PortBinding](x) + + /** Check if a given `Data` is a Wire + * @param x the `Data` to check + * @return `true` if x is a Wire, `false` otherwise + */ + def isWire(x: Data): Boolean = hasBinding[WireBinding](x) + + /** Check if a given `Data` is a Reg + * @param x the `Data` to check + * @return `true` if x is a Reg, `false` otherwise + */ + def isReg(x: Data): Boolean = hasBinding[RegBinding](x) + /** Check if two Chisel types are the same type. * Internally, this is dispatched to each Chisel type's * `typeEquivalent` function for each type to determine diff --git a/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala b/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala new file mode 100644 index 00000000..731596ec --- /dev/null +++ b/src/test/scala/chiselTests/experimental/DataMirrorSpec.scala @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chiselTests.experimental + +import chisel3._ +import chisel3.util.Valid +import chisel3.stage.ChiselStage +import chisel3.experimental.DataMirror +import chiselTests.ChiselFlatSpec + +class DataMirrorSpec extends ChiselFlatSpec { + behavior.of("DataMirror") + + def assertBinding(x: Data, io: Boolean, wire: Boolean, reg: Boolean) = { + DataMirror.isIO(x) should be(io) + DataMirror.isWire(x) should be(wire) + DataMirror.isReg(x) should be(reg) + } + + def assertIO(x: Data) = assertBinding(x, true, false, false) + + def assertWire(x: Data) = assertBinding(x, false, true, false) + + def assertReg(x: Data) = assertBinding(x, false, false, true) + + def assertNone(x: Data) = assertBinding(x, false, false, false) + + it should "validate bindings" in { + class MyModule extends Module { + val typ = UInt(4.W) + val vectyp = Vec(8, UInt(4.W)) + val io = IO(new Bundle { + val in = Input(UInt(4.W)) + val vec = Input(vectyp) + val out = Output(UInt(4.W)) + }) + val vec = Wire(vectyp) + val regvec = Reg(vectyp) + val wire = Wire(UInt(4.W)) + val reg = RegNext(wire) + + assertIO(io) + assertIO(io.in) + assertIO(io.out) + assertIO(io.vec(1)) + assertIO(io.vec) + assertWire(vec) + assertWire(vec(0)) + assertWire(wire) + assertReg(reg) + assertReg(regvec) + assertReg(regvec(2)) + assertNone(typ) + assertNone(vectyp) + } + ChiselStage.elaborate(new MyModule) + } +} |
