2019-08-04 05:08:26 +02:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR=`dirname "${BASH_SOURCE[0]}"`
|
2020-07-12 23:53:17 +02:00
|
|
|
SV2V="$SCRIPT_DIR/../../bin/sv2v +RTS -N1 -RTS"
|
2019-08-04 05:08:26 +02:00
|
|
|
|
|
|
|
|
assertExists() {
|
|
|
|
|
file=$1
|
|
|
|
|
[ -f "$file" ]
|
|
|
|
|
assertTrue "$file does not exist" $?
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# USAGE: simulate <vcd-file> <log-file> <top-module> <file> [<file> ...]
|
|
|
|
|
simulate() {
|
|
|
|
|
# arguments
|
2019-10-03 05:26:48 +02:00
|
|
|
sim_vcd=$1
|
|
|
|
|
sim_log=$2
|
|
|
|
|
sim_top=$3
|
|
|
|
|
shift 3
|
2019-08-04 05:08:26 +02:00
|
|
|
# compile the files
|
2021-08-02 00:38:41 +02:00
|
|
|
sim_vcd_tmp=$SHUNIT_TMPDIR/simvcdtmp
|
2019-10-03 05:26:48 +02:00
|
|
|
sim_prog=$SHUNIT_TMPDIR/simprog.exe
|
2019-08-04 05:08:26 +02:00
|
|
|
iv_output=`iverilog \
|
|
|
|
|
-Wall \
|
2021-05-21 20:02:29 +02:00
|
|
|
-Wno-portbind \
|
2019-10-03 05:26:48 +02:00
|
|
|
-o $sim_prog \
|
2019-08-04 05:08:26 +02:00
|
|
|
-g2005 \
|
2021-08-10 06:10:29 +02:00
|
|
|
-gstrict-expr-width \
|
2021-08-02 00:38:41 +02:00
|
|
|
-DTEST_VCD="\"$sim_vcd_tmp\"" \
|
2019-08-04 05:08:26 +02:00
|
|
|
-DTEST_TOP=$sim_top \
|
2021-08-10 06:10:29 +02:00
|
|
|
"$@" \
|
2019-10-03 05:26:48 +02:00
|
|
|
$SCRIPT_DIR/tb_dumper.v \
|
2021-08-10 06:10:29 +02:00
|
|
|
2>&1`
|
|
|
|
|
if [ $? -ne 0 ]; then
|
|
|
|
|
fail "iverilog on $1 failed:\n$iv_output"
|
|
|
|
|
return
|
|
|
|
|
elif [ "$EXPECT_IVERILOG_WARNINGS" != "0" ]; then
|
|
|
|
|
assertNull "iverilog on $1 emitted warnings:\n$iv_output" "$iv_output"
|
|
|
|
|
else
|
|
|
|
|
assertNotNull "iverilog on $1 did not emit any warnings" "$iv_output"
|
|
|
|
|
fi
|
2019-08-04 05:08:26 +02:00
|
|
|
# run the simulation
|
2021-08-02 00:38:41 +02:00
|
|
|
$sim_prog > $sim_log
|
2019-08-04 05:08:26 +02:00
|
|
|
assertTrue "simulating $1 failed" $?
|
|
|
|
|
# remove the date from the VCD
|
2021-08-02 00:38:41 +02:00
|
|
|
sed -e "1,3d" < $sim_vcd_tmp > $sim_vcd
|
2019-08-04 05:08:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertConverts() {
|
2019-10-03 05:26:48 +02:00
|
|
|
ac_file=$1
|
2021-06-25 20:53:03 +02:00
|
|
|
|
2019-10-03 05:26:48 +02:00
|
|
|
ac_tmpa=$SHUNIT_TMPDIR/ac-conv-tmpa.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "1st conversion of $ac_file" $ac_tmpa $ac_file
|
2021-06-25 20:53:03 +02:00
|
|
|
|
2019-10-03 05:26:48 +02:00
|
|
|
ac_tmpb=$SHUNIT_TMPDIR/ac-conv-tmpb.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "2nd conversion of $ac_file" $ac_tmpb $ac_tmpa
|
|
|
|
|
|
2021-01-24 21:17:54 +01:00
|
|
|
diff $ac_tmpa $ac_tmpb > /dev/null
|
|
|
|
|
assertTrue "conversion of $ac_file not stable after the first iteration" $?
|
2021-06-25 20:53:03 +02:00
|
|
|
|
|
|
|
|
ac_tmpc=$SHUNIT_TMPDIR/ac-conv-tmpc.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "pass through of $ac_file" $ac_tmpc --pass-through $ac_file
|
|
|
|
|
|
2021-06-25 20:53:03 +02:00
|
|
|
ac_tmpd=$SHUNIT_TMPDIR/ac-conv-tmpd.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "conversion of pass through of $ac_file" $ac_tmpd $ac_tmpc
|
|
|
|
|
|
2021-06-25 20:53:03 +02:00
|
|
|
diff $ac_tmpa $ac_tmpd > /dev/null
|
|
|
|
|
assertTrue "pass through then conversion differs for $ac_file" $?
|
|
|
|
|
|
2021-06-04 03:18:32 +02:00
|
|
|
# using sed to remove quoted strings
|
|
|
|
|
filtered=`sed -E 's/"([^"]|\")+"//g' $ac_tmpa`
|
2019-09-25 05:35:06 +02:00
|
|
|
# check for various things iverilog accepts which we don't want to output
|
2021-05-23 03:55:37 +02:00
|
|
|
prefix="conversion of $ac_file still contains"
|
|
|
|
|
assertNotMatch "$filtered" "$prefix dimension queries" \
|
|
|
|
|
'\$bits|\$dimensions|\$unpacked_dimensions|\$left|\$right|\$low|\$high|\$increment|\$size'
|
|
|
|
|
assertNotMatch "$filtered" "$prefix SystemVerilog types" \
|
|
|
|
|
'[[:space:]](int|bit|logic|byte|struct|enum|longint|shortint)[[:space:]]'
|
|
|
|
|
assertNotMatch "$filtered" "$prefix unsigned keyword" \
|
|
|
|
|
'[^\$a-zA-Z_]unsigned'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assertNotMatch() {
|
|
|
|
|
if [[ "$1" =~ $3 ]]; then
|
|
|
|
|
fail "$2"
|
|
|
|
|
fi
|
2019-08-04 05:08:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# convert SystemVerilog source file(s)
|
|
|
|
|
convert() {
|
2021-08-02 17:18:45 +02:00
|
|
|
description=$1
|
|
|
|
|
out_file=$2
|
|
|
|
|
shift 2
|
|
|
|
|
$SV2V "$@" 2> $SHUNIT_TMPDIR/stderr > $out_file
|
|
|
|
|
assertTrue "$description failed" $?
|
|
|
|
|
if [ -s $SHUNIT_TMPDIR/stderr ]; then
|
|
|
|
|
fail "$description emitted warnings:"
|
|
|
|
|
cat $SHUNIT_TMPDIR/stderr
|
|
|
|
|
fi
|
2019-08-04 05:08:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simpleTest() {
|
2019-10-03 05:26:48 +02:00
|
|
|
sv=$1
|
|
|
|
|
ve=$2
|
|
|
|
|
tb=$3
|
2019-08-04 05:08:26 +02:00
|
|
|
|
2019-10-03 05:26:48 +02:00
|
|
|
assertConverts $sv
|
2020-12-08 19:39:17 +01:00
|
|
|
|
|
|
|
|
# some tests use inputs compatible with iverilog directly and so omit the
|
|
|
|
|
# reference manually converted file
|
|
|
|
|
if [ ! -f $ve ]; then
|
|
|
|
|
ve=$sv
|
|
|
|
|
else
|
|
|
|
|
assertConverts $ve
|
|
|
|
|
fi
|
2019-08-04 05:08:26 +02:00
|
|
|
|
|
|
|
|
# some tests don't have a separate testbench, instead having the top-level
|
|
|
|
|
# module defined in both of the input files
|
2019-10-03 05:26:48 +02:00
|
|
|
if [ ! -f $tb ]; then
|
|
|
|
|
tb=$SCRIPT_DIR/empty.v
|
|
|
|
|
else
|
|
|
|
|
assertConverts $tb
|
2019-08-04 05:08:26 +02:00
|
|
|
fi
|
|
|
|
|
|
2021-05-23 21:54:49 +02:00
|
|
|
cs=$SHUNIT_TMPDIR/cs.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "standard conversion" $cs $sv
|
2019-08-04 05:08:26 +02:00
|
|
|
|
2021-05-23 21:54:49 +02:00
|
|
|
cv=$SHUNIT_TMPDIR/cv.v
|
2021-08-02 17:18:45 +02:00
|
|
|
convert "verbose conversion" $cv $sv -v
|
2021-05-23 21:54:49 +02:00
|
|
|
|
|
|
|
|
simulateAndCompare $ve $cs $cv $tb
|
2019-08-04 05:08:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
simulateAndCompare() {
|
2021-05-23 21:54:49 +02:00
|
|
|
ve=$1 # reference verilog
|
|
|
|
|
cs=$2 # converted succinct
|
|
|
|
|
cv=$3 # converted verbose
|
|
|
|
|
tb=$4 # testbench
|
2019-08-04 05:08:26 +02:00
|
|
|
|
2019-10-03 05:26:48 +02:00
|
|
|
ref_vcd=$SHUNIT_TMPDIR/ref.vcd
|
2021-05-23 21:54:49 +02:00
|
|
|
cvs_vcd=$SHUNIT_TMPDIR/cvs.vcd
|
|
|
|
|
cvv_vcd=$SHUNIT_TMPDIR/cvv.vcd
|
2019-10-03 05:26:48 +02:00
|
|
|
ref_log=$SHUNIT_TMPDIR/ref.log
|
2021-05-23 21:54:49 +02:00
|
|
|
cvs_log=$SHUNIT_TMPDIR/cvs.log
|
|
|
|
|
cvv_log=$SHUNIT_TMPDIR/cvv.log
|
2019-08-04 05:08:26 +02:00
|
|
|
|
2021-05-23 21:54:49 +02:00
|
|
|
# simulate the three files
|
2019-10-03 05:26:48 +02:00
|
|
|
simulate $ref_vcd $ref_log top $ve $tb
|
2021-05-23 21:54:49 +02:00
|
|
|
simulate $cvs_vcd $cvs_log top $cs $tb
|
|
|
|
|
simulate $cvv_vcd $cvv_log top $cv $tb
|
|
|
|
|
|
|
|
|
|
# compare reference verilog to converted succinct
|
|
|
|
|
output=`diff $ref_vcd $cvs_vcd`
|
|
|
|
|
assertTrue "VE/CS VCDs are different:\n$output" $?
|
|
|
|
|
output=`diff $ref_log $cvs_log`
|
|
|
|
|
assertTrue "VE/CS simulation outputs differ:\n$output" $?
|
|
|
|
|
|
|
|
|
|
# compare converted verbose to converted succinct
|
|
|
|
|
output=`diff $cvv_vcd $cvs_vcd`
|
|
|
|
|
assertTrue "CV/CS VCDs are different:\n$output" $?
|
|
|
|
|
output=`diff $cvv_log $cvs_log`
|
|
|
|
|
assertTrue "CV/CS simulation outputs differ:\n$output" $?
|
|
|
|
|
|
|
|
|
|
rm -f $ref_vcd $cvs_vcd $cvv_vcd $ref_log $cvs_log $cvv_log
|
2019-08-04 05:08:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
runTest() {
|
2019-10-03 05:26:48 +02:00
|
|
|
test=$1
|
2019-08-04 05:08:26 +02:00
|
|
|
simpleTest "${test}.sv" "${test}.v" "${test}_tb.v"
|
|
|
|
|
}
|
2021-01-29 00:34:55 +01:00
|
|
|
|
|
|
|
|
runAndCapture() {
|
|
|
|
|
$SV2V "$@" > "$SHUNIT_TMPDIR/stdout" 2> "$SHUNIT_TMPDIR/stderr"
|
|
|
|
|
result=$?
|
|
|
|
|
stdout=`cat $SHUNIT_TMPDIR/stdout`
|
|
|
|
|
stderr=`cat $SHUNIT_TMPDIR/stderr`
|
|
|
|
|
}
|