diff options
| author | Hasan Genc | 2018-10-12 12:52:48 -0700 |
|---|---|---|
| committer | Chick Markley | 2018-10-12 12:52:48 -0700 |
| commit | 600405254c20c14fb3389aa4758ec27dffe992d0 (patch) | |
| tree | 65605ab857b375f3d740c1dc69c46f52ede1fb52 /chiselFrontend/src/main/scala/chisel3/core/Bits.scala | |
| parent | 10d54720fbe1c0e87051956cdd61a862e1303224 (diff) | |
Strong enums (#892)
* Added new strongly-typed enum construct called "StrongEnum". "StrongEnum" will automatically generate annotations that HDL backends can use to mark components as enums
Removed "override val width" constructor parameter from "Element" so that classes with variable widths, like the new strong enums, can inherit from it
Changed the parameter types of certain functions, such as "switch", "is", and "LitArg.bindLitArg" from "Bits" to "Element", so that they can take the new strong enums as arguments
* Added tests for the new strong enums
* Changed StrongEnum exception names and made sure in StrongEnum tests that the correct types of exceptions are thrown
* Fixed bug where an enum's global annotation would not be set if it was used in multiple circuits
Made styling changes to StrongEnum.scala
* Reverted accidental changes to the AnnotatingDiamond test
* Changed the API for casting non-literal UInts to enums
Added an isValid function that checks whether or not enums have valid values
Calling getWidth on an enum's companion object now returns a BigInt instead of an Int
* Casting a literal to an enum using the StrongEnum.castFromNonLit(n) function is now simply a wrapper for StrongEnum.apply(n)
* Fixed compilation bug
* * Added "next" method to EnumType
* Renamed "castFromNonLit" to "fromBits"
* The FSM example in the test/scala/cookbook now uses StrongEnums
* * Changed strong enum API, so that users no longer have to declare both a class and a companion object for each strong enum
* Strong enums do not have to be static any longer
* * Added scope protections to ChiselEnum.Value so that users cannot call it
outside of a ChiselEnum definition
* Renamed ChiselEnum.Value type to ChiselEnum.Type so that we can give
it a companion object just like UInt and Bool do
* * Moved strong enums into experimental package
* Non-literal UInts can now be cast to enums with apply() rather than
fromBits()
* Reduced code-duplication by moving some functions from EnumType and
Bits to Element
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/Bits.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index e9458446..9356a91c 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -19,7 +19,11 @@ import chisel3.internal.firrtl.PrimOp._ * * @define coll element */ -abstract class Element(private[chisel3] val width: Width) extends Data { +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) @@ -30,9 +34,32 @@ abstract class Element(private[chisel3] val width: Width) extends Data { } } - private[chisel3] final def allElements: Seq[Element] = Seq(this) - def widthKnown: Boolean = width.known - def name: String = getRef.name + 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 + } + + private[core] def litArgOption: Option[LitArg] = topBindingOpt match { + case Some(ElementLitBinding(litArg)) => Some(litArg) + case _ => None + } + + override def litOption: Option[BigInt] = litArgOption.map(_.num) + private[core] 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[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = { // If the source is a DontCare, generate a DefInvalid for the sink, @@ -69,7 +96,7 @@ private[chisel3] sealed trait ToBoolable extends Element { * @define sumWidth @note The width of the returned $coll is `width of this` + `width of that`. * @define unchangedWidth @note The width of the returned $coll is unchanged, i.e., the `width of this`. */ -sealed abstract class Bits(width: Width) extends Element(width) with ToBoolable { //scalastyle:off number.of.methods +sealed abstract class Bits(private[chisel3] val width: Width) extends Element with ToBoolable { //scalastyle:off number.of.methods // TODO: perhaps make this concrete? // Arguments for: self-checking code (can't do arithmetic on bits) // Arguments against: generates down to a FIRRTL UInt anyways @@ -79,33 +106,6 @@ sealed abstract class Bits(width: Width) extends Element(width) with ToBoolable 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 - } - - private[core] def litArgOption: Option[LitArg] = topBindingOpt match { - case Some(ElementLitBinding(litArg)) => Some(litArg) - case _ => None - } - - override def litOption: Option[BigInt] = litArgOption.map(_.num) - private[core] 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 - } - /** Tail operator * * @param n the number of bits to remove @@ -1693,7 +1693,7 @@ object FixedPoint { * * @note This API is experimental and subject to change */ -final class Analog private (width: Width) extends Element(width) { +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") private[core] override def typeEquivalent(that: Data): Boolean = |
