diff options
| author | ducky | 2018-06-28 15:57:13 -0700 |
|---|---|---|
| committer | Richard Lin | 2018-07-04 18:39:28 -0500 |
| commit | 7ab85ec6f781fc48796add6d895174a952383806 (patch) | |
| tree | 77fd3a4706131a5ca90f036fa6b51818f174048a | |
| parent | 4cf5caf86a072bc4af581536930469b82796dd27 (diff) | |
binding => topBinding so that partial Bundles work and undefined Bundle members properly forward to DontCareBinding
6 files changed, 21 insertions, 15 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index c74b5135..54932bcc 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -738,7 +738,7 @@ abstract class Bundle(implicit compileOptions: CompileOptions) extends Record { // (which could lead to data conflicts, since it's likely the user didn't know to re-bind them). // This is not guaranteed to catch all cases (for example, Data in Tuples or Iterables). val boundDataParamNames = ctorParamsNameVals.collect { - case (paramName, paramVal: Data) if paramVal.hasBinding => paramName + case (paramName, paramVal: Data) if paramVal.topBindingOpt.isDefined => paramName } if (boundDataParamNames.nonEmpty) { autoClonetypeError(s"constructor parameters (${boundDataParamNames.sorted.mkString(", ")}) have values that are hardware types, which is likely to cause subtle errors." + diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala index d056efba..1dcb968d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala @@ -186,7 +186,7 @@ object BiConnect { // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>). // If either is a DontCareBinding, just issue a DefInvalid for the other, // otherwise, issue a Connect. - (left.binding, right.binding) match { + (left.topBinding, right.topBinding) match { case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref)) case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref)) case (_, _) => pushCommand(Connect(sourceInfo, right.lref, left.ref)) @@ -197,7 +197,7 @@ object BiConnect { // Source and sink are ambiguous in the case of a Bi/Bulk Connect (<>). // If either is a DontCareBinding, just issue a DefInvalid for the other, // otherwise, issue a Connect. - (left.binding, right.binding) match { + (left.topBinding, right.topBinding) match { case (lb: DontCareBinding, _) => pushCommand(DefInvalid(sourceInfo, right.lref)) case (_, rb: DontCareBinding) => pushCommand(DefInvalid(sourceInfo, left.lref)) case (_, _) => pushCommand(Connect(sourceInfo, left.lref, right.ref)) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala index ecec3676..b3b754de 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala @@ -27,7 +27,7 @@ object requireIsHardware { case Some(x: BaseModule) => x._compatAutoWrapPorts case _ => } - if (!node.hasBinding) { + if (!node.topBindingOpt.isDefined) { val prefix = if (msg.nonEmpty) s"$msg " else "" throw Binding.ExpectedHardwareException(s"$prefix'$node' must be hardware, " + "not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?") @@ -38,7 +38,7 @@ object requireIsHardware { /** Requires that a node is a chisel type (not hardware, "unbound") */ object requireIsChiselType { - def apply(node: Data, msg: String = "") = if (node.hasBinding) { + def apply(node: Data, msg: String = "") = if (node.topBindingOpt.isDefined) { val prefix = if (msg.nonEmpty) s"$msg " else "" throw Binding.ExpectedChiselTypeException(s"$prefix'$node' must be a Chisel type, not hardware") } @@ -102,7 +102,7 @@ case class RegBinding(enclosure: UserModule) extends ConstrainedBinding case class WireBinding(enclosure: UserModule) extends ConstrainedBinding case class ChildBinding(parent: Data) extends Binding { - def location = parent.binding.location + def location = parent.topBinding.location } // A DontCare element has a specific Binding, somewhat like a literal. // It is a source (RHS). It may only be connected/applied to sinks. diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index eae605c1..ca38ef83 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -72,11 +72,19 @@ sealed abstract class Bits(width: Width) def cloneType: this.type = cloneTypeWidth(width) + private[core] override def topBindingOpt: Option[TopBinding] = super.topBindingOpt match { + // Translate Bundle lit bindings to Element lit bindings + case Some(BundleLitBinding(litMap)) => litMap.get(this) match { + case Some(litArg) => Some(ElementLitBinding(litArg)) + case _ => Some(DontCareBinding()) + } + case topBindingOpt => topBindingOpt + } + override def elementLitArg: Option[LitArg] = litArgOption protected def litArgOption: Option[LitArg] = topBindingOpt match { case Some(ElementLitBinding(litArg)) => Some(litArg) - case Some(BundleLitBinding(litMap)) => litMap.get(this) case _ => None } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index ab277d9f..7ff1ec0b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -88,7 +88,7 @@ object DataMirror { // Internal reflection-style APIs, subject to change and removal whenever. object internal { - def isSynthesizable(target: Data) = target.hasBinding + def isSynthesizable(target: Data) = target.topBindingOpt.isDefined // For those odd cases where you need to care about object reference and uniqueness def chiselTypeClone[T<:Data](target: Data): T = { target.cloneTypeFull.asInstanceOf[T] @@ -241,10 +241,8 @@ abstract class Data extends HasId with NamedComponent { // This information is supplemental (more than is necessary to generate FIRRTL) and is used to // perform checks in Chisel, where more informative error messages are possible. private var _binding: Option[Binding] = None - private[core] def bindingOpt = _binding - private[core] def hasBinding = _binding.isDefined // Only valid after node is bound (synthesizable), crashes otherwise - private[core] def binding = _binding.get + protected def binding: Option[Binding] = _binding protected def binding_=(target: Binding) { if (_binding.isDefined) { throw Binding.RebindingException(s"Attempted reassignment of binding to $this") @@ -253,7 +251,7 @@ abstract class Data extends HasId with NamedComponent { } private[core] def topBindingOpt: Option[TopBinding] = { - bindingOpt match { + _binding match { case Some(binding) => binding match { case ChildBinding(parent) => parent.topBindingOpt case binding: TopBinding => Some(binding) diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala index c4e880b7..eba24870 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala @@ -142,7 +142,7 @@ object MonoConnect { private def issueConnect(sink: Element, source: Element)(implicit sourceInfo: SourceInfo): Unit = { // If the source is a DontCare, generate a DefInvalid for the sink, // otherwise, issue a Connect. - source.binding match { + source.topBinding match { case b: DontCareBinding => pushCommand(DefInvalid(sourceInfo, sink.lref)) case _ => pushCommand(Connect(sourceInfo, sink.lref, source.ref)) } @@ -154,8 +154,8 @@ object MonoConnect { import BindingDirection.{Internal, Input, Output} // Using extensively so import these // If source has no location, assume in context module // This can occur if is a literal, unbound will error previously - val sink_mod: BaseModule = sink.binding.location.getOrElse(throw UnwritableSinkException) - val source_mod: BaseModule = source.binding.location.getOrElse(context_mod) + val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException) + val source_mod: BaseModule = source.topBinding.location.getOrElse(context_mod) val sink_direction = BindingDirection.from(sink.topBinding, sink.direction) val source_direction = BindingDirection.from(source.topBinding, source.direction) |
