Further improved and extended xsthammer

This commit is contained in:
Clifford Wolf 2013-06-11 19:49:35 +02:00
parent 8ce99fa686
commit 4b311b7b99
7 changed files with 231 additions and 142 deletions

View File

@ -234,6 +234,7 @@ supply1 { return TOK_SUPPLY1; }
">=" { return OP_GE; }
"===" { return OP_EQ; }
"!==" { return OP_NE; }
/* "~&" { return OP_NAND; } */
/* "~|" { return OP_NOR; } */

View File

@ -1,4 +1,5 @@
generate
generate.lst
rtl
xst
xst_temp

28
tests/xsthammer/Makefile Normal file
View File

@ -0,0 +1,28 @@
include generate.lst
test: $(TARGETS)
check/%.log: rtl/%.v xst/%.v
bash run-check.sh $(notdir $(basename $<))
xst/%.v: rtl/%.v
bash run-xst.sh $(notdir $(basename $<))
generate.lst: generate.cc
clang -Wall -o generate generate.cc -lstdc++
./generate
{ echo -n "TARGETS := "; ls rtl/ | sed 's,\.v$$,.log,; s,^,check/,;' | tr '\n' ' '; } > generate.lst
check_xl_cells:
../../yosys xl_cells_tb.ys
clean:
rm -rf generate generate.lst check_temp xst_temp
mrproper: clean
rm -rf rtl xst check
.PHONY: test check_xl_cells clean mrproper
.PRECIOUS: check/%.log xst/%.v rtl/%.v generate.lst

View File

@ -9,15 +9,6 @@ to synthesize them with Yosys and Xilinx XST and perform formal equivialence
checks using the Yosys SAT-based equivialence checker. This will hopefully
reveal some bugs in both applications.. ;-)
Generating the Test Cases:
clang -Wall -o generate generate.cc -lstdc++
./generate
Running XST Synthesis:
bash run-xst.sh
rm -rf xst_temp
Running Yosys Synthesis and Check:
TBD
Simply run 'make' to generate all test cases and run all the tests.
(Use 'make -j N' to use N parallel cores.)

View File

@ -13,19 +13,47 @@ const char *arg_types[][2] = {
{ "{dir} signed [5:0] {name}", "{name}" } // 05
};
const char *ops[] = {
// See Table 5-1 (page 42) in IEEE Std 1364-2005
// for a list of all Verilog oprators.
const char *binary_ops[] = {
"+", // 00
"-", // 01
"*", // 02
"&&", // 03
"||", // 04
"&", // 05
// "/",
// "%",
// "**",
">", // 03
">=", // 04
"<", // 05
"<=", // 06
"&&", // 07
"||", // 08
"==", // 09
"!=", // 10
"===", // 11
"!==", // 12
"&", // 13
"|", // 14
"^", // 15
"^~", // 16
"<<", // 17
">>", // 18
"<<<", // 19
">>>", // 20
};
const char *unary_ops[] = {
"+", // 00
"-", // 01
"!", // 02
"~", // 03
"&", // 04
"~&", // 05
"|", // 06
"^", // 07
"<<", // 08
">>", // 09
"<<<", // 10
">>>", // 11
"~|", // 07
"^", // 08
"~^", // 09
};
void strsubst(std::string &str, const std::string &match, const std::string &replace)
@ -38,10 +66,13 @@ void strsubst(std::string &str, const std::string &match, const std::string &rep
int main()
{
mkdir("rtl", 0777);
// generate test cases for binary operators
for (int ai = 0; ai < sizeof(arg_types)/sizeof(arg_types[0]); ai++)
for (int bi = 0; bi < sizeof(arg_types)/sizeof(arg_types[0]); bi++)
for (int yi = 0; yi < sizeof(arg_types)/sizeof(arg_types[0]); yi++)
for (int oi = 0; oi < sizeof(ops)/sizeof(ops[0]); oi++)
for (int oi = 0; oi < sizeof(binary_ops)/sizeof(binary_ops[0]); oi++)
{
std::string a_decl = arg_types[ai][0];
strsubst(a_decl, "{dir}", "input");
@ -76,10 +107,46 @@ int main()
fprintf(f, "%s;\n", b_decl.c_str());
fprintf(f, "%s;\n", y_decl.c_str());
fprintf(f, "assign %s = %s %s %s;\n", y_ref.c_str(),
a_ref.c_str(), ops[oi], b_ref.c_str());
a_ref.c_str(), binary_ops[oi], b_ref.c_str());
fprintf(f, "endmodule\n");
fclose(f);
}
// generate test cases for unary operators
for (int ai = 0; ai < sizeof(arg_types)/sizeof(arg_types[0]); ai++)
for (int yi = 0; yi < sizeof(arg_types)/sizeof(arg_types[0]); yi++)
for (int oi = 0; oi < sizeof(unary_ops)/sizeof(unary_ops[0]); oi++)
{
std::string a_decl = arg_types[ai][0];
strsubst(a_decl, "{dir}", "input");
strsubst(a_decl, "{name}", "a");
std::string y_decl = arg_types[yi][0];
strsubst(y_decl, "{dir}", "output");
strsubst(y_decl, "{name}", "y");
std::string a_ref = arg_types[ai][1];
strsubst(a_ref, "{dir}", "input");
strsubst(a_ref, "{name}", "a");
std::string y_ref = arg_types[yi][1];
strsubst(y_ref, "{dir}", "output");
strsubst(y_ref, "{name}", "y");
char buffer[1024];
snprintf(buffer, 1024, "rtl/unary_ops_%02d%02d%02d.v", ai, yi, oi);
FILE *f = fopen(buffer, "w");
fprintf(f, "module unary_ops_%02d%02d%02d(a, b, y);\n", ai, yi, oi);
fprintf(f, "%s;\n", a_decl.c_str());
fprintf(f, "%s;\n", y_decl.c_str());
fprintf(f, "assign %s = %s %s;\n", y_ref.c_str(),
unary_ops[oi], a_ref.c_str());
fprintf(f, "endmodule\n");
fclose(f);
}
return 0;
}

View File

@ -1,65 +1,65 @@
#!/bin/bash
set -e
mkdir -p check
rm -rf check_temp
mkdir check_temp
cd check_temp
if [ $# -eq 0 ]; then
set -- $( ls ../rtl | sed 's,\.v$,,' )
echo "Usage: $0 <job_id>" >&2
exit 1
fi
for job
do
job="$1"
set --
set -e
mkdir -p check check_temp
cd check_temp
{
echo "module ${job}_top(a, b, y_rtl, y_xst);"
sed -r '/^(input|output) / !d; /output/ { s/ y;/ y_rtl;/; p; }; s/ y_rtl;/ y_xst;/;' ../rtl/$job.v
echo "${job}_rtl rtl_variant (.a(a), .b(b), .y(y_rtl));"
echo "${job}_xst xst_variant (.a(a), .b(b), .y(y_xst));"
echo "endmodule"
} > ${job}_top.v
for mode in nomap techmap; do
{
echo "module ${job}_top(a, b, y_rtl, y_xst);"
sed -r '/^(input|output) / !d; /output/ { s/ y;/ y_rtl;/; p; }; s/ y_rtl;/ y_xst;/;' ../rtl/$job.v
echo "${job}_rtl rtl_variant (.a(a), .b(b), .y(y_rtl));"
echo "${job}_xst xst_variant (.a(a), .b(b), .y(y_xst));"
echo "endmodule"
} > ${job}_top.v
echo "read_verilog -DGLBL ../xst/$job.v"
echo "rename $job ${job}_xst"
for mode in nomap techmap; do
{
echo "read_verilog -DGLBL ../xst/$job.v"
echo "rename $job ${job}_xst"
echo "read_verilog ../rtl/$job.v"
echo "rename $job ${job}_rtl"
if [ $mode = techmap ]; then
echo "techmap ${job}_rtl"
fi
echo "read_verilog ../rtl/$job.v"
echo "rename $job ${job}_rtl"
if [ $mode = techmap ]; then
echo "techmap ${job}_rtl"
fi
echo "read_verilog ${job}_top.v"
echo "read_verilog ../xl_cells.v"
echo "read_verilog ${job}_top.v"
echo "read_verilog ../xl_cells.v"
echo "hierarchy -top ${job}_top"
echo "flatten ${job}_top"
echo "hierarchy -top ${job}_top"
echo "opt_clean"
echo "hierarchy -top ${job}_top"
echo "flatten ${job}_top"
echo "hierarchy -top ${job}_top"
echo "opt_clean"
echo "rename ${job}_top ${job}_top_${mode}"
echo "write_ilang ${job}_top_${mode}.il"
} > ${job}_top_${mode}.ys
../../../yosys -q ${job}_top_${mode}.ys
done
{
echo "read_ilang ${job}_top_nomap.il"
echo "read_ilang ${job}_top_techmap.il"
echo "sat -verify -show a,b,y_rtl,y_xst -prove y_rtl y_xst ${job}_top_nomap"
echo "sat -verify -show a,b,y_rtl,y_xst -prove y_rtl y_xst ${job}_top_techmap"
} > ${job}_cmp.ys
if ../../../yosys -l ${job}.log ${job}_cmp.ys; then
mv ${job}.log ../check/${job}.log
rm -f ../check/${job}.err
else
mv ${job}.log ../check/${job}.err
rm -f ../check/${job}.log
# break
fi
echo "rename ${job}_top ${job}_top_${mode}"
echo "write_ilang ${job}_top_${mode}.il"
} > ${job}_top_${mode}.ys
../../../yosys -q ${job}_top_${mode}.ys
done
{
echo "read_ilang ${job}_top_nomap.il"
echo "read_ilang ${job}_top_techmap.il"
echo "sat -verify -show a,b,y_rtl,y_xst -prove y_rtl y_xst ${job}_top_nomap"
echo "sat -verify -show a,b,y_rtl,y_xst -prove y_rtl y_xst ${job}_top_techmap"
} > ${job}_cmp.ys
if ../../../yosys -l ${job}.log ${job}_cmp.ys; then
mv ${job}.log ../check/${job}.log
rm -f ../check/${job}.err
else
mv ${job}.log ../check/${job}.err
rm -f ../check/${job}.log
exit 1
fi
exit 0

View File

@ -1,75 +1,76 @@
#!/bin/bash
set -e
mkdir -p xst
. /opt/Xilinx/14.2/ISE_DS/settings64.sh
rm -rf xst_temp
mkdir xst_temp
cd xst_temp
if [ $# -eq 0 ]; then
set -- $( ls ../rtl | sed 's,\.v$,,' )
echo "Usage: $0 <job_id>" >&2
exit 1
fi
for job
do
cat > $job.xst <<- EOT
run
-ifn $job.prj
-ifmt mixed
-ofn $job
-ofmt NGC
-p xc6vlx75t-2-ff784
-top $job
-opt_mode Speed
-opt_level 1
-power NO
-iuc NO
-keep_hierarchy NO
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case maintain
-slice_utilization_ratio 100
-bram_utilization_ratio 100
-dsp_utilization_ratio 100
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style lut
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-shreg_extract YES
-rom_style Auto
-auto_bram_packing NO
-resource_sharing YES
-async_to_sync NO
-use_dsp48 auto
-iobuf NO
-max_fanout 100000
-bufg 32
-register_duplication YES
-register_balancing No
-optimize_primitives NO
-use_clock_enable Auto
-use_sync_set Auto
-use_sync_reset Auto
-iob auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5
EOT
job="$1"
set --
cat > $job.prj <<- EOT
verilog work "../rtl/$job.v"
EOT
set -e
mkdir -p xst xst_temp/$job
cd xst_temp/$job
xst -ifn $job.xst
netgen -w -ofmt verilog $job.ngc $job
cp $job.v ../xst/$job.v
done
cat > $job.xst <<- EOT
run
-ifn $job.prj
-ifmt mixed
-ofn $job
-ofmt NGC
-p xc6vlx75t-2-ff784
-top $job
-opt_mode Speed
-opt_level 1
-power NO
-iuc NO
-keep_hierarchy NO
-rtlview Yes
-glob_opt AllClockNets
-read_cores YES
-write_timing_constraints NO
-cross_clock_analysis NO
-hierarchy_separator /
-bus_delimiter <>
-case maintain
-slice_utilization_ratio 100
-bram_utilization_ratio 100
-dsp_utilization_ratio 100
-fsm_extract YES -fsm_encoding Auto
-safe_implementation No
-fsm_style lut
-ram_extract Yes
-ram_style Auto
-rom_extract Yes
-shreg_extract YES
-rom_style Auto
-auto_bram_packing NO
-resource_sharing YES
-async_to_sync NO
-use_dsp48 auto
-iobuf NO
-max_fanout 100000
-bufg 32
-register_duplication YES
-register_balancing No
-optimize_primitives NO
-use_clock_enable Auto
-use_sync_set Auto
-use_sync_reset Auto
-iob auto
-equivalent_register_removal YES
-slice_utilization_ratio_maxmargin 5
EOT
cat > $job.prj <<- EOT
verilog work "../../rtl/$job.v"
EOT
. /opt/Xilinx/14.2/ISE_DS/settings64.sh
xst -ifn $job.xst
netgen -w -ofmt verilog $job.ngc $job
cp $job.v ../../xst/$job.v
exit 0