2019-05-23 17:03:08 -05:00
|
|
|
#!/usr/bin/env bash
|
2018-11-30 22:14:43 -06:00
|
|
|
|
|
|
|
libs=""
|
|
|
|
genvcd=false
|
|
|
|
use_xsim=false
|
|
|
|
use_modelsim=false
|
|
|
|
verbose=false
|
|
|
|
keeprunning=false
|
|
|
|
makejmode=false
|
2019-05-23 18:55:49 -05:00
|
|
|
frontend="verilog -noblackbox"
|
|
|
|
backend_opts="-noattr -noexpr -siminit"
|
2018-11-30 22:14:43 -06:00
|
|
|
autotb_opts=""
|
|
|
|
include_opts=""
|
|
|
|
xinclude_opts=""
|
|
|
|
minclude_opts=""
|
|
|
|
scriptfiles=""
|
|
|
|
scriptopt=""
|
|
|
|
toolsdir="$(cd $(dirname $0); pwd)"
|
|
|
|
warn_iverilog_git=false
|
2019-05-23 18:55:49 -05:00
|
|
|
# The following are used in verilog to firrtl regression tests.
|
|
|
|
# Typically these will be passed as environment variables:
|
|
|
|
#EXTRA_FLAGS="--firrtl2verilog 'java -cp /.../firrtl/utils/bin/firrtl.jar firrtl.Driver'"
|
|
|
|
# The tests are skipped if firrtl2verilog is the empty string (the default).
|
|
|
|
firrtl2verilog=""
|
|
|
|
xfirrtl="../xfirrtl"
|
2019-11-27 15:40:39 -06:00
|
|
|
abcprog="$toolsdir/../../yosys-abc"
|
2018-11-30 22:14:43 -06:00
|
|
|
|
|
|
|
if [ ! -f $toolsdir/cmp_tbdata -o $toolsdir/cmp_tbdata.c -nt $toolsdir/cmp_tbdata ]; then
|
|
|
|
( set -ex; ${CC:-gcc} -Wall -o $toolsdir/cmp_tbdata $toolsdir/cmp_tbdata.c; ) || exit 1
|
|
|
|
fi
|
|
|
|
|
2019-11-27 15:40:39 -06:00
|
|
|
while getopts xmGl:wkjvref:s:p:n:S:I:A:-: opt; do
|
2018-11-30 22:14:43 -06:00
|
|
|
case "$opt" in
|
|
|
|
x)
|
|
|
|
use_xsim=true ;;
|
|
|
|
m)
|
|
|
|
use_modelsim=true ;;
|
|
|
|
G)
|
|
|
|
warn_iverilog_git=true ;;
|
|
|
|
l)
|
|
|
|
libs="$libs $(cd $(dirname $OPTARG); pwd)/$(basename $OPTARG)";;
|
|
|
|
w)
|
|
|
|
genvcd=true ;;
|
|
|
|
k)
|
|
|
|
keeprunning=true ;;
|
|
|
|
j)
|
|
|
|
makejmode=true ;;
|
|
|
|
v)
|
|
|
|
verbose=true ;;
|
|
|
|
r)
|
|
|
|
backend_opts="$backend_opts -norename" ;;
|
|
|
|
e)
|
2019-05-23 18:55:49 -05:00
|
|
|
backend_opts="$( echo " $backend_opts " | sed 's, -noexpr , ,; s,^ ,,; s, $,,;'; )" ;;
|
2018-11-30 22:14:43 -06:00
|
|
|
f)
|
|
|
|
frontend="$OPTARG" ;;
|
|
|
|
s)
|
|
|
|
[[ "$OPTARG" == /* ]] || OPTARG="$PWD/$OPTARG"
|
|
|
|
scriptfiles="$scriptfiles $OPTARG" ;;
|
|
|
|
p)
|
|
|
|
scriptopt="$OPTARG" ;;
|
|
|
|
n)
|
|
|
|
autotb_opts="$autotb_opts -n $OPTARG" ;;
|
|
|
|
S)
|
|
|
|
autotb_opts="$autotb_opts -seed $OPTARG" ;;
|
|
|
|
I)
|
|
|
|
include_opts="$include_opts -I $OPTARG"
|
|
|
|
xinclude_opts="$xinclude_opts -i $OPTARG"
|
|
|
|
minclude_opts="$minclude_opts +incdir+$OPTARG" ;;
|
2019-11-27 15:40:39 -06:00
|
|
|
A)
|
|
|
|
abcprog="$OPTARG" ;;
|
2019-05-23 18:55:49 -05:00
|
|
|
-)
|
|
|
|
case "${OPTARG}" in
|
|
|
|
xfirrtl)
|
|
|
|
xfirrtl="${!OPTIND}"
|
|
|
|
OPTIND=$(( $OPTIND + 1 ))
|
|
|
|
;;
|
|
|
|
firrtl2verilog)
|
|
|
|
firrtl2verilog="${!OPTIND}"
|
|
|
|
OPTIND=$(( $OPTIND + 1 ))
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
if [ "$OPTERR" == 1 ] && [ "${optspec:0:1}" != ":" ]; then
|
|
|
|
echo "Unknown option --${OPTARG}" >&2
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac;;
|
2018-11-30 22:14:43 -06:00
|
|
|
*)
|
2019-05-23 18:55:49 -05:00
|
|
|
echo "Usage: $0 [-x|-m] [-G] [-w] [-k] [-j] [-v] [-r] [-e] [-l libs] [-f frontend] [-s script] [-p cmdstring] [-n iters] [-S seed] [-I incdir] [--xfirrtl FIRRTL test exclude file] [--firrtl2verilog command to generate verilog from firrtl] verilog-files\n" >&2
|
2018-11-30 22:14:43 -06:00
|
|
|
exit 1
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
compile_and_run() {
|
|
|
|
exe="$1"; output="$2"; shift 2
|
2019-11-27 15:40:39 -06:00
|
|
|
if [ "${2##*.}" == "sv" ]; then
|
|
|
|
language_gen="-g2012"
|
|
|
|
else
|
|
|
|
language_gen="-g2005"
|
|
|
|
fi
|
|
|
|
|
2018-11-30 22:14:43 -06:00
|
|
|
if $use_modelsim; then
|
|
|
|
altver=$( ls -v /opt/altera/ | grep '^[0-9]' | tail -n1; )
|
|
|
|
/opt/altera/$altver/modelsim_ase/bin/vlib work
|
|
|
|
/opt/altera/$altver/modelsim_ase/bin/vlog $minclude_opts +define+outfile=\"$output\" "$@"
|
|
|
|
/opt/altera/$altver/modelsim_ase/bin/vsim -c -do 'run -all; exit;' testbench
|
|
|
|
elif $use_xsim; then
|
|
|
|
xilver=$( ls -v /opt/Xilinx/Vivado/ | grep '^[0-9]' | tail -n1; )
|
|
|
|
/opt/Xilinx/Vivado/$xilver/bin/xvlog $xinclude_opts -d outfile=\"$output\" "$@"
|
|
|
|
/opt/Xilinx/Vivado/$xilver/bin/xelab -R work.testbench
|
|
|
|
else
|
2019-11-27 15:40:39 -06:00
|
|
|
iverilog $language_gen $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@"
|
2018-11-30 22:14:43 -06:00
|
|
|
vvp -n "$exe"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
|
|
|
|
for fn
|
|
|
|
do
|
2019-05-23 18:55:49 -05:00
|
|
|
bn=${fn%.*}
|
|
|
|
ext=${fn##*.}
|
2019-11-27 15:40:39 -06:00
|
|
|
if [[ "$ext" != "v" ]] && [[ "$ext" != "sv" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then
|
2018-11-30 22:14:43 -06:00
|
|
|
echo "Invalid argument: $fn" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
[[ "$bn" == *_tb ]] && continue
|
|
|
|
|
|
|
|
if $makejmode; then
|
|
|
|
status_prefix="Test: $bn "
|
|
|
|
else
|
|
|
|
status_prefix=""
|
|
|
|
echo -n "Test: $bn "
|
|
|
|
fi
|
|
|
|
|
2019-11-27 15:40:39 -06:00
|
|
|
if [ "$ext" == sv ]; then
|
|
|
|
frontend="$frontend -sv"
|
|
|
|
fi
|
|
|
|
|
2019-05-23 17:03:08 -05:00
|
|
|
rm -f ${bn}.{err,log,skip}
|
2018-11-30 22:14:43 -06:00
|
|
|
mkdir -p ${bn}.out
|
|
|
|
rm -rf ${bn}.out/*
|
|
|
|
|
|
|
|
body() {
|
|
|
|
cd ${bn}.out
|
|
|
|
fn=$(basename $fn)
|
|
|
|
bn=$(basename $bn)
|
2019-11-27 15:40:39 -06:00
|
|
|
refext=v
|
2018-11-30 22:14:43 -06:00
|
|
|
|
2019-05-23 18:55:49 -05:00
|
|
|
rm -f ${bn}_ref.fir
|
|
|
|
if [[ "$ext" == "v" ]]; then
|
|
|
|
egrep -v '^\s*`timescale' ../$fn > ${bn}_ref.${ext}
|
2019-11-27 15:40:39 -06:00
|
|
|
elif [[ "$ext" == "aig" ]] || [[ "$ext" == "aag" ]]; then
|
|
|
|
$abcprog -c "read_aiger ../${fn}; write ${bn}_ref.${refext}"
|
2019-05-23 18:55:49 -05:00
|
|
|
else
|
2019-11-27 15:40:39 -06:00
|
|
|
refext=$ext
|
|
|
|
cp ../${fn} ${bn}_ref.${refext}
|
2019-05-23 18:55:49 -05:00
|
|
|
fi
|
2018-11-30 22:14:43 -06:00
|
|
|
|
|
|
|
if [ ! -f ../${bn}_tb.v ]; then
|
2019-11-27 15:40:39 -06:00
|
|
|
"$toolsdir"/../../yosys -f "$frontend $include_opts -D_AUTOTB" -b "test_autotb $autotb_opts" -o ${bn}_tb.v ${bn}_ref.${refext}
|
2018-11-30 22:14:43 -06:00
|
|
|
else
|
|
|
|
cp ../${bn}_tb.v ${bn}_tb.v
|
|
|
|
fi
|
|
|
|
if $genvcd; then sed -i 's,// \$dump,$dump,g' ${bn}_tb.v; fi
|
2019-11-27 15:40:39 -06:00
|
|
|
compile_and_run ${bn}_tb_ref ${bn}_out_ref ${bn}_tb.v ${bn}_ref.${refext} $libs \
|
2019-05-23 18:55:49 -05:00
|
|
|
"$toolsdir"/../../techlibs/common/simlib.v \
|
|
|
|
"$toolsdir"/../../techlibs/common/simcells.v
|
2018-11-30 22:14:43 -06:00
|
|
|
if $genvcd; then mv testbench.vcd ${bn}_ref.vcd; fi
|
|
|
|
|
|
|
|
test_count=0
|
|
|
|
test_passes() {
|
|
|
|
"$toolsdir"/../../yosys -b "verilog $backend_opts" -o ${bn}_syn${test_count}.v "$@"
|
|
|
|
compile_and_run ${bn}_tb_syn${test_count} ${bn}_out_syn${test_count} \
|
|
|
|
${bn}_tb.v ${bn}_syn${test_count}.v $libs \
|
|
|
|
"$toolsdir"/../../techlibs/common/simlib.v \
|
|
|
|
"$toolsdir"/../../techlibs/common/simcells.v
|
|
|
|
if $genvcd; then mv testbench.vcd ${bn}_syn${test_count}.vcd; fi
|
|
|
|
$toolsdir/cmp_tbdata ${bn}_out_ref ${bn}_out_syn${test_count}
|
|
|
|
test_count=$(( test_count + 1 ))
|
|
|
|
}
|
|
|
|
|
2019-11-27 15:40:39 -06:00
|
|
|
if [ "$frontend" = "verific" -o "$frontend" = "verific_gates" ] && grep -q VERIFIC-SKIP ${bn}_ref.${refext}; then
|
2018-11-30 22:14:43 -06:00
|
|
|
touch ../${bn}.skip
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$scriptfiles" ]; then
|
2019-11-27 15:40:39 -06:00
|
|
|
test_passes -f "$frontend $include_opts" ${bn}_ref.${refext} $scriptfiles
|
2018-11-30 22:14:43 -06:00
|
|
|
elif [ -n "$scriptopt" ]; then
|
2019-11-27 15:40:39 -06:00
|
|
|
test_passes -f "$frontend $include_opts" -p "$scriptopt" ${bn}_ref.${refext}
|
2018-11-30 22:14:43 -06:00
|
|
|
elif [ "$frontend" = "verific" ]; then
|
2019-11-27 15:40:39 -06:00
|
|
|
test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -all; opt; memory;;"
|
2018-11-30 22:14:43 -06:00
|
|
|
elif [ "$frontend" = "verific_gates" ]; then
|
2019-11-27 15:40:39 -06:00
|
|
|
test_passes -p "verific -vlog2k ${bn}_ref.${refext}; verific -import -gates -all; opt; memory;;"
|
2018-11-30 22:14:43 -06:00
|
|
|
else
|
2019-11-27 15:40:39 -06:00
|
|
|
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.${refext}
|
|
|
|
test_passes -f "$frontend $include_opts" -p "hierarchy; synth -run coarse; techmap; opt; abc -dff" ${bn}_ref.${refext}
|
2019-05-23 18:55:49 -05:00
|
|
|
if [ -n "$firrtl2verilog" ]; then
|
|
|
|
if test -z "$xfirrtl" || ! grep "$fn" "$xfirrtl" ; then
|
2019-11-27 15:40:39 -06:00
|
|
|
"$toolsdir"/../../yosys -b "firrtl" -o ${bn}_ref.fir -f "$frontend $include_opts" -p "prep -nordff; proc; opt; memory; opt; fsm; opt -full -fine; pmuxtree" ${bn}_ref.${refext}
|
2019-05-23 18:55:49 -05:00
|
|
|
$firrtl2verilog -i ${bn}_ref.fir -o ${bn}_ref.fir.v
|
|
|
|
test_passes -f "$frontend $include_opts" -p "hierarchy; proc; opt; memory; opt; fsm; opt -full -fine" ${bn}_ref.fir.v
|
|
|
|
fi
|
|
|
|
fi
|
2018-11-30 22:14:43 -06:00
|
|
|
fi
|
|
|
|
touch ../${bn}.log
|
|
|
|
}
|
|
|
|
|
|
|
|
if $verbose; then
|
|
|
|
echo ".."
|
|
|
|
echo "Output written to console." > ${bn}.err
|
|
|
|
( set -ex; body; )
|
|
|
|
else
|
|
|
|
( set -ex; body; ) > ${bn}.err 2>&1
|
|
|
|
fi
|
|
|
|
|
2019-05-23 18:55:49 -05:00
|
|
|
did_firrtl=""
|
|
|
|
if [ -f ${bn}.out/${bn}_ref.fir ]; then
|
|
|
|
did_firrtl="+FIRRTL "
|
|
|
|
fi
|
2018-11-30 22:14:43 -06:00
|
|
|
if [ -f ${bn}.log ]; then
|
|
|
|
mv ${bn}.err ${bn}.log
|
2019-05-23 18:55:49 -05:00
|
|
|
echo "${status_prefix}${did_firrtl}-> ok"
|
2018-11-30 22:14:43 -06:00
|
|
|
elif [ -f ${bn}.skip ]; then
|
|
|
|
mv ${bn}.err ${bn}.skip
|
|
|
|
echo "${status_prefix}-> skip"
|
|
|
|
else
|
2019-05-23 18:55:49 -05:00
|
|
|
echo "${status_prefix}${did_firrtl}-> ERROR!"
|
2018-11-30 22:14:43 -06:00
|
|
|
if $warn_iverilog_git; then
|
|
|
|
echo "Note: Make sure that 'iverilog' is an up-to-date git checkout of Icarus Verilog."
|
|
|
|
fi
|
|
|
|
$keeprunning || exit 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
exit 0
|