VCS and coverage by Aviral Mittal
Connect @ Aviral Mittal


As usual I am putting mixed unstructured infromation on yet another tool, this time it is VCS.
I believe that it will provide a lot of practical information for users than the user guides or any other tutorial
provides. Any questions, please write to me at avimit at yahoo dat com.

VCS is 3 step process 
1. Analyze (vhdlan vlogan) This command complies the given code and checks for syntax errors.
2. Elaborate ( vcs <entity name> or <module name> or <entity__archname> or <cfg_name>)
3. Simulate ( simv )

While using VHDL design files, a simulaiton file 'synopsys_sim.setup' is usually defined, which defines
the compiled vhdl library.
Example 'synopsys_sim.setup' file:
DEFAULT : ./work
memlib : ./mem_lib
xm_bus_lib : ./xm_bus_lib
The first line maps the WORK library to a name 'DEFAULT', and the second line maps the 'DEFAULT' library
to a physcial directory called './work'.
The second line defines a library memlib which is mapped to a physcial directory called 'mem_lib'.

In the absence of any 'synopsys_sim.setup' file in your working directory, vcs will look for the same file in your home directory,
and if there is no 'synopsys_sim.setup' in your home directory, it will look for the same file in the tool installation directory.
The default 'synopsys_sim.setup' is in the tool installation directory, which maps the default work directory to '.'.
You will see complied VHDL files in '.' in case you dont have a 'synopsys_sim.setup' file.

Example vhdlan commands:

vhdlan -w memlib../../pid_filter/rtl/fun_pkg.vhdl
vhdlan -w work ../vhdl/state_machine.vhd
vhdlan ./state_machine_tb.vhd

Example elaboration commands:
vcs -cm line+cond+fsm+tgl+path pid_filter_tb
This steps generates an executable file which is named simv by default. This name can be changed.

Example simulaiton commands:
simv -ucli -do file.cmds
Contents of a simple file.cmds
run 1 ms
simv -gui
simv -cm line+cond+fsm+tgl+path -gui
simv -g generics_file

contents of 'generic_file'
assign 1 /TOP/LEN
assign "OK.dat" /TOP/G1/vhdl1/FILE_NAME
assign (4 ns) /TOP/G1/VHDL1/delay
assign 16 /TOP/width
assign 4 /TOP/add_width

VCS can be a 2 step process if only verilog is being used
vcs <source-files> [compile options]

Generating Makefile:
vcs -lca -makedepends=makefile state_machine_tb
It seems that the same above command is used to generate makefile, and to do an incrimental compliation.
Incremental compliation is enabled by default:

VCS commands
removing like ncrm
updating like ncupdate
hierarchy browsing using commands
dump values in a txt file like ncsim
how to define the hierarchy
forcing nets in simulation, syntax.

Latches, linting, cross clock domain checking. Can write the rule in leda.

setenv VCS_HOME < VCS_Install_Dir>
set path = ($VCS_HOME/bin $path) -v : will tell about environment
vcs -doc
command_name -help

The simulation flow:
synopsys_sim.setup : to map logical and physcial libraries

setenv SYNOPSYS_SIM_SETUP <path>/<filename> : global preference
1 tools setup
2 home
3 current dir

include: not sure.

WORK> logical_name
WORK > gate_lib
gate_lib : /libs/glib




RUNREAD = <filename>
run this file automatically when it starts.


show_setup -lib

-v means file containing many modules
-y means directories where tech libs are


 uum : unified use model. $VCS_HOME/doc/uum.pdf

-ucli - Enable Tcl command-line interface
-debug : allows to dump waveforms
-debug_all : line debug
-cm <options>: enable coverage options

vcs -makedepends = <makefile> <options>
gamke makefile

vcs <file.c> -cflags "<gcc options"
vcs -hsopt <options> improve gate-level and debug simulation speed

vcs -debug_pp (post processing)
for tcl and gui
vcs -debug



vcs -debug +memcbk to dump say vhdl record types, which are not dumped by default
initial $sdf_annotate(...);
vcs -sdf=[min|typ|max]:instance_name:

-P $VCS_ROOT/include/ for
hdl_xmr instead of init_signal_spy in modelsim

library synopsys;
use synopsys.hdl_xmr_pkg.all

above to use the signal_spy kinda thing

ncmirror I guess is an eq in cadence.

scope /E/UUT/A_BLOCK
add_wave RESET : will add a wave from A_BLOCK as the scope has been set

-gv <gen=value> -Override run time VHDL generics
 -do instead of -i : because gives more than -i
-i <run.tcl>

-gv can also be used with vcs -gv, which will help in changing all generics instead of limited as in vsim -gv

Recommendation: Always analyze verilog first

vcs -cm line : enable line coverage

IF it crashes, to clean up do the following:
rm -rf physcial_lib_dirs/*, simv*, csrc*
OPTIMISE = FALSE -- In synopsys_sim.setup

vcs -gui -debug : only show if compilation is successfull
vcs -debug_pp
vcs -debug_all
vcs -debug=1|2|3|4(level of debug)

simv -gui : preferred way of doing it. I.E first create a executable.

vcs -assert dve -Enable assertion debug
dve -vpd <filename>

run -posedge my_sig


help -ucli
help -gui


dump -file <fname> -type VPD
dump -add /tb
dump -add <list> -depth <n>
dump <signal_name>
dump -fid -VPD0 -add * -depth 0

fid is a file identifier returned by command dump -file <fname> -type VPD
 add '-aggregates'  in the dump command  for dumping multi dim arrays

vpd2vcd +morevhdl
+morevhdl will dump 'records' type as well.

//VCS coverage off
//VCS coverage on

vcs -cm <options>
simv -cm <options>

urg : unified report generator
urg -dir ./ -grade -report ./reports

VCS libraries for VHDL compilation

VHDL files are compiled into a library.
Usually the default library is 'work' which is mapped to your current working directory i.e "."

Usually you will see that this 'work' library path is changed by defining the work library in synopsys_sim.setup file

DEFAULT : ./work_lib

Then other libs may be defined in the same file i.e synopsys_sim.setup file:

memlib : ./memlib
pkg_lib : ./allcompiledpkgs
xm_bus_lib : ./xm_bus_lib

Further observation about vhdl library and vhdl compliation:

vhdlan -work work fun_pkg.vhdl
vhdlan fun_pkg.vhdl

which means that 'fun_pkg.vhdl' is complied into work_lib
when you see the contents of work_lib you will see files FUN_PKG.sim    FUN_PKG__.sim

Now I have another file called
xmbus_master.vhd which intends to use 'fun_pkg' package from the work lib
i.e the xmbus_master.vhd has the following lines

use work.fun_pkg.all

now if I compile the xmbus_master.vhd like this

vhdlan -w xm_bus_lib xmbus_master.vhd

I would expect that the complier picks up fun_pkg from work_lib. But it DOESNOT!

Which emplies that 'work' in the statemetn use work.fun_pkg.all refers to the library xm_bus_lib, to which xmbus_master.vhd is being complied into.

On the other hand if I do the following

vhdlan -w memlib fun_pkg.vhdl

Then I use the following lines in xmbus_master.vhd

library memlib;
use memlib.fun_pkg.all;

then I compile xmbus_master.vhd like

vhdlan -w xm_bus_lib xmbus_master.vhd

Then things are FINE, this time the complier picks up complied 'fun_pkg' from the memlib.

So the conclusion is:

when using 'use work.abcd.all', 'work' refers to the current compliation lib given with -w option while compliling the file
containing 'use work.abcd.all' , and NOT to the 'work_lib' which is the default compliation lib


show_setup -lib


llib -l pidf
It will show the source file, dependency files

vhdlan options:

-q : quite
-nc : supress the copyright message
-l : log file


vcs -debug_all : to enable force/line debug etc.

vcs -o <name> gives named output executable

VCS/Synopsys Code Coverage:

3 Step Process: (after vhdlan or vlogan)
Step 1: Include -cm option during vcs: This step makes sure that the selected code is complied for selected type of coverage
vcs -cm line+cond+fsm+tgl+path pid_filter_tb
vcs -cm_tgl mda -lca -cm line+cond+fsm+tgl+path -debug_all pidf_tb
vcs -lca -cm line+cond+fsm+tgl+path -debug pidf_tb -cm_tgl mda -cm_hier cm_hier.file

Step 2: Include -cm option during simulation: This Step makes sures that simulator doesnot forget to collect coverage data during simulaiton
simv -cm line+cond+fsm+tgl+path -gui

Step 3: cmView : for gui based analysis : This Step will let you see coverage results in a GUI

Step 3: vcs -cm_pp : for batch mode post processing. This step outputs report files
vcs -cm_pp -cm_report summary
This will generate human viewable reports in the directory.
it also writes a summary file in the same directory, named 'cmView.summary'

vcs -cm line|cond|fsm|tgl|path|branch|assert

Example command
vcs -cm line+cond pid_filter_tb

vcs -cm line+cond+fsm+tgl+path pid_filter_tb

adding -path gives an Error to avoid it use -lca

vcs -lca -cm path pid_filter_tb

And dont forget the -debug, in case you want to see anything : ).

vcs -lca -debug_all -cm line+cond+fsm+tgl+path pid_filter_tb

Still I have to face problems, so the final command line looked like:

vcs -cm_tgl mda -lca -cm line+cond+fsm+tgl+path -debug_all pidf_tb

Now simulaiton may be launched, again all the coverage options given at the 'vcs' compilation
MUST be given to the simv as well or there will be NO coverage recorded.
But then you cant use '-cm_tgl mda'. You see dont apply your common sense, or nothing will work.
After all vcs is developed by Synopsys not Google.

simv -cm line+cond+fsm+tgl+path -gui


-cm option creates directory

During Simulation following files are produced:
test.line and test.fsm etc.. depending upon the coverage option.

To over ride the default 'test' name you can use
vcs source.v -cm line -cm_name test1
vcs source.v -cm line -cm_name test2 ...etc
simv -cm line -cm_name test2
simv -cm line -cm_name test3 etc...

Also, during simulation, VCS and VCS MX write the cm.decl_info file
in either the directory (for Verilog) or the
db/vhdl directory (for VHDL). cmView needs this file to show
coverage information.

If you invoke your binary executable from a different location, then
use -cm_dir option at runtime to specify the the path for the
coverage database directory

By default VCS does not compile the following for coverage:
• The source code in Verilog library directories
• Verilog library files
• Any module defined under the celldefine compiler directive

For compiling for coverage source code from Verilog libraries.
For compiling for coverage modules defined under the

vcs source.v -v mylib.v -y /net/libs/teamlib -cm fsm -cm_libs yv+celldefine

To prevent this lowering of coverage percentages, use the
-cm_noconst compile-time option
Constant filtering for toggle coverage is available only for
Verilog-only designs

simv -cm fsm -cm_log run1.log

Hierarcy in the design, and inclusion/exclusion of modules/files/instances.
-tree instance_name [level_number]
A level number of 0 (or no level number) specifies the entire
subhierarchy, 1 specifies only this instance, 2 specifies this
instance and those instances directly under this instance, and so

vcs -lca -cm line+cond+fsm+tgl+path -debug pidf_tb -cm_tgl mda -cm_hier cm_hier.file

cm_hire.file contents
  line+cond+fsm+tgl+path  -file ../../pid_filter/rtl/fun_pkg.vhdl
  line+cond+fsm+tgl+path  -tree STATE_MACHINE_TB 1

Interesting observation
If I miss (all) coverage options on the command line, with this file its an error
If I miss (all) coverage options in the cm_hier.file, its an error.

Various hit and trials:
vcs -lca -cm line+cond+fsm+tgl+path -debug pidf_tb -cm_tgl mda -cm_hier cm_hier.file
simv -cm line+cond+fsm+tgl+path -gui
cm_hier file is:
  line+cond+fsm+tgl+path  -module pidf
  //The above line means exclude line, cond, fsm, tgl, path coverage from module pidf

Another example which worked
  cond+tgl+path -module pidf

I intended to exclude cond+tgl+path, and include the fsm coverage.
The above does write the fsm coverage, since fsm is not excluded from the list inside the cm_hier.file
NOTE: line coverage is always opened for modules or instances that have cond/path/fsm/branch coverage ON.

After several unsuccessfull runs to use '-tree' options, I concluded that it is 'case sensitive', even though i have a VHDL design,
and in my vhdl design pidf_tb, and pidf_u1 are lower case.
For some reason I am required to put the instance name in upper case
Following works
  fsm+line -tree PIDF_TB.PIDF_U1
BUT the following DoestNOT work.
  fsm+line -tree pidf_tb.pidf_u1

Now my objective is only to remove the top level testbench from coverage collection. For this I will have to use [level number]
  line+cond+fsm+tgl+path -tree PIDF_TB 1
 //using level number 1 will make sure only the testbench level is excluded from the coverage collection

If I dont use the [level number] in front of PIDF_TB, then by default all scopes under PIDF_TB will be excluded from coverage
This is the same as using level number 0.

PROBLEM: while trying to use the -file option
Warning-[VCM-HFUFR] Hier Config: regions not found
  In the hier config file ( given by -cm_hier option ), pattern "-file or
  specified by -filelist ---
  /projects/leota/amittal/block_design_flow_dev/pid_filter/rtl/pidf.vhd" did
  not match any pattern.
  Please check the hier config file "cm_hier.file".

Warning-[VCM-HFNM] Hier Config: No pattern match
  None of the patterns in the hier config file ( given by -cm_hier option )
  matched any pattern.
  Please check the hier config file "cm_hier.file".

I have been trying to use -file option and above is the warning message. The corresponding cm_hier.file is
Note that I have used full path for the file I wanted to exclude. This doesNOT work.
  line+cond+fsm+tgl+path -file  /projects/leota/amittal/block_design_flow_dev/pid_filter/rtl/pidf.vhd

Now if I use relative path, then vcs does not complain about the file and things go on fine: The corresponding cm_hier.file is
This Does Work.
  line+cond+fsm+tgl+path -file ../rtl/pidf.vhd

The HDL Compiler and Behavioral Compiler user can use the
//synopsys translate_off directive in place of the //VCS
coverage off pragma and the
//synopsys translate_on directive in place of the //VCS
coverage on pragma.
The //VCS coverage on pragma enables line coverage after a
//synopsys translate_off directive and a
//synopsys translate_off directive disables line coverage
after a //VCS coverage on pragma.
Similarly the //VCS coverage off pragma disables line coverage
after a //synopsys translate_on directive and a
//synopsys translate_on directive enables line coverage after
a //VCS coverage off pragma.

Pragmas do not exclude module instances. For example:
module test;
reg clk, a;
// Synopsys translate_off
mod1 inst1(a,clk);
// Synopsys translate_on
This example does not exclude test.inst1 from coverage

--synopsys coverage_off or --VCS Cover off
--synopsys coverage_on or --VCS Cover on

Glitch supression.
To prevent this, there is the -cm_glitch compile-time option. Its
syntax is as follows:
vcs -cm line+cond+tgl -cm_glitch period

The -cm_glitch option is also a runtime option, but it only works
for toggle coverage

Collecting an Execution Count
-cm_count compile-time option

Post Processing:
vcs -cm_pp -cm_report summary
The above command is used to post process the results of Code Coverage generated during simulaion.
This command produces results in directory.

Some more imp commands:
vcs -cm_pp -cm line+cond -cm_report testlists

The graphical user interface (GUI) for cmView does not display
path coverage information. You must have cmView write path
coverage reports

VCS and VCS MX do not monitor the if statement in the for loop
statement and the if statement in the user-defined task

Branch coverage is implemented for Verilog simulation only :(

By default VCS and VCS MX do not monitor for branch coverage if
and case statements and uses of the ternary operator (?:) if they
are in user-defined tasks or functions or in code that executes as a
result of a for loop. You can, however, enable branch coverage in
this code. See “For Loops and User-Defined Tasks and Functions”
on page 4

Assignment Coverage
-cm_line assigntgl compile-time option and keyword argument.
This is a Verilog-only feature. There is no similar report for VHDL

Glitch suppression does not work for VHDL code

VCS Mixed Simulation
VCS VHDL Verilog Mixed language simulation with UVM

Mixed language rules:
vcs -debug_all -ntb_opts uvm <top_module>


vlogan -debug_all -sverilog -override_timescale=1ps/1ps\

Note that the need of is essential, and so is the use of -ntb_opts uvm or you will get the following error:

Error-[DPI-DIFNF] DPI import function not found
/pkg/qct/software/dv_meth/uvm/uvm-1.1d_r2/release/src/base/uvm_resource.svh, 390
  The definition of DPI import function/task 'uvm_glob_to_re' does not exist.
  Please check the stated DPI import function/task is defined, and its
  definition is either passed in a source file at compile-time, or provided in
  a shared library specified using the LRM Annex-J options at run-time.

$finish at simulation time                    0
Error: [UCLI-018] VCS Runtime Error
The simulation is not active due to an error. Commands are not being accepted
Use "start <toolname> <cmd-line-args>" to restart tool at the ucli prompt. If problem persists, please contact a synopsys representative
Error: synopsys::finish -immediate
Error: can't read "State(status)": no such variable
Warning: [DVIT006]

VCS_OPTS += -lca -ntb -ntb_opts vera_compat -debug_pp -debug_all +notimingcheck
VCS_OPTS += $(foreach __ver,${QCMEMMODEL_VERSION},-P ${QCMEMMODEL_HOME_14lpp}/${__ver}/pli/bin/qcmemmodel_pli_$(subst .,_,${__ver}).tab ${QCMEMMODEL_HOME_14lpp}/${__ver}/pli/bin/$(if $(filter -qc_force32,${QC_OPTS} ${QC_OPTS_}),,amd64/)qcmemmodel_pli_$(subst .,_,${__ver}).so)
#for codec ends
NCELAB_OPTS += -loadvpi ${QCMEMMODEL_HOME_14lpp}/1.21/pli/bin/amd64/,VerilogModel_init_trace_1_21_register
NCELAB_OPTS += -loadvpi ${QCMEMMODEL_HOME_14lpp}/1.22/pli/bin/amd64/,VerilogModel_init_trace_1_22_register
VSIM_OPTS += $(foreach __ver,${QCMEMMODEL_VERSIONS},-pli ${QCMEMMODEL_HOME_14lpp}/${__ver}/pli/bin/$(if $(filter -qc_force32,${QC_OPTS} ${QC_OPTS_}),,amd64/)qcmemmodel_pli_$(subst .,_,${__ver}).so)