From 23ef9aa7ffef5bbf8fe124fc9be7683f005c3612 Mon Sep 17 00:00:00 2001 From: mergify[bot] Date: Tue, 16 Aug 2022 19:04:28 +0000 Subject: Add OpaqueType support to Records (backport #2662) (#2679) * Add OpaqueType support to Records (#2662) OpaqueTypes are essentially type aliases that hide the underlying type. They are implemented in Chisel as Records of a single, unnamed element where the wrapping Record does not exist in the emitted FIRRTL. Co-authored-by: Jack Koenig (cherry picked from commit df5afee2d41b5bcd82d4013b977965c0dfe046fd) * Fix test compilation * Fix OpaqueType tests in RecordSpec Need to implement cloneType correctly and to warn instead of error when accessing .toTarget of non-hardware types because that is a warning (not error) in 3.5. * Waive MiMa false positives Co-authored-by: Aditya Naik <91489422+adkian-sifive@users.noreply.github.com> Co-authored-by: Jack Koenig --- core/src/main/scala/chisel3/Aggregate.scala | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'core/src/main/scala/chisel3/Aggregate.scala') diff --git a/core/src/main/scala/chisel3/Aggregate.scala b/core/src/main/scala/chisel3/Aggregate.scala index 82c02cbc..042e78b1 100644 --- a/core/src/main/scala/chisel3/Aggregate.scala +++ b/core/src/main/scala/chisel3/Aggregate.scala @@ -923,6 +923,20 @@ trait VecLike[T <: Data] extends IndexedSeq[T] with HasId with SourceInfoDoc { */ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptions) extends Aggregate { + /** Indicates if this Record represents an "Opaque Type" + * + * Opaque types provide a mechanism for user-defined types + * that do not impose any "boxing" overhead in the emitted FIRRTL and Verilog. + * You can think about an opaque type Record as a box around + * a single element that only exists at Chisel elaboration time. + * Put another way, if opaqueType is overridden to true, + * The Record may only contain a single element with an empty name + * and there will be no `_` in the name for that element in the emitted Verilog. + * + * @see RecordSpec in Chisel's tests for example usage and expected output + */ + def opaqueType: Boolean = false + // Doing this earlier than onModuleClose allows field names to be available for prefixing the names // of hardware created when connecting to one of these elements private def setElementRefs(): Unit = { @@ -930,7 +944,13 @@ abstract class Record(private[chisel3] implicit val compileOptions: CompileOptio // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog // which can cause collisions val _namespace = Namespace.empty - for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name, leadingDigitOk = true)) } + require( + !opaqueType || (elements.size == 1 && elements.head._1 == ""), + s"Opaque types must have exactly one element with an empty name, not ${elements.size}: ${elements.keys.mkString(", ")}" + ) + for ((name, elt) <- elements) { + elt.setRef(this, _namespace.name(name, leadingDigitOk = true), opaque = opaqueType) + } } private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection): Unit = { -- cgit v1.2.3