Skip to content

Commit

Permalink
Preserve UInt and SInt literals across .pad (backport #4156) (#4157)
Browse files Browse the repository at this point in the history
* Preserve UInt and SInt literals across .pad (#4156)

(cherry picked from commit 65a05b2)

* Waive false binary compatibility issue

---------

Co-authored-by: Jack Koenig <koenig@sifive.com>
  • Loading branch information
mergify[bot] and jackkoenig authored Jun 7, 2024
1 parent a7cb2ff commit 505ce19
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
4 changes: 3 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,9 @@ lazy val unipublish =
// chisel3.HasTarget is sealed
ProblemFilters.exclude[ReversedMissingMethodProblem]("chisel3.package#HasTarget.suggestName"),
// chisel3.internal.firrtl.ir.LitArg is package private
ProblemFilters.exclude[ReversedMissingMethodProblem]("chisel3.internal.firrtl.ir#LitArg.cloneWithValue")
ProblemFilters.exclude[ReversedMissingMethodProblem]("chisel3.internal.firrtl.ir#LitArg.cloneWithValue"),
// chisel3.Bits is sealed
ProblemFilters.exclude[ReversedMissingMethodProblem]("chisel3.Bits._padLit")
),
// Forward doc command to unidoc
Compile / doc := (ScalaUnidoc / doc).value,
Expand Down
14 changes: 14 additions & 0 deletions core/src/main/scala/chisel3/Bits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,13 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi
*/
final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg

// Pad literal to that width
protected def _padLit(that: Int): this.type

/** @group SourceInfoTransformMacro */
def do_pad(that: Int)(implicit sourceInfo: SourceInfo): this.type = this.width match {
case KnownWidth(w) if w >= that => this
case _ if this.isLit => this._padLit(that)
case _ => binop(sourceInfo, cloneTypeWidth(this.width.max(Width(that))), PadOp, that)
}

Expand Down Expand Up @@ -453,6 +457,11 @@ sealed class UInt private[chisel3] (width: Width) extends Bits(width) with Num[U
private[chisel3] override def cloneTypeWidth(w: Width): this.type =
new UInt(w).asInstanceOf[this.type]

override protected def _padLit(that: Int): this.type = {
val value = this.litValue
UInt.Lit(value, this.width.max(Width(that))).asInstanceOf[this.type]
}

// TODO: refactor to share documentation with Num or add independent scaladoc
/** Unary negation (expanding width)
*
Expand Down Expand Up @@ -812,6 +821,11 @@ sealed class SInt private[chisel3] (width: Width) extends Bits(width) with Num[S
private[chisel3] override def cloneTypeWidth(w: Width): this.type =
new SInt(w).asInstanceOf[this.type]

override protected def _padLit(that: Int): this.type = {
val value = this.litValue
SInt.Lit(value, this.width.max(Width(that))).asInstanceOf[this.type]
}

/** Unary negation (constant width)
*
* @return a hardware $coll equal to zero minus this $coll
Expand Down
7 changes: 3 additions & 4 deletions src/test/scala/chiselTests/ProbeSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -537,10 +537,9 @@ class ProbeSpec extends ChiselFlatSpec with Utils {
Array("--full-stacktrace")
)
(processChirrtl(chirrtl) should contain).allOf(
"node _T = pad(UInt<7>(0h7b), 16)",
"force_initial(p, _T)",
"node _T_2 = pad(in, 16)",
"force(clock, _T_1, p, _T_2)"
"force_initial(p, UInt<16>(0h7b))",
"node _T_1 = pad(in, 16)",
"force(clock, _T, p, _T_1)"
)
}

Expand Down
18 changes: 18 additions & 0 deletions src/test/scala/chiselTests/SIntOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,22 @@ class SIntOpsSpec extends ChiselPropSpec with Utils {
3.S.asSInt.litValue should be(3)
-5.S.asSInt.litValue should be(-5)
}

property("Calling .pad on a SInt literal should maintain the literal value") {
-5.S.getWidth should be(4)
-5.S.pad(2).litValue should be(-5)
-5.S.pad(2).getWidth should be(4)
-5.S.pad(4).litValue should be(-5)
-5.S.pad(4).getWidth should be(4)
-5.S.pad(6).litValue should be(-5)
-5.S.pad(6).getWidth should be(6)

-5.S(8.W).getWidth should be(8)
-5.S(8.W).pad(2).litValue should be(-5)
-5.S(8.W).pad(2).getWidth should be(8)
-5.S(8.W).pad(8).litValue should be(-5)
-5.S(8.W).pad(8).getWidth should be(8)
-5.S(8.W).pad(16).litValue should be(-5)
-5.S(8.W).pad(16).getWidth should be(16)
}
}
18 changes: 18 additions & 0 deletions src/test/scala/chiselTests/UIntOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -512,4 +512,22 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils {
0.U.zext.widthOption should be(Some(2))
0.U(0.W).zext.widthOption should be(Some(1))
}

property("Calling .pad on a UInt literl should maintain the literal value") {
5.U.getWidth should be(3)
5.U.pad(2).litValue should be(5)
5.U.pad(2).getWidth should be(3)
5.U.pad(3).litValue should be(5)
5.U.pad(3).getWidth should be(3)
5.U.pad(4).litValue should be(5)
5.U.pad(4).getWidth should be(4)

5.U(8.W).getWidth should be(8)
5.U(8.W).pad(2).litValue should be(5)
5.U(8.W).pad(2).getWidth should be(8)
5.U(8.W).pad(8).litValue should be(5)
5.U(8.W).pad(8).getWidth should be(8)
5.U(8.W).pad(16).litValue should be(5)
5.U(8.W).pad(16).getWidth should be(16)
}
}

0 comments on commit 505ce19

Please sign in to comment.