mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #111 from Silimate/timing_balance_impl
silimate: add opt_timing_balance pass and tests
This commit is contained in:
commit
7a35a982d3
|
|
@ -35,14 +35,14 @@ runs:
|
|||
if: runner.os == 'Linux'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: gawk git make python3 bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libnsl-dev libdwarf-dev libelf-dev elfutils libdw-dev ccache
|
||||
packages: gawk git make python3 bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libnsl-dev libdwarf-dev libelf-dev elfutils libdw-dev ccache
|
||||
version: ${{ inputs.runs-on }}-commonys
|
||||
|
||||
- name: Linux build dependencies
|
||||
if: runner.os == 'Linux' && inputs.get-build-deps == 'true'
|
||||
uses: awalsh128/cache-apt-pkgs-action@v1.6.0
|
||||
with:
|
||||
packages: bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libgtest-dev
|
||||
packages: gawk git make python3 bison clang flex libffi-dev libfl-dev libreadline-dev pkg-config tcl-dev zlib1g-dev libnsl-dev libdwarf-dev libelf-dev elfutils libdw-dev ccache libgtest-dev
|
||||
version: ${{ inputs.runs-on }}-buildys
|
||||
|
||||
- name: Linux docs dependencies
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ jobs:
|
|||
uses: ./.github/actions/setup-build-env
|
||||
with:
|
||||
runs-on: ${{ matrix.os }}
|
||||
get-test-deps: true
|
||||
get-build-deps: true
|
||||
get-iverilog: true
|
||||
|
||||
- name: Download build artifact
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ OBJS += passes/silimate/reg_rename.o
|
|||
OBJS += passes/silimate/splitfanout.o
|
||||
OBJS += passes/silimate/splitlarge.o
|
||||
OBJS += passes/silimate/splitnetlist.o
|
||||
OBJS += passes/silimate/opt_timing_balance.o
|
||||
|
||||
OBJS += passes/silimate/opt_expand.o
|
||||
GENFILES += passes/silimate/peepopt_expand.h
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,511 @@
|
|||
#
|
||||
# opt_timing_balance regression coverage
|
||||
#
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: XOR chain with late leaf should be rewritten
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: xor late leaf rewrite"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late ^ a ^ b ^ c ^ d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -logic
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$xor
|
||||
select o:y %ci2 t:$xor %i -set root_xor
|
||||
select @root_xor i:late -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Default mode should rewrite both logic and arithmetic cones
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: default mode mixed categories"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [7:0] u2,
|
||||
input wire [7:0] u3,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y_add,
|
||||
output wire [15:0] y_xor
|
||||
);
|
||||
wire [15:0] late_add = u0 * u1;
|
||||
wire [15:0] late_xor = u2 * u3;
|
||||
assign y_add = late_add + a + b + c + d;
|
||||
assign y_xor = late_xor ^ a ^ b ^ c ^ d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance
|
||||
design -load postopt
|
||||
select -assert-min 1 t:$add a:timing_balance_generated=1 %i
|
||||
select -assert-min 1 t:$xor a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Running the pass twice should be idempotent on generated cones
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: idempotent second invocation"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late + a + b + c + d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
opt_timing_balance -arith
|
||||
select -assert-count 4 t:$add a:timing_balance_generated=1 %i
|
||||
opt_timing_balance -arith
|
||||
select -assert-count 4 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Without negopt -pre, subtraction chains should not be rewritten
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: direct subtraction conservative skip"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
input wire [7:0] c,
|
||||
input wire [7:0] d,
|
||||
output wire [7:0] y
|
||||
);
|
||||
assign y = a - b - c - d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-count 3 t:$sub
|
||||
select -assert-count 0 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Signed-width logic extension semantics are preserved under rewrite
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: signed logic extension equivalence"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire signed [1:0] a,
|
||||
input wire [3:0] b,
|
||||
input wire [3:0] c,
|
||||
output wire [3:0] y
|
||||
);
|
||||
wire [3:0] late = u0 * u1;
|
||||
assign y = late & a & b & c;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -logic
|
||||
design -load postopt
|
||||
select -assert-min 1 t:$and a:timing_balance_generated=1 %i
|
||||
select o:y %ci2 t:$and %i -set signed_logic_root
|
||||
select @signed_logic_root i:late -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: AND chain with late leaf should be rewritten
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: and late leaf rewrite"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late & a & b & c & d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -logic
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$and
|
||||
select o:y %ci2 t:$and %i -set root_and
|
||||
select @root_and i:late -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: OR chain with late leaf should be rewritten
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: or late leaf rewrite"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late | a | b | c | d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -logic
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$or
|
||||
select o:y %ci2 t:$or %i -set root_or
|
||||
select @root_or i:late -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: ADD chain with late leaf should be rewritten
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: add late leaf rewrite"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late + a + b + c + d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$add
|
||||
select o:y %ci2 t:$add %i -set root_add
|
||||
select @root_add i:late -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Balanced add tree should remain unchanged (no rewrite)
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: balanced add no-op"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
input wire [15:0] e,
|
||||
input wire [15:0] f,
|
||||
input wire [15:0] g,
|
||||
input wire [15:0] h,
|
||||
output wire [15:0] y
|
||||
);
|
||||
assign y = ((a+b)+(c+d))+((e+f)+(g+h));
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-count 7 t:$add
|
||||
select -assert-count 0 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: -logic mode must not rewrite arithmetic cones
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: mode filter logic-only"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late + a + b + c + d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -logic
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$add
|
||||
select -assert-count 0 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: -arith mode must not rewrite logic cones
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: mode filter arith-only"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late ^ a ^ b ^ c ^ d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-count 4 t:$xor
|
||||
select -assert-count 0 t:$xor a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Shared-fanout cone must preserve both tap and final output semantics
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: shared fanout tap safety"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] tap,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] x0 = a + b;
|
||||
wire [15:0] x1 = x0 + c;
|
||||
assign tap = x1;
|
||||
assign y = x1 + d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select o:tap %ci2 t:$add %i -assert-count 1
|
||||
select o:y %ci2 t:$add %i -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Subtraction chain after negopt -pre should be balanced as add/neg
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: negopt-pre normalized subtraction chain"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] a,
|
||||
input wire [7:0] b,
|
||||
input wire [7:0] c,
|
||||
input wire [7:0] d,
|
||||
output wire [7:0] y
|
||||
);
|
||||
assign y = a - b - c - d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
negopt -pre
|
||||
select -assert-count 0 t:$sub
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-min 1 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Mixed-sign add chains should be skipped conservatively
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: mixed-sign conservative skip"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire signed [7:0] a,
|
||||
input wire [7:0] b,
|
||||
input wire [7:0] c,
|
||||
output wire [8:0] y
|
||||
);
|
||||
assign y = a + b + c;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-count 2 t:$add
|
||||
select -assert-count 0 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Two independent arithmetic heads should both rewrite
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: multi-head arithmetic rewrite"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [7:0] u2,
|
||||
input wire [7:0] u3,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
input wire [15:0] e,
|
||||
input wire [15:0] f,
|
||||
input wire [15:0] g,
|
||||
input wire [15:0] h,
|
||||
output wire [15:0] y0,
|
||||
output wire [15:0] y1
|
||||
);
|
||||
wire [15:0] late0 = u0 * u1;
|
||||
wire [15:0] late1 = u2 * u3;
|
||||
assign y0 = late0 + a + b + c + d;
|
||||
assign y1 = late1 + e + f + g + h;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-min 2 t:$add
|
||||
select o:y0 %ci2 t:$add %i -set root0
|
||||
select o:y1 %ci2 t:$add %i -set root1
|
||||
select @root0 i:late0 -assert-count 1
|
||||
select @root1 i:late1 -assert-count 1
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case: Generated-cell tagging exists for rewritten cones (contract test)
|
||||
# ---------------------------------------------------------------------------
|
||||
log -header "opt_timing_balance: generated tag contract"
|
||||
log -push
|
||||
design -reset
|
||||
read_verilog <<EOF
|
||||
module top (
|
||||
input wire [7:0] u0,
|
||||
input wire [7:0] u1,
|
||||
input wire [15:0] a,
|
||||
input wire [15:0] b,
|
||||
input wire [15:0] c,
|
||||
input wire [15:0] d,
|
||||
output wire [15:0] y
|
||||
);
|
||||
wire [15:0] late = u0 * u1;
|
||||
assign y = late + a + b + c + d;
|
||||
endmodule
|
||||
EOF
|
||||
check -assert
|
||||
|
||||
equiv_opt -assert opt_timing_balance -arith
|
||||
design -load postopt
|
||||
select -assert-min 1 t:$add a:timing_balance_generated=1 %i
|
||||
|
||||
design -reset
|
||||
log -pop
|
||||
Loading…
Reference in New Issue