Merge pull request #1404 from sifferman/param-string-compare

Fix assert on constant == with unequal-length string operands
This commit is contained in:
Cary R. 2026-07-02 18:57:44 -07:00 committed by GitHub
commit 50b477bc1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 0 deletions

View File

@ -916,6 +916,17 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
eval_expr(lp, l_width_);
eval_expr(rp, r_width_);
// test_width() does not equalize operand widths for string
// operands, but constant evaluation expects equal widths.
if (left_->expr_type() == IVL_VT_STRING ||
right_->expr_type() == IVL_VT_STRING) {
if (dynamic_cast<NetEConst*>(lp) && dynamic_cast<NetEConst*>(rp)) {
unsigned use_wid = max(lp->expr_width(), rp->expr_width());
lp = pad_to_width(lp, use_wid, false, *this);
rp = pad_to_width(rp, use_wid, false, *this);
}
}
// Handle some operand-specific special cases...
switch (op_) {
case 'E': /* === */

View File

@ -0,0 +1,36 @@
// Regression test: comparing a `string` parameter to a string constant of
// a different length must constant-fold cleanly instead of tripping the
// "lv.len() == rv.len()" assertion in the NetEBComp evaluation functions.
// Covers ==, !=, ===, !==, ==? and !=? with the string operand on either
// side and both shorter and longer than the other operand.
module main #(parameter string Target = "A",
parameter string Long = "ABC");
integer errors = 0;
// Equality / inequality, parameter shorter than the literal.
if (Target == "AA") initial begin errors += 1; $display("FAILED: Target == \"AA\""); end
if (Target != "A") initial begin errors += 1; $display("FAILED: Target != \"A\""); end
// Literal on the left.
if ("AA" == Target) initial begin errors += 1; $display("FAILED: \"AA\" == Target"); end
// Parameter longer than the literal.
if (Long == "AB") initial begin errors += 1; $display("FAILED: Long == \"AB\""); end
if (Long != "ABC") initial begin errors += 1; $display("FAILED: Long != \"ABC\""); end
// Two string parameters of different lengths.
if (Target == Long) initial begin errors += 1; $display("FAILED: Target == Long"); end
// Case equality.
if (Target === "AA") initial begin errors += 1; $display("FAILED: Target === \"AA\""); end
if (Target !== "A") initial begin errors += 1; $display("FAILED: Target !== \"A\""); end
// Wildcard equality.
if (Target ==? "AA") initial begin errors += 1; $display("FAILED: Target ==? \"AA\""); end
if (Target !=? "A") initial begin errors += 1; $display("FAILED: Target !=? \"A\""); end
initial #1 if (errors == 0) $display("PASSED");
endmodule

View File

@ -416,6 +416,7 @@ net_string_fail CE,-g2005-sv ivltests
package_vec_part_select normal,-g2005-sv ivltests
packeda normal,-g2009 ivltests
packeda2 normal,-g2009 ivltests
param_string_compare normal,-g2009 ivltests
parameter_in_generate2 CE,-g2005-sv ivltests
parameter_no_default normal,-g2005-sv ivltests
parameter_no_default_fail1 CE ivltests