diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index fa5c2a825..cb67d6329 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -36,3 +36,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v)) $(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v)) +$(eval $(call add_share_file,share/choices,techlibs/common/choices/han-carlson.v)) diff --git a/techlibs/common/choices/han-carlson.v b/techlibs/common/choices/han-carlson.v new file mode 100644 index 000000000..2ddcf75e9 --- /dev/null +++ b/techlibs/common/choices/han-carlson.v @@ -0,0 +1,57 @@ +(* techmap_celltype = "$lcu" *) +module _80_lcu_han_carlson (P, G, CI, CO); + parameter WIDTH = 2; + + (* force_downto *) + input [WIDTH-1:0] P, G; + input CI; + + (* force_downto *) + output [WIDTH-1:0] CO; + + integer i, j; + (* force_downto *) + reg [WIDTH-1:0] p, g; + + always @* begin + i = 0; + p = P; + g = G; + + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); + if (i < $clog2(WIDTH)) begin + + // First layer: BK + for (j = WIDTH - 1; j >= 0; j = j - 1) begin + if (j % 2 == 1) begin + g[j] = g[j] | p[j] & g[j - 1]; + p[j] = p[j] & p[j - 1]; + end + end + + // Inner (log(WIDTH) - 1) layers: KS + for (i = 1; i < $clog2(WIDTH); i = i + 1) begin + for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin + if (j % 2 == 1) begin + g[j] = g[j] | p[j] & g[j - 2**i]; + p[j] = p[j] & p[j - 2**i]; + end + end + end + + // Last layer: BK + if (i < ($clog2(WIDTH) + 1)) begin + for (j = WIDTH - 1; j >= 0; j = j - 1) begin + if ((j % 2 == 0) && (j > 0)) begin + g[j] = g[j] | p[j] & g[j - 1]; + p[j] = p[j] & p[j - 1]; + end + end + end + + end + end + + assign CO = g; +endmodule diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh index 2b26d8c98..b997fa12d 100755 --- a/tests/gen-tests-makefile.sh +++ b/tests/gen-tests-makefile.sh @@ -20,6 +20,13 @@ generate_ys_test() { generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.log $yosys_args_ $ys_file" } +# $ generate_tcl_test tcl_file [yosys_args] +generate_tcl_test() { + tcl_file=$1 + yosys_args_=${2:-} + generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.log $yosys_args_ $tcl_file" +} + # $ generate_bash_test bash_file generate_bash_test() { bash_file=$1 @@ -29,6 +36,7 @@ generate_bash_test() { # $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] generate_tests() { do_ys=false + do_tcl=false do_sv=false do_sh=false yosys_args="" @@ -40,6 +48,10 @@ generate_tests() { do_ys=true shift ;; + -t|--tcl-scripts) + do_tcl=true + shift + ;; -s|--prove-sv) do_sv=true shift @@ -59,7 +71,7 @@ generate_tests() { esac done - if [[ ! ( $do_ys = true || $do_sv = true || $do_sh = true ) ]]; then + if [[ ! ( $do_ys = true || $do_tcl = true || $do_sv = true || $do_sh = true ) ]]; then echo >&2 "Error: No file types selected" exit 1 fi @@ -72,6 +84,11 @@ generate_tests() { generate_ys_test "$x" "$yosys_args" done fi; + if [[ $do_tcl = true ]]; then + for x in *.tcl; do + generate_tcl_test "$x" "$yosys_args" + done + fi; if [[ $do_sv = true ]]; then for x in *.sv; do if [ ! -f "${x%.sv}.ys" ]; then diff --git a/tests/techmap/han-carlson.tcl b/tests/techmap/han-carlson.tcl new file mode 100644 index 000000000..0d9068b5e --- /dev/null +++ b/tests/techmap/han-carlson.tcl @@ -0,0 +1,15 @@ +yosys -import + +read_verilog +/choices/han-carlson.v +read_verilog -icells lcu_refined.v +design -save init + +for {set i 1} {$i <= 16} {incr i} { + design -load init + chparam -set WIDTH $i + yosys proc + opt_clean + equiv_make lcu _80_lcu_han_carlson equiv + equiv_simple equiv + equiv_status -assert equiv +} diff --git a/tests/techmap/kogge-stone.tcl b/tests/techmap/kogge-stone.tcl new file mode 100644 index 000000000..1209b1338 --- /dev/null +++ b/tests/techmap/kogge-stone.tcl @@ -0,0 +1,15 @@ +yosys -import + +read_verilog +/choices/kogge-stone.v +read_verilog -icells lcu_refined.v +design -save init + +for {set i 1} {$i <= 16} {incr i} { + design -load init + chparam -set WIDTH $i + yosys proc + opt_clean + equiv_make lcu _80_lcu_kogge_stone equiv + equiv_simple equiv + equiv_status -assert equiv +} diff --git a/tests/techmap/kogge-stone.ys b/tests/techmap/kogge-stone.ys deleted file mode 100644 index fc3637f10..000000000 --- a/tests/techmap/kogge-stone.ys +++ /dev/null @@ -1 +0,0 @@ -test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu diff --git a/tests/techmap/lcu_refined.v b/tests/techmap/lcu_refined.v new file mode 100644 index 000000000..e0747f3f2 --- /dev/null +++ b/tests/techmap/lcu_refined.v @@ -0,0 +1,13 @@ +module lcu (P, G, CI, CO); + parameter WIDTH = 2; + + input [WIDTH-1:0] P, G; + input CI; + + output [WIDTH-1:0] CO; + + reg [WIDTH-1:0] p, g; + + \$lcu #(.WIDTH(WIDTH)) impl (.P(P), .G(G), .CI(CI), .CO(CO)); + +endmodule diff --git a/tests/techmap/run-test.sh b/tests/techmap/run-test.sh index 581847ab0..16741cace 100755 --- a/tests/techmap/run-test.sh +++ b/tests/techmap/run-test.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -eu source ../gen-tests-makefile.sh -run_tests --yosys-scripts --bash --yosys-args "-e 'select out of bounds'" +run_tests --yosys-scripts --tcl-scripts --bash --yosys-args "-e 'select out of bounds'"