summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala
diff options
context:
space:
mode:
authorKamyar Mohajerani2019-08-23 14:28:06 -0400
committerSchuyler Eldridge2019-08-28 15:51:35 -0400
commite12868235c6bb756b6163511f0430cbed7ff473f (patch)
tree929befeac8c73f0f1a4ce49f37eec657fdff41ca /chiselFrontend/src/main/scala
parent5bccb888fd3bd129b00e09f946bf820c17f7cc7f (diff)
Refactor Element, Num, and Analog classes to their own files (no functional changes)
Diffstat (limited to 'chiselFrontend/src/main/scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Bits.scala306
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Element.scala62
-rw-r--r--chiselFrontend/src/main/scala/chisel3/Num.scala179
-rw-r--r--chiselFrontend/src/main/scala/chisel3/experimental/Analog.scala86
4 files changed, 330 insertions, 303 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/Bits.scala b/chiselFrontend/src/main/scala/chisel3/Bits.scala
index 5a6db7c1..9939f3a2 100644
--- a/chiselFrontend/src/main/scala/chisel3/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/Bits.scala
@@ -3,72 +3,17 @@
package chisel3
import scala.language.experimental.macros
-import collection.mutable
-import chisel3.experimental.{FixedPoint, RawModule}
+import chisel3.experimental.FixedPoint
import chisel3.internal._
-import chisel3.internal.Builder.{pushCommand, pushOp}
+import chisel3.internal.Builder.pushOp
import chisel3.internal.firrtl._
-import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform,
+import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform,
UIntTransform}
import chisel3.internal.firrtl.PrimOp._
// scalastyle:off method.name line.size.limit file.size.limit
-/** Element is a leaf data type: it cannot contain other [[Data]] objects. Example uses are for representing primitive
- * data types, like integers and bits.
- *
- * @define coll element
- */
-abstract class Element extends Data {
- private[chisel3] final def allElements: Seq[Element] = Seq(this)
- def widthKnown: Boolean = width.known
- def name: String = getRef.name
-
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- binding = target
- val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
- direction = ActualDirection.fromSpecified(resolvedDirection)
- }
-
- private[chisel3] 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
- }
-
- private[chisel3] def litArgOption: Option[LitArg] = topBindingOpt match {
- case Some(ElementLitBinding(litArg)) => Some(litArg)
- case _ => None
- }
-
- 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.
- if (that == DontCare) {
- pushCommand(DefInvalid(sourceInfo, Node(this)))
- } else {
- pushCommand(Connect(sourceInfo, Node(this), that.ref))
- }
- }
-}
-
/** Exists to unify common interfaces of [[Bits]] and [[Reset]].
*
* @note This is a workaround because macros cannot override abstract methods.
@@ -440,176 +385,6 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
}
}
-// REVIEW TODO: Further discussion needed on what Num actually is.
-/** Abstract trait defining operations available on numeric-like hardware data types.
- *
- * @tparam T the underlying type of the number
- * @groupdesc Arithmetic Arithmetic hardware operators
- * @groupdesc Comparison Comparison hardware operators
- * @groupdesc Logical Logical hardware operators
- * @define coll numeric-like type
- * @define numType hardware type
- * @define canHaveHighCost can result in significant cycle time and area costs
- * @define canGenerateA This method generates a
- * @define singleCycleMul @note $canGenerateA fully combinational multiplier which $canHaveHighCost.
- * @define singleCycleDiv @note $canGenerateA fully combinational divider which $canHaveHighCost.
- * @define maxWidth @note The width of the returned $numType is `max(width of this, width of that)`.
- * @define maxWidthPlusOne @note The width of the returned $numType is `max(width of this, width of that) + 1`.
- * @define sumWidth @note The width of the returned $numType is `width of this` + `width of that`.
- * @define unchangedWidth @note The width of the returned $numType is unchanged, i.e., the `width of this`.
- */
-abstract trait Num[T <: Data] {
- self: Num[T] =>
- // def << (b: T): T
- // def >> (b: T): T
- //def unary_-(): T
-
- // REVIEW TODO: double check ops conventions against FIRRTL
-
- /** Addition operator
- *
- * @param that a $numType
- * @return the sum of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def + (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_+ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Multiplication operator
- *
- * @param that a $numType
- * @return the product of this $coll and `that`
- * $sumWidth
- * $singleCycleMul
- * @group Arithmetic
- */
- final def * (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_* (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Division operator
- *
- * @param that a $numType
- * @return the quotient of this $coll divided by `that`
- * $singleCycleDiv
- * @todo full rules
- * @group Arithmetic
- */
- final def / (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_/ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Modulo operator
- *
- * @param that a $numType
- * @return the remainder of this $coll divided by `that`
- * $singleCycleDiv
- * @group Arithmetic
- */
- final def % (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_% (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Subtraction operator
- *
- * @param that a $numType
- * @return the difference of this $coll less `that`
- * $maxWidthPlusOne
- * @group Arithmetic
- */
- final def - (that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_- (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Less than operator
- *
- * @param that a $numType
- * @return a hardware [[Bool]] asserted if this $coll is less than `that`
- * @group Comparison
- */
- final def < (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_< (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Less than or equal to operator
- *
- * @param that a $numType
- * @return a hardware [[Bool]] asserted if this $coll is less than or equal to `that`
- * @group Comparison
- */
- final def <= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_<= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Greater than operator
- *
- * @param that a hardware component
- * @return a hardware [[Bool]] asserted if this $coll is greater than `that`
- * @group Comparison
- */
- final def > (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_> (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Greater than or equal to operator
- *
- * @param that a hardware component
- * @return a hardware [[Bool]] asserted if this $coll is greather than or equal to `that`
- * @group Comparison
- */
- final def >= (that: T): Bool = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_>= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
-
- /** Absolute value operator
- *
- * @return a $numType with a value equal to the absolute value of this $coll
- * $unchangedWidth
- * @group Arithmetic
- */
- final def abs(): T = macro SourceInfoTransform.noArg
-
- /** @group SourceInfoTransformMacro */
- def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
-
- /** Minimum operator
- *
- * @param that a hardware $coll
- * @return a $numType with a value equal to the mimimum value of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def min(that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_min(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- Mux(this < that, this.asInstanceOf[T], that)
-
- /** Maximum operator
- *
- * @param that a $numType
- * @return a $numType with a value equal to the mimimum value of this $coll and `that`
- * $maxWidth
- * @group Arithmetic
- */
- final def max(that: T): T = macro SourceInfoTransform.thatArg
-
- /** @group SourceInfoTransformMacro */
- def do_max(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
- Mux(this < that, that, this.asInstanceOf[T])
-}
-
/** A data type for unsigned integers, represented as a binary bitvector. Defines arithmetic operations between other
* integer types.
*
@@ -1817,80 +1592,5 @@ package experimental {
}
}
-
- }
- /** Data type for representing bidirectional bitvectors of a given width
- *
- * Analog support is limited to allowing wiring up of Verilog BlackBoxes with bidirectional (inout)
- * pins. There is currently no support for reading or writing of Analog types within Chisel code.
- *
- * Given that Analog is bidirectional, it is illegal to assign a direction to any Analog type. It
- * is legal to "flip" the direction (since Analog can be a member of aggregate types) which has no
- * effect.
- *
- * Analog types are generally connected using the bidirectional [[attach]] mechanism, but also
- * support limited bulkconnect `<>`. Analog types are only allowed to be bulk connected *once* in a
- * given module. This is to prevent any surprising consequences of last connect semantics.
- *
- * @note This API is experimental and subject to change
- */
- final class Analog private (private[chisel3] val width: Width) extends Element {
- require(width.known, "Since Analog is only for use in BlackBoxes, width must be known")
-
- override def toString: String = {
- s"Analog$width$bindingToString"
- }
-
- private[chisel3] override def typeEquivalent(that: Data): Boolean =
- that.isInstanceOf[Analog] && this.width == that.width
-
- override def litOption: Option[BigInt] = None
-
- def cloneType: this.type = new Analog(width).asInstanceOf[this.type]
-
- // Used to enforce single bulk connect of Analog types, multi-attach is still okay
- // Note that this really means 1 bulk connect per Module because a port can
- // be connected in the parent module as well
- private[chisel3] val biConnectLocs = mutable.Map.empty[RawModule, SourceInfo]
-
- // Define setter/getter pairing
- // Analog can only be bound to Ports and Wires (and Unbound)
- private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
- SpecifiedDirection.fromParent(parentDirection, specifiedDirection) match {
- case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip =>
- case x => throwException(s"Analog may not have explicit direction, got '$x'")
- }
- val targetTopBinding = target match {
- case target: TopBinding => target
- case ChildBinding(parent) => parent.topBinding
- // See https://github.com/freechipsproject/chisel3/pull/946
- case SampleElementBinding(parent) => parent.topBinding
- }
-
- // Analog counts as different directions based on binding context
- targetTopBinding match {
- case WireBinding(_) => direction = ActualDirection.Unspecified // internal wire
- case PortBinding(_) => direction = ActualDirection.Bidirectional(ActualDirection.Default)
- case x => throwException(s"Analog can only be Ports and Wires, not '$x'")
- }
- binding = target
- }
-
- override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
- throwException("Analog does not support asUInt")
-
- private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
- compileOptions: CompileOptions): Unit = {
- throwException("Analog does not support connectFromBits")
- }
-
- final def toPrintable: Printable = PString("Analog")
- }
- /** Object that provides factory methods for [[Analog]] objects
- *
- * @note This API is experimental and subject to change
- */
- object Analog {
- def apply(width: Width): Analog = new Analog(width)
}
}
diff --git a/chiselFrontend/src/main/scala/chisel3/Element.scala b/chiselFrontend/src/main/scala/chisel3/Element.scala
new file mode 100644
index 00000000..fccae9ab
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/Element.scala
@@ -0,0 +1,62 @@
+// See LICENSE for license details.
+
+package chisel3
+
+import chisel3.internal.Builder.pushCommand
+import chisel3.internal.firrtl._
+import chisel3.internal.sourceinfo.SourceInfo
+import chisel3.internal._
+
+/** Element is a leaf data type: it cannot contain other [[Data]] objects. Example uses are for representing primitive
+ * data types, like integers and bits.
+ *
+ * @define coll element
+ */
+abstract class Element extends Data {
+ private[chisel3] final def allElements: Seq[Element] = Seq(this)
+ def widthKnown: Boolean = width.known
+ def name: String = getRef.name
+
+ private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
+ binding = target
+ val resolvedDirection = SpecifiedDirection.fromParent(parentDirection, specifiedDirection)
+ direction = ActualDirection.fromSpecified(resolvedDirection)
+ }
+
+ private[chisel3] 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
+ }
+
+ private[chisel3] def litArgOption: Option[LitArg] = topBindingOpt match {
+ case Some(ElementLitBinding(litArg)) => Some(litArg)
+ case _ => None
+ }
+
+ 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.
+ if (that == DontCare) {
+ pushCommand(DefInvalid(sourceInfo, Node(this)))
+ } else {
+ pushCommand(Connect(sourceInfo, Node(this), that.ref))
+ }
+ }
+}
diff --git a/chiselFrontend/src/main/scala/chisel3/Num.scala b/chiselFrontend/src/main/scala/chisel3/Num.scala
new file mode 100644
index 00000000..2c63c86e
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/Num.scala
@@ -0,0 +1,179 @@
+// See LICENSE for license details.
+
+package chisel3
+
+import scala.language.experimental.macros
+import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform}
+
+// scalastyle:off method.name line.size.limit file.size.limit
+
+// REVIEW TODO: Further discussion needed on what Num actually is.
+
+/** Abstract trait defining operations available on numeric-like hardware data types.
+ *
+ * @tparam T the underlying type of the number
+ * @groupdesc Arithmetic Arithmetic hardware operators
+ * @groupdesc Comparison Comparison hardware operators
+ * @groupdesc Logical Logical hardware operators
+ * @define coll numeric-like type
+ * @define numType hardware type
+ * @define canHaveHighCost can result in significant cycle time and area costs
+ * @define canGenerateA This method generates a
+ * @define singleCycleMul @note $canGenerateA fully combinational multiplier which $canHaveHighCost.
+ * @define singleCycleDiv @note $canGenerateA fully combinational divider which $canHaveHighCost.
+ * @define maxWidth @note The width of the returned $numType is `max(width of this, width of that)`.
+ * @define maxWidthPlusOne @note The width of the returned $numType is `max(width of this, width of that) + 1`.
+ * @define sumWidth @note The width of the returned $numType is `width of this` + `width of that`.
+ * @define unchangedWidth @note The width of the returned $numType is unchanged, i.e., the `width of this`.
+ */
+trait Num[T <: Data] {
+ self: Num[T] =>
+ // def << (b: T): T
+ // def >> (b: T): T
+ //def unary_-(): T
+
+ // REVIEW TODO: double check ops conventions against FIRRTL
+
+ /** Addition operator
+ *
+ * @param that a $numType
+ * @return the sum of this $coll and `that`
+ * $maxWidth
+ * @group Arithmetic
+ */
+ final def + (that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_+ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Multiplication operator
+ *
+ * @param that a $numType
+ * @return the product of this $coll and `that`
+ * $sumWidth
+ * $singleCycleMul
+ * @group Arithmetic
+ */
+ final def * (that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_* (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Division operator
+ *
+ * @param that a $numType
+ * @return the quotient of this $coll divided by `that`
+ * $singleCycleDiv
+ * @todo full rules
+ * @group Arithmetic
+ */
+ final def / (that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_/ (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Modulo operator
+ *
+ * @param that a $numType
+ * @return the remainder of this $coll divided by `that`
+ * $singleCycleDiv
+ * @group Arithmetic
+ */
+ final def % (that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_% (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Subtraction operator
+ *
+ * @param that a $numType
+ * @return the difference of this $coll less `that`
+ * $maxWidthPlusOne
+ * @group Arithmetic
+ */
+ final def - (that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_- (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Less than operator
+ *
+ * @param that a $numType
+ * @return a hardware [[Bool]] asserted if this $coll is less than `that`
+ * @group Comparison
+ */
+ final def < (that: T): Bool = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_< (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
+
+ /** Less than or equal to operator
+ *
+ * @param that a $numType
+ * @return a hardware [[Bool]] asserted if this $coll is less than or equal to `that`
+ * @group Comparison
+ */
+ final def <= (that: T): Bool = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_<= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
+
+ /** Greater than operator
+ *
+ * @param that a hardware component
+ * @return a hardware [[Bool]] asserted if this $coll is greater than `that`
+ * @group Comparison
+ */
+ final def > (that: T): Bool = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_> (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
+
+ /** Greater than or equal to operator
+ *
+ * @param that a hardware component
+ * @return a hardware [[Bool]] asserted if this $coll is greather than or equal to `that`
+ * @group Comparison
+ */
+ final def >= (that: T): Bool = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_>= (that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool
+
+ /** Absolute value operator
+ *
+ * @return a $numType with a value equal to the absolute value of this $coll
+ * $unchangedWidth
+ * @group Arithmetic
+ */
+ final def abs(): T = macro SourceInfoTransform.noArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_abs(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T
+
+ /** Minimum operator
+ *
+ * @param that a hardware $coll
+ * @return a $numType with a value equal to the mimimum value of this $coll and `that`
+ * $maxWidth
+ * @group Arithmetic
+ */
+ final def min(that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_min(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
+ Mux(this < that, this.asInstanceOf[T], that)
+
+ /** Maximum operator
+ *
+ * @param that a $numType
+ * @return a $numType with a value equal to the mimimum value of this $coll and `that`
+ * $maxWidth
+ * @group Arithmetic
+ */
+ final def max(that: T): T = macro SourceInfoTransform.thatArg
+
+ /** @group SourceInfoTransformMacro */
+ def do_max(that: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T =
+ Mux(this < that, that, this.asInstanceOf[T])
+}
diff --git a/chiselFrontend/src/main/scala/chisel3/experimental/Analog.scala b/chiselFrontend/src/main/scala/chisel3/experimental/Analog.scala
new file mode 100644
index 00000000..469720e0
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/experimental/Analog.scala
@@ -0,0 +1,86 @@
+// See LICENSE for license details.
+
+package chisel3.experimental
+
+import chisel3.internal.firrtl.Width
+import chisel3.internal.sourceinfo.SourceInfo
+import chisel3.internal._
+import chisel3.{ActualDirection, Bits, CompileOptions, Data, Element, PString, Printable, SpecifiedDirection, UInt}
+
+import scala.collection.mutable
+
+/** Data type for representing bidirectional bitvectors of a given width
+ *
+ * Analog support is limited to allowing wiring up of Verilog BlackBoxes with bidirectional (inout)
+ * pins. There is currently no support for reading or writing of Analog types within Chisel code.
+ *
+ * Given that Analog is bidirectional, it is illegal to assign a direction to any Analog type. It
+ * is legal to "flip" the direction (since Analog can be a member of aggregate types) which has no
+ * effect.
+ *
+ * Analog types are generally connected using the bidirectional [[attach]] mechanism, but also
+ * support limited bulkconnect `<>`. Analog types are only allowed to be bulk connected *once* in a
+ * given module. This is to prevent any surprising consequences of last connect semantics.
+ *
+ * @note This API is experimental and subject to change
+ */
+final class Analog private (private[chisel3] val width: Width) extends Element {
+ require(width.known, "Since Analog is only for use in BlackBoxes, width must be known")
+
+ override def toString: String = {
+ s"Analog$width$bindingToString"
+ }
+
+ private[chisel3] override def typeEquivalent(that: Data): Boolean =
+ that.isInstanceOf[Analog] && this.width == that.width
+
+ override def litOption: Option[BigInt] = None
+
+ def cloneType: this.type = new Analog(width).asInstanceOf[this.type]
+
+ // Used to enforce single bulk connect of Analog types, multi-attach is still okay
+ // Note that this really means 1 bulk connect per Module because a port can
+ // be connected in the parent module as well
+ private[chisel3] val biConnectLocs = mutable.Map.empty[RawModule, SourceInfo]
+
+ // Define setter/getter pairing
+ // Analog can only be bound to Ports and Wires (and Unbound)
+ private[chisel3] override def bind(target: Binding, parentDirection: SpecifiedDirection) {
+ SpecifiedDirection.fromParent(parentDirection, specifiedDirection) match {
+ case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip =>
+ case x => throwException(s"Analog may not have explicit direction, got '$x'")
+ }
+ val targetTopBinding = target match {
+ case target: TopBinding => target
+ case ChildBinding(parent) => parent.topBinding
+ // See https://github.com/freechipsproject/chisel3/pull/946
+ case SampleElementBinding(parent) => parent.topBinding
+ }
+
+ // Analog counts as different directions based on binding context
+ targetTopBinding match {
+ case WireBinding(_) => direction = ActualDirection.Unspecified // internal wire
+ case PortBinding(_) => direction = ActualDirection.Bidirectional(ActualDirection.Default)
+ case x => throwException(s"Analog can only be Ports and Wires, not '$x'")
+ }
+ binding = target
+ }
+
+ override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
+ throwException("Analog does not support asUInt")
+
+ private[chisel3] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
+ compileOptions: CompileOptions): Unit = {
+ throwException("Analog does not support connectFromBits")
+ }
+
+ def toPrintable: Printable = PString("Analog")
+}
+
+/** Object that provides factory methods for [[Analog]] objects
+ *
+ * @note This API is experimental and subject to change
+ */
+object Analog {
+ def apply(width: Width): Analog = new Analog(width)
+} \ No newline at end of file