Mentor Questa do versus source

The standard TCL command "source" is the common way to read in source of one file into the current environment - similar to an `include in Verilog.  Mentor Questa runs a TCL interpreter and adds a few custom features to the environment one of which is the command: "do".  For many uses the "do" and the "source" command will have identical output.  In fact, whatever can be done with "source" can be done with "do" - it is a superset of "source".  The "do" command does add at least two useful or at least interesting features.

Error Handling

One of the more interesting features of "do" is that it defines ways to handle tcl errors at different points in the design.  The commands:

onbreak
onerror
onElabError
onfinish

That can tell what the "do" command should do when the TCL it is executing comes across a breakpoint, error, elaboration error, or the end of the sim.  An example of "do" versus "source" will help make this more clear.  Below is the source of "ex1.do" which is a simple tcl script that shows the use of the "onerror" command used with a "do" call.  The command "add wave b" won't work because there is no sim even occurring so it won't find that signal to monitor.


 onerror {resume}
 # onerror {quit -f}
 
 puts "hello from START"

 add wave b

 puts "got to END"

If you called this within Mentor Questa you will get the following output when called with "do":

> vsim -c -do ex1.do

# do ex1.do 
hello from START
# ** Error: Active logfile is not in simulation mode
# Executing ONERROR command at macro ./ex1.do line 6
got to END
QuestaSim> Reading pref.tcl 

You can see that both of the "puts" lines were executed.  But if you called this command via "source":

> vsim -c -do "source ex1.do"

# source ex1.do 
hello from START
# Active logfile is not in simulation mode
QuestaSim> Reading pref.tcl 

When we call "ex1.do" with "source" the TCL interpreter within Questa errors out before it gets to the final "puts" line.  This is the conventional way that TCL works, if it encounters and error it will stop execution.  The "onerror" command is catching any errors within the script and then running a command to decide what to do.  In fact, it is very similar to putting a "catch" around every TCL command, but much easier to implement and use.

Instead of doing "onerror {resume}" you can try "onerror {quit -f}" or other options defined within the Questa Reference manual.  This is a great way to read in things like wave setup files which might have different names or to execute code which you want to complete, but could have some errors during processing.

Path Differences

The other feature that is interesting is if a "do" command calls another "do" command the search path is relative to the "do".  The full explanation from the vendor might help:

If the do command is executed from another macro file, pathnames are relative to the directory of the calling macro file. This allows groups of macro files to be stored in a separate sub-directory.
— Mentor Questa Command Reference

Here is an example with using "do" versus "source".  The code is not complex at all, but 

> vsim -c -do ex2.do

# do ex2.do 
ex2.do called
lib1.do called
lib2.do called
QuestaSim> Reading pref.tcl 
vsim -c -do "source ex2.tcl"

# source ex2.tcl 
ex2.tcl called
lib1.tcl called
lib2.tcl called
QuestaSim> 

The two execute the same flow the difference is that when "lib2" is called you use a different relative path if you are using "do" (lib1.do) than "source" (lib2.tcl).

What is this good for?  That is a good question.  TCL gets along fine without needing to have different rules for how search paths are done.  The inclusion of this method is likely more confusing that it needed to be.  The vendor notes that this allows macro files to be stored in a separate sub directory which may help define why there is different behavior than "source".

Conclusion

There are other differences between "do" and "source" dealing with performance and chaining how refresh is done, but these were the two differences I thought most interesting.  I think if you are a pure Mentor Questa flow you should really consider using some of Error Handling features of "do" - they would save a lot of use of the "catch" command.  But, if you have to write TCL that is cross simulator you won't be able to use the "on*" commands and "do"; which will force you to stick with "source".

For more check out the Mentor Questa Command Reference and the Mentor Questa User's Guide.