summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Naik2024-08-06 05:35:30 -0700
committerAditya Naik2024-08-06 05:35:30 -0700
commit51864db8176662d134e1a260f92eafc83f9933d8 (patch)
treea92572eb64033060304df5ab9ebec0047e97dbbb
parentcf31062758d4d9722ac30f89fdfe7cc7c1d8cc74 (diff)
Update ChiselEnum.scala
And more changes
-rw-r--r--core/src/main/scala/chisel3/ChiselEnum.scala (renamed from core/src/main/scala/chisel3/experimental/ChiselEnum.scala)123
-rw-r--r--core/src/main/scala/chisel3/Width.scala71
-rw-r--r--core/src/main/scala/chisel3/experimental/EnumAnnotations.scala63
-rw-r--r--core/src/main/scala/chisel3/experimental/package.scala13
-rw-r--r--core/src/main/scala/chisel3/internal/Binding.scala1
-rw-r--r--core/src/main/scala/chisel3/internal/Error.scala4
-rw-r--r--core/src/main/scala/chisel3/internal/Warning.scala36
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/IR.scala38
-rw-r--r--core/src/main/scala/chisel3/package.scala4
9 files changed, 221 insertions, 132 deletions
diff --git a/core/src/main/scala/chisel3/experimental/ChiselEnum.scala b/core/src/main/scala/chisel3/ChiselEnum.scala
index d0ad6949..881bbc62 100644
--- a/core/src/main/scala/chisel3/experimental/ChiselEnum.scala
+++ b/core/src/main/scala/chisel3/ChiselEnum.scala
@@ -1,75 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
-package chisel3.experimental
+package chisel3
import scala.collection.mutable
import chisel3._
-import chisel3.internal.Builder.pushOp
+import chisel3.internal.Builder
+import chisel3.internal.Builder._
import chisel3.internal.firrtl.PrimOp._
import chisel3.internal.firrtl._
-import chisel3.internal.{throwException, Binding, Builder, ChildBinding, ConstrainedBinding}
-import firrtl.annotations._
+import chisel3.internal.{throwException, Binding, Builder, ChildBinding, ConstrainedBinding, Warning, WarningID}
+import chisel3.experimental.{annotate, requireIsHardware, ChiselAnnotation}
+import chisel3.experimental.EnumAnnotations._
-object EnumAnnotations {
- /** An annotation for strong enum instances that are ''not'' inside of Vecs
- *
- * @param target the enum instance being annotated
- * @param enumTypeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- */
- case class EnumComponentAnnotation(target: Named, enumTypeName: String) extends SingleTargetAnnotation[Named] {
- def duplicate(n: Named): EnumComponentAnnotation = this.copy(target = n)
- }
-
- case class EnumComponentChiselAnnotation(target: InstanceId, enumTypeName: String) extends ChiselAnnotation {
- def toFirrtl: EnumComponentAnnotation = EnumComponentAnnotation(target.toNamed, enumTypeName)
- }
-
- /** An annotation for Vecs of strong enums.
- *
- * The ''fields'' parameter deserves special attention, since it may be difficult to understand. Suppose you create a the following Vec:
- *
- * {{{
- * VecInit(new Bundle {
- * val e = MyEnum()
- * val b = new Bundle {
- * val inner_e = MyEnum()
- * }
- * val v = Vec(3, MyEnum())
- * }
- * }}}
- *
- * Then, the ''fields'' parameter will be: ''Seq(Seq("e"), Seq("b", "inner_e"), Seq("v"))''. Note that for any Vec that doesn't contain Bundles, this field will simply be an empty Seq.
- *
- * @param target the Vec being annotated
- * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- * @param fields a list of all chains of elements leading from the Vec instance to its inner enum fields.
- */
- case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]])
- extends SingleTargetAnnotation[Named] {
- def duplicate(n: Named): EnumVecAnnotation = this.copy(target = n)
- }
-
- case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]])
- extends ChiselAnnotation {
- override def toFirrtl: EnumVecAnnotation = EnumVecAnnotation(target.toNamed, typeName, fields)
- }
-
- /** An annotation for enum types (rather than enum ''instances'').
- *
- * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
- * @param definition a map describing which integer values correspond to which enum names
- */
- case class EnumDefAnnotation(typeName: String, definition: Map[String, BigInt]) extends NoTargetAnnotation
-
- case class EnumDefChiselAnnotation(typeName: String, definition: Map[String, BigInt]) extends ChiselAnnotation {
- override def toFirrtl: Annotation = EnumDefAnnotation(typeName, definition)
- }
-}
-
-import EnumAnnotations._
-
-@deprecated("This type has moved to chisel3", "Chisel 3.5")
abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating: Boolean = true) extends Element {
// Use getSimpleName instead of enumTypeName because for debugging purposes
@@ -196,7 +139,7 @@ abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating
case b: Bundle => enumFields(b)
case _ => Seq()
}
- case b: Bundle =>
+ case b: Record =>
b.elements.collect {
case (name, e: EnumType) if this.typeEquivalent(e) => Seq(Seq(name))
case (name, v: Vec[_]) if this.typeEquivalent(v.sample_element) => Seq(Seq(name))
@@ -221,20 +164,21 @@ abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating
}
private def annotateEnum(): Unit = {
- val anno = outerMostVec() match {
- case Some(v) => EnumVecChiselAnnotation(v, enumTypeName, enumFields(v))
- case None => EnumComponentChiselAnnotation(this, enumTypeName)
- }
-
- if (!Builder.enumAnnos.contains(anno)) {
- Builder.enumAnnos += anno
- annotate(anno)
- }
-
- if (!Builder.enumAnnos.contains(factory.globalAnnotation)) {
- Builder.enumAnnos += factory.globalAnnotation
- annotate(factory.globalAnnotation)
- }
+ // add after builder.enumAnnos
+ // val anno = outerMostVec() match {
+ // case Some(v) => EnumVecChiselAnnotation(v, enumTypeName, enumFields(v))
+ // case None => EnumComponentChiselAnnotation(this, enumTypeName)
+ // }
+
+ // if (!Builder.enumAnnos.contains(anno)) {
+ // Builder.enumAnnos += anno
+ // annotate(anno)
+ // }
+
+ // if (!Builder.enumAnnos.contains(factory.globalAnnotation)) {
+ // Builder.enumAnnos += factory.globalAnnotation
+ // annotate(factory.globalAnnotation)
+ // }
}
protected def enumTypeName: String = factory.enumTypeName
@@ -253,6 +197,9 @@ abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating
for ((name, value) <- allNamesPadded) {
when(this === value) {
for ((r, c) <- result.zip(name)) {
+ // toChar doesn't work with
+ // An extension method was tried, but could not be fully constructed:
+ // chisel3.fromLongToLiteral(c.toChar)
r := c.toInt.U
}
}
@@ -261,11 +208,15 @@ abstract class EnumType(private[chisel3] val factory: ChiselEnum, selfAnnotating
}
}
-@deprecated("This type has been moved and renamed to chisel3.ChiselEnum", "Chisel 3.5")
-abstract class EnumFactory {
+private[chisel3] object ChiselEnum {
+ // add after buildercontextcache
+// private[chisel3] case object CacheKey extends BuilderContextCache.Key[mutable.HashSet[ChiselAnnotation]]
+}
+
+abstract class ChiselEnum {
class Type extends EnumType(this)
object Type {
- def apply(): Type = EnumFactory.this.apply()
+ def apply(): Type = ChiselEnum.this.apply()
}
private var id: BigInt = 0
@@ -287,7 +238,7 @@ abstract class EnumFactory {
}
private[chisel3] def globalAnnotation: EnumDefChiselAnnotation =
- EnumDefChiselAnnotation(enumTypeName, (enumNames, enumValues).zipped.toMap)
+ EnumDefChiselAnnotation(enumTypeName, enumNames.zip(enumValues).toMap)
def getWidth: Int = width.get
@@ -303,7 +254,7 @@ abstract class EnumFactory {
val result = new Type
// We have to use UnknownWidth here, because we don't actually know what the final width will be
- result.bindToLiteral(id, UnknownWidth())
+ result.bindToLiteral(id, UnknownWidth)
enumRecords.append(EnumRecord(result, name))
@@ -343,10 +294,11 @@ abstract class EnumFactory {
} else if (n.getWidth > this.getWidth) {
throwException(s"The UInt being cast to $enumTypeName is wider than $enumTypeName's width ($getWidth)")
} else {
+ // TODO fold this into warning filters
if (!Builder.suppressEnumCastWarning && warn && !this.isTotal) {
- Builder.warning(
+ val msg =
s"Casting non-literal UInt to $enumTypeName. You can use $enumTypeName.safe to cast without this warning."
- )
+ Builder.warning(Warning(WarningID.UnsafeUIntCastToEnum, msg))
}
val glue = Wire(new UnsafeEnum(width))
glue := n
@@ -401,7 +353,6 @@ private object UnsafeEnum extends ChiselEnum
* }
* }}}
*/
-@deprecated("This type has moved to chisel3", "Chisel 3.5")
object suppressEnumCastWarning {
def apply[T](block: => T): T = {
val parentWarn = Builder.suppressEnumCastWarning
diff --git a/core/src/main/scala/chisel3/Width.scala b/core/src/main/scala/chisel3/Width.scala
new file mode 100644
index 00000000..3c1abf5e
--- /dev/null
+++ b/core/src/main/scala/chisel3/Width.scala
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3
+
+object Width {
+ def apply(x: Int): Width = KnownWidth(x)
+ def apply(): Width = UnknownWidth
+}
+
+sealed abstract class Width {
+ type W = Int
+ def min(that: Width): Width = this.op(that, _ min _)
+ def max(that: Width): Width = this.op(that, _ max _)
+ def +(that: Width): Width = this.op(that, _ + _)
+ def +(that: Int): Width = this.op(this, (a, b) => a + that)
+ @deprecated(
+ "The width of shift-right now differs by type, use unsignedShiftRight and signedShiftRight",
+ "Chisel 7.0.0"
+ )
+ def shiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that))
+ def unsignedShiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that))
+ def signedShiftRight(that: Int): Width = this.op(this, (a, b) => 1.max(a - that))
+ def dynamicShiftLeft(that: Width): Width =
+ this.op(that, (a, b) => a + (1 << b) - 1)
+
+ def known: Boolean
+ def get: W
+ protected def op(that: Width, f: (W, W) => W): Width
+}
+
+case object UnknownWidth extends Width {
+ def known: Boolean = false
+ def get: Int = None.get
+ def op(that: Width, f: (W, W) => W): Width = this
+ override def toString: String = ""
+
+ @deprecated("UnknownWidth is now a case object, remove the parentheses", "Chisel 7.0")
+ def apply(): UnknownWidth.type = this
+
+ @deprecated("UnknownWidth is now a case object, remove the parentheses", "Chisel 7.0")
+ def unapply(x: UnknownWidth.type): Boolean = true
+}
+
+sealed case class KnownWidth private (value: Int) extends Width {
+
+ @deprecated("Use the companion object appy method (remove the \"new\")", "Chisel 7.0")
+ def this(value: Int, dummy: Int = 0) = this(value.toInt)
+
+ require(value >= 0, s"Widths must be non-negative, got $value")
+ def known: Boolean = true
+ def get: Int = value
+ def op(that: Width, f: (W, W) => W): Width = that match {
+ case KnownWidth(x) => KnownWidth(f(value, x))
+ case _ => that
+ }
+ override def toString: String = s"<${value.toString}>"
+}
+object KnownWidth {
+ private val maxCached = 1024
+ private val cache = new Array[KnownWidth](maxCached + 1)
+ def apply(value: Int): KnownWidth = {
+ if (0 <= value && value <= maxCached) {
+ var w = cache(value)
+ if (w eq null) {
+ w = new KnownWidth(value)
+ cache(value) = w
+ }
+ w
+ } else new KnownWidth(value)
+ }
+}
diff --git a/core/src/main/scala/chisel3/experimental/EnumAnnotations.scala b/core/src/main/scala/chisel3/experimental/EnumAnnotations.scala
new file mode 100644
index 00000000..4719928e
--- /dev/null
+++ b/core/src/main/scala/chisel3/experimental/EnumAnnotations.scala
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.experimental
+
+import chisel3._
+import firrtl.annotations._
+
+object EnumAnnotations {
+
+ /** An annotation for strong enum instances that are ''not'' inside of Vecs
+ *
+ * @param target the enum instance being annotated
+ * @param enumTypeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
+ */
+ case class EnumComponentAnnotation(target: Named, enumTypeName: String) extends SingleTargetAnnotation[Named] {
+ def duplicate(n: Named): EnumComponentAnnotation = this.copy(target = n)
+ }
+
+ case class EnumComponentChiselAnnotation(target: InstanceId, enumTypeName: String) extends ChiselAnnotation {
+ def toFirrtl: EnumComponentAnnotation = EnumComponentAnnotation(target.toNamed, enumTypeName)
+ }
+
+ /** An annotation for Vecs of strong enums.
+ *
+ * The ''fields'' parameter deserves special attention, since it may be difficult to understand. Suppose you create a the following Vec:
+ *
+ * {{{
+ * VecInit(new Bundle {
+ * val e = MyEnum()
+ * val b = new Bundle {
+ * val inner_e = MyEnum()
+ * }
+ * val v = Vec(3, MyEnum())
+ * }
+ * }}}
+ *
+ * Then, the ''fields'' parameter will be: ''Seq(Seq("e"), Seq("b", "inner_e"), Seq("v"))''. Note that for any Vec that doesn't contain Bundles, this field will simply be an empty Seq.
+ *
+ * @param target the Vec being annotated
+ * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
+ * @param fields a list of all chains of elements leading from the Vec instance to its inner enum fields.
+ */
+ case class EnumVecAnnotation(target: Named, typeName: String, fields: Seq[Seq[String]])
+ extends SingleTargetAnnotation[Named] {
+ def duplicate(n: Named): EnumVecAnnotation = this.copy(target = n)
+ }
+
+ case class EnumVecChiselAnnotation(target: InstanceId, typeName: String, fields: Seq[Seq[String]])
+ extends ChiselAnnotation {
+ override def toFirrtl: EnumVecAnnotation = EnumVecAnnotation(target.toNamed, typeName, fields)
+ }
+
+ /** An annotation for enum types (rather than enum ''instances'').
+ *
+ * @param typeName the name of the enum's type (e.g. ''"mypackage.MyEnum"'')
+ * @param definition a map describing which integer values correspond to which enum names
+ */
+ case class EnumDefAnnotation(typeName: String, definition: Map[String, BigInt]) extends NoTargetAnnotation
+
+ case class EnumDefChiselAnnotation(typeName: String, definition: Map[String, BigInt]) extends ChiselAnnotation {
+ override def toFirrtl: Annotation = EnumDefAnnotation(typeName, definition)
+ }
+}
diff --git a/core/src/main/scala/chisel3/experimental/package.scala b/core/src/main/scala/chisel3/experimental/package.scala
index 6dc14afb..d07bcf4a 100644
--- a/core/src/main/scala/chisel3/experimental/package.scala
+++ b/core/src/main/scala/chisel3/experimental/package.scala
@@ -23,6 +23,19 @@ package object experimental {
type Direction = ActualDirection
val Direction = ActualDirection
+ /** Requires that a node is hardware ("bound")
+ */
+ object requireIsHardware {
+ def apply(node: Data, msg: String = ""): Unit = {
+ if (!node.isSynthesizable) {
+ val prefix = if (msg.nonEmpty) s"$msg " else ""
+ throw ExpectedHardwareException(
+ s"$prefix'$node' must be hardware, " +
+ "not a bare Chisel type. Perhaps you forgot to wrap it in Wire(_) or IO(_)?"
+ )
+ }
+ }
+ }
// class dump extends chisel3.internal.naming.dump
// class treedump extends chisel3.internal.naming.treedump
diff --git a/core/src/main/scala/chisel3/internal/Binding.scala b/core/src/main/scala/chisel3/internal/Binding.scala
index 3a12afde..db85b355 100644
--- a/core/src/main/scala/chisel3/internal/Binding.scala
+++ b/core/src/main/scala/chisel3/internal/Binding.scala
@@ -10,6 +10,7 @@ import scala.collection.immutable.VectorMap
/** Requires that a node is hardware ("bound")
*/
+// remove/move this to chisel3.experimental once references are fixed
object requireIsHardware {
def apply(node: Data, msg: String = ""): Unit = {
node._parent match { // Compatibility layer hack
diff --git a/core/src/main/scala/chisel3/internal/Error.scala b/core/src/main/scala/chisel3/internal/Error.scala
index b7c4be35..730c9510 100644
--- a/core/src/main/scala/chisel3/internal/Error.scala
+++ b/core/src/main/scala/chisel3/internal/Error.scala
@@ -324,10 +324,6 @@ private class Error(msg: => String, line: Option[StackTraceElement]) extends Log
def format: String = tag("error", Console.RED)
}
-class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
- def format: String = tag("warn", Console.YELLOW)
-}
-
private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
def format: String = tag("info", Console.MAGENTA)
}
diff --git a/core/src/main/scala/chisel3/internal/Warning.scala b/core/src/main/scala/chisel3/internal/Warning.scala
new file mode 100644
index 00000000..5ac506c9
--- /dev/null
+++ b/core/src/main/scala/chisel3/internal/Warning.scala
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package chisel3.internal
+
+///////////////////////////////////////////////////
+// Never remove IDs and only ever add to the end //
+///////////////////////////////////////////////////
+
+// TODO should deprecations be included here?
+private[chisel3] object WarningID extends Enumeration {
+ type WarningID = Value
+
+ val NoID = Value(0) // Reserved
+ val UnsafeUIntCastToEnum = Value(1)
+ val DynamicBitSelectTooWide = Value(2)
+ val DynamicBitSelectTooNarrow = Value(3)
+ val DynamicIndexTooWide = Value(4)
+ val DynamicIndexTooNarrow = Value(5)
+ val ExtractFromVecSizeZero = Value(6)
+ val BundleLiteralValueTooWide = Value(7)
+ val AsTypeOfReadOnly = Value(8)
+}
+import WarningID.WarningID
+
+// Argument order differs from apply below to avoid type signature collision with apply method below
+private[chisel3] case class Warning(id: WarningID, msg: String)
+private[chisel3] object Warning {
+ def apply(id: WarningID, msg: String): Warning = {
+ val num = f"[W${id.id}%03d] "
+ new Warning(info, id, num + msg)
+ }
+ def noInfo(id: WarningID, msg: String): Warning = {
+ implicit val info = SourceInfo.materializeFromStacktrace
+ Warning(id, msg)
+ }
+}
diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
index de3d8716..9fee727c 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -216,44 +216,6 @@ case class LitIndex(imm: Arg, value: Int) extends Arg {
override def localName: String = s"${imm.localName}[$value]"
}
-object Width {
- def apply(x: Int): Width = KnownWidth(x)
- def apply(): Width = UnknownWidth()
-}
-
-sealed abstract class Width {
- type W = Int
- def min(that: Width): Width = this.op(that, _ min _)
- def max(that: Width): Width = this.op(that, _ max _)
- def +(that: Width): Width = this.op(that, _ + _)
- def +(that: Int): Width = this.op(this, (a, b) => a + that)
- def shiftRight(that: Int): Width = this.op(this, (a, b) => 0.max(a - that))
- def dynamicShiftLeft(that: Width): Width =
- this.op(that, (a, b) => a + (1 << b) - 1)
-
- def known: Boolean
- def get: W
- protected def op(that: Width, f: (W, W) => W): Width
-}
-
-sealed case class UnknownWidth() extends Width {
- def known: Boolean = false
- def get: Int = None.get
- def op(that: Width, f: (W, W) => W): Width = this
- override def toString: String = ""
-}
-
-sealed case class KnownWidth(value: Int) extends Width {
- require(value >= 0)
- def known: Boolean = true
- def get: Int = value
- def op(that: Width, f: (W, W) => W): Width = that match {
- case KnownWidth(x) => KnownWidth(f(value, x))
- case _ => that
- }
- override def toString: String = s"<${value.toString}>"
-}
-
object BinaryPoint {
def apply(x: Int): BinaryPoint = KnownBinaryPoint(x)
def apply(): BinaryPoint = UnknownBinaryPoint
diff --git a/core/src/main/scala/chisel3/package.scala b/core/src/main/scala/chisel3/package.scala
index 6633e7ab..be5fb7b5 100644
--- a/core/src/main/scala/chisel3/package.scala
+++ b/core/src/main/scala/chisel3/package.scala
@@ -18,10 +18,6 @@ package object chisel3 {
import scala.language.implicitConversions
- type ChiselEnum = experimental.ChiselEnum
- type EnumType = experimental.EnumType
- val suppressEnumCastWarning = experimental.suppressEnumCastWarning
-
/**
* These implicit classes allow one to convert [[scala.Int]] or [[scala.BigInt]] to
* Chisel.UInt|Chisel.SInt by calling .asUInt|.asSInt on them, respectively.