Skip to content
Snippets Groups Projects
Commit 007961fe authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Updated for RadioHDL. The lp and mk commands work ok, only mk test is not...

Updated for RadioHDL. The lp and mk commands work ok, only mk test is not supported yet. The as and ds commands are not changed.
parent 469c1d5e
No related branches found
No related tags found
No related merge requests found
###############################################################################
#
# Copyright (C) 2009
# Copyright (C) 2014
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
......@@ -24,48 +24,34 @@
#
# * The user commands are typically used at the Modelsim prompt are:
#
# . lp <name> : load UniBoard <name>.mpf project
# . mk <name> : make one or range of UniBoard mpf projects
# . lp <name> : load HDL library <name>.mpf project
# . mk <name> : make one or range of HDL library mpf projects
# . as # : add signals for # levels of hierarchy to the wave window
# . ds : delete all signals from the wave window
#
# * The other procedures in this commands.do are internal command procedures
# that are typically not used at the Modelsim prompt. However they can be
# used to create user commands for other projects (i.e. another arg_env then
# UNB with other arg_dir for the libraries).
#
# * The general lp and mk commands assume that the Modelsim project file is
# located at:
#
# "$env($arg_env)/Firmware/$sdir/$arg_lib/build/sim/modelsim"
#
# or for designs with an SOPC system at:
#
# "$env($arg_env)/Firmware/$sdir/$arg_lib/build/synth/quartus/*_sim/"
# that are typically not used at the Modelsim prompt.
#
# * The recommended project directory structure is:
#
# $arg_lib/build/sim/modelsim : Modelsim project file
# /synth/quartus : Quartus project file
# /src/vhdl : VHDL source code that gets synthesized
# /tb/vhdl : VHDL source code for test bench
# $arg_lib/build/modelsim : Modelsim project file
# /quartus : Quartus project file
# /src/vhdl : VHDL source code that gets synthesized
# /tb/vhdl : VHDL source code for test bench
#
# Alternatively the build/ directory may be located at another more central
# location.
#
#-------------------------------------------------------------------------------
# UniBoard settings
# HDL library settings
#-------------------------------------------------------------------------------
puts "Loading general UniBoard commands..."
puts "Loading general HDL library commands..."
# UniBoard environment variable
proc unb_env {} {
return "UNB"
}
# UniBoard project directories
proc unb_dir {} {
return {"designs" "modules" "modules/Altera" "modules/MegaWizard" "modules/Lofar" "dsp" "systems"}
proc hdl_env {} {
global env
return $env(RADIOHDL)
}
......@@ -73,52 +59,24 @@ proc unb_dir {} {
# LP = Load project
#-------------------------------------------------------------------------------
# Default load UniBoard project
proc lp {{arg_lib ""}} {
lpu $arg_lib
}
# UniBoard load project
proc lpu {{arg_lib ""}} {
set arg_env [unb_env]
set arg_dir [unb_dir]
lp_gen $arg_env $arg_dir $arg_lib
proc get_cur_lib {} {
set mpf [eval project env]
set cur_lib [string range $mpf [expr [string last / $mpf]+1] [expr [string last . $mpf]-1]]
return $cur_lib
}
# General load project
proc lp_gen {arg_env arg_dir arg_lib} {
set mpf [eval project env]
set cur_lib [string range $mpf [expr [string last / $mpf]+1] [expr [string last . $mpf]-1]]
if {[string equal $arg_lib ""] || [string equal $arg_lib $cur_lib]} {
# find out current module name
return $cur_lib
} elseif [file exists $arg_lib] {
set mpf $arg_lib
} else {
set sim [simdir $arg_env $arg_dir $arg_lib]
set mpf $sim/$arg_lib.mpf
}
if [file exists $mpf] then {
# if {[this_os]=="Windows"} {
# if [file attributes $mpf -readonly] then {
# file attributes $mpf -readonly 0
# }
# } else {
# set mpf_readonly [file attributes $mpf -permissions] ;# 5 char string: 0,0,u(rwx),g(rwx),a(rwx)
# set mpf_readonly [expr !([string index $mpf_readonly 2] & 0x2)] ;# filter out user write status
# if {$mpf_readonly==1} then {
# file attributes $mpf -permissions u+w
# }
# }
if {! [string equal $cur_lib ""]} then {
project close
proc lp {{arg_lib ""}} {
set cur_lib [get_cur_lib]
if {$arg_lib == "" || $arg_lib == $cur_lib} {
return $cur_lib
} else {
set sim [simdir $arg_lib]
if {[eval project env]!=""} {
project close
}
project open $sim/$arg_lib.mpf
return $arg_lib
}
project open $mpf
} else {
error "Project file $arg_lib not found"
}
return $arg_lib
}
......@@ -126,244 +84,180 @@ proc lp_gen {arg_env arg_dir arg_lib} {
# MK = Make project
#-------------------------------------------------------------------------------
# Default make UniBoard project
# . The args is a special TCL argument because it allows more than one formal.
# However when args is subsequently passed on to proc mku, then all arguments
# in args will be treated as a signal argument in mku. Therefore duplicate
# the content of proc mku in proc mk, because simply calling mku $args in mk
# does not work.
# . However using an alias also works and is a nicer solution:
# One can also define a command as an alias to a sequence of one or more
# words, which will be substituted for it before execution. (The funny {}
# arguments are names of the source and target interpreter, which typically
# is the current one, named by the empty string {} or "").
interp alias {} mk {} mku
# UniBoard make project
proc mku args {
set arg_env [unb_env]
set arg_dir [unb_dir]
set arg_cmd [parse_for_cmds $args]
set arg_lib [parse_for_libs $args]
set arg_lib [extract_unb_libs $arg_lib]
mk_gen $arg_env $arg_dir $arg_cmd $arg_lib
}
# Extract groups of UniBoard libs from arg_lib
proc extract_unb_libs arg_lib {
# Check arg_lib for make groups of UniBoard modules and designs
# Remarks:
# . order of groups is important
# . for the designs that have an SOPC system that needs to be generated first with SOPC Builder (to avoid pop up windows if these files are missing)
# . e.g. group of designs for which the node component is reused in other designs
# . e.g. group of reference designs that are still maintained
set m_unb_common {fmf easics tst common mm dp uth}
set m_unb_lofar {async_logic diag util i2c rcuh sens mdio eth ado pfs pft2 ss st}
set m_unb_dsp {bf rTwoSDF fft filter wpfb}
set m_unb_modules {diagnostics ppsh tse aduh tr_nonbonded ddr3 udp_packetizer remu epcs unb_common}
set m_unb_designs {unb_tr_nonbonded unb_ddr3 unb_tr_xaui bn_terminal_bg fn_terminal_db}
set m_old_designs {unb_sens unb_tse unb_heater fn_mdio unb_base bn_base fn_base}
set m_apertif_designs {bn_capture fn_bf bn_filterbank fn_beamformer}
if [ string equal $arg_lib "all_mod" ] { set arg_lib "$m_unb_common $m_unb_lofar $m_unb_modules $m_unb_dsp"
} elseif [ string equal $arg_lib "unb_designs" ] { set arg_lib "$m_unb_designs"
} elseif [ string equal $arg_lib "all_unb" ] { set arg_lib "$m_unb_common $m_unb_lofar $m_unb_modules $m_unb_dsp $m_unb_designs"
} elseif [ string equal $arg_lib "all_apertif" ] { set arg_lib "$m_unb_common $m_unb_lofar $m_unb_modules $m_unb_dsp $m_unb_designs $m_apertif_designs"
} elseif [ string equal $arg_lib "old_designs" ] { set arg_lib "$m_old_designs"
} elseif [ string equal $arg_lib "all" ] { set arg_lib "$m_unb_common $m_unb_lofar $m_unb_modules $m_unb_dsp $m_unb_designs $m_apertif_designs $m_old_designs"
}
return $arg_lib
proc project_mk_cmds {} {
return {clean compile files make test vmake} ;# mk with arg_cmd="" will default to "make"
}
# Get commands from the mk args
proc parse_for_cmds arg_list {
set cmds {}
if [ string equal $arg_list "help" ] then {
puts "mk \[commands\] \[projects\]"
puts " possible commands are:"
puts " check: check for absolute paths in project sources"
puts " clean: removes the library files"
puts " compile: runs project compileall"
puts " delete: delete Modelsim project file"
puts " files: list files in compile order"
puts " help: displays this help"
puts " make: runs makefile"
puts " test: runs test cases"
puts " vmake: creates makefile"
puts ""
puts "commands are executed for the projects indicated"
puts "- when no command is specified, 'make' is used as default"
puts "- when no projects are specified, the current project is used"
puts "- the keyword 'all_mod' is expanded to a subset of all uniboard reuseable modules"
puts "- the keyword 'all_unb' is expanded to a subset of all uniboard reuseable designs and reference designs"
puts ""
return
} else {
# search for commands in arg_list
foreach cmd {check clean compile delete files make test vmake} {
if {[lsearch $arg_list $cmd] >= 0} then {
lappend cmds $cmd
}
}
if {[llength $cmds] == 0} then {
# no commands found, use default commands
set cmds {make}
set cmds {}
if [ string equal $arg_list "help" ] then {
puts "mk \[commands\] \[projects\]"
puts " possible commands are:"
puts " clean: removes the library files"
puts " compile: runs project compileall"
puts " files: list files in compile order"
puts " help: displays this help"
puts " make: runs makefile"
puts " test: runs test cases"
puts " vmake: creates makefile"
puts ""
puts "commands are executed for the projects indicated"
puts "- when no command is specified, 'make' is used as default"
puts "- when no projects are specified, the current project is used"
puts "- when the keyword 'all' is specified, then the command is applied to all projects that the current project depends on"
puts ""
return
} else {
# search for commands in arg_list
foreach cmd [project_mk_cmds] {
if {[lsearch $arg_list $cmd] >= 0} then {
lappend cmds $cmd
}
}
if {[llength $cmds] == 0} then {
# no commands found, use default command
set cmds {make}
}
}
}
return $cmds
return $cmds
}
# Get libraries (modules, designs) from the mk args
# Get libraries from the mk args
proc parse_for_libs arg_list {
# strip the commands from arg_list to keep only the modules
set libs $arg_list
foreach cmd {check clean compile delete files make test vmake} {
set i [lsearch $libs $cmd]
if {$i >= 0} then {
set libs [lreplace $libs $i $i]
# strip the commands from arg_list to keep only the libraries
set libs $arg_list
foreach cmd [project_mk_cmds] {
set i [lsearch $libs $cmd]
if {$i >= 0} then {
set libs [lreplace $libs $i $i]
}
}
}
return $libs
return $libs
}
# Extract this lib or all libs that it depends on for arg_lib
proc extract_all_libs arg_lib {
if {$arg_lib=="all"} {
set cur_lib [get_cur_lib]
return [read_lib_compile_order_file $cur_lib]
} else {
return $arg_lib
}
}
# General make project
proc mk_gen {arg_env arg_dir arg_cmd arg_lib} {
if {[llength $arg_cmd] > 0} then {
set cur_lib [lp_gen $arg_env $arg_dir ""]
# without arguments mk current lib
proc mk args {
# Parse the args, the args is a special TCL argument because it allows more than one formal.
set arg_cmd [parse_for_cmds $args]
set arg_lib [parse_for_libs $args]
# Extract arg_lib or all libs that it depends on for arg_lib
set arg_lib [extract_all_libs $arg_lib]
# keep current lib
set cur_lib [get_cur_lib]
# Without arguments mk current lib
if { [llength $arg_lib] == 0 } {
set arg_lib $cur_lib
set arg_lib $cur_lib
}
# perform the commands on the specified libs
# Perform the commands on the specified libs
foreach cmd $arg_cmd {
foreach lib $arg_lib {
if { [ catch { eval ["mk_$cmd" $arg_env $arg_dir $lib] } msg ] } {
puts stderr $msg
foreach lib $arg_lib {
if { [ catch { eval ["mk_$cmd" $lib] } msg ] } {
puts stderr $msg
}
}
}
}
# back to original lib
lp_gen $arg_env $arg_dir $cur_lib
}
lp $cur_lib
}
proc mk_check {arg_env arg_dir arg_lib} {
lp_gen $arg_env $arg_dir $arg_lib
puts "\[mk check $arg_lib\]"
foreach file [project compileorder] {
if {[string first "../" $file] != 0 &&
[string first "\$" $file] != 0} {
puts stderr "Warning: $file is an absolute path"
proc mk_clean {arg_lib} {
puts "\[mk clean $arg_lib\]"
set sim [simdir $arg_lib]
if {[file exists "$sim/work"]} then {
vdel -lib $sim/work -all
}
if {[file exists "$sim/makefile"]} then {
file delete $sim/makefile
}
if {[file exists "$sim/vsim.wlf"]} then {
file delete $sim/vsim.wlf
}
if {[file exists "$sim/$arg_lib.cr.mti"]} then {
file delete $sim/$arg_lib.cr.mti
}
}
}
# Issue mk delete all to delete all Modelsim project files to ensure that SVN
# update refreshes them all from the repository. This is necessary because
# Modelsim edits the mpf files even when they have no significant modification
# and then the edited mpf files will not get SVN updated.
proc mk_delete {arg_env arg_dir arg_lib} {
puts "\[mk delete $arg_lib\]"
set sim [simdir $arg_env $arg_dir $arg_lib]
if {[file exists "$sim/$arg_lib.mpf"]} then {
file delete $sim/$arg_lib.mpf
}
}
proc mk_clean {arg_env arg_dir arg_lib} {
puts "\[mk clean $arg_lib\]"
set sim [simdir $arg_env $arg_dir $arg_lib]
if {[file exists "$sim/work"]} then {
vdel -lib $sim/work -all
}
if {[file exists "$sim/makefile"]} then {
file delete $sim/makefile
}
if {[file exists "$sim/vsim.wlf"]} then {
file delete $sim/vsim.wlf
}
if {[file exists "$sim/$arg_lib.cr.mti"]} then {
file delete $sim/$arg_lib.cr.mti
}
}
proc mk_compile {arg_env arg_dir arg_lib} {
if {[string compare [env] "<No Context>"] != 0} {
puts "A project cannot be closed while a simulation is in progress.\nUse the \"quit -sim\" command to unload the design first."
return
}
puts "\[mk compile $arg_lib\]"
lp_gen $arg_env $arg_dir $arg_lib
if {![file exists work"]} then {
vlib work;
}
project compileall
proc mk_compile {arg_lib} {
if {[string compare [env] "<No Context>"] != 0} {
puts "A project cannot be closed while a simulation is in progress.\nUse the \"quit -sim\" command to unload the simulation first."
return
}
puts "\[mk compile $arg_lib\]"
lp $arg_lib
if {![file exists work"]} then {
vlib work;
}
project compileall
}
proc mk_files {arg_env arg_dir arg_lib} {
lp_gen $arg_env $arg_dir $arg_lib
foreach file [project compileorder] {
puts $file
}
proc mk_files {arg_lib} {
lp $arg_lib
foreach file [project compileorder] {
puts $file
}
}
proc mk_vmake {arg_env arg_dir arg_lib} {
set sim [simdir $arg_env $arg_dir $arg_lib]
if {![file exists "$sim/work/_info"]} then {
mk_compile $arg_env $arg_dir $arg_lib
}
puts "\[mk vmake $arg_lib\]"
if {![file exists "$sim/makefile"] ||
([file mtime "$sim/makefile"] < [file mtime "$sim/work/_info"]) } then {
# Both the specific library name $(arg_lib)_lib and the work library map to the same local work library,
# so to be compatible for both names always use work to generate the makefile
puts [exec vmake -fullsrcpath work > $sim/makefile]
adapt_makefile "$sim/makefile"
}
if {[file exists "$sim/work"]} then {
vdel -lib $sim/work -all
vlib work
}
proc mk_vmake {arg_lib} {
set sim [simdir $arg_lib]
if {![file exists "$sim/work/_info"]} then {
mk_compile $arg_lib
}
puts "\[mk vmake $arg_lib\]"
if {![file exists "$sim/makefile"] ||
([file mtime "$sim/makefile"] < [file mtime "$sim/work/_info"]) } then {
# Both the specific library name $(arg_lib)_lib and the work library map to the same local work library,
# so to be compatible for both names always use work to generate the makefile
puts [exec vmake -fullsrcpath work > $sim/makefile]
}
if {[file exists "$sim/work"]} then {
vdel -lib $sim/work -all
vlib work
}
}
proc mk_make {arg_env arg_dir arg_lib} {
global env
set sim [simdir $arg_env $arg_dir $arg_lib]
if {! [file exists "$sim/makefile"] } then {
mk_vmake $arg_env $arg_dir $arg_lib
}
puts "\[mk make $arg_lib\]"
if {[this_os]=="Windows"} {
puts [exec $env(UNB)/Firmware/sim/bin/make.exe -C $sim -s -k -f makefile]
} else {
puts [exec /usr/bin/make -C $sim -s -k -f makefile]
}
proc mk_make {arg_lib} {
set sim [simdir $arg_lib]
if {! [file exists "$sim/makefile"] } then {
mk_vmake $arg_lib
}
puts "\[mk make $arg_lib\]"
if {[this_os]=="Windows"} {
puts [exec [hdl_env]/tools/bin/make.exe -C $sim -s -k -f makefile]
} else {
puts [exec /usr/bin/make -C $sim -s -k -f makefile]
}
}
proc mk_test {arg_env arg_dir arg_lib} {
# only for directory /modules, so arg_dir is not used but kept to match the other proc mk_*
proc mk_test {arg_lib} {
puts "\[mk test $arg_lib\]"
radix -decimal
vsim -quiet tst_lib.tb_$arg_lib
set tb [tbdir $arg_env $arg_lib]
set tb [tbdir $arg_lib]
foreach tc [glob -directory $tb/data -type d -nocomplain tc*] {
puts "testcase $tc"
foreach fileName [glob -directory $tc -type f -nocomplain *.in *.out *.ref] {
file copy -force $fileName .
}
restart -force
run 1 ms
foreach fileName [glob -dir . -type f -nocomplain *.in *.out *.ref] {
file delete -force $fileName
}
puts "testcase $tc"
foreach fileName [glob -directory $tc -type f -nocomplain *.in *.out *.ref] {
file copy -force $fileName .
}
restart -force
run 1 ms
foreach fileName [glob -dir . -type f -nocomplain *.in *.out *.ref] {
file delete -force $fileName
}
}
quit -sim
}
......@@ -373,86 +267,79 @@ proc mk_test {arg_env arg_dir arg_lib} {
# Auxiliary procedures
#-------------------------------------------------------------------------------
# compute simulation directory
proc simdir {arg_env arg_dir arg_lib {return_code -1}} {
global env
# The order of arg_dir is important when modules with the same name exist,
# the first one where the mpf is found will be used
foreach sdir $arg_dir {
# First look in the project default Modelsim project directory
if {[file exists "$env($arg_env)/Firmware/$sdir/$arg_lib/build/sim/modelsim"]} {
return $env($arg_env)/Firmware/$sdir/$arg_lib/build/sim/modelsim
proc read_modelsim_project_files_file {} {
set fp [open [hdl_env]/tools/modelsim/modelsim_project_files.txt]
set data [read $fp]
close $fp
set lines [split $data \n]
set lib_names {}
set mpf_paths {}
foreach line $lines {
set ll [split $line]
if {[lindex $ll 1]== "="} {
lappend lib_names [lindex $ll 0]
lappend mpf_paths [lindex $ll 2]
}
}
set ret {}
lappend ret $lib_names
lappend ret $mpf_paths
return $ret
}
proc read_lib_compile_order_file {arg_lib} {
set sim [simdir $arg_lib]
set file_name $arg_lib
append file_name "_lib_order.txt"
set fp [open $sim/$file_name]
set data [read $fp]
close $fp
set lib_names [split $data]
puts $lib_names
return $lib_names
}
# Compute simulation directory where the mpf is located
proc simdir {arg_lib} {
set project_libs [read_modelsim_project_files_file]
set lib_names [lindex $project_libs 0]
set mpf_paths [lindex $project_libs 1]
set lib_index [lsearch $lib_names $arg_lib]
if {$lib_index >= 0} {
return [lindex $mpf_paths $lib_index]
} else {
# then also support the <sopc design name>_sim directory generated by SOPC Builder
# note that for this path to be found the modelsim/ directory in sim/ must be deleted
if {[catch {glob -directory $env($arg_env)/Firmware/$sdir/$arg_lib/build/synth/quartus *_sim/}] == 0} {
# If there exists more then one dir ending at '_sim' then return only the first
return [lindex [glob -directory $env($arg_env)/Firmware/$sdir/$arg_lib/build/synth/quartus *_sim/] 0]
}
error "Project directory $arg_lib not found"
return -1
}
}
if {$return_code==-1} {
# Default raise error to abort script
error "Project directory $arg_lib not found"
} else {
# Optionally return with return_code to continue script
return $return_code
}
}
# compute tb directory
proc tbdir {arg_env arg_lib} {
global env
return $arg_env/Firmware/modules/$arg_lib/tb
# Compute tb directory
proc tbdir {arg_lib} {
}
# find out which environment operating system we are on
proc this_os {} {
if {$::tcl_platform(platform)=="windows"} {
return "Windows"
} else {
return "Not Windows" ;# Linux, Unix, ...
}
}
# adapt makefile to allow (arch_name) in filenames by changing them into \\(arch_name\\)
proc adapt_makefile arg {
if {[this_os]=="Windows"} {
# Nothing to do, works OK
} else {
set arch_names {"pkg" "rtl" "str" "wrap" "recursive" "beh" "empty" "stratix4"}
set fh [open $arg r]
set txt [read $fh]
close $fh
foreach an $arch_names {
set ai [string first "($an)" $txt]
while {$ai != -1} {
set txt [string replace $txt $ai [expr $ai + [string length $an] + 1] "\\($an\\)"]
incr ai 2
set ai [string first "($an)" $txt $ai]
}
if {$::tcl_platform(platform)=="windows"} {
return "Windows"
} else {
return "Not Windows" ;# Linux, Unix, ...
}
set fh [open $arg w]
puts $fh $txt
close $fh
}
}
#-------------------------------------------------------------------------------
# DS = Delete Signals : deletes all signals in the waveform window.
#-------------------------------------------------------------------------------
proc ds {} {
delete wave *
delete wave *
}
#-------------------------------------------------------------------------------
# AS = Add signals : adds all signals up to hierarchy depth to the wave window
#-------------------------------------------------------------------------------
proc as {depth {inst ""}} {
#asf $depth
asg $depth $inst
#asf $depth
asg $depth $inst
}
#-------------------------------------------------------------------------------
......@@ -461,18 +348,18 @@ proc as {depth {inst ""}} {
# nxt_ and i_ signals. Altera alt_ blocks will also be ignored.
#-------------------------------------------------------------------------------
proc asf depth {
global env
# Start with all signals in the model.
add wave -noupdate -divider {as}
add wave -noupdate -depth $depth -r "/*"
# Allow users to set environment variable if they don't want the signals to be deleted
if { ![info exists ::env(MODELSIM_WAVE_NO_DEL) ] } {
delete wave */nxt_*
delete wave */i_*
}
#delete wave */alt*
configure wave -signalnamewidth 0
echo "Done."
global env
# Start with all signals in the model.
add wave -noupdate -divider {as}
add wave -noupdate -depth $depth -r "/*"
# Allow users to set environment variable if they don't want the signals to be deleted
if { ![info exists ::env(MODELSIM_WAVE_NO_DEL) ] } {
delete wave */nxt_*
delete wave */i_*
}
#delete wave */alt*
configure wave -signalnamewidth 0
echo "Done."
}
#-------------------------------------------------------------------------------
......@@ -487,68 +374,68 @@ proc asf depth {
# NOTE: instance_name = NOT the entity name!
#-------------------------------------------------------------------------------
proc asg {depth {inst ""}} {
add_wave_grouped_recursive "" "" $depth $inst 0
wave refresh
# The grouping already displays the hierarchy, so use short signal names.
config wave -signalnamewidth 1
# With our short signal names, the name column can be narrower than default.
config wave -namecolwidth 300
add_wave_grouped_recursive "" "" $depth $inst 0
wave refresh
# The grouping already displays the hierarchy, so use short signal names.
config wave -signalnamewidth 1
# With our short signal names, the name column can be narrower than default.
config wave -namecolwidth 300
}
# called by ASG:
proc add_wave_grouped_recursive {current_level prev_group_option depth target_inst target_inst_det} {
# Find all instances (=next hierarchy levels) in the ecurrent hierarchy level
set found_instances [find instances "$current_level/*"]
# Find all blocks (=GENERATE statement labels that are also hierarchy levels to be explored)
set found_blocks [find blocks "$current_level/*"]
# Concatenate the instance list with the block list, sort them alphabetically
set objects [lsort -dictionary [concat $found_instances $found_blocks]]
foreach object $objects {
# Separate "/object_path" from "(entity_name)"
set object_path [lindex [split $object " "] 0]
# Get the word after last "/"
set gname [lrange [split $object_path "/"] end end]
if {[path_depth $object_path]<$depth} {
if { $gname == $target_inst || $target_inst_det==1} {
# Found an instance that matches user input - or we're already inside that instance.
add_wave_grouped_recursive "$object_path" "$prev_group_option -group $gname" $depth $target_inst 1
} else {
add_wave_grouped_recursive "$object_path" "$prev_group_option -group $gname" $depth $target_inst 0
}
}
}
# Find all instances (=next hierarchy levels) in the ecurrent hierarchy level
set found_instances [find instances "$current_level/*"]
if { $current_level != "" } {
# First check if what we're about to add is an instance, not merely a GENERATE level
if {[context isInst $current_level]==1} {
set CMD "add wave -noupdate -radix unsigned $prev_group_option $current_level/*"
if {$target_inst!=""} {
# User passed a target inst. Check if we inside of it.
if {$target_inst_det==0} {
# We're not in in instance. Only add a group and move on.
set CMD "add wave -noupdate -radix unsigned $prev_group_option"
# Find all blocks (=GENERATE statement labels that are also hierarchy levels to be explored)
set found_blocks [find blocks "$current_level/*"]
# Concatenate the instance list with the block list, sort them alphabetically
set objects [lsort -dictionary [concat $found_instances $found_blocks]]
foreach object $objects {
# Separate "/object_path" from "(entity_name)"
set object_path [lindex [split $object " "] 0]
# Get the word after last "/"
set gname [lrange [split $object_path "/"] end end]
if {[path_depth $object_path]<$depth} {
if { $gname == $target_inst || $target_inst_det==1} {
# Found an instance that matches user input - or we're already inside that instance.
add_wave_grouped_recursive "$object_path" "$prev_group_option -group $gname" $depth $target_inst 1
} else {
add_wave_grouped_recursive "$object_path" "$prev_group_option -group $gname" $depth $target_inst 0
}
}
}
# Use catch so e.g. empty entities don't cause script to fail
catch {eval $CMD}
}
return
}
if { $current_level != "" } {
# First check if what we're about to add is an instance, not merely a GENERATE level
if {[context isInst $current_level]==1} {
set CMD "add wave -noupdate -radix unsigned $prev_group_option $current_level/*"
if {$target_inst!=""} {
# User passed a target inst. Check if we inside of it.
if {$target_inst_det==0} {
# We're not in in instance. Only add a group and move on.
set CMD "add wave -noupdate -radix unsigned $prev_group_option"
}
}
# Use catch so e.g. empty entities don't cause script to fail
catch {eval $CMD}
}
return
}
}
# Count the number of occurences in a string:
proc scount {subs string} {
regsub -all $subs $string $subs string
regsub -all $subs $string $subs string
}
# Return the depth of a given path; e.g. /some/path/to/some/thing = 5.
proc path_depth path {
scount "/" $path
scount "/" $path
}
......@@ -557,6 +444,6 @@ proc path_depth path {
# Use argument 0 to enable the warnings again.
#-------------------------------------------------------------------------------
proc nowarn {{off 1}} {
set ::StdArithNoWarnings $off
set ::NumericStdNoWarnings $off
set ::StdArithNoWarnings $off
set ::NumericStdNoWarnings $off
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment