summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Lin2016-11-23 16:01:50 -0800
committerGitHub2016-11-23 16:01:50 -0800
commitedb19a0559686a471141c74438f677c1e217a298 (patch)
tree8745e2a31ab2e91f42c00999a68057916721bcdc
parent08b4f68db403d6925fba8c9e943216ef8f38d69e (diff)
Simplify Enum API (#385)
Get rid of some cruft exposed in #373 This also allows Bits.fromtInt(...) to be removed. Yay! All old APIs (with some new restrictions, rocket still works fine) are preserved without deprecation in Chisel._, aside from the non-compile-time-checkable Map[] enum constructor which probably should have been deprecated during chisel2. The Map[] enums have been removed from chisel3._ without deprecation. The new restriction is that nodeType (legacy API) may only be of UInt type with unspecified width. Note that Bits() creates a UInt, and if you can't control the enum values, it makes little sense to specify a bitwidth.
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala17
-rw-r--r--src/main/scala/chisel3/compatibility.scala57
-rw-r--r--src/main/scala/chisel3/util/Enum.scala41
-rw-r--r--src/test/scala/chiselTests/Risc.scala2
-rw-r--r--src/test/scala/chiselTests/VendingMachine.scala2
5 files changed, 72 insertions, 47 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index cab1a82e..035ac213 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -54,8 +54,6 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
// Arguments for: self-checking code (can't do arithmetic on bits)
// Arguments against: generates down to a FIRRTL UInt anyways
- private[chisel3] def fromInt(x: BigInt, w: Int): this.type
-
private[chisel3] def flatten: IndexedSeq[Bits] = IndexedSeq(this)
def cloneType: this.type = cloneTypeWidth(width)
@@ -402,9 +400,6 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
new UInt(w).asInstanceOf[this.type]
private[chisel3] def toType = s"UInt$width"
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type =
- value.asUInt(width.W).asInstanceOf[this.type]
-
// TODO: refactor to share documentation with Num or add independent scaladoc
final def unary_- (): UInt = macro SourceInfoTransform.noArg
final def unary_-% (): UInt = macro SourceInfoTransform.noArg
@@ -562,9 +557,6 @@ sealed class SInt private[core] (width: Width, lit: Option[SLit] = None)
new SInt(w).asInstanceOf[this.type]
private[chisel3] def toType = s"SInt$width"
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type =
- value.asSInt(width.W).asInstanceOf[this.type]
-
final def unary_- (): SInt = macro SourceInfoTransform.noArg
final def unary_-% (): SInt = macro SourceInfoTransform.noArg
@@ -696,11 +688,6 @@ sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) {
new Bool().asInstanceOf[this.type]
}
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type = {
- require((value == 0 || value == 1) && width == 1)
- (value == 1).asBool.asInstanceOf[this.type]
- }
-
// REVIEW TODO: Why does this need to exist and have different conventions
// than Bits?
final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg
@@ -823,10 +810,6 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit
case _ => this badConnect that
}
- private[chisel3] def fromInt(value: BigInt, width: Int): this.type = {
- throwException(s"Don't use $this.fromInt($value, $width): Use literal constructors instead")
- }
-
final def unary_- (): FixedPoint = macro SourceInfoTransform.noArg
final def unary_-% (): FixedPoint = macro SourceInfoTransform.noArg
diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala
index 51176d9d..4ffd0b86 100644
--- a/src/main/scala/chisel3/compatibility.scala
+++ b/src/main/scala/chisel3/compatibility.scala
@@ -250,7 +250,62 @@ package object Chisel { // scalastyle:ignore package.object.name
type Queue[T <: Data] = chisel3.util.Queue[T]
val Queue = chisel3.util.Queue
- val Enum = chisel3.util.Enum
+ object Enum extends chisel3.util.Enum {
+ /** Returns n unique values of the specified type. Can be used with unpacking to define enums.
+ *
+ * nodeType must be of UInt type (note that Bits() creates a UInt) with unspecified width.
+ *
+ * @example {{{
+ * val state_on :: state_off :: Nil = Enum(UInt(), 2)
+ * val current_state = UInt()
+ * switch (current_state) {
+ * is (state_on) {
+ * ...
+ * }
+ * if (state_off) {
+ * ...
+ * }
+ * }
+ * }}}
+ */
+ def apply[T <: Bits](nodeType: T, n: Int): List[T] = {
+ require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
+ require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
+ apply(n).asInstanceOf[List[T]]
+ }
+
+ /** An old Enum API that returns a map of symbols to UInts.
+ *
+ * Unlike the new list-based Enum, which can be unpacked into vals that the compiler
+ * understands and can check, map accesses can't be compile-time checked and typos may not be
+ * caught until runtime.
+ *
+ * Despite being deprecated, this is not to be removed from the compatibility layer API.
+ * Deprecation is only to nag users to do something safer.
+ */
+ @deprecated("Use list-based Enum", "not soon enough")
+ def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = {
+ require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
+ require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
+ (l zip createValues(l.length)).toMap.asInstanceOf[Map[Symbol, T]]
+ }
+
+ /** An old Enum API that returns a map of symbols to UInts.
+ *
+ * Unlike the new list-based Enum, which can be unpacked into vals that the compiler
+ * understands and can check, map accesses can't be compile-time checked and typos may not be
+ * caught until runtime.
+ *
+ * Despite being deprecated, this is not to be removed from the compatibility layer API.
+ * Deprecation is only to nag users to do something safer.
+ */
+ @deprecated("Use list-based Enum", "not soon enough")
+ def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = {
+ require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
+ require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
+ (l zip createValues(l.length)).toMap.asInstanceOf[Map[Symbol, T]]
+ }
+ }
val LFSR16 = chisel3.util.LFSR16
diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala
index 55b595ee..45aee62a 100644
--- a/src/main/scala/chisel3/util/Enum.scala
+++ b/src/main/scala/chisel3/util/Enum.scala
@@ -7,15 +7,15 @@ package chisel3.util
import chisel3._
-object Enum {
+trait Enum {
/** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */
- private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] =
- (0 until n).map(x => nodeType.fromInt(x, log2Up(n)))
+ protected def createValues(n: Int): Seq[UInt] =
+ (0 until n).map(_.U(log2Up(n).W))
- /** Returns n unique values of the specified type. Can be used with unpacking to define enums.
+ /** Returns n unique UInt values, use with unpacking to specify an enumeration.
*
* @example {{{
- * val state_on :: state_off :: Nil = Enum(UInt(), 2)
+ * val state_on :: state_off :: Nil = Enum(2)
* val current_state = UInt()
* switch (current_state) {
* is (state_on) {
@@ -26,28 +26,15 @@ object Enum {
* }
* }
* }}}
- *
*/
- def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList
-
- /** Returns a map of the input symbols to unique values of the specified type.
- *
- * @example {{{
- * val states = Enum(UInt(), 'on, 'off)
- * val current_state = UInt()
- * switch (current_state) {
- * is (states('on)) {
- * ...
- * }
- * if (states('off)) {
- * ..
- * }
- * }
- * }}}
- */
- def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap
+ def apply(n: Int): List[UInt] = createValues(n).toList
+}
- /** Returns a map of the input symbols to unique values of the specified type.
- */
- def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap
+object Enum extends Enum {
+ @deprecated("use Enum(n)", "chisel3, will be removed soon")
+ def apply[T <: Bits](nodeType: T, n: Int): List[T] = {
+ require(nodeType.isInstanceOf[UInt], "Only UInt supported for enums")
+ require(!nodeType.widthKnown, "Bit width may no longer be specified for enums")
+ apply(n).asInstanceOf[List[T]]
+ }
}
diff --git a/src/test/scala/chiselTests/Risc.scala b/src/test/scala/chiselTests/Risc.scala
index 57586c97..0d03ff65 100644
--- a/src/test/scala/chiselTests/Risc.scala
+++ b/src/test/scala/chiselTests/Risc.scala
@@ -19,7 +19,7 @@ class Risc extends Module {
val code = Mem(memSize, Bits(32.W))
val pc = Reg(init=0.U(8.W))
- val add_op :: imm_op :: Nil = Enum(Bits(8.W), 2)
+ val add_op :: imm_op :: Nil = Enum(2)
val inst = code(pc)
val op = inst(31,24)
diff --git a/src/test/scala/chiselTests/VendingMachine.scala b/src/test/scala/chiselTests/VendingMachine.scala
index c474430b..712b5b7a 100644
--- a/src/test/scala/chiselTests/VendingMachine.scala
+++ b/src/test/scala/chiselTests/VendingMachine.scala
@@ -12,7 +12,7 @@ class VendingMachine extends Module {
val valid = Output(Bool())
})
val c = 5.U(3.W)
- val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(UInt(), 5)
+ val sIdle :: s5 :: s10 :: s15 :: sOk :: Nil = Enum(5)
val state = Reg(init = sIdle)
when (state === sIdle) {
when (io.nickel) { state := s5 }