mirror of https://github.com/YosysHQ/yosys.git
Further improved and extended xsthammer
This commit is contained in:
parent
8ce99fa686
commit
4b311b7b99
|
@ -234,6 +234,7 @@ supply1 { return TOK_SUPPLY1; }
|
||||||
">=" { return OP_GE; }
|
">=" { return OP_GE; }
|
||||||
|
|
||||||
"===" { return OP_EQ; }
|
"===" { return OP_EQ; }
|
||||||
|
"!==" { return OP_NE; }
|
||||||
|
|
||||||
/* "~&" { return OP_NAND; } */
|
/* "~&" { return OP_NAND; } */
|
||||||
/* "~|" { return OP_NOR; } */
|
/* "~|" { return OP_NOR; } */
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
generate
|
generate
|
||||||
|
generate.lst
|
||||||
rtl
|
rtl
|
||||||
xst
|
xst
|
||||||
xst_temp
|
xst_temp
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
checks using the Yosys SAT-based equivialence checker. This will hopefully
|
||||||
reveal some bugs in both applications.. ;-)
|
reveal some bugs in both applications.. ;-)
|
||||||
|
|
||||||
|
Simply run 'make' to generate all test cases and run all the tests.
|
||||||
Generating the Test Cases:
|
(Use 'make -j N' to use N parallel cores.)
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
@ -13,19 +13,47 @@ const char *arg_types[][2] = {
|
||||||
{ "{dir} signed [5:0] {name}", "{name}" } // 05
|
{ "{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
|
"+", // 00
|
||||||
"-", // 01
|
"-", // 01
|
||||||
"*", // 02
|
"*", // 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
|
"|", // 06
|
||||||
"^", // 07
|
"~|", // 07
|
||||||
"<<", // 08
|
"^", // 08
|
||||||
">>", // 09
|
"~^", // 09
|
||||||
"<<<", // 10
|
|
||||||
">>>", // 11
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void strsubst(std::string &str, const std::string &match, const std::string &replace)
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
mkdir("rtl", 0777);
|
mkdir("rtl", 0777);
|
||||||
|
|
||||||
|
// generate test cases for binary operators
|
||||||
|
|
||||||
for (int ai = 0; ai < sizeof(arg_types)/sizeof(arg_types[0]); ai++)
|
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 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 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];
|
std::string a_decl = arg_types[ai][0];
|
||||||
strsubst(a_decl, "{dir}", "input");
|
strsubst(a_decl, "{dir}", "input");
|
||||||
|
@ -76,10 +107,46 @@ int main()
|
||||||
fprintf(f, "%s;\n", b_decl.c_str());
|
fprintf(f, "%s;\n", b_decl.c_str());
|
||||||
fprintf(f, "%s;\n", y_decl.c_str());
|
fprintf(f, "%s;\n", y_decl.c_str());
|
||||||
fprintf(f, "assign %s = %s %s %s;\n", y_ref.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");
|
fprintf(f, "endmodule\n");
|
||||||
fclose(f);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,65 +1,65 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
|
||||||
mkdir -p check
|
|
||||||
|
|
||||||
rm -rf check_temp
|
|
||||||
mkdir check_temp
|
|
||||||
cd check_temp
|
|
||||||
|
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
set -- $( ls ../rtl | sed 's,\.v$,,' )
|
echo "Usage: $0 <job_id>" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for job
|
job="$1"
|
||||||
do
|
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);"
|
echo "read_verilog -DGLBL ../xst/$job.v"
|
||||||
sed -r '/^(input|output) / !d; /output/ { s/ y;/ y_rtl;/; p; }; s/ y_rtl;/ y_xst;/;' ../rtl/$job.v
|
echo "rename $job ${job}_xst"
|
||||||
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 "read_verilog ../rtl/$job.v"
|
||||||
{
|
echo "rename $job ${job}_rtl"
|
||||||
echo "read_verilog -DGLBL ../xst/$job.v"
|
if [ $mode = techmap ]; then
|
||||||
echo "rename $job ${job}_xst"
|
echo "techmap ${job}_rtl"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "read_verilog ../rtl/$job.v"
|
echo "read_verilog ${job}_top.v"
|
||||||
echo "rename $job ${job}_rtl"
|
echo "read_verilog ../xl_cells.v"
|
||||||
if [ $mode = techmap ]; then
|
|
||||||
echo "techmap ${job}_rtl"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "read_verilog ${job}_top.v"
|
echo "hierarchy -top ${job}_top"
|
||||||
echo "read_verilog ../xl_cells.v"
|
echo "flatten ${job}_top"
|
||||||
|
echo "hierarchy -top ${job}_top"
|
||||||
|
echo "opt_clean"
|
||||||
|
|
||||||
echo "hierarchy -top ${job}_top"
|
echo "rename ${job}_top ${job}_top_${mode}"
|
||||||
echo "flatten ${job}_top"
|
echo "write_ilang ${job}_top_${mode}.il"
|
||||||
echo "hierarchy -top ${job}_top"
|
} > ${job}_top_${mode}.ys
|
||||||
echo "opt_clean"
|
../../../yosys -q ${job}_top_${mode}.ys
|
||||||
|
|
||||||
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
|
|
||||||
done
|
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
|
||||||
|
|
||||||
|
|
|
@ -1,75 +1,76 @@
|
||||||
#!/bin/bash
|
#!/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
|
if [ $# -eq 0 ]; then
|
||||||
set -- $( ls ../rtl | sed 's,\.v$,,' )
|
echo "Usage: $0 <job_id>" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for job
|
job="$1"
|
||||||
do
|
set --
|
||||||
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
|
set -e
|
||||||
verilog work "../rtl/$job.v"
|
mkdir -p xst xst_temp/$job
|
||||||
EOT
|
cd xst_temp/$job
|
||||||
|
|
||||||
xst -ifn $job.xst
|
cat > $job.xst <<- EOT
|
||||||
netgen -w -ofmt verilog $job.ngc $job
|
run
|
||||||
cp $job.v ../xst/$job.v
|
-ifn $job.prj
|
||||||
done
|
-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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue