This is a general script for compiling, recompiling and simulating VHDL/Verilog code using ModelSim. It is intended for rapid code writing and testing where small code modifications can be checked very quickly using few keystrokes. Once ModelSim is running in GUI mode and the script has been sourced then recompiling out-of-date files and rerunning a simulation requires two keystrokes: r for recompile and press the Enter key. The key features are:
Here's the script. There's a zip file to download it with some example VHDL/Verilog at the end.
puts { ModelSim general compile script version 1.2 Copyright (c) Doulos June 2017, SD } # Simply change the project settings in this section # for each new project. There should be no need to # modify the rest of the script. set library_file_list { design_library {counter.vhd} test_library {countertb.vhd countercf.vhd} } set top_level test_library.Cfg_CounterTB set wave_patterns { /* } set wave_radices { hexadecimal {data q} } # After sourcing the script from ModelSim for the # first time use these commands to recompile. proc r {} {uplevel #0 source compile.tcl} proc rr {} {global last_compile_time set last_compile_time 0 r } proc q {} {quit -force } #Does this installation support Tk? set tk_ok 1 if [catch {package require Tk}] {set tk_ok 0} # Prefer a fixed point font for the transcript set PrefMain(font) {Courier 10 roman normal} # Compile out of date files set time_now [clock seconds] if [catch {set last_compile_time}] { set last_compile_time 0 } foreach {library file_list} $library_file_list { vlib $library vmap work $library foreach file $file_list { if { $last_compile_time < [file mtime $file] } { if [regexp {.vhdl?$} $file] { vcom -93 $file } else { vlog $file } set last_compile_time 0 } } } set last_compile_time $time_now # Load the simulation eval vsim $top_level # If waves are required if [llength $wave_patterns] { noview wave foreach pattern $wave_patterns { add wave $pattern } configure wave -signalnamewidth 1 foreach {radix signals} $wave_radices { foreach signal $signals { catch {property wave -radix $radix $signal} } } } # Run the simulation run -all # If waves are required if [llength $wave_patterns] { if $tk_ok {wave zoomfull} } puts { Script commands are: r = Recompile changed and dependent files rr = Recompile everything q = Quit without confirmation } # How long since project began? if {[file isfile start_time.txt] == 0} { set f [open start_time.txt w] puts $f "Start time was [clock seconds]" close $f } else { set f [open start_time.txt r] set line [gets $f] close $f regexp {\d+} $line start_time set total_time [expr ([clock seconds]-$start_time)/60] puts "Project time is $total_time minutes" }
Download a copy of this script along with some example VHDL/Verilog code (up down counter with test bench), compile_script.zip. Then modify the script settings and use it for your own ModelSim projects.
The Tcl variable library_file_list stores the library name(s) and files that should be compiled into each library. It is a two-dimensional Tcl formatted list. The first element is the name of a library, the second element is a list of files that should be compiled into that library. If there is more than one library then a third and fourth element should be written for the second library name and its list of files. And so on.
The order of libraries and files is significant, they should appear in order of dependency. The script will compile every file the first time. Subsequent recompiles will run through the list of files looking for a file that has been modified since the last compile time. The modified file and every file after it in the list will be recompiled.
The Tcl variable top_level keeps the library and name of the top level for elaboration. In fact the contents of this variable are used as the arguments to ModelSim's vsim command, so any valid options may be specified, for example:
set top_level {-t ps -sdftyp /uut=counter.sdf test_library.cfg_gate}
The Tcl variable wave_patterns can contain a list of signals or patterns that should be loaded into the wave window. For most block level testbenches just /* is enough. If no waves are required or the script is being used for command line simulations then this list can be left empty (nothing but white space).
The Tcl variable wave_radices is a two dimensional Tcl formatted list like library_file_list. The first element is a radix to use: hexadecimal, unsigned, binary etc. The second element is a list of wave signals for applying this radix to. There can be zero, one or more pairs of elements in this list.
To recompile out-of-date and dependent files type r and Enter. To force complete recompilation type rr and Enter. To quit without ModelSim confirming that you want to quit type q and Enter.
To start ModelSim and source this script from the command line, type this:
vsim -do compile.tcl
Or, if ModelSim is already running with the correct working directory, type this in the ModelSim main window:
source compile.tcl
You can save even more project time and become more productive when you learn more Tcl/Tk. Invest in your career development. Develop your scripting skills with Essential Tcl/Tk training from Doulos.