functions.sh 3.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!/bin/bash

SCRIPT_DIR=`dirname "${BASH_SOURCE[0]}"`
SV2V="$SCRIPT_DIR/../../bin/sv2v"

assertExists() {
    file=$1
    [ -f "$file" ]
    assertTrue "$file does not exist" $?
}

# USAGE: simulate <vcd-file> <log-file> <top-module> <file> [<file> ...]
simulate() {
    # arguments
15 16 17 18
    sim_vcd=$1
    sim_log=$2
    sim_top=$3
    shift 3
19
    # compile the files
20
    sim_prog=$SHUNIT_TMPDIR/simprog.exe
21 22 23
    iv_output=`iverilog \
        -Wall \
        -Wno-select-range \
24
        -Wno-anachronisms \
25
        -o $sim_prog \
26 27 28
        -g2005 \
        -DTEST_VCD="\"$sim_vcd\"" \
        -DTEST_TOP=$sim_top \
29
        $SCRIPT_DIR/tb_dumper.v \
30 31
        "$@" 2>&1`
    assertTrue "iverilog on $1 failed" $?
32 33
    if [ -n "$iv_output" ]; then
        assertNull "iverilog emitted warnings:" "$iv_output"
34 35 36
        echo "$iv_output"
    fi
    # run the simulation
37
    $sim_prog > $sim_log.temp
38
    assertTrue "simulating $1 failed" $?
39
    assertExists $sim_vcd
40
    # remove the date from the VCD
41
    sed -i.orig -e "1,3d" $sim_vcd
42
    # remove extraneous log lines
43
    cat $sim_log.temp | grep -v "VCD info: dumpfile" > $sim_log
44 45 46
}

assertConverts() {
47 48 49
    ac_file=$1
    ac_tmpa=$SHUNIT_TMPDIR/ac-conv-tmpa.v
    $SV2V $ac_file 2> /dev/null > $ac_tmpa
50
    assertTrue "1st conversion of $ac_file failed" $?
51 52
    ac_tmpb=$SHUNIT_TMPDIR/ac-conv-tmpb.v
    $SV2V $ac_tmpa 2> /dev/null > $ac_tmpb
53
    assertTrue "2nd conversion of $ac_file failed" $?
54 55 56 57 58 59 60
    if [ -n "$(diff $ac_tmpa $ac_tmpb)" ]; then
        ac_tmpc=$SHUNIT_TMPDIR/ac-conv-tmpc.v
        $SV2V $ac_tmpb 2> /dev/null > $ac_tmpc
        assertTrue "3rd conversion of $ac_file failed" $?
        diff $ac_tmpb $ac_tmpc > /dev/null
        assertTrue "conversion of $ac_file not stable after the second iteration" $?
    fi
61
    # using sed to remove quoted strings
62
    filtered=`sed -E 's/"([^"]|\")+"//g' $ac_tmpa`
63 64 65 66
    # check for various things iverilog accepts which we don't want to output
    PATTERNS="\$bits\|\$dimensions\|\$unpacked_dimensions\|\$left\|\$right\|\$low\|\$high\|\$increment\|\$size"
    echo "$filtered" | grep "$PATTERNS" > /dev/null
    assertFalse "conversion of $ac_file still contains dimension queries" $?
67 68
    echo "$filtered" | egrep "\s(int\|bit\|logic\|byte\|struct\|enum\|longint\|shortint)\s"
    assertFalse "conversion of $ac_file still contains SV types" $?
69 70
    echo "$filtered" | grep "[^$]unsigned" > /dev/null
    assertFalse "conversion of $ac_file still contains unsigned keyword" $?
71 72 73 74
}

# convert SystemVerilog source file(s)
convert() {
75 76
    out_file=$1; shift
    $SV2V "$@" 2> /dev/null > $out_file
77 78 79 80
    assertTrue "conversion failed" $?
}

simpleTest() {
81 82 83
    sv=$1
    ve=$2
    tb=$3
84

85 86
    assertConverts $sv
    assertConverts $ve
87 88 89

    # some tests don't have a separate testbench, instead having the top-level
    # module defined in both of the input files
90 91 92 93
    if [ ! -f $tb ]; then
        tb=$SCRIPT_DIR/empty.v
    else
        assertConverts $tb
94 95
    fi

96 97
    cv=$SHUNIT_TMPDIR/conv.v
    convert $cv $sv
98

99
    simulateAndCompare $ve $cv $tb
100 101 102
}

simulateAndCompare() {
103 104 105
    ve=$1
    cv=$2
    tb=$3
106

107 108 109 110
    ref_vcd=$SHUNIT_TMPDIR/ref.vcd
    gen_vcd=$SHUNIT_TMPDIR/gen.vcd
    ref_log=$SHUNIT_TMPDIR/ref.log
    gen_log=$SHUNIT_TMPDIR/gen.log
111 112

    # simulate and compare the two files
113 114 115
    simulate $ref_vcd $ref_log top $ve $tb
    simulate $gen_vcd $gen_log top $cv $tb
    output=`diff $ref_vcd $gen_vcd`
116
    assertTrue "VCDs are different:\n$output" $?
117
    output=`diff $ref_log $gen_log`
118 119 120 121
    assertTrue "Simulation outputs differ:\n$output" $?
}

runTest() {
122
    test=$1
123 124
    simpleTest "${test}.sv" "${test}.v" "${test}_tb.v"
}