Skip to content

XLS should codegen explicitly-sized sub-expressions to avoid self-determined widths #2048

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

Open
mikex-oss opened this issue Apr 23, 2025 · 0 comments
Labels
enhancement New feature or request 🧦 sox

Comments

@mikex-oss
Copy link
Collaborator

mikex-oss commented Apr 23, 2025

What's hard to do? (limit 100 words)

XLS generates expressions relying on implicitly sized bitwidths according to LRM Table 11-21. In general, for hardware design, this is problematic because the bitlengths of self-determined expressions can be counterintuitive. Examples:

  • a * b and a + b, etc. produces a result of length max($bits(a), $bits(b)). 2'b10 + 2'b10 as a subexpression produces a result of 2'b00.
  • In logic [7:0] foo; logic bar; logic baz; assign foo = {(bar << 3), (baz << 3)};, bar << 3 has length 1 ($bits(bar)), and foo evaluates to zero.

Due to these types of bugs that can be quite hard to detect in DV, chip projects commonly have lint rules in place to flag self-determined bitlengths in arithmetic expressions that may not produce the intended result. The Google Verilog style guide specifies avoiding these cases by either:

  • Casting the sub-expression to a specific width
  • Breaking down compound expressions into separate intermediate variables.

XLS knows the bitwidths of everything so should actually do the right thing, but generated code can still hit these lint errors. For example,

let first_lost_bit_idx = lsb_index - u32:1;
let round_bit = fraction[first_lost_bit_idx+:u1];
match round_style {
RoundStyle::TIES_TO_EVEN => {
// Extract the last bit which is retained.
let lsb = lsb_index < FRACTION_SZ && fraction[lsb_index+:u1];
// Whether any bits before the round_bit are 1.
let sticky = std::or_reduce_lsb(fraction, lsb_index - u32:1);

results in something including:

'23'h7f_ffff << fltirst_lost_bit_idx__1

where fltirst_lost_bit_idx__1 is 32 bits, so the lint tool thinks you might expect a larger result. In actuality, we know that the bit index is something in range, and we still expect a 23 bit result.

Current best alternative workaround (limit 100 words)

We can globally waive this type of lint error for an XLS generated file.

Your view of the "best case XLS enhancement" (limit 100 words)

Ideally, XLS generated RTL should be lint clean when reasonable and follow established best style practices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request 🧦 sox
Projects
Status: No status
Development

No branches or pull requests

1 participant