# 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\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 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"} 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} } } main }