summaryrefslogtreecommitdiff
path: root/core/src/main/scala/chisel3/experimental
diff options
context:
space:
mode:
authorJack2022-11-11 06:53:04 +0000
committerJack2022-11-11 06:53:04 +0000
commit3ce953c81f06519351c48277e3474b5720ec07ff (patch)
treeac79dcb80d0528c2ae86ca21da4cf424715ab645 /core/src/main/scala/chisel3/experimental
parentadccde9998c91875e5490cff6d5822ffacc593ed (diff)
parentc8046636a25474be4c547c6fe9c6d742ea7b1d13 (diff)
Merge branch '3.5.x' into 3.5-release
Diffstat (limited to 'core/src/main/scala/chisel3/experimental')
-rw-r--r--core/src/main/scala/chisel3/experimental/Analog.scala3
-rw-r--r--core/src/main/scala/chisel3/experimental/Attach.scala45
-rw-r--r--core/src/main/scala/chisel3/experimental/OpaqueType.scala27
-rw-r--r--core/src/main/scala/chisel3/experimental/Trace.scala50
-rw-r--r--core/src/main/scala/chisel3/experimental/dataview/DataView.scala23
-rw-r--r--core/src/main/scala/chisel3/experimental/dataview/package.scala14
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala2
-rw-r--r--core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala17
-rw-r--r--core/src/main/scala/chisel3/experimental/package.scala28
9 files changed, 185 insertions, 24 deletions
diff --git a/core/src/main/scala/chisel3/experimental/Analog.scala b/core/src/main/scala/chisel3/experimental/Analog.scala
index a366f0c3..7d89025c 100644
--- a/core/src/main/scala/chisel3/experimental/Analog.scala
+++ b/core/src/main/scala/chisel3/experimental/Analog.scala
@@ -69,7 +69,8 @@ final class Analog private (private[chisel3] val width: Width) extends Element {
}
targetTopBinding match {
- case _: WireBinding | _: PortBinding => direction = ActualDirection.Bidirectional(ActualDirection.Default)
+ case _: WireBinding | _: PortBinding | _: ViewBinding | _: AggregateViewBinding =>
+ direction = ActualDirection.Bidirectional(ActualDirection.Default)
case x => throwException(s"Analog can only be Ports and Wires, not '$x'")
}
binding = target
diff --git a/core/src/main/scala/chisel3/experimental/Attach.scala b/core/src/main/scala/chisel3/experimental/Attach.scala
new file mode 100644
index 00000000..5c9cfe53
--- /dev/null
+++ b/core/src/main/scala/chisel3/experimental/Attach.scala
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.experimental
+
+import chisel3.RawModule
+import chisel3.internal._
+import chisel3.internal.Builder.pushCommand
+import chisel3.internal.firrtl._
+import chisel3.internal.sourceinfo.SourceInfo
+
+object attach {
+ // Exceptions that can be generated by attach
+ case class AttachException(message: String) extends ChiselException(message)
+ def ConditionalAttachException: AttachException =
+ AttachException(": Conditional attach is not allowed!")
+
+ // Actual implementation
+ private[chisel3] def impl(elts: Seq[Analog], contextModule: RawModule)(implicit sourceInfo: SourceInfo): Unit = {
+ if (Builder.whenDepth != 0) throw ConditionalAttachException
+
+ // TODO Check that references are valid and can be attached
+
+ pushCommand(Attach(sourceInfo, elts.map(_.lref)))
+ }
+
+ /** Create an electrical connection between [[Analog]] components
+ *
+ * @param elts The components to attach
+ *
+ * @example
+ * {{{
+ * val a1 = Wire(Analog(32.W))
+ * val a2 = Wire(Analog(32.W))
+ * attach(a1, a2)
+ * }}}
+ */
+ def apply(elts: Analog*)(implicit sourceInfo: SourceInfo): Unit = {
+ try {
+ impl(elts, Builder.forcedUserModule)
+ } catch {
+ case AttachException(message) =>
+ throwException(elts.mkString("Attaching (", ", ", s") failed @$message"))
+ }
+ }
+}
diff --git a/core/src/main/scala/chisel3/experimental/OpaqueType.scala b/core/src/main/scala/chisel3/experimental/OpaqueType.scala
new file mode 100644
index 00000000..e7a2a15d
--- /dev/null
+++ b/core/src/main/scala/chisel3/experimental/OpaqueType.scala
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.experimental
+
+import chisel3._
+
+/** 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 this trait is mixed into a Record,
+ * 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
+ */
+trait OpaqueType { self: Record =>
+
+ /** If set to true, indicates that this Record is an OpaqueType
+ *
+ * Users can override this if they need more dynamic control over the behavior for when
+ * instances of this type are considered opaque
+ */
+ def opaqueType: Boolean = true
+}
diff --git a/core/src/main/scala/chisel3/experimental/Trace.scala b/core/src/main/scala/chisel3/experimental/Trace.scala
index 4ab615a5..eb2ed46a 100644
--- a/core/src/main/scala/chisel3/experimental/Trace.scala
+++ b/core/src/main/scala/chisel3/experimental/Trace.scala
@@ -1,7 +1,7 @@
package chisel3.experimental
import chisel3.internal.HasId
-import chisel3.{Aggregate, Data, Element, Module}
+import chisel3.{Aggregate, Data, Element, Module, RawModule}
import firrtl.AnnotationSeq
import firrtl.annotations.{Annotation, CompleteTarget, SingleTargetAnnotation}
import firrtl.transforms.DontTouchAllTargets
@@ -22,13 +22,22 @@ import firrtl.transforms.DontTouchAllTargets
object Trace {
/** Trace a Instance name. */
- def traceName(x: Module): Unit = {
+ @deprecated("switch to traceNameV2 (until Chisel 3.6)", "3.5.5")
+ def traceName(x: Module): Unit = traceName(x: RawModule)
+
+ /** Trace a Instance name. */
+ @deprecated("switch to traceNameV2 (until Chisel 3.6)", "3.5.5")
+ def traceName(x: RawModule): Unit = {
annotate(new ChiselAnnotation {
def toFirrtl: Annotation = TraceNameAnnotation(x.toAbsoluteTarget, x.toAbsoluteTarget)
})
}
- /** Trace a Data name. */
+ /** Trace a Data name. This adds "don't touch" semantics to anything traced. */
+ @deprecated(
+ "switch to traceNameV2 (until Chisel 3.6) and add dontTouch if you want \"don't touch\" behavior",
+ "3.5.5"
+ )
def traceName(x: Data): Unit = {
x match {
case aggregate: Aggregate =>
@@ -43,7 +52,29 @@ object Trace {
}
}
- /** An Annotation that records the original target annotate from Chisel.
+ /** Trace an Instance name. */
+ def traceNameV2(x: RawModule): Unit = {
+ annotate(new ChiselAnnotation {
+ def toFirrtl: Annotation = TraceAnnotation(x.toAbsoluteTarget, x.toAbsoluteTarget)
+ })
+ }
+
+ /** Trace a Data name. This does NOT add "don't touch" semantics to the traced data. If you want this behavior, use an explicit [[chisel3.dontTouch]]. */
+ def traceNameV2(x: Data): Unit = {
+ x match {
+ case aggregate: Aggregate =>
+ annotate(new ChiselAnnotation {
+ def toFirrtl: Annotation = TraceAnnotation(aggregate.toAbsoluteTarget, aggregate.toAbsoluteTarget)
+ })
+ aggregate.elementsIterator.foreach(traceNameV2)
+ case element: Element =>
+ annotate(new ChiselAnnotation {
+ def toFirrtl: Annotation = TraceAnnotation(element.toAbsoluteTarget, element.toAbsoluteTarget)
+ })
+ }
+ }
+
+ /** An Annotation that records the original target annotate from Chisel. This adds don't touch behavior.
*
* @param target target that should be renamed by [[firrtl.RenameMap]] in the firrtl transforms.
* @param chiselTarget original annotated target in Chisel, which should not be changed or renamed in FIRRTL.
@@ -54,6 +85,16 @@ object Trace {
def duplicate(n: T): Annotation = this.copy(target = n)
}
+ /** An Annotation that records the original target annotate from Chisel. This does NOT add don't touch behavior.
+ *
+ * @param target target that should be renamed by [[firrtl.RenameMap]] in the firrtl transforms.
+ * @param chiselTarget original annotated target in Chisel, which should not be changed or renamed in FIRRTL.
+ */
+ private case class TraceAnnotation[T <: CompleteTarget](target: T, chiselTarget: T)
+ extends SingleTargetAnnotation[T] {
+ def duplicate(n: T): Annotation = this.copy(target = n)
+ }
+
/** Get [[CompleteTarget]] of the target `x` for `annos`.
* This API can be used to find the final reference to a signal or module which is marked by `traceName`
*/
@@ -65,5 +106,6 @@ object Trace {
*/
def finalTargetMap(annos: AnnotationSeq): Map[CompleteTarget, Seq[CompleteTarget]] = annos.collect {
case TraceNameAnnotation(t, chiselTarget) => chiselTarget -> t
+ case TraceAnnotation(t, chiselTarget) => chiselTarget -> t
}.groupBy(_._1).map { case (k, v) => k -> v.map(_._2) }
}
diff --git a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala
index 7f20964d..cc555b11 100644
--- a/core/src/main/scala/chisel3/experimental/dataview/DataView.scala
+++ b/core/src/main/scala/chisel3/experimental/dataview/DataView.scala
@@ -592,4 +592,27 @@ object PartialDataView {
implicit sourceInfo: SourceInfo
): DataView[T, V] =
new DataView[T, V](mkView, mapping, _total = false)
+
+ /** Constructs a non-total [[DataView]] mapping from a [[Bundle]] type to a parent [[Bundle]] type
+ *
+ * @param mkView a function constructing an instance `V` from an instance of `T`
+ * @return the [[DataView]] that enables viewing instances of a [[Bundle]] as instances of a parent type
+ */
+ def supertype[T <: Bundle, V <: Bundle](
+ mkView: T => V
+ )(
+ implicit ev: SubTypeOf[T, V],
+ sourceInfo: SourceInfo
+ ): DataView[T, V] =
+ mapping[T, V](
+ mkView,
+ {
+ case (a, b) =>
+ val aElts = a.elements
+ val bElts = b.elements
+ val bKeys = bElts.keySet
+ val keys = aElts.keysIterator.filter(bKeys.contains)
+ keys.map(k => aElts(k) -> bElts(k)).toSeq
+ }
+ )
}
diff --git a/core/src/main/scala/chisel3/experimental/dataview/package.scala b/core/src/main/scala/chisel3/experimental/dataview/package.scala
index 71ae2d8f..a52e88cf 100644
--- a/core/src/main/scala/chisel3/experimental/dataview/package.scala
+++ b/core/src/main/scala/chisel3/experimental/dataview/package.scala
@@ -43,24 +43,14 @@ package object dataview {
"${A} is not a subtype of ${B}! Did you mean .viewAs[${B}]? " +
"Please see https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview"
)
- private type SubTypeOf[A, B] = A <:< B
+ private[dataview] type SubTypeOf[A, B] = A <:< B
/** Provides `viewAsSupertype` for subclasses of [[Bundle]] */
implicit class BundleUpcastable[T <: Bundle](target: T) {
/** View a [[Bundle]] or [[Record]] as a parent type (upcast) */
def viewAsSupertype[V <: Bundle](proto: V)(implicit ev: SubTypeOf[T, V], sourceInfo: SourceInfo): V = {
- implicit val dataView = PartialDataView.mapping[T, V](
- _ => proto,
- {
- case (a, b) =>
- val aElts = a.elements
- val bElts = b.elements
- val bKeys = bElts.keySet
- val keys = aElts.keysIterator.filter(bKeys.contains)
- keys.map(k => aElts(k) -> bElts(k)).toSeq
- }
- )
+ implicit val dataView = PartialDataView.supertype[T, V](_ => proto)
target.viewAs[V]
}
}
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
index 36bf6f87..99eacc7d 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala
@@ -103,7 +103,7 @@ object Definition extends SourceInfoDoc {
): Definition[T] = {
val dynamicContext = {
val context = Builder.captureContext()
- new DynamicContext(Nil, context.throwOnFirstError, context.warnReflectiveNaming)
+ new DynamicContext(Nil, context.throwOnFirstError, context.warnReflectiveNaming, context.warningsAsErrors)
}
Builder.globalNamespace.copyTo(dynamicContext.globalNamespace)
dynamicContext.inDefinition = true
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
index c83479b0..aa35455d 100644
--- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
+++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala
@@ -335,11 +335,20 @@ object Lookupable {
}
def instanceLookup[A](that: A => B, instance: Instance[A]): C = {
val ret = that(instance.proto)
- val ioMap: Option[Map[Data, Data]] = instance.underlying match {
- case Clone(x: ModuleClone[_]) => Some(x.ioMap)
- case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap)
- case _ => None
+
+ def getIoMap(hierarchy: Hierarchy[_]): Option[Map[Data, Data]] = {
+ hierarchy.underlying match {
+ case Clone(x: ModuleClone[_]) => Some(x.ioMap)
+ case Proto(x: BaseModule) => Some(x.getChiselPorts.map { case (_, data) => data -> data }.toMap)
+ case Clone(x: InstantiableClone[_]) => getIoMap(x._innerContext)
+ case Clone(x: InstanceClone[_]) => None
+ case other => {
+ Builder.exception(s"Internal Error! Unexpected case where we can't get IO Map: $other")
+ }
+ }
}
+ val ioMap = getIoMap(instance)
+
if (isView(ret)) {
cloneViewToContext(ret, instance.cache, ioMap, instance.getInnerDataContext)
} else {
diff --git a/core/src/main/scala/chisel3/experimental/package.scala b/core/src/main/scala/chisel3/experimental/package.scala
index b1d9cae4..39131943 100644
--- a/core/src/main/scala/chisel3/experimental/package.scala
+++ b/core/src/main/scala/chisel3/experimental/package.scala
@@ -235,9 +235,33 @@ package object experimental {
}
}
- // Use to add a prefix to any component generated in input scope
+ /** Use to add a prefix to any components generated in the provided scope.
+ *
+ * @example {{{
+ *
+ * val x1 = prefix("first") {
+ * // Anything generated here will be prefixed with "first"
+ * }
+ *
+ * val x2 = prefix(mysignal) {
+ * // Anything generated here will be prefixed with the name of mysignal
+ * }
+ *
+ * }}}
+ */
val prefix = chisel3.internal.prefix
- // Use to remove prefixes not in provided scope
+
+ /** Use to clear existing prefixes so no signals within the scope are prefixed
+ * by signals/names outside the scope
+ *
+ * @example {{{
+ *
+ * val x1 = prefix("first") {
+ * // Anything generated here will have no prefix.
+ * // The result returned from this would *still* be called `x1` however.
+ * }
+ * }}}
+ */
val noPrefix = chisel3.internal.noPrefix
// ****************************** Hardware equivalents of Scala Tuples ******************************