Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
HDL
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
RTSD
HDL
Commits
e5458f5f
Commit
e5458f5f
authored
10 years ago
by
Eric Kooistra
Browse files
Options
Downloads
Patches
Plain Diff
Commit to recover from SVN issue with commands.do
parent
95acae9a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tools/modelsim/commands.do
+0
-562
0 additions, 562 deletions
tools/modelsim/commands.do
with
0 additions
and
562 deletions
tools/modelsim/commands.do
deleted
100644 → 0
+
0
−
562
View file @
95acae9a
###############################################################################
#
# Copyright (C) 2009
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
# Purpose: Provide useful commands for simulating Modelsim projects
# Desription:
#
# * 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
# . 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/"
#
# * 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
#
#-------------------------------------------------------------------------------
# UniBoard settings
#-------------------------------------------------------------------------------
puts
"Loading general UniBoard 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"
}
}
#-------------------------------------------------------------------------------
# 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
}
# 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
}
project
open
$mpf
}
else
{
error
"Project file $arg_lib not found"
}
return
$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
}
# 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
}
}
}
return
$cmds
}
# Get libraries (modules, designs) 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
]
}
}
return
$libs
}
# 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
if
{
[
llength
$arg_lib
]
==
0
}
{
set
arg_lib
$cur_lib
}
# 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
}
}
}
# back to original lib
lp_gen
$arg_env
$arg_dir
$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"
}
}
}
# 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_files
{
arg_env
arg_dir
arg_lib
}
{
lp_gen
$arg_env
$arg_dir
$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_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_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_*
puts
"\[mk test $arg_lib\]"
radix
-
decimal
vsim
-
quiet
tst_lib
.
tb_
$arg_lib
set
tb
[
tbdir
$arg_env
$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
}
}
quit
-
sim
}
#-------------------------------------------------------------------------------
# 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
}
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
]
}
}
}
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
}
# 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
]
}
}
set
fh
[
open
$arg
w
]
puts
$fh
$txt
close
$fh
}
}
#-------------------------------------------------------------------------------
# DS = Delete Signals : deletes all signals in the waveform window.
#-------------------------------------------------------------------------------
proc
ds
{}
{
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 = add signals flat : flat adds all signals up to hierarchy depth to the wave window
# It will automatically add dividers between the blocks, and it will discard all
# 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."
}
#-------------------------------------------------------------------------------
# ASG = add signals in groups : recursively scans the hierarchy and adds signals
# groupwise to the wave window.
# Normal use:
# . asg [depth]
# => Adds all signals down to a depth of [depth].
# Advanced/debugging use:
# . asg [depth] [instance_name]
# => Adds all signals in [instance_name] down to to a level of [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
}
# 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
}
}
}
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
}
# Return the depth of a given path; e.g. /some/path/to/some/thing = 5.
proc
path_depth
path
{
scount
"/"
$path
}
#-------------------------------------------------------------------------------
# NOWARN default disables the library warnings for subsequent simulation runs.
# Use argument 0 to enable the warnings again.
#-------------------------------------------------------------------------------
proc
nowarn
{{
off
1
}}
{
set
::
StdArithNoWarnings
$off
set
::
NumericStdNoWarnings
$off
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment