aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml39
-rwxr-xr-x.travis/setup.sh2
-rw-r--r--Dockerfile74
-rw-r--r--passes/opt/opt_expr.cc50
-rw-r--r--tests/various/opt_expr.ys205
5 files changed, 244 insertions, 126 deletions
diff --git a/.travis.yml b/.travis.yml
index 4102f05fe..09f380831 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -40,35 +40,6 @@ matrix:
env:
- MATRIX_EVAL="CONFIG=gcc && CC=gcc-4.8 && CXX=g++-4.8"
- # Latest gcc-6 on Travis Linux
- - os: linux
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - g++-6
- - gperf
- - build-essential
- - bison
- - flex
- - libreadline-dev
- - gawk
- - tcl-dev
- - libffi-dev
- - git
- - graphviz
- - xdot
- - pkg-config
- - python
- - python3
- - libboost-system-dev
- - libboost-python-dev
- - libboost-filesystem-dev
- - zlib1g-dev
- env:
- - MATRIX_EVAL="CONFIG=gcc && CC=gcc-6 && CXX=g++-6"
-
# Latest gcc supported on Travis Linux
- os: linux
addons:
@@ -76,7 +47,7 @@ matrix:
sources:
- ubuntu-toolchain-r-test
packages:
- - g++-7
+ - g++-9
- gperf
- build-essential
- bison
@@ -96,7 +67,7 @@ matrix:
- libboost-filesystem-dev
- zlib1g-dev
env:
- - MATRIX_EVAL="CONFIG=gcc && CC=gcc-7 && CXX=g++-7"
+ - MATRIX_EVAL="CONFIG=gcc && CC=gcc-9 && CXX=g++-9"
# Clang which ships on Trusty Linux
- os: linux
@@ -133,9 +104,9 @@ matrix:
addons:
apt:
sources:
- - llvm-toolchain-trusty-5.0
+ - llvm-toolchain-xenial-8
packages:
- - clang-5.0
+ - clang-8
- gperf
- build-essential
- bison
@@ -155,7 +126,7 @@ matrix:
- libboost-filesystem-dev
- zlib1g-dev
env:
- - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0"
+ - MATRIX_EVAL="CONFIG=clang && CC=clang-8 && CXX=clang++-8"
# # Latest clang on Mac OS X
# - os: osx
diff --git a/.travis/setup.sh b/.travis/setup.sh
index 4af0b8ee9..02879b974 100755
--- a/.travis/setup.sh
+++ b/.travis/setup.sh
@@ -51,7 +51,7 @@ fi
git clone git://github.com/steveicarus/iverilog.git
cd iverilog
autoconf
- ./configure --prefix=$HOME/.local-bin
+ CC=gcc CXX=g++ ./configure --prefix=$HOME/.local-bin
make
make install
echo
diff --git a/Dockerfile b/Dockerfile
index 3c7188d82..549c73c97 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,33 +1,57 @@
-FROM ubuntu:18.04 as builder
-LABEL author="Abdelrahman Hosny <abdelrahman.hosny@hotmail.com>"
-ENV DEBIAN_FRONTEND=noninteractive
-RUN apt-get update && apt-get install -y build-essential \
+ARG IMAGE="python:3-slim-buster"
+
+#---
+
+FROM $IMAGE AS base
+
+RUN apt-get update -qq \
+ && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
+ ca-certificates \
clang \
+ curl \
+ libffi-dev \
+ libreadline-dev \
+ tcl-dev \
+ graphviz \
+ xdot \
+ && apt-get autoclean && apt-get clean && apt-get -y autoremove \
+ && update-ca-certificates \
+ && rm -rf /var/lib/apt/lists
+
+#---
+
+FROM base AS build
+
+RUN apt-get update -qq \
+ && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \
bison \
flex \
- libreadline-dev \
gawk \
- tcl-dev \
- libffi-dev \
+ gcc \
git \
+ iverilog \
pkg-config \
- python3 && \
- rm -rf /var/lib/apt/lists
-COPY . /
-RUN make && \
- make install
-
-FROM ubuntu:18.04
-ENV DEBIAN_FRONTEND=noninteractive
-RUN apt-get update && apt-get install -y libreadline-dev tcl-dev
-
-COPY --from=builder /yosys /build/yosys
-COPY --from=builder /yosys-abc /build/yosys-abc
-COPY --from=builder /yosys-config /build/yosys-config
-COPY --from=builder /yosys-filterlib /build/yosys-filterlib
-COPY --from=builder /yosys-smtbmc /build/yosys-smtbmc
-
-ENV PATH /build:$PATH
+ && apt-get autoclean && apt-get clean && apt-get -y autoremove \
+ && rm -rf /var/lib/apt/lists
+
+COPY . /yosys
+
+ENV PREFIX /opt/yosys
+
+RUN cd /yosys \
+ && make \
+ && make install \
+ && make test
+
+#---
+
+FROM base
+
+COPY --from=build /opt/yosys /opt/yosys
+
+ENV PATH /opt/yosys/bin:$PATH
+
RUN useradd -m yosys
USER yosys
-ENTRYPOINT ["yosys"]
+
+CMD ["yosys"]
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 8f6e660a2..fcdc1d173 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -641,7 +641,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
}
}
- if (cell->type.in(ID($add), ID($sub))) {
+ if (cell->type.in(ID($add), ID($sub)))
+ {
RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID(A)));
RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID(B)));
RTLIL::SigSpec sig_y = cell->getPort(ID(Y));
@@ -665,6 +666,53 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
did_something = true;
}
}
+
+ if (cell->type == "$alu")
+ {
+ RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
+ RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B"));
+ RTLIL::SigBit sig_ci = assign_map(cell->getPort("\\CI"));
+ RTLIL::SigBit sig_bi = assign_map(cell->getPort("\\BI"));
+ RTLIL::SigSpec sig_x = cell->getPort("\\X");
+ RTLIL::SigSpec sig_y = cell->getPort("\\Y");
+ RTLIL::SigSpec sig_co = cell->getPort("\\CO");
+
+ if (sig_ci.wire || sig_bi.wire)
+ goto next_cell;
+
+ bool sub = (sig_ci == State::S1 && sig_bi == State::S1);
+
+ // If not a subtraction, yet there is a carry or B is inverted
+ // then no optimisation is possible as carry will not be constant
+ if (!sub && (sig_ci != State::S0 || sig_bi != State::S0))
+ goto next_cell;
+
+ int i;
+ for (i = 0; i < GetSize(sig_y); i++) {
+ if (sig_b.at(i, State::Sx) == State::S0 && sig_a.at(i, State::Sx) != State::Sx) {
+ module->connect(sig_x[i], sub ? module->Not(NEW_ID, sig_a[i]).as_bit() : sig_a[i]);
+ module->connect(sig_y[i], sig_a[i]);
+ module->connect(sig_co[i], sub ? State::S1 : State::S0);
+ }
+ else if (!sub && sig_a.at(i, State::Sx) == State::S0 && sig_b.at(i, State::Sx) != State::Sx) {
+ module->connect(sig_x[i], sig_b[i]);
+ module->connect(sig_y[i], sig_b[i]);
+ module->connect(sig_co[i], State::S0);
+ }
+ else
+ break;
+ }
+ if (i > 0) {
+ cover("opt.opt_expr.fine.$alu");
+ cell->setPort("\\A", sig_a.extract_end(i));
+ cell->setPort("\\B", sig_b.extract_end(i));
+ cell->setPort("\\X", sig_x.extract_end(i));
+ cell->setPort("\\Y", sig_y.extract_end(i));
+ cell->setPort("\\CO", sig_co.extract_end(i));
+ cell->fixup_parameters();
+ did_something = true;
+ }
+ }
}
if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($shift), ID($shiftx), ID($shl), ID($shr), ID($sshl), ID($sshr),
diff --git a/tests/various/opt_expr.ys b/tests/various/opt_expr.ys
index 0c61ac881..f0306efa1 100644
--- a/tests/various/opt_expr.ys
+++ b/tests/various/opt_expr.ys
@@ -5,144 +5,219 @@ module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o);
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
+equiv_opt -assert opt_expr -fine
+design -load postopt
-opt_expr -fine
-wreduce
+select -assert-count 1 t:$add r:A_WIDTH=5 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+##########
-design -stash gate
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_add_test(input [3:0] i, input [7:0] j, output [8:0] o);
+ assign o = (i << 4) + j;
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
##########
+design -reset
read_verilog <<EOT
module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
assign o = (i << 4) + j;
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
+equiv_opt -assert opt_expr -fine
+design -load postopt
-opt_expr -fine
-wreduce
+select -assert-count 1 t:$add r:A_WIDTH=5 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-select -assert-count 1 t:$add r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+##########
-design -stash gate
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_add_signed_test(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
+ assign o = (i << 4) + j;
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
##########
+design -reset
read_verilog <<EOT
module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o);
assign o = j - (i << 4);
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
+equiv_opt -assert opt_expr -fine
+design -load postopt
-opt_expr -fine
-wreduce
+select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
-select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+##########
-design -stash gate
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_sub_test1(input [3:0] i, input [7:0] j, output [8:0] o);
+ assign o = j - (i << 4);
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+dump
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
##########
+design -reset
read_verilog <<EOT
module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
assign o = j - (i << 4);
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
+equiv_opt -assert opt_expr -fine
+design -load postopt
-opt_expr -fine
-wreduce
+select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
-select -assert-count 1 t:$sub r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+##########
-design -stash gate
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_sub_signed_test1(input signed [3:0] i, input signed [7:0] j, output signed [8:0] o);
+ assign o = j - (i << 4);
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=5 r:Y_WIDTH=5 %i %i %i
##########
+design -reset
read_verilog <<EOT
module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o);
assign o = (i << 4) - j;
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
+equiv_opt -assert opt_expr -fine
+design -load postopt
-opt_expr -fine
-wreduce
+select -assert-count 1 t:$sub r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
-select -assert-count 1 t:$sub r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
+##########
-design -stash gate
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_sub_test2(input [3:0] i, input [7:0] j, output [8:0] o);
+ assign o = (i << 4) - j;
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+alumacc
+opt_expr -fine
+equiv_opt -assert opt_expr -fine
+design -load postopt
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+select -assert-count 1 t:$alu r:A_WIDTH=9 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i
##########
+design -reset
read_verilog <<EOT
module opt_expr_sub_test4(input [3:0] i, output [8:0] o);
assign o = 5'b00010 - i;
endmodule
EOT
-hierarchy -auto-top
-proc
-design -save gold
-
-opt_expr -fine
wreduce
+equiv_opt -assert opt_expr -fine
+design -load postopt
select -assert-count 1 t:$sub r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
-design -stash gate
+##########
+
+# alumacc version of above
+design -reset
+read_verilog <<EOT
+module opt_expr_sub_test4(input [3:0] i, output [8:0] o);
+ assign o = 5'b00010 - i;
+endmodule
+EOT
-design -import gold -as gold
-design -import gate -as gate
+wreduce
+alumacc
+equiv_opt -assert opt_expr -fine
+design -load postopt
+
+select -assert-count 1 t:$alu r:A_WIDTH=2 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+###########
+
+design -reset
+read_verilog -icells <<EOT
+module opt_expr_alu_test_ci0_bi0(input [7:0] a, input [3:0] b, output [8:0] x, y, co);
+ \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b0), .BI(1'b0), .X(x), .Y(y), .CO(co));
+endmodule
+EOT
+check
+
+equiv_opt -assert opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+###########
+
+design -reset
+read_verilog -icells <<EOT
+module opt_expr_alu_test_ci1_bi1(input [7:0] a, input [3:0] b, output [8:0] x, y, co);
+ \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b1), .BI(1'b1), .X(x), .Y(y), .CO(co));
+endmodule
+EOT
+check
+
+equiv_opt opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$alu r:A_WIDTH=4 r:B_WIDTH=4 r:Y_WIDTH=5 %i %i %i
+
+###########
+
+design -reset
+read_verilog -icells <<EOT
+module opt_expr_alu_test_ci0_bi1(input [7:0] a, input [3:0] b, output [8:0] x, y, co);
+ \$alu #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(8), .Y_WIDTH(9)) alu (.A(a), .B({b, 4'b0000}), .CI(1'b0), .BI(1'b1), .X(x), .Y(y), .CO(co));
+endmodule
+EOT
+check
-miter -equiv -flatten -make_assert -make_outputs gold gate miter
-sat -verify -prove-asserts -show-ports miter
+equiv_opt opt_expr -fine
+design -load postopt
+select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i