mirror of https://github.com/YosysHQ/yosys.git
opt_expr: refactor simplification of signed X>=0 and X<0. NFCI.
This commit is contained in:
parent
8e53d2e0bf
commit
9e9846a6ea
|
@ -1373,38 +1373,59 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
|
|
||||||
if (const_sig.is_fully_def() && const_sig.is_fully_const())
|
if (const_sig.is_fully_def() && const_sig.is_fully_const())
|
||||||
{
|
{
|
||||||
const char *condition, *replacement;
|
std::string condition, replacement;
|
||||||
SigSpec result_sig(State::S0, GetSize(cell->getPort("\\Y")));
|
SigSpec result_sig(State::S0, GetSize(cell->getPort("\\Y")));
|
||||||
result_sig[0] = State::Sx;
|
bool replace = false;
|
||||||
|
|
||||||
if (!is_signed)
|
if (!is_signed)
|
||||||
{
|
{ /* unsigned */
|
||||||
if (const_sig.is_fully_zero() && cmp_type == "$lt") {
|
if (const_sig.is_fully_zero() && cmp_type == "$lt") {
|
||||||
condition = "unsigned X<0";
|
condition = "unsigned X<0";
|
||||||
replacement = "constant 0";
|
replacement = "constant 0";
|
||||||
result_sig[0] = State::S0;
|
result_sig[0] = State::S0;
|
||||||
|
replace = true;
|
||||||
}
|
}
|
||||||
if (const_sig.is_fully_zero() && cmp_type == "$ge") {
|
if (const_sig.is_fully_zero() && cmp_type == "$ge") {
|
||||||
condition = "unsigned X>=0";
|
condition = "unsigned X>=0";
|
||||||
replacement = "constant 1";
|
replacement = "constant 1";
|
||||||
result_sig[0] = State::S1;
|
result_sig[0] = State::S1;
|
||||||
|
replace = true;
|
||||||
}
|
}
|
||||||
if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") {
|
if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") {
|
||||||
condition = "unsigned X>~0";
|
condition = "unsigned X>~0";
|
||||||
replacement = "constant 0";
|
replacement = "constant 0";
|
||||||
result_sig[0] = State::S0;
|
result_sig[0] = State::S0;
|
||||||
|
replace = true;
|
||||||
}
|
}
|
||||||
if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") {
|
if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") {
|
||||||
condition = "unsigned X<=~0";
|
condition = "unsigned X<=~0";
|
||||||
replacement = "constant 1";
|
replacement = "constant 1";
|
||||||
result_sig[0] = State::S1;
|
result_sig[0] = State::S1;
|
||||||
|
replace = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* signed */
|
||||||
|
if (const_sig.is_fully_zero() && cmp_type == "$lt")
|
||||||
|
{
|
||||||
|
condition = "signed X<0";
|
||||||
|
replacement = stringf("X[%d]", var_width - 1);
|
||||||
|
result_sig[0] = var_sig[var_width - 1];
|
||||||
|
replace = true;
|
||||||
|
}
|
||||||
|
if (const_sig.is_fully_zero() && cmp_type == "$ge")
|
||||||
|
{
|
||||||
|
condition = "signed X>=0";
|
||||||
|
replacement = stringf("X[%d]", var_width - 1);
|
||||||
|
module->addNot(NEW_ID, var_sig[var_width - 1], result_sig);
|
||||||
|
replace = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result_sig.is_fully_def())
|
if (replace)
|
||||||
{
|
{
|
||||||
log("Replacing %s cell `%s' (implementing %s) with %s.\n",
|
log("Replacing %s cell `%s' (implementing %s) with %s.\n",
|
||||||
log_id(cell->type), log_id(cell), condition, replacement);
|
log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str());
|
||||||
module->connect(cell->getPort("\\Y"), result_sig);
|
module->connect(cell->getPort("\\Y"), result_sig);
|
||||||
module->remove(cell);
|
module->remove(cell);
|
||||||
did_something = true;
|
did_something = true;
|
||||||
|
@ -1453,25 +1474,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
|
||||||
} else
|
} else
|
||||||
log_abort();
|
log_abort();
|
||||||
|
|
||||||
// replace a(signed) < 0 with the high bit of a
|
|
||||||
if (sigConst.is_fully_const() && sigConst.is_fully_zero() && var_signed == true)
|
|
||||||
{
|
|
||||||
RTLIL::SigSpec a_prime(RTLIL::State::S0, cell->parameters["\\Y_WIDTH"].as_int());
|
|
||||||
a_prime[0] = sigVar[width - 1];
|
|
||||||
if (is_lt) {
|
|
||||||
log("Replacing %s cell `%s' (implementing X<0) with X[%d]: %s\n",
|
|
||||||
log_id(cell->type), log_id(cell), width-1, log_signal(a_prime));
|
|
||||||
module->connect(cell->getPort("\\Y"), a_prime);
|
|
||||||
module->remove(cell);
|
|
||||||
} else {
|
|
||||||
log("Replacing %s cell `%s' (implementing X>=0) with ~X[%d]: %s\n",
|
|
||||||
log_id(cell->type), log_id(cell), width-1, log_signal(a_prime));
|
|
||||||
module->addNot(NEW_ID, a_prime, cell->getPort("\\Y"));
|
|
||||||
module->remove(cell);
|
|
||||||
}
|
|
||||||
did_something = true;
|
|
||||||
goto next_cell;
|
|
||||||
} else
|
|
||||||
if (sigConst.is_fully_const() && sigConst.is_fully_def() && var_signed == false)
|
if (sigConst.is_fully_const() && sigConst.is_fully_def() && var_signed == false)
|
||||||
{
|
{
|
||||||
int const_bit_set = get_onehot_bit_index(sigConst);
|
int const_bit_set = get_onehot_bit_index(sigConst);
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
module top(...);
|
module top(...);
|
||||||
input [3:0] a;
|
input [3:0] a;
|
||||||
output o1 = 4'b0000 > a;
|
|
||||||
output o2 = 4'b0000 <= a;
|
output o1_1 = 4'b0000 > a;
|
||||||
output o3 = 4'b1111 < a;
|
output o1_2 = 4'b0000 <= a;
|
||||||
output o4 = 4'b1111 >= a;
|
output o1_3 = 4'b1111 < a;
|
||||||
output o5 = a < 4'b0000;
|
output o1_4 = 4'b1111 >= a;
|
||||||
output o6 = a >= 4'b0000;
|
output o1_5 = a < 4'b0000;
|
||||||
output o7 = a > 4'b1111;
|
output o1_6 = a >= 4'b0000;
|
||||||
output o8 = a <= 4'b1111;
|
output o1_7 = a > 4'b1111;
|
||||||
|
output o1_8 = a <= 4'b1111;
|
||||||
|
|
||||||
|
output o2_1 = 4'sb0000 > $signed(a);
|
||||||
|
output o2_2 = 4'sb0000 <= $signed(a);
|
||||||
|
output o2_3 = $signed(a) < 4'sb0000;
|
||||||
|
output o2_4 = $signed(a) >= 4'sb0000;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue