summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorJack Koenig2020-12-01 22:44:11 -0800
committerGitHub2020-12-01 22:44:11 -0800
commit5a6ce6604b5bde06dc88c55bc76aaf76aff87437 (patch)
treed05b075b94a521889129ec3f2e96a983d136faaa /core/src
parentba05dcaf10251f0c5e9eb0f8e30e101b83830c59 (diff)
Fix RegInit of Bundle lits (#1688)
Implemented by folding Element.ref into Data.ref. Element.ref had special handling for literals, but because Bundles can also be literals, there were code paths that tried to get the ref of a Bundle literal which was non-existent. Now, all literals are handled together. Because FIRRTL does not have support for Bundle literals, Bundle literal refs are implemented by materializing a Wire.
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/chisel3/Data.scala38
-rw-r--r--core/src/main/scala/chisel3/Element.scala10
2 files changed, 27 insertions, 21 deletions
diff --git a/core/src/main/scala/chisel3/Data.scala b/core/src/main/scala/chisel3/Data.scala
index 5d398aa6..a1f6abf8 100644
--- a/core/src/main/scala/chisel3/Data.scala
+++ b/core/src/main/scala/chisel3/Data.scala
@@ -453,8 +453,9 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
topBindingOpt match {
case Some(tb: TopBinding) if (mod == Builder.currentModule) =>
case Some(pb: PortBinding) if (mod.flatMap(Builder.retrieveParent(_,Builder.currentModule.get)) == Builder.currentModule) =>
+ case Some(_: UnconstrainedBinding) =>
case _ =>
- throwException(s"operand is not visible from the current module")
+ throwException(s"operand '$this' is not visible from the current module")
}
if (!MonoConnect.checkWhenVisibility(this)) {
throwException(s"operand has escaped the scope of the when in which it was constructed")
@@ -472,18 +473,33 @@ abstract class Data extends HasId with NamedComponent with SourceInfoDoc {
}
}
-
- // Internal API: returns a ref, if bound. Literals should override this as needed.
- private[chisel3] def ref: Arg = {
- requireIsHardware(this)
- if (Builder.currentModule.isDefined) {
- // This is allowed (among other cases) for evaluating args of Printf / Assert / Printable, which are
- // partially resolved *after* elaboration completes. If this is resolved, the check should be unconditional.
- requireVisible()
+ // Internal API: returns a ref, if bound
+ private[chisel3] final def ref: Arg = {
+ def materializeWire(): Arg = {
+ if (!Builder.currentModule.isDefined) throwException(s"internal error: cannot materialize ref for $this")
+ implicit val compileOptions = ExplicitCompileOptions.Strict
+ implicit val sourceInfo = UnlocatableSourceInfo
+ WireDefault(this).ref
}
+ requireIsHardware(this)
topBindingOpt match {
- case Some(binding: LitBinding) => throwException(s"internal error: can't handle literal binding $binding")
- case Some(binding: TopBinding) => Node(this)
+ // Literals
+ case Some(ElementLitBinding(litArg)) => litArg
+ case Some(BundleLitBinding(litMap)) =>
+ litMap.get(this) match {
+ case Some(litArg) => litArg
+ case _ => materializeWire() // FIXME FIRRTL doesn't have Bundle literal expressions
+ }
+ case Some(DontCareBinding()) =>
+ materializeWire() // FIXME FIRRTL doesn't have a DontCare expression so materialize a Wire
+ // Non-literals
+ case Some(binding: TopBinding) =>
+ if (Builder.currentModule.isDefined) {
+ // This is allowed (among other cases) for evaluating args of Printf / Assert / Printable, which are
+ // partially resolved *after* elaboration completes. If this is resolved, the check should be unconditional.
+ requireVisible()
+ }
+ Node(this)
case opt => throwException(s"internal error: unknown binding $opt in generating LHS ref")
}
}
diff --git a/core/src/main/scala/chisel3/Element.scala b/core/src/main/scala/chisel3/Element.scala
index 7596bc82..55415f3d 100644
--- a/core/src/main/scala/chisel3/Element.scala
+++ b/core/src/main/scala/chisel3/Element.scala
@@ -40,16 +40,6 @@ abstract class Element extends Data {
override def litOption: Option[BigInt] = litArgOption.map(_.num)
private[chisel3] def litIsForcedWidth: Option[Boolean] = litArgOption.map(_.forcedWidth)
- // provide bits-specific literal handling functionality here
- override private[chisel3] def ref: Arg = topBindingOpt match {
- case Some(ElementLitBinding(litArg)) => litArg
- case Some(BundleLitBinding(litMap)) => litMap.get(this) match {
- case Some(litArg) => litArg
- case _ => throwException(s"internal error: DontCare should be caught before getting ref")
- }
- case _ => super.ref
- }
-
private[chisel3] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = {
// If the source is a DontCare, generate a DefInvalid for the sink,
// otherwise, issue a Connect.