Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intern Width #4242

Merged
merged 1 commit into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/src/main/scala/chisel3/Aggregate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ sealed class Vec[T <: Data] private[chisel3] (gen: => T, val length: Int) extend
if (m < n) Some(index -> lit) else None
case (KnownWidth(_), _) =>
None
case (UnknownWidth(), _) =>
case (UnknownWidth, _) =>
None
case _ =>
Some(index -> lit)
Expand Down Expand Up @@ -1226,7 +1226,7 @@ abstract class Record extends Aggregate {
case (field, value) =>
field.width match {
// If width is unknown, then it is set by the literal value.
case UnknownWidth() => field -> value
case UnknownWidth => field -> value
case width @ KnownWidth(widthValue) =>
val valuex = if (widthValue < value.width.get) {
// For legacy reasons, 0.U is 1-bit, don't warn when it comes up as a literal value for 0-bit Bundle lit field.
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/scala/chisel3/Bits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
case KnownWidth(x) =>
require(x >= n, s"Can't tail($n) for width $x < $n")
Width(x - n)
case UnknownWidth() => Width()
case UnknownWidth => Width()
}
binop(sourceInfo, UInt(width = w), TailOp, n)
}

/** @group SourceInfoTransformMacro */
def do_head(n: Int)(implicit sourceInfo: SourceInfo): UInt = {
width match {
case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
case UnknownWidth() =>
case KnownWidth(x) => require(x >= n, s"Can't head($n) for width $x < $n")
case UnknownWidth => ()
}
binop(sourceInfo, UInt(Width(n)), HeadOp, n)
}
Expand Down Expand Up @@ -695,7 +695,7 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
resultWidth match {
// To emulate old FIRRTL behavior where minimum width is 1, we need to insert pad(_, 1) whenever
// the width is or could be 0. Thus we check if it is known to be 0 or is unknown.
case w @ (KnownWidth(0) | UnknownWidth()) =>
case w @ (KnownWidth(0) | UnknownWidth) =>
// Because we are inserting an extra op but we want stable emission (so the user can diff the output),
// we need to seed a name to avoid name collisions.
op.autoSeed("_shrLegacyWidthFixup")
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/ChiselEnum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ abstract class ChiselEnum {
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))

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/Data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@ final case object DontCare extends Element with connectable.ConnectableDocs {
// otherwise this "Chisel" object will end up on the UserModule's id list.
// We make it private to chisel3 so it has to be accessed through the package object.

private[chisel3] override val width: Width = UnknownWidth()
private[chisel3] override val width: Width = UnknownWidth

bind(DontCareBinding(), SpecifiedDirection.Output)
override def cloneType: this.type = DontCare
Expand Down
30 changes: 27 additions & 3 deletions core/src/main/scala/chisel3/Width.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package chisel3

object Width {
def apply(x: Int): Width = KnownWidth(x)
def apply(): Width = UnknownWidth()
def apply(): Width = UnknownWidth
}

sealed abstract class Width {
Expand All @@ -28,14 +28,24 @@ sealed abstract class Width {
protected def op(that: Width, f: (W, W) => W): Width
}

sealed case class UnknownWidth() extends 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(value: Int) extends Width {
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
Expand All @@ -45,3 +55,17 @@ sealed case class KnownWidth(value: Int) extends Width {
}
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)
}
}
4 changes: 2 additions & 2 deletions core/src/main/scala/chisel3/internal/firrtl/Converter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private[chisel3] object Converter {
case ModuleCloneIO(mod, name) =>
if (mod eq ctx.id) clonedModuleIOError(mod, name, info)
else fir.Reference(name)
case u @ ULit(n, UnknownWidth()) =>
case u @ ULit(n, UnknownWidth) =>
fir.UIntLiteral(n, fir.IntWidth(u.minWidth))
case ULit(n, w) =>
fir.UIntLiteral(n, convert(w))
Expand Down Expand Up @@ -343,7 +343,7 @@ private[chisel3] object Converter {
}

def convert(width: Width): fir.Width = width match {
case UnknownWidth() => fir.UnknownWidth
case UnknownWidth => fir.UnknownWidth
case KnownWidth(value) => fir.IntWidth(value)
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/internal/firrtl/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package object firrtl {
val Width = chisel3.Width

@deprecated("This type has moved to package chisel3", "Chisel 6.0")
type UnknownWidth = chisel3.UnknownWidth
type UnknownWidth = chisel3.UnknownWidth.type
@deprecated("This type has moved to package chisel3", "Chisel 6.0")
val UnknownWidth = chisel3.UnknownWidth

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/chisel3/properties/Property.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ sealed trait Property[T] extends Element { self =>
def toPrintable: Printable = {
throwException(s"Properties do not support hardware printing" + this._errorContext)
}
private[chisel3] def width: Width = UnknownWidth()
private[chisel3] def width: Width = UnknownWidth

override def typeName: String = s"Property[${tpe.getPropertyType().serialize}]"

Expand Down
2 changes: 1 addition & 1 deletion panamaconverter/src/PanamaCIRCTConverter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ class PanamaCIRCTConverter(val circt: PanamaCIRCT, fos: Option[FirtoolOptions],
): Reference.Value = {
def referToNewConstant(n: BigInt, w: Width, isSigned: Boolean): Reference.Value = {
val (firWidth, valWidth) = w match {
case _: UnknownWidth =>
case UnknownWidth =>
// We need to keep the most significant sign bit for signed literals
val bitLen = if (!isSigned) max(n.bitLength, 1) else n.bitLength + 1
(fir.IntWidth(bitLen), bitLen)
Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/chiselTests/ChiselEnum.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class SafeCastFromNonLit extends Module {
}

class CastFromNonLitWidth(w: Option[Int] = None) extends Module {
val width = if (w.isDefined) w.get.W else UnknownWidth()
val width = if (w.isDefined) w.get.W else UnknownWidth

val io = IO(new Bundle {
val in = Input(UInt(width))
Expand Down