3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-24 01:25:33 +00:00

neg sub pass

This commit is contained in:
Alain Dargelas 2025-03-10 13:47:06 -07:00
parent 2679e1d458
commit 6de80bc6b3
4 changed files with 166 additions and 0 deletions

View file

@ -34,6 +34,7 @@ PEEPOPT_PATTERN += passes/opt/peepopt_muldiv.pmg
PEEPOPT_PATTERN += passes/opt/peepopt_muldiv_c.pmg
PEEPOPT_PATTERN += passes/opt/peepopt_muxorder.pmg
PEEPOPT_PATTERN += passes/opt/peepopt_formal_clockgateff.pmg
PEEPOPT_PATTERN += passes/opt/peepopt_sub_neg.pmg
passes/opt/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
$(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)

View file

@ -121,6 +121,7 @@ struct PeepoptPass : public Pass {
pm.run_shiftmul_left();
pm.run_muldiv();
pm.run_muldiv_c();
pm.run_sub_neg();
if (muxorder)
pm.run_muxorder();
}

View file

@ -0,0 +1,62 @@
pattern sub_neg
//
// Authored by Akash Levy and Alain Dargelas of Silimate, Inc. under ISC license.
// Transforms -(a-b) ----> (b-a)
state <SigSpec> a b sub_y
match sub
// Select sub
select sub->type == $sub
endmatch
code a b sub_y
// Get sub signals
a = port(sub, \A);
b = port(sub, \B);
sub_y = port(sub, \Y);
bool a_signed = sub->getParam(ID::A_SIGNED).as_bool();
bool b_signed = sub->getParam(ID::B_SIGNED).as_bool();
// Fanout of each sub Y bit should be 1 (no bit-split)
if (nusers(sub_y) != 2)
reject;
// Both operands need to be signed to be swapped
if (!a_signed || !b_signed)
reject;
// A and B can be interchanged
branch;
std::swap(a, b);
endcode
match neg
// Select neg of form -(a-b)
select neg->type == $neg
index <SigSpec> remove_bottom_padding(port(neg, \A)) === sub_y
endmatch
code
// Get neg signals
SigSpec neg_a = port(neg, \A);
SigSpec neg_y = port(neg, \Y);
bool a_signed = neg->getParam(ID::A_SIGNED).as_bool();
if (!a_signed)
reject;
// Rewire to only keep sub
sub->setPort(\A, b);
sub->setPort(\B, a);
sub->setPort(\Y, neg_y);
// Remove neg
autoremove(neg);
// Log, fixup, accept
log("sub_neg pattern in %s: neg=%s, sub=%s\n", log_id(module), log_id(neg), log_id(sub));
accept;
endcode