Skip to content

Commit

Permalink
Merge pull request #20 from alainmarcel/new_peepopts
Browse files Browse the repository at this point in the history
All tests pass
  • Loading branch information
alaindargelas authored Dec 20, 2024
2 parents a497be5 + cd503d4 commit a731570
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
65 changes: 47 additions & 18 deletions passes/pmgen/peepopt_muxadd.pmg
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ pattern muxadd
// Authored by Akash Levy and Alain Dargelas of Silimate, Inc. under ISC license.
// Transforms add->mux into mux->add:
// y = s ? (a + b) : a ===> y = a + (s ? b : 0)
//
// or
// y = s ? a : (a + b) ===> y = a + (s ? 0 : b)

state <SigSpec> add_a add_b add_y add_a_ext
state <SigSpec> add_a add_b add_y add_a_ext mux_a mux_b mux_y
state <Const> add_a_signed
state <IdString> add_a_id add_b_id
state <IdString> add_a_id add_b_id mux_a_id mux_b_id

match add
// Select adder
Expand All @@ -32,28 +33,36 @@ code add_y add_a add_b add_a_ext

endcode

match mux
match mux
// Select mux of form s ? (a + b) : a, allow leading 0s when A_WIDTH != Y_WIDTH
// or s ? a : (a + b)
select mux->type == $mux
index <SigSpec> port(mux, \A) === add_a_ext
index <SigSpec> port(mux, \B) === add_y
choice <IdString> AB {\A, \B}
define <IdString> BA (AB == \A ? \B : \A)
set mux_y port(mux, \Y)
set mux_a port(mux, AB)
set mux_b port(mux, BA)
set mux_a_id AB
set mux_b_id BA
index <SigSpec> port(mux, AB) === add_a_ext
index <SigSpec> port(mux, BA) === add_y
endmatch

code
code add_y add_a add_b add_a_ext add_a_id add_b_id mux_y mux_a mux_b mux_a_id mux_b_id
// Get mux signal
SigSpec mux_y = port(mux, \Y);
SigSpec mux_a = port(mux, \A);
SigSpec mux_b = port(mux, \B);
SigSpec mid;
std::string adder_y_name;
if (add_y.is_wire())
adder_y_name = add_y.as_wire()->name.c_str();
else
adder_y_name = add_y.as_string();

// Create new mid wire
SigSpec mid = module->addWire(NEW_ID, GetSize(add_b));

// Rewire

// Start by renaming the lhs of an eventual assign stmt where the rhs is the adder output (That is getting rewired).
// Renaming the signal allows equiv_opt to function as it would otherwize try to match the functionality witch would fail
// as the lhs signal has indeed changed function.
std::string adder_y_name = add_y.as_wire()->name.c_str();
// Adder output could be assigned...
for (auto it = module->connections().begin(); it != module->connections().end(); ++it) {
RTLIL::SigSpec rhs = it->second;
const std::string& rhs_name = rhs.as_wire()->name.c_str();
Expand All @@ -64,12 +73,32 @@ code
break;
}
}
// ...or the port name could be a wire name
if (add_y.is_wire()) {
if (adder_y_name.size()) {
if (adder_y_name[0] != '$') {
module->rename(adder_y_name, module->uniquify("$" + adder_y_name));
}
}
} else {
for (auto chunk : add_y.chunks()) {
if (chunk.is_wire()) {
const std::string& name = chunk.wire->name.c_str();
if (name[0] != '$') {
module->rename(name, module->uniquify("$" + name));
}
}
}
}

// Create new mid wire
mid = module->addWire(NEW_ID, GetSize(add_b));

add->setPort(\B, mid);
add->setPort(\A, add_a);
add->setPort(add_b_id, mid);
add->setPort(add_a_id, add_a);
add->setPort(\Y, add_y);
mux->setPort(add_a_id, Const(State::S0, GetSize(add_b)));
mux->setPort(add_b_id, add_b);
mux->setPort(mux_a_id, Const(State::S0, GetSize(add_b)));
mux->setPort(mux_b_id, add_b);
mux->setPort(\Y, mid);
module->connect(mux_y, add_y);
// Log, fixup, accept
Expand Down
4 changes: 2 additions & 2 deletions tests/peepopt/muxadd.ys
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ wreduce
opt_clean
equiv_opt -assert peepopt
design -load postopt
select -assert-none t:$add %co1 %a w:y %i
select -assert-any t:$add %co1 %a w:y %i

log -pop
log -header "Test transform when (a+b) wider than a, adder’s a input is signed, a sign-extended on the muxes input"
Expand All @@ -265,7 +265,7 @@ wreduce
opt_clean
equiv_opt -assert peepopt
design -load postopt
select -assert-none t:$add %co1 %a w:y %i
select -assert-any t:$add %co1 %a w:y %i

log -pop
log -header "Test transform when pattern is s?a:(a+b)"
Expand Down

0 comments on commit a731570

Please sign in to comment.