# Tcl launcher script for the project
namespace eval project_launcher {
# Help information for this script
proc print_help {} {
variable script_file "project.tcl"
puts "\nDescription:"
puts "Perform actions related to this project.\n"
puts "Syntax:"
puts "$script_file"
puts "$script_file \[action\] \[args\]"
puts "Usage:"
puts "Name Description"
puts "-------------------------------------------------------------------------"
puts "\[action\] Determine the action to be performed. Default value: help\n"
puts " Current actions: help, clean, sim, verify, test, view\n"
puts "\[args\] Arguments related to the action.\n"
puts " --root
changes the root reference for the project.\n"
puts "-------------------------------------------------------------------------\n"
exit 0
}
proc do_clean { root_dir } {
variable dir "$root_dir/runs"
puts "Cleaning all files in directory $dir...\n"
# Checking if the folder is empty to avoid error
if {[catch { glob "$dir/*" } result] != 1} {
file delete -force -- {*}[glob "$dir/*" ]
}
}
proc do_sim_icarus { root_dir verbose } {
# Checking if the folder is empty to avoid error
if {[file exists "$root_dir/scripts/run_iverilog.tcl"] == 1} {
#global root_dir_loc $root_dir
#source $root_dir/scripts/run_iverilog.tcl
try {
set results [exec tclsh $root_dir/scripts/run_iverilog.tcl $root_dir ]
set status 0
} trap CHILDSTATUS {results options} {
set status [lindex [dict get $options -errorcode] 2]
}
if {$status != 0} {
puts "Problem running the script :"
puts $results
return
}
if {[expr $verbose]} {
# output the result of the execution
puts $results
}
} else {
puts "The script run_iverilog.tcl does not exist in $root_dir/scripts"
}
}
proc do_sim_pytest { root_dir verbose } {
exec pytest $root_dir/tests/ >@stdout 2>@stderr
}
proc do_formal { root_dir } {
# We suppose that the sby file is meant to be run from the inside of the folder
# hence we cd there
if {[file pathtype $root_dir] != "absolute"} {
set root_dir "../$root_dir"
}
#set root_dir [file normalize $root_dir]
cd verification
#variable fname [glob -nocomplain $root_dir/verification/*.sby]
variable fname [glob -nocomplain *.sby]
if {[llength $fname]} {
set fname [lindex $fname 0]
puts "Using $fname file..."
exec sby -f $fname --prefix $root_dir/runs/verification/counter >@stdout 2>@stderr
} else {
puts "There are no .sby files present..."
cd ..
return
}
cd ..
}
proc do_view { root_dir } {
# Checking if the folder is empty to avoid error
if {[file exists "$root_dir/scripts/run_gtkwave.tcl"] == 1} {
try {
set results [exec tclsh $root_dir/scripts/run_gtkwave.tcl $root_dir ]
set status 0
} trap CHILDSTATUS {results options} {
set status [lindex [dict get $options -errorcode] 2]
}
if {$status != 0} {
puts "Problem running the script :"
puts $results
return
}
} else {
puts "The script run_gtkwave.tcl does not exist in $root_dir/scripts"
}
}
proc main {} {
variable root_dir
# Set the reference directory to where the script is
#set root_dir [file dirname [info script]]
# Set the reference directory for source file relative paths (by default the value is script directory path)
set root_dir "."
# Use origin directory path location variable, if specified in the tcl shell
if { [info exists ::root_dir_loc] } {
set root_dir $::root_dir_loc
}
variable action "help"
variable verbose false
if { $::argc > 0 } {
for {set i 0} {$i < $::argc} {incr i} {
set option [string trim [lindex $::argv $i]]
switch -regexp -- $option {
"--root" { incr i; set root_dir [lindex $::argv $i] }
"--help" { print_help }
"help" { print_help }
"clean" { set action "clean" }
"sim" {incr i; set action "sim_[lindex $::argv $i]" }
"--verbose" { set verbose true }
"-v" { set verbose true }
{pytest|cocotb|test} {set action "pytest"}
{formal|verify|verification} {set action "formal"}
{view} {set action "view"}
default {
if { [regexp {^-} $option] } {
puts "ERROR: Unknown option '$option' specified, please type '$script_file -tclargs --help' for usage info.\n"
return 1
}
}
}
}
} else {
print_help
}
puts "Script started. The root dir is $root_dir. The action is: $action\n"
switch -regexp -- $action {
"clean" { do_clean $root_dir }
{sim_icarus|^sim_$|sim_iverilog} { do_sim_icarus $root_dir $verbose}
{sim_cocotb|pytest} { do_sim_pytest $root_dir $verbose}
"formal" { do_formal $root_dir}
"view" {do_view $root_dir}
}
}
main
}