|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Adjust paths regardless of where the script is called from |
| 4 | +SCRIPT_NAME=$(basename $0) |
| 5 | +SCRIPT_DIR=$(dirname $(realpath $0)) |
| 6 | +ROOT_DIR=$(realpath ${SCRIPT_DIR}/..) |
| 7 | +VSIM_DIR="${ROOT_DIR}/vsim" |
| 8 | + |
| 9 | +# Set variables |
| 10 | +VSIM=${VSIM:-vsim} |
| 11 | + |
| 12 | +# Set up logging |
| 13 | +if [ -t 1 ]; then |
| 14 | + RED=$'\033[31m' |
| 15 | + YELLOW=$'\033[33m' |
| 16 | + BOLD=$'\033[1m' |
| 17 | + RESET=$'\033[0m' |
| 18 | +else |
| 19 | + RED="" |
| 20 | + YELLOW="" |
| 21 | + BOLD="" |
| 22 | + RESET="" |
| 23 | +fi |
| 24 | + |
| 25 | +usage () { |
| 26 | + cat <<EOF |
| 27 | +Usage: ${BOLD}${SCRIPT_NAME} <command> [args...]${RESET} |
| 28 | +
|
| 29 | +Commands: |
| 30 | + ${BOLD}compile ${RESET} : Compile Croc RTL and testbench with QuestaSim |
| 31 | + ${BOLD}compile-net ${RESET} : Compile Croc netlist and testbench with QuestaSim |
| 32 | + ${BOLD}run <binary>${RESET} : Run <binary> simulation with QuestaSim |
| 33 | + ${BOLD}cleanup ${RESET} : Remove generated files and QuestaSim work library |
| 34 | + ${BOLD}help ${RESET} : Show this help message |
| 35 | +EOF |
| 36 | +} |
| 37 | + |
| 38 | +error () { |
| 39 | + printf '%b\n' "${RED}${BOLD}ERROR:${RESET} $*" >&2 |
| 40 | +} |
| 41 | + |
| 42 | +fatal_error () { |
| 43 | + error $* |
| 44 | + usage |
| 45 | + exit 1 |
| 46 | +} |
| 47 | + |
| 48 | +warning () { |
| 49 | + printf '%b\n' "${YELLOW}${BOLD}WARNING:${RESET} $*" >&2 |
| 50 | +} |
| 51 | + |
| 52 | +# Gather all errors and warnings in a single report file |
| 53 | +vsim_compile_report () { |
| 54 | + LOG_FILE="$1" |
| 55 | + REPORT_FILE="$2" |
| 56 | + if [ ! -f ${LOG_FILE} ]; then |
| 57 | + warning "no compile log found; skipping report" |
| 58 | + return |
| 59 | + fi |
| 60 | + echo "--- QuestaSim compilation report ---" > ${REPORT_FILE} |
| 61 | + echo "Errors:" >> ${REPORT_FILE} |
| 62 | + grep "Error:" ${LOG_FILE} >> ${REPORT_FILE} |
| 63 | + echo "" >> ${REPORT_FILE} |
| 64 | + echo "Warnings:" >> ${REPORT_FILE} |
| 65 | + grep "Warning:" ${LOG_FILE} >> ${REPORT_FILE} |
| 66 | +} |
| 67 | + |
| 68 | +# Show short summary from QuestaSim compilation log |
| 69 | +vsim_compile_report_print_summary () { |
| 70 | + REPORT_FILE="$1" |
| 71 | + NUM_ERRORS=$(cat ${REPORT_FILE} | grep Error: | wc -l) |
| 72 | + NUM_WARNINGS=$(cat ${REPORT_FILE} | grep Warning: | wc -l) |
| 73 | + echo "#######################################################" |
| 74 | + echo "############### Compilation report ####################" |
| 75 | + echo "#######################################################" |
| 76 | + echo " Errors : ${NUM_ERRORS}" |
| 77 | + echo " Warnings : ${NUM_WARNINGS}" |
| 78 | + echo "See '${REPORT_FILE}' for a complete list of errors and warnings" |
| 79 | + echo "#######################################################" |
| 80 | +} |
| 81 | + |
| 82 | +# Compile testbench and design for RTL simulation |
| 83 | +vsim_compile () { |
| 84 | + if [ ! -f ${VSIM_DIR}/compile_rtl.tcl ]; then |
| 85 | + fatal_error "missing RTL compile script 'compile_rtl.tcl'" |
| 86 | + fi |
| 87 | + cd ${VSIM_DIR} |
| 88 | + ${VSIM} -c -do "set ROOT ${ROOT_DIR}; source compile_rtl.tcl; exit" | tee compile_rtl.log |
| 89 | + vsim_compile_report compile_rtl.log compile_rtl.rpt |
| 90 | + vsim_compile_report_print_summary compile_rtl.rpt |
| 91 | +} |
| 92 | + |
| 93 | +# Compile testbench and design for post-synthesis simulation |
| 94 | +vsim_compile_net () { |
| 95 | + if [ ! -f ${VSIM_DIR}/compile_netlist.tcl ]; then |
| 96 | + fatal_error "missing netlist compile script 'compile_netlist.tcl'" |
| 97 | + fi |
| 98 | + if [ ! -f ${VSIM_DIR}/compile_tech.tcl ]; then |
| 99 | + fatal_error "missing technology compile script 'compile_net.tcl'" |
| 100 | + fi |
| 101 | + cd ${VSIM_DIR} |
| 102 | + ${VSIM} -c -do "source compile_netlist.tcl; source compile_tech.tcl; exit" |
| 103 | +} |
| 104 | + |
| 105 | +# Run simulation with QuestaSim |
| 106 | +vsim_run () { |
| 107 | + BINARY="$1" |
| 108 | + USE_GUI="$2" |
| 109 | + cd ${VSIM_DIR} |
| 110 | + if [ "${USE_GUI}" = "1" ]; then |
| 111 | + ${VSIM} +binary="${BINARY}" -gui tb_croc_soc -t 1ns -voptargs=+acc -suppress vsim-3009 -suppress vsim-8683 -suppress vsim-8386 |
| 112 | + else |
| 113 | + ${VSIM} +binary="${BINARY}" -c tb_croc_soc -t 1ns -voptargs=+acc -suppress vsim-3009 -suppress vsim-8683 -suppress vsim-8386 -do "run -a; quit" |
| 114 | + fi |
| 115 | +} |
| 116 | + |
| 117 | +# Clean up simulation files |
| 118 | +vsim_cleanup () { |
| 119 | + cd ${VSIM_DIR} |
| 120 | + rm -rf work/ |
| 121 | + rm -f transcript modelsim.ini vsim.wlf ./*.fst ./*.vcd ./*.log ./*.rpt |
| 122 | +} |
| 123 | + |
| 124 | +# Parse command line |
| 125 | +if [ $# -lt 1 ]; then |
| 126 | + fatal_error "missing command" |
| 127 | +fi |
| 128 | + |
| 129 | +COMMAND="$1" |
| 130 | +shift |
| 131 | + |
| 132 | +case "${COMMAND}" in |
| 133 | + compile) |
| 134 | + vsim_compile |
| 135 | + ;; |
| 136 | + compile-net) |
| 137 | + vsim_compile_net |
| 138 | + ;; |
| 139 | + run) |
| 140 | + USE_GUI=0 |
| 141 | + if [[ "${1-}" == "-gui" ]]; then |
| 142 | + USE_GUI=1 |
| 143 | + shift |
| 144 | + fi |
| 145 | + if [ $# -lt 1 ]; then |
| 146 | + fatal_error "missing binary" |
| 147 | + fi |
| 148 | + if [ ! -f "$1" ]; then |
| 149 | + fatal_error "cannot open binary file '$1'" |
| 150 | + fi |
| 151 | + vsim_run $(realpath "$1") ${USE_GUI} |
| 152 | + ;; |
| 153 | + cleanup) |
| 154 | + vsim_cleanup |
| 155 | + ;; |
| 156 | + help) |
| 157 | + usage |
| 158 | + ;; |
| 159 | + *) |
| 160 | + fatal_error "unknown command '${COMMAND}'" |
| 161 | + ;; |
| 162 | +esac |
0 commit comments