Merge pull request #6114 from YosysHQ/nick/fix-6085

cmp2lut techmap fix + re-adding tests
This commit is contained in:
Nick Allison 2026-08-14 19:57:43 +00:00 committed by GitHub
commit f77ddfb875
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 106 additions and 38 deletions

View File

@ -32,6 +32,7 @@ parameter _TECHMAP_CONSTVAL_B_ = 0;
function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut;
input integer width;
input integer cst_width;
input integer operation;
input integer swap;
input integer sign;
@ -40,11 +41,13 @@ function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut;
begin
gen_lut = width'b0;
for (n = 0; n < (1 << width); n++) begin
if (sign)
if (sign) begin
i_var = n[width-1:0];
else
i_cst = operand[cst_width-1:0];
end else begin
i_var = n;
i_cst = operand;
i_cst = operand;
end
if (swap) begin
lhs = i_cst;
rhs = i_var;
@ -78,7 +81,7 @@ generate
else if (&_TECHMAP_CONSTMSK_B_)
\$lut #(
.WIDTH(A_WIDTH),
.LUT({ gen_lut(A_WIDTH, operation, 0, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_B_) })
.LUT({ gen_lut(A_WIDTH, B_WIDTH, operation, 0, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_B_) })
) _TECHMAP_REPLACE_ (
.A(A),
.Y(Y)
@ -86,7 +89,7 @@ generate
else if (&_TECHMAP_CONSTMSK_A_)
\$lut #(
.WIDTH(B_WIDTH),
.LUT({ gen_lut(B_WIDTH, operation, 1, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_A_) })
.LUT({ gen_lut(B_WIDTH, A_WIDTH, operation, 1, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_A_) })
) _TECHMAP_REPLACE_ (
.A(B),
.Y(Y)

View File

@ -66,6 +66,7 @@ MK_TEST_DIRS += ./arch
MK_TEST_DIRS += ./rpc
MK_TEST_DIRS += ./memfile
MK_TEST_DIRS += ./fmt
MK_TEST_DIRS += ./lut
MK_TEST_DIRS += ./cxxrtl
MK_TEST_DIRS += ./liberty
#ifeq ($(ENABLE_FUNCTIONAL_TESTS),1)

8
tests/lut/generate_mk.py Normal file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env python3
import sys
sys.path.append("..")
import gen_tests_makefile
gen_tests_makefile.generate(["--bash"])

26
tests/lut/lut.sh Executable file
View File

@ -0,0 +1,26 @@
set -e
DIR=$(cd "$(dirname "$0")" && pwd)
run_cmp_test()
{
cmp=$1
log=${DIR}/map_cmp_${cmp}_eq.log
echo "Running ${DIR}/map_cmp.v with CMP=4'd${cmp}.."
${YOSYS} -D "CMP_VALUE=4'd${cmp}" -q -s ${DIR}/check_map.ys -l ${log} -f verilog ${DIR}/map_cmp.v
}
cmp=0
while [ ${cmp} -lt 16 ]; do
run_cmp_test ${cmp}
cmp=$((cmp + 1))
done
for x in ${DIR}/*.v; do
echo "Running $x.."
${YOSYS} -q -s ${DIR}/check_map.ys -l ${x%.v}.log -f verilog $x
done
for x in ${DIR}/map_cmp.v; do
echo "Running $x.."
${YOSYS} -q -s ${DIR}/check_map_lut6.ys -l ${x%.v}_lut6.log -f verilog $x
done

View File

@ -1,30 +1,71 @@
`ifndef CMP_VALUE
`define CMP_VALUE {(LUT_WIDTH/2){2'b10}}
`endif
module top(...);
parameter LUT_WIDTH = 4; // Multiples of 2 only
input [LUT_WIDTH-1:0] a;
output o1_1 = {(LUT_WIDTH/2){2'b10}} <= a;
output o1_2 = {(LUT_WIDTH/2){2'b10}} < a;
output o1_3 = {(LUT_WIDTH/2){2'b10}} >= a;
output o1_4 = {(LUT_WIDTH/2){2'b10}} > a;
output o1_5 = {(LUT_WIDTH/2){2'b10}} == a;
output o1_6 = {(LUT_WIDTH/2){2'b10}} != a;
output o1_1 = $unsigned(`CMP_VALUE) <= $unsigned(a);
output o1_2 = $unsigned(`CMP_VALUE) < $unsigned(a);
output o1_3 = $unsigned(`CMP_VALUE) >= $unsigned(a);
output o1_4 = $unsigned(`CMP_VALUE) > $unsigned(a);
output o1_5 = $unsigned(`CMP_VALUE) == $unsigned(a);
output o1_6 = $unsigned(`CMP_VALUE) != $unsigned(a);
output o2_1 = a <= {(LUT_WIDTH/2){2'b10}};
output o2_2 = a < {(LUT_WIDTH/2){2'b10}};
output o2_3 = a >= {(LUT_WIDTH/2){2'b10}};
output o2_4 = a > {(LUT_WIDTH/2){2'b10}};
output o2_5 = a == {(LUT_WIDTH/2){2'b10}};
output o2_6 = a != {(LUT_WIDTH/2){2'b10}};
output o2_1 = $unsigned(a) <= $unsigned(`CMP_VALUE);
output o2_2 = $unsigned(a) < $unsigned(`CMP_VALUE);
output o2_3 = $unsigned(a) >= $unsigned(`CMP_VALUE);
output o2_4 = $unsigned(a) > $unsigned(`CMP_VALUE);
output o2_5 = $unsigned(a) == $unsigned(`CMP_VALUE);
output o2_6 = $unsigned(a) != $unsigned(`CMP_VALUE);
output o3_1 = {(LUT_WIDTH/2){2'sb01}} <= $signed(a);
output o3_2 = {(LUT_WIDTH/2){2'sb01}} < $signed(a);
output o3_3 = {(LUT_WIDTH/2){2'sb01}} >= $signed(a);
output o3_4 = {(LUT_WIDTH/2){2'sb01}} > $signed(a);
output o3_5 = {(LUT_WIDTH/2){2'sb01}} == $signed(a);
output o3_6 = {(LUT_WIDTH/2){2'sb01}} != $signed(a);
// ########################
output o4_1 = $signed(a) <= {LUT_WIDTH{1'sb0}};
output o4_2 = $signed(a) < {LUT_WIDTH{1'sb0}};
output o4_3 = $signed(a) >= {LUT_WIDTH{1'sb0}};
output o4_4 = $signed(a) > {LUT_WIDTH{1'sb0}};
output o3_1 = $signed(`CMP_VALUE) <= $unsigned(a);
output o3_2 = $signed(`CMP_VALUE) < $unsigned(a);
output o3_3 = $signed(`CMP_VALUE) >= $unsigned(a);
output o3_4 = $signed(`CMP_VALUE) > $unsigned(a);
output o3_5 = $signed(`CMP_VALUE) == $unsigned(a);
output o3_6 = $signed(`CMP_VALUE) != $unsigned(a);
output o4_1 = $unsigned(a) <= $signed(`CMP_VALUE);
output o4_2 = $unsigned(a) < $signed(`CMP_VALUE);
output o4_3 = $unsigned(a) >= $signed(`CMP_VALUE);
output o4_4 = $unsigned(a) > $signed(`CMP_VALUE);
output o4_5 = $unsigned(a) == $signed(`CMP_VALUE);
output o4_6 = $unsigned(a) != $signed(`CMP_VALUE);
// ########################
output o5_1 = $unsigned(`CMP_VALUE) <= $signed(a);
output o5_2 = $unsigned(`CMP_VALUE) < $signed(a);
output o5_3 = $unsigned(`CMP_VALUE) >= $signed(a);
output o5_4 = $unsigned(`CMP_VALUE) > $signed(a);
output o5_5 = $unsigned(`CMP_VALUE) == $signed(a);
output o5_6 = $unsigned(`CMP_VALUE) != $signed(a);
output o6_1 = $signed(a) <= $unsigned(`CMP_VALUE);
output o6_2 = $signed(a) < $unsigned(`CMP_VALUE);
output o6_3 = $signed(a) >= $unsigned(`CMP_VALUE);
output o6_4 = $signed(a) > $unsigned(`CMP_VALUE);
output o6_5 = $signed(a) == $unsigned(`CMP_VALUE);
output o6_6 = $signed(a) != $unsigned(`CMP_VALUE);
// ########################
output o7_1 = $signed(`CMP_VALUE) <= $signed(a);
output o7_2 = $signed(`CMP_VALUE) < $signed(a);
output o7_3 = $signed(`CMP_VALUE) >= $signed(a);
output o7_4 = $signed(`CMP_VALUE) > $signed(a);
output o7_5 = $signed(`CMP_VALUE) == $signed(a);
output o7_6 = $signed(`CMP_VALUE) != $signed(a);
output o8_1 = $signed(a) <= $signed(`CMP_VALUE);
output o8_2 = $signed(a) < $signed(`CMP_VALUE);
output o8_3 = $signed(a) >= $signed(`CMP_VALUE);
output o8_4 = $signed(a) > $signed(`CMP_VALUE);
output o8_5 = $signed(a) == $signed(`CMP_VALUE);
output o8_6 = $signed(a) != $signed(`CMP_VALUE);
endmodule

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
set -e
for x in *.v; do
echo "Running $x.."
../../yosys -q -s check_map.ys -l ${x%.v}.log $x
done
for x in map_cmp.v; do
echo "Running $x.."
../../yosys -q -s check_map_lut6.ys -l ${x%.v}_lut6.log $x
done