It takes a little bit more to get it working than that. The following template should work:
set module [lindex $quartus(args) 0]
set revision [lindex $quartus(args) 2]
if {[string match "quartus_asm" $module]} {
#Commands which are run after the Quartus Assembler
post_message "Running TCL after Quartus Assembler"
#Use Chain file to program sof.
qexec "quartus_pgm ProgramSof.cdf"
}
Place the template in a TCL script file of whatever name you choose, e.g. PostModule.tcl
, then in your projects .qsf
file, and the following line:
set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:PostModule.tcl
The line in the .qsf
file will instruct Quartus to run the TCL script each time a module (e.g. fitter, assembler, timequest, etc.) finishes running.
In the script we get the current module that is being run, and can also get the corresponding project revision. Then we check whether the current module is the one that we want to run the script after - in this case Quartus Assembler (quartus_asm
).
Any commands you put within that if statement are now executed every time that the Quartus Assembler finishes.
The simplest way to achieve the programming is to use a chain file. If you open the Quartus programmer and set up everything - programming hardware, sof filename, device list, and so on. Then save that file as something like "ProgramSof.cdf". The template above will then execute the Quartus programmer using that chain file which will use all the settings you have saved.
You can also change the command to do it entirely via command line switches rather than a chain file, however if you are going to do this you need to specify the programming cable name, the devices in the JTAG chain if there is more than one (e.g. many dev kits have MAX V supervisors in the chain with the main FPGA), and so forth. It is easier to simply save a chain file and then if you need to change any settings you can just edit that chain file.