mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-05 05:41:24 +00:00
neg sub pass
This commit is contained in:
parent
2679e1d458
commit
6de80bc6b3
4 changed files with 166 additions and 0 deletions
|
@ -34,6 +34,7 @@ PEEPOPT_PATTERN += passes/opt/peepopt_muldiv.pmg
|
||||||
PEEPOPT_PATTERN += passes/opt/peepopt_muldiv_c.pmg
|
PEEPOPT_PATTERN += passes/opt/peepopt_muldiv_c.pmg
|
||||||
PEEPOPT_PATTERN += passes/opt/peepopt_muxorder.pmg
|
PEEPOPT_PATTERN += passes/opt/peepopt_muxorder.pmg
|
||||||
PEEPOPT_PATTERN += passes/opt/peepopt_formal_clockgateff.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)
|
passes/opt/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
|
||||||
$(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
$(P) mkdir -p $(dir $@) && $(PYTHON_EXECUTABLE) $< -o $@ -p peepopt $(filter-out $<,$^)
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct PeepoptPass : public Pass {
|
||||||
pm.run_shiftmul_left();
|
pm.run_shiftmul_left();
|
||||||
pm.run_muldiv();
|
pm.run_muldiv();
|
||||||
pm.run_muldiv_c();
|
pm.run_muldiv_c();
|
||||||
|
pm.run_sub_neg();
|
||||||
if (muxorder)
|
if (muxorder)
|
||||||
pm.run_muxorder();
|
pm.run_muxorder();
|
||||||
}
|
}
|
||||||
|
|
62
passes/opt/peepopt_sub_neg.pmg
Normal file
62
passes/opt/peepopt_sub_neg.pmg
Normal 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
|
102
tests/peepopt/neg_sub.ys
Normal file
102
tests/peepopt/neg_sub.ys
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
log -header "Test simple positive case"
|
||||||
|
log -push
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOF
|
||||||
|
module equation_example (
|
||||||
|
input signed [7:0] a,
|
||||||
|
input signed [7:0] b,
|
||||||
|
output signed [8:0] result
|
||||||
|
);
|
||||||
|
assign result = - (a - b);
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
check -assert
|
||||||
|
equiv_opt -assert -post peepopt
|
||||||
|
select -assert-none t:$neg
|
||||||
|
select -assert-any t:$sub
|
||||||
|
design -reset
|
||||||
|
log -pop
|
||||||
|
|
||||||
|
log -header "Test positive case with intermediate signal"
|
||||||
|
log -push
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOF
|
||||||
|
module equation_example (
|
||||||
|
input signed [7:0] a,
|
||||||
|
input signed [7:0] b,
|
||||||
|
output signed [8:0] result
|
||||||
|
);
|
||||||
|
wire signed [8:0] difference;
|
||||||
|
assign difference = a - b;
|
||||||
|
assign result = - difference;
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
check -assert
|
||||||
|
equiv_opt -assert -post peepopt
|
||||||
|
select -assert-none t:$neg
|
||||||
|
select -assert-any t:$sub
|
||||||
|
design -reset
|
||||||
|
log -pop
|
||||||
|
|
||||||
|
log -header "Test negative case (fanout)"
|
||||||
|
log -push
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOF
|
||||||
|
module equation_example (
|
||||||
|
input signed [7:0] a,
|
||||||
|
input signed [7:0] b,
|
||||||
|
output signed [8:0] result,
|
||||||
|
output signed [8:0] not_diff
|
||||||
|
);
|
||||||
|
wire signed [8:0] difference;
|
||||||
|
assign difference = a - b;
|
||||||
|
assign result = -difference;
|
||||||
|
assign not_diff = ~difference;
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
check -assert
|
||||||
|
equiv_opt -assert -post peepopt
|
||||||
|
select -assert-any t:$neg
|
||||||
|
select -assert-any t:$sub
|
||||||
|
design -reset
|
||||||
|
log -pop
|
||||||
|
|
||||||
|
log -header "Test negative case (unsigned intermediate signal)"
|
||||||
|
log -push
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOF
|
||||||
|
module equation_example (
|
||||||
|
input signed [7:0] a,
|
||||||
|
input signed [7:0] b,
|
||||||
|
output signed [8:0] result
|
||||||
|
);
|
||||||
|
wire [8:0] difference;
|
||||||
|
assign difference = a - b;
|
||||||
|
assign result = -difference;
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
check -assert
|
||||||
|
equiv_opt -assert -post peepopt
|
||||||
|
select -assert-any t:$neg
|
||||||
|
select -assert-any t:$sub
|
||||||
|
design -reset
|
||||||
|
log -pop
|
||||||
|
|
||||||
|
log -header "Test negative case, inputs are not signed"
|
||||||
|
log -push
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOF
|
||||||
|
module equation_example (
|
||||||
|
input [7:0] a,
|
||||||
|
input [7:0] b,
|
||||||
|
output signed [8:0] result
|
||||||
|
);
|
||||||
|
assign result = - (a - b);
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
check -assert
|
||||||
|
equiv_opt -assert -post peepopt
|
||||||
|
select -assert-any t:$neg
|
||||||
|
select -assert-any t:$sub
|
||||||
|
design -reset
|
||||||
|
log -pop
|
Loading…
Add table
Add a link
Reference in a new issue