Skip to content

Commit

Permalink
Make it a warning to have too-wide literal values in Bundle Literals (#…
Browse files Browse the repository at this point in the history
…4093) (#4095)

(cherry picked from commit 4f33bf6)

Co-authored-by: Jack Koenig <koenig@sifive.com>
  • Loading branch information
mergify[bot] and jackkoenig authored May 24, 2024
1 parent 3e4382b commit 0445acf
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 7 deletions.
4 changes: 3 additions & 1 deletion core/src/main/scala/chisel3/Aggregate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,7 @@ abstract class Record extends Aggregate {
* )
* }}}
*/
private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*): this.type = {
private[chisel3] def _makeLit(elems: (this.type => (Data, Data))*)(implicit sourceInfo: SourceInfo): this.type = {

requireIsChiselType(this, "bundle literal constructor model")
val clone = cloneType
Expand Down Expand Up @@ -1222,6 +1222,8 @@ abstract class Record extends Aggregate {
// TODO make this a warning then an error, but for older versions, just truncate.
val valuex = if (widthValue < value.width.get) {
// Mask the value to the width of the field.
val msg = s"Literal value $value is too wide for field ${cloneFields(field)} with width $widthValue"
Builder.warning(Warning(WarningID.BundleLiteralValueTooWide, msg))
val mask = (BigInt(1) << widthValue) - 1
value.cloneWithValue(value.num & mask).cloneWithWidth(width)
} else if (widthValue > value.width.get) value.cloneWithWidth(width)
Expand Down
1 change: 1 addition & 0 deletions core/src/main/scala/chisel3/internal/Warning.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ private[chisel3] object WarningID extends Enumeration {
val DynamicIndexTooWide = Value(4)
val DynamicIndexTooNarrow = Value(5)
val ExtractFromVecSizeZero = Value(6)
val BundleLiteralValueTooWide = Value(7)
}
import WarningID.WarningID

Expand Down
7 changes: 7 additions & 0 deletions docs/src/explanations/warnings.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,10 @@ It can be fixed as described in the [Cookbook](../cookbooks/cookbook#how-do-i-re

This warning occurs when indexing a `Vec` with no elements.
It can be fixed by removing the indexing operation for the size zero `Vec` (perhaps via guarding with an `if-else` or `Option.when`).

### [W007] Bundle literal value too wide

This warning occurs when creating a [Bundle Literal](../appendix/experimental-features#bundle-literals) where the literal value for a
field is wider than the Bundle field's width.
It can be fixed by reducing the width of the literal (perhaps choosing a different value if it is impossible to encode the value in the
field's width).
8 changes: 5 additions & 3 deletions src/test/scala/chiselTests/BundleLiteralSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,17 @@ class BundleLiteralSpec extends ChiselFlatSpec with Utils {
exc.getMessage should include(".c")
}

"bundle literals with too-wide of literal values" should "truncate" in {
"bundle literals with too-wide of literal values" should "warn and truncate" in {
class SimpleBundle extends Bundle {
val a = UInt(4.W)
val b = UInt(4.W)
}
val chirrtl = ChiselStage.emitCHIRRTL(new RawModule {
val (stdout, _, chirrtl) = grabStdOutErr(ChiselStage.emitCHIRRTL(new RawModule {
val lit = (new SimpleBundle).Lit(_.a -> 0xde.U, _.b -> 0xad.U)
val x = lit.asUInt
})
}))
stdout should include("[W007] Literal value ULit(222,) is too wide for field _.a with width 4")
stdout should include("[W007] Literal value ULit(173,) is too wide for field _.b with width 4")
chirrtl should include("node x = cat(UInt<4>(0he), UInt<4>(0hd))")
}

Expand Down
5 changes: 2 additions & 3 deletions src/test/scala/chiselTests/VecLiteralSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -436,17 +436,16 @@ class VecLiteralSpec extends ChiselFreeSpec with Utils {

class VecExample extends RawModule {
val out = IO(Output(Vec(2, new SubBundle)))
// Note that 22.U is too wide for bar so gets truncated below.
val bundle = Vec(2, new SubBundle).Lit(
0 -> (new SubBundle).Lit(_.foo -> 42.U, _.bar -> 22.U),
0 -> (new SubBundle).Lit(_.foo -> 42.U, _.bar -> 0xd.U),
1 -> (new SubBundle).Lit(_.foo -> 7.U, _.bar -> 3.U)
)
out := bundle
}

"vec literals can contain bundles and should not be bulk connected" in {
val chirrtl = ChiselStage.emitCHIRRTL(new VecExample)
chirrtl should include("""connect out[0].bar, UInt<4>(0h6)""")
chirrtl should include("""connect out[0].bar, UInt<4>(0hd)""")
chirrtl should include("""connect out[0].foo, UInt<8>(0h2a)""")
chirrtl should include("""connect out[1].bar, UInt<4>(0h3)""")
chirrtl should include("""connect out[1].foo, UInt<8>(0h7)""")
Expand Down

0 comments on commit 0445acf

Please sign in to comment.