3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-17 12:45:44 +00:00
yosys/tests/silimate/negexpand.ys
tondapusili 643427d9c9 Add negopt pass with comprehensive pattern matching
This commit introduces the negopt pass with pre/post optimization modes
for handling negation patterns in arithmetic circuits.

Pre-optimization patterns (expose for tree balancing):
- manual2sub: (a + ~b) + 1 → a - b
- sub2neg: a - b → a + (-b)
- negexpand: -(a + b) → (-a) + (-b) [with output width fix]
- negneg: -(-a) → a
- negmux: -(s ? a : b) → s ? (-a) : (-b)

Post-optimization patterns (cleanup/rebuild):
- negrebuild: (-a) + (-b) → -(a + b)
- muxneg: s ? (-a) : (-b) → -(s ? a : b)
- neg2sub: a + (-b) → a - b

All patterns use nusers() for fanout checking (standard Yosys style).
Comprehensive test coverage with positive/negative cases and formal
verification via equiv_opt.
2026-02-03 17:21:21 -08:00

65 lines
1.4 KiB
Text

log -header "Simple positive case (same width)"
log -push
design -reset
read_verilog <<EOF
module top(a, b, y);
input wire signed [7:0] a;
input wire signed [7:0] b;
output wire signed [7:0] y;
assign y = -(a + b);
endmodule
EOF
proc; opt
check -assert
equiv_opt -assert negopt -pre
design -load postopt
select -assert-count 1 t:$add
select -assert-count 2 t:$neg
design -reset
log -pop
log -header "Width extension case (output wider than inputs)"
log -push
design -reset
read_verilog <<EOF
module top(a, b, y);
input wire signed [7:0] a;
input wire signed [7:0] b;
output wire signed [9:0] y;
assign y = -(a + b);
endmodule
EOF
proc; opt
check -assert
equiv_opt -assert negopt -pre
design -load postopt
# Negations should use output width (9 bits) not input width (8 bits)
select -assert-count 1 t:$add
select -assert-count 2 t:$neg
design -reset
log -pop
log -header "Negative case: fanout on add output"
log -push
design -reset
read_verilog <<EOF
module top(a, b, y, z);
input wire signed [7:0] a;
input wire signed [7:0] b;
output wire signed [7:0] y;
output wire signed [7:0] z;
(* keep *) wire signed [7:0] sum;
assign sum = a + b;
assign y = -sum;
assign z = sum;
endmodule
EOF
proc; opt
check -assert
equiv_opt -assert negopt -pre
design -load postopt
# Should NOT transform due to extra fanout on add output
select -assert-count 1 t:$add
select -assert-count 1 t:$neg
design -reset
log -pop