diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index cab1a82ee2e..035ac213b2f 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 51176d9d7ad..4ffd0b8600f 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 55b595ee60f..45aee62aa95 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 57586c9787a..0d03ff65fd3 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 c474430b8f6..712b5b7a6c6 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 }