3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-05-25 11:26:22 +00:00

Preserve param signedness across overrides.

This commit is contained in:
nella 2026-05-13 16:25:15 +02:00
parent 2046a23a2f
commit 7d3e56523b
5 changed files with 36 additions and 2 deletions

View file

@ -615,6 +615,15 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const
return as_int(is_signed);
}
void RTLIL::Const::tag_bare_integer_const(const std::string &value)
{
if (value.empty() || value.find('\'') != std::string::npos)
return;
size_t start = (value[0] == '-' || value[0] == '+') ? 1 : 0;
if (start < value.size() && std::all_of(value.begin() + start, value.end(), ::isdigit))
flags |= RTLIL::CONST_FLAG_SIGNED;
}
int RTLIL::Const::get_min_size(bool is_signed) const
{
if (empty()) return 0;

View file

@ -1091,6 +1091,8 @@ public:
// over/underflow, otherwise the max/min value for int depending on the sign.
int as_int_saturating(bool is_signed = false) const;
void tag_bare_integer_const(const std::string &value);
std::string as_string(const char* any = "-") const;
static Const from_string(const std::string &str);
std::vector<RTLIL::State> to_bits() const;

View file

@ -41,6 +41,7 @@ struct setunset_t
if (!RTLIL::SigSpec::parse(sig_value, nullptr, set_value))
log_cmd_error("Can't decode value '%s'!\n", set_value);
value = sig_value.as_const();
value.tag_bare_integer_const(set_value);
}
}
};

View file

@ -985,7 +985,9 @@ struct HierarchyPass : public Pass {
SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
log_cmd_error("Can't decode value '%s'!\n", para.second);
top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
RTLIL::Const c = sig_value.as_const();
c.tag_bare_integer_const(para.second);
top_parameters[RTLIL::escape_id(para.first)] = c;
}
}
@ -1073,7 +1075,9 @@ struct HierarchyPass : public Pass {
SigSpec sig_value;
if (!RTLIL::SigSpec::parse(sig_value, NULL, para.second))
log_cmd_error("Can't decode value '%s'!\n", para.second);
top_parameters[RTLIL::escape_id(para.first)] = sig_value.as_const();
RTLIL::Const c = sig_value.as_const();
c.tag_bare_integer_const(para.second);
top_parameters[RTLIL::escape_id(para.first)] = c;
}
top_mod = design->module(top_mod->derive(design, top_parameters));

View file

@ -0,0 +1,18 @@
# Issue #5745: chparam values are unsigned when using read_verilog frontend
#
# When chparam overrides a parameter value, the signed attribute is lost,
# causing signed comparisons to silently use unsigned logic.
#
# m = -32 (signed 9-bit), p2 = 11. Correct signed semantics: -32 < 11, so k = 1.
# Bug: chparam strips the signed attribute from p2. The $lt cell gets A_SIGNED=0,
# B_SIGNED=0, so the comparison treats m as unsigned (480 > 11), giving k = 0.
read_verilog <<EOT
module mod #(parameter p2=11) (output k);
wire signed [8:0] m = -32;
assign k = m < p2;
endmodule
EOT
chparam -set p2 11
hierarchy -top mod
sat -prove k 1 -verify