mirror of https://github.com/YosysHQ/yosys.git
peepopt: Support shift amounts zero-padded from below
The `opt_expr` pass running before `peepopt` can interfere with the detection of a shiftmul pattern due to some of the bottom bits of the shift amount being replaced with constant zero. Extend the detection to cover those situations as well.
This commit is contained in:
parent
dd1a8ae49a
commit
038a5e1ed4
|
@ -8,9 +8,13 @@ match shift
|
||||||
filter !port(shift, \B).empty()
|
filter !port(shift, \B).empty()
|
||||||
endmatch
|
endmatch
|
||||||
|
|
||||||
|
// the right shift amount
|
||||||
state <SigSpec> shift_amount
|
state <SigSpec> shift_amount
|
||||||
|
// log2 scale factor in interpreting of shift_amount
|
||||||
|
// due to zero padding on the shift cell's B port
|
||||||
|
state <int> log2scale
|
||||||
|
|
||||||
code shift_amount
|
code shift_amount log2scale
|
||||||
shift_amount = port(shift, \B);
|
shift_amount = port(shift, \B);
|
||||||
if (shift->type.in($shr) || !param(shift, \B_SIGNED).as_bool())
|
if (shift->type.in($shr) || !param(shift, \B_SIGNED).as_bool())
|
||||||
shift_amount.append(State::S0);
|
shift_amount.append(State::S0);
|
||||||
|
@ -25,6 +29,13 @@ code shift_amount
|
||||||
if (shift_amount.empty()) reject;
|
if (shift_amount.empty()) reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log2scale = 0;
|
||||||
|
while (shift_amount[0] == State::S0) {
|
||||||
|
shift_amount.remove(0);
|
||||||
|
if (shift_amount.empty()) reject;
|
||||||
|
log2scale++;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetSize(shift_amount) > 20)
|
if (GetSize(shift_amount) > 20)
|
||||||
reject;
|
reject;
|
||||||
endcode
|
endcode
|
||||||
|
@ -41,7 +52,7 @@ match mul
|
||||||
filter port(mul, constport).is_fully_const()
|
filter port(mul, constport).is_fully_const()
|
||||||
|
|
||||||
define <IdString> varport (constport == \A ? \B : \A)
|
define <IdString> varport (constport == \A ? \B : \A)
|
||||||
set mul_const port(mul, constport).as_const()
|
set mul_const SigSpec({port(mul, constport), SigSpec(State::S0, log2scale)}).as_const()
|
||||||
// get mul_din unmapped (so no `port()` shorthand)
|
// get mul_din unmapped (so no `port()` shorthand)
|
||||||
// because we will be using it to set the \A port
|
// because we will be using it to set the \A port
|
||||||
// on the shift cell, and we want to stay close
|
// on the shift cell, and we want to stay close
|
||||||
|
@ -61,7 +72,7 @@ code
|
||||||
|
|
||||||
int factor_bits = ceil_log2(mul_const.as_int());
|
int factor_bits = ceil_log2(mul_const.as_int());
|
||||||
// make sure the multiplication never wraps around
|
// make sure the multiplication never wraps around
|
||||||
if (GetSize(shift_amount) < factor_bits + GetSize(mul_din))
|
if (GetSize(shift_amount) + log2scale < factor_bits + GetSize(mul_din))
|
||||||
reject;
|
reject;
|
||||||
|
|
||||||
did_something = true;
|
did_something = true;
|
||||||
|
|
Loading…
Reference in New Issue