2010年9月17日星期五

Makefile example

#***************************************************************************
#
# Author:      $SVF TG (auto generated)$
# File:        $Makefile$
# Revision:    $Revision:$
# Date:        $Date:$
#
#****************************************************************************/
## Variables and scripts
VIP    = ../../vips
APB    = $(VIP)/apb
APB_INC    = $(APB)/include
APB_SRC    = $(APB)/src
AXI    = $(VIP)/axi
AXI_INC    = $(AXI)/include
AXI_SRC    = $(AXI)/src
FWD    = $(VIP)/fwd
FWD_INC    = $(FWD)/include
FWD_SRC    = $(FWD)/src
MAC    = $(VIP)/mac
MAC_INC    = $(MAC)/include
MAC_SRC    = $(MAC)/src
ENV    = ../env
COMMON    = ../../common
COMMON_INC   = ../../common/include
COMMON_SRC   = ../../common/src
TEST_DIR   = .
# USER - Change this to point to your actual RTL code.
#   Also, for MTI, uncomment the vlog line in the run_mti section
#   once there is actual RTL code to run
DUT    = ../../../../../rtl
DUT_SRC    =
INC    = +incdir+$(COMMON_INC) \
      +incdir+$(COMMON_SRC) \
      +incdir+$(APB_INC) \
      +incdir+$(APB_SRC) \
      +incdir+$(AXI_INC) \
      +incdir+$(AXI_SRC) \
      +incdir+$(FWD_INC) \
      +incdir+$(FWD_SRC) \
      +incdir+$(MAC_INC) \
      +incdir+$(MAC_SRC) \
      +incdir+$(ENV) \
      +incdir+$(TEST_DIR)/basic \
      +incdir+$(TEST_DIR)/advanced \
      +incdir+$(TEST_DIR)
# If UVM_HOME is not set, then attempt to determine if it is distributed with
# the simulator.
ifeq ($(strip $(UVM_HOME)),)
  ifeq (test_mti,$(findstring test_mti,$(MAKECMDGOALS)))
    ERROR_MSG := Unable to determine UVM_HOME for Modelsim, please set UVM_HOME or MTI_HOME environment variable
    ifneq ($(strip $(MTI_HOME)),)
      UVM_HOME := /usr/proj/work/svf/nguo/uvm
      ifneq (${UVM_HOME},$(shell ls -d ${UVM_HOME} 2>&1))
        $(error $(ERROR_MSG))
      endif
    else
      $(error $(ERROR_MSG))
    endif
  endif
  ifeq (test_ius,$(findstring test_ius,$(MAKECMDGOALS)))
    ERROR_MSG := Unable to determine UVM_HOME for IUS, please set UVM_HOME environment variable
    NCROOT    := $(shell ncroot)
    UVM_HOME  := $(NCROOT)/tools/uvm
    ifneq (${UVM_HOME},$(shell ls -d ${UVM_HOME} 2>&1))
      $(error $(ERROR_MSG))
    endif
  endif
endif
ifneq ($(strip $(UVM_HOME)),)
UVM               = $(UVM_HOME)
else
UVM               = "<UVM_HOME UNDEFINED>"
endif
UVM_SRC_DIR   = $(UVM)/src
UVM_SRC       = $(UVM_SRC_DIR)/uvm_pkg.sv
UVM_MACRO_SRC = $(UVM_SRC_DIR)/uvm_macros.svh
UVM_VERSION   = "1_0"
ifneq ($(strip $(USE_SV_PACKAGE)),)
USE_SV_PACKAGE = 1
PKG_OPT     =   +define+USE_SV_PACKAGE
PKG_LIST    =   $(UVM_SRC) \
                $(COMMON_INC)/common_pkg.sv \
             $(APB_INC)/apb_pkg.sv \
             $(AXI_INC)/axi_pkg.sv \
             $(FWD_INC)/fwd_pkg.sv \
             $(MAC_INC)/mac_pkg.sv \
                $(ENV)/txd_pkg.sv
IUS_OPT     =
else
PKG_OPT     =
PKG_LIST    =
IUS_OPT     = $(UVM)/src/uvm.svh $(UVM_MACROS_SRC)
endif
TESTNAME          = test_example
SEED              = 1
TB_FILENAME       = $(ENV)/txd_tb_top.sv
VERBOSITY         = UVM_FULL
IUS_OPTIONS    =  \
      $(IUS_OPT) \
      +svseed=$(SEED) \
      +incdir+$(UVM_SRC_DIR) \
             $(INC) \
             -nowarn IGNFMT \
             +UVM_TESTNAME=$(TESTNAME) \
             +UVM_MSG_DETAIL=$(VERBOSITY) \
             $(PKG_OPT) \
             $(PKG_LIST) \
      +incdir+$(DUT) $(DUT_SRC) \
             $(TB_FILENAME)
VCS_OPTIONS   = -q +warn=noISALS \
  -sverilog \
  -timescale=1ns/100ps \
  $(INC) \
  +incdir+$(UVM_SRC_DIR) \
  +incdir+$(DUT) $(DUT_SRC) \
  $(COMPILE_OPT) \
  -Mdir=./csrc \
  -o simv \
                -Mupdate \
                -debug_pp \
         +libext+.sv+.v+.vh+.vmd+.vo+.bv+.lmcds \
                +v2k \
                +define+UVM_VERSION_STRING=$(UVM_VERSION) \
         +error+100 +lint=TMR
VCS_RUN_OPTIONS = +wc \
                  +notimingchecks \
                  +ntb_random_seed=$(SEED) \
           +UVM_TESTNAME=$(TESTNAME) \
    +UVM_MSG_DETAIL=$(VERBOSITY)

#******************************************************************************#
# Targets
#******************************************************************************#
help :
 @echo " ----------------------------------------------------------------";
 @echo "|             PW TEMPLATE GENERATOR EXAMPLE MAKEFILE             |";
 @echo " ----------------------------------------------------------------";
 @echo "|                                                                |";
 @echo "| Usage:                                                         |";
 @echo "|                                                                |";
 @echo "| make <target> [ TESTNAME=<testname> SEED=<num> USE_SV_PACKAGE  |";
 @echo "|               VERBOSITY=<verbosity_level> OPT=<user options> ] |";
 @echo "|                                                                |";
 @echo "| Mandatory Arguments:                                           |";
 @echo "| Available targets                                              |";
 @echo "|   test_ius    : Execute a test using cadence simulator.        |";
 @echo "|   test_mti    : Execute a test using mentor simulator.         |";
 @echo "|   test_vcs    : Execute a test using synopsys simulator.       |";
 @echo "|   clean       : Remove simulation files and directories.       |";
 @echo "|                                                                |";
 @echo "| Optional Arguments:                                            |";
 @echo "| To compile using SystemVerilog Packages use the following:     |";
 @echo "|  USE_SV_PACKAGE=1                                              |"
 @echo "|                                                                |";
 @echo "| Available verbosity_level for VERBOSITY                        |";
 @echo "|  UVM_NONE, UVM_LOW, UVM_MEDIUM, UVM_HIGH, UVM_FULL, or integer |";
 @echo "|  default is UVM_FULL                                           |";
 @echo "|                                                                |";
 @echo " ----------------------------------------------------------------";
test_ius   : clean run_ius check_test_ius
test_mti : clean run_mti check_test_mti
test_vcs : clean run_vcs check_test_vcs
clean:
 -rm -rf *.log *.df waves.shm INCA_libs *~ assertion_summary *.trn *.vcd simvision verilog.dump waves.shm irun.key irun.log* work transcript svp_work vsim.wlf csrc simv simv.daidir simv.vdb
run_ius :
 @echo "PKG LIST =  $(PKG_LIST)"
 @echo "USE_SV_PACKAGE =  $(USE_SV_PACKAGE)"
 irun $(IUS_OPTIONS) $(OPT)
run_mti:
 rm -rf work
 @echo "PKG LIST =  $(PKG_LIST)"
 @echo "USE_SV_PACKAGE =  $(USE_SV_PACKAGE)"
 vlib work
# vlog +incdir+$(DUT) $(DUT_SRC)
 vlog +incdir+$(UVM_SRC_DIR) \
        $(INC) \
        $(PKG_OPT) \
        $(PKG_LIST) \
 $(ENV)/txd_tb_top.sv
 vsim -do vsim.do -c -suppress 3829 -sv_seed $(SEED) +UVM_TESTNAME=$(TESTNAME) +UVM_MSG_DETAIL=$(VERBOSITY) $(OPT) txd_tb_top
run_vcs :
 @echo "PKG LIST =  $(PKG_LIST)"
 @echo "USE_SV_PACKAGE =  $(USE_SV_PACKAGE)"
 vcs +vcs+lic+wait $(VCS_OPTIONS) $(COMPILE_OPT) $(OPT) -l $(TESTNAME).log $(TB_FILENAME)
 ./simv $(VCS_RUN_OPTIONS) $(OPT) $(PKG_OPT) $(PKG_LIST) -l vrun.log
check_test_ius:
 @if test -f irun.log; then \
 if ( (grep "ERR" irun.log|grep -v "0">/dev/null) || (grep "WARN" irun.log|grep -v "0">/dev/null) || (grep "FATAL" irun.log|grep -v "0">/dev/null) ); then \
 echo "TEST FAILED - check irun.log file for details."; \
 else \
 echo "TEST PASSED";\
 fi; \
 else \
 echo "TEST FAILED - logfile irun.log does not exist."; \
 exit -1; \
 fi; \
 if test -f INCA_libs/svpplib/assertion_summary; then \
 mv INCA_libs/svpplib/assertion_summary .; \
 fi
check_test_mti:
 @if test -f transcript; then \
 if ( (grep "ERR" transcript|grep -v "0">/dev/null) || (grep "WARN" transcript|grep -v "0">/dev/null) || (grep "FATAL" transcript|grep -v "0">/dev/null) ); then \
 echo "TEST FAILED - check transcript file for details."; \
 else \
 echo "TEST PASSED";\
 fi; \
 else \
 echo "TEST FAILED - logfile transcript does not exist."; \
 exit -1; \
 fi;
check_test_vcs:
 @if test -f vrun.log; then \
 if ( (grep "ERR" vrun.log|grep -q "1") || (grep "WARN" vrun.log|grep -q "1") || (grep "FATAL" vrun.log|grep -q "1") ); then \
 echo "TEST FAILED - check vrun.log file for details."; \
 else \
 echo "TEST PASSED";\
 fi; \
 else \
 echo "TEST FAILED - logfile vrun.log does not exist."; \
 exit -1; \
 fi;

2010年9月13日星期一

enable 'emacs verilog mode autos' for gvim

1,enable auto filetype detection

"~/.vim/filetype.vim
au BufNewFile,BufRead *.v,*.vh setf verilog
au BufNewFile,BufRead *.sv,*.svh setf verilog_systemverilog

download
"~/.vim/syntax/verilg_systemverilog.vim
"verilog.vim could be found at VIM's install path

"~/.vimrc
syntax on

2,download
~/elisp/verilog-mode.el

3, download
~/.vim/ftplugin/verilog_emacsauto.vim
~/.vim/ftplugin/verilog_systemverilog_emacsauto.vim " make a copy for sv
*modify the keymap if you want

4,
"~/.vimrc
filetype plugin indent on

5, you are ready to use the autos in both .v and .sv
put ./module_a.v ./module_b.v
edit ./tb_top.v:
module tb_top;
module_a u_a(/*AUTOINST*/
);
module_b u_b(/*AUTOINST*/
);
endmodule

*use keymap Ctrl-A to extract /*AUTOINST*/ and Ctrl-D to delete

2010年9月10日星期五

SystemVerilog - connect multiple clients by interface modport

// Bus interface with parameterized number of client modports
interface intf_t #(num_clients = 0);
bit [num_clients-1:0] req;

// Similar with the 'generate statement' in Verilog
// The instance name will be mps[i].client_mp
for (genvar i=0; i++) begin: mps
modport client_mp (output .client_req( req[i] ));
end
endinterface

// A generic client that attaches to the bus
module client_m (interface client_ifc);
// ... code will drive client_ifc.client_req
endmodule

// The bus system with N clients
module bus #(N = 0);
intf_t #(.num_clients(N)) intf();
// Similar with the 'generate statement' in Verilog
// Similarly, the instance names will be clients[n].client
for (genvar j=0; j++) begin: clients
client_m client (.client_ifc (intf.mps[j].client_mp));
end

endmodule

**This feature is NOT yet supported by NCVLOG

2010年9月9日星期四

another example of .vimrc

Sample .vimrc
When vim is run by default it will look for a vimrc file that contains configuration info and scripts that it can use while it is running. The file can also be found here.

"
" .vimrc
"
" Vim configuration resource file. Specifies desired
" behavior for the vim editor.
"
:set showmode " Tell you if you're in insert mode
:set tabstop=4 " Set the tabstop to 4 spaces
:set shiftwidth=4 " Shiftwidth should match tabstop
:set expandtab " Convert tabs to number of spaces
:set nowrap " Do not wrap lines longer than the window
:set wrapscan " Wrap to the top of the file while searching
:set ruler " Show the cursor position all the time
:set showmatch " Show matching [] () {} etc...
:set smartindent " Let vim help you with your code indention
:set formatoptions+=ro " Automatically insert the comment character when
" you hit (r) or o/O (o) in a block comment.
:set backspace=2 " makes backspace work like you expect
:set nohlsearch " Don't highlight strings you're searching for
:set incsearch " Do highlight as you type your search
:set ignorecase " makes searches case-insensitive

" Disable paren highlighting
"let loaded_matchparen = 1

" Switch syntax highlighting on, when the terminal can support colors
" if # of terminal colors > 2 OR you're using Gvim
if &t_Co > 2 has("gui_running")
:syntax on
" Change the highlight color for Comment and Special
" to Cyan. Blue is too dark for a black background.
:highlight Comment term=bold ctermfg=cyan guifg=cyan
:highlight Special term=bold ctermfg=cyan guifg=cyan
:highlight Constant term=bold ctermfg=red guifg=cyan
endif

" Make vim turn *off* expandtab for files named Makefile or makefile
" We need the tab literal
:autocmd BufNewFile,BufRead [Mm]akefile* set noexpandtab

" Make vim recognize a file ending in ".template" be a C++ source file
:autocmd BufNewFile,BufRead *.template set ft=cpp

" Make vim tab 2 spaces for HTML files
:autocmd BufNewFile,BufRead *.htm* set tabstop=2
:autocmd BufNewFile,BufRead *.htm* set shiftwidth=2
" Make vin tab 2 spaces for PHP files
:autocmd BufNewFile,BufRead *.php set tabstop=2
:autocmd BufNewFile,BufRead *.php set shiftwidth=2

" Make vim recognize Y86 assembly files
:autocmd BufNewFile,BufRead *.ys set ft=asm
:autocmd BufNewFile,BufRead *.ys set nosmartindent

" Make vim recognize R files
:autocmd BufNewFile,BufRead *.[Rr] set ft=r

" Make vim recognize Prolog files
:autocmd BufNewFile,BufRead *.pl set ft=prolog
" Turn off paren matching for Prolog files
:autocmd BufNewFile,BufRead *.pl NoMatchParen

" Adds main program heading from Program Style Guidelines
function FileHeading()
let s:line=line(".")
call setline( s:line,"// Program: ")
call append( s:line,"// Author: Derrick")
call append(s:line+1,"// Date: ".strftime("%b %d %Y"))
call append(s:line+2,"// Assignment: ")
call append(s:line+3,"// Purpose: ")
call append(s:line+4,"// ")
call append(s:line+5,"// Input: ")
call append(s:line+6,"// Output: ")
call append(s:line+7,"// Related")
call append(s:line+8,"// Files: ")
call append(s:line+9,"// Functions: ")
call append(s:line+10,"// ")
call append(s:line+11,"")
unlet s:line
endfunction

" Adds class heading from Program Style Guidelines
function ClassHeading()
let s:line=line(".")
call setline( s:line,"// Program Name: ")
call append( s:line,"// Author: Derrick")
call append(s:line+1,"// Date: ".strftime("%b %d %Y"))
call append(s:line+2,"// Assignment: ")
call append(s:line+3,"// Purpose: ")
call append(s:line+4,"// ")
call append(s:line+5,"// Public class variables")
call append(s:line+6,"// ")
call append(s:line+7,"// Public functions:")
call append(s:line+8,"// ")
call append(s:line+9,"// Related files:")
call append(s:line+10,"// ")
call append(s:line+11,"")
unlet s:line
endfunction

" Adds function heading from Program Style Guidelines
function FunctionHeading()
let s:line=line(".")
call setline( s:line,"//****************************************************************************")
call append( s:line,"// Function name: ")
call append(s:line+1,"// Author: Derrick")
call append(s:line+2,"// Date: ".strftime("%b %d %Y"))
call append(s:line+3,"// Purpose: ")
call append(s:line+4,"// Params: ")
call append(s:line+5,"// ")
call append(s:line+6,"// Returns: ")
call append(s:line+7,"//****************************************************************************")
unlet s:line
endfunction

" Adds HTML skeleton to file
function HTMLFrame()
let s:line=line(".")
call setline( s:line,"")
call append( s:line," ")
call append(s:line+1," ")
call append(s:line+2," ")
call append(s:line+3," ")
call append(s:line+4," ")
call append(s:line+5," ")
call append(s:line+6,"")
unlet s:line
endfunction

" Adds Unix shebang line to beginning of
" any new Ruby script
function RubyFile()
let s:line=line(".")
call setline( s:line,"#!/usr/bin/env ruby")
call append( s:line,"")
unlet s:line
endfunction

" If opening new file with these file extentions
" then execute corresponding functions
:autocmd BufNewFile *.C,*.c execute FileHeading()
:autocmd BufNewFile *.h execute ClassHeading()
:autocmd BufNewFile *.htm* execute HTMLFrame()
:autocmd BufNewFile *.php execute HTMLFrame()
:autocmd BufNewFile *.rb execute RubyFile()

" Map keys to perform series of key strokes and functions
" Ex, If F2 is pressed then execute FileHeading function,
" and move cursor to first line of comments
imap mz:execute FileHeading()`zA
imap mz:execute FunctionHeading()'zjA
imap mz:execute ClassHeading()'zA

2010年9月7日星期二

env_set.sh

#!/bin/ksh
#******************************************************************************#
# #
# Copyright (c) 2007 Cadence Design Systems, Inc. #
# #
#******************************************************************************#
# #
# PCE Makefile #
# #
#******************************************************************************#

## Variables and scripts
export DUT_IC_NAME=txd
export DUT_TOP=txd
export MGW_HOME=${PROJ_HOME}
export DUT_IC_HOME=${PROJ_HOME}/chip/ppb/gige/txd
export E_COMPILE_TOP_DIR=${PROJ_HOME}/chip/ppb/gige/txd/sim/specman/e
export E_STUB_DIR=${PROJ_HOME}/chip/ppb/gige/txd/sim/specman/config
export E_COMPILE_TOP=txd_compile_top
export E_TOP_DIR=${DUT_IC_HOME}/sim/specman/config
export E_TOP=txd_common_config
export E_STUB=txd_common_config
export TB_SIM_RUN=${DUT_IC_HOME}/sim/run

#Specman Path
export SPECMAN_PATH=${DUT_IC_HOME}/sim/specman/e:${DUT_IC_HOME}/sim/specman/config:${PROJ_HOME}/evc_lib:${PROJ_HOME}/chip/ppb/evc_lib:${PROJ_HOME}/chip/ppb/gige/txd/evc_lib:$VERDI_HOME/share/PLI/specman:${VERDI_HOME}/share/PLI/nc61:${DUT_IC_HOME}/sim/run

export VRST_APPLICATION_HOME=/tools/sn-6.20.001/components/sn_06.20.001-p
export SPECMAN_NCVLOG_ADAPTER="$VRST_APPLICATION_HOME/linux64/libncvlog_sn_adapter.so"

export INCDIR_PATH=" -incdir ${SYNOPSYS}/packages/gtech/src_ver -incdir ${SYNOPSYS}/dw/sim_ver -incdir ${SYNOPSYS}/dw/dw03/src_ver -incdir ${DUT_IC_HOME}/txd_tb/hdl -incdir ${DUT_IC_HOME}/hdl "


export RTL_TOP_FILE="-F ${DUT_IC_HOME}/hdl/txd.f"
export TB_TOP_FILE="${RTL_TOP_FILE} \
-F ${DUT_IC_HOME}/txd_tb/hdl/txd_tb.f"

export FILES_TO_FETCH="${DUT_IC_HOME}/cad/lib/.specman ${PROJ_HOME}/chip/ppb/cad/lib/mt47h128m16_5e.soma ${PROJ_HOME}/chip/ppb/cad/lib/mt47h64m16_37e.spc"

if [[ -e Makefile ]];
then
rm Makefile
fi
ln -fs ${PROJ_HOME}/scripts/Makefile .

# Move Specman-pre_commands for use by irun -snprerun option
SPECMAN_PRE_COMMANDS="config cover -write_model=ucm; config cover -database_format=ucd; set_config(memory, max_size, 800M, absolute_max_size, 900M);set notify -severity=WARNING DEPR_PACKAGE_TYPE_IN_FIELD;set notify -severity=WARNING DEPR_*;set_config(simulation,enable_ports_unification,TRUE);"; export SPECMAN_PRE_COMMANDS
echo $SPECMAN_PRE_COMMANDS > ./sn_pre_run.ecom

2010年9月6日星期一

Interface connection -- SV

1.1 Interface Connection

1.1.1 DUT I/O Interfafce Connection
DUT I/O interfaces need to be connected to the virtual interfaces in the testbench components. This is normally achieved with the following steps:
1. Declare interfaces in the top module where DUT is instantiated
2. Connect the interfaces to DUT interfaces when instantiating the DUT
3. Assign the interfaces to the virtual interfaces in testbench components

The step1 and 2 are very straightforward. Below we talk about the step 3.
As mentioned in “5.2.7 Virtual Interface Assignment”, we would like to separate the DUT hierarchy from the testbench hierarchy. In other words, we should be able to instantiate a VIP and connect it to the design interface within different design hierarchy with the same virtual interface setting method. This can be achieved by using the uvm_config_prop_pkg described in the book “A Practical Guide to Adopting the Universal Verification Methodology (UVM)”[Page 107].
The following utility is the uvm_config_prob_pkg:
1. package uvm_config_prop_pkg;
2. import uvm_pkg::*;
3. class uvm_config_prop #(type T=int) extends uvm_object;
4. T value;
5. function new(T value);
6. this.value = value;
7. endfunction
8.
9. static function void set_config(string target,
10. string field,
11. T value,
12. uvm_component cntxt=null);
13. uvm_config_prop#(T) wrapper = new(value);
14. if(cntxt == null) cntxt = uvm_root::get();
15. cntxt.set_config_object(target, field, wrapper, 0);
16. endfunction: set_config

17. static function bit get_config(uvm_component cntxt,
18. string field,
19. output T value);
20. uvm_config_prop#(T) wrapper;
21. uvm_object obj;
22. if(cntxt == null) cntxt = uvm_root::get();
23. if(!cntxt.get_config_ojbect(field, obj, 0)) return 0;
24. if(!$cast(wrapper, obj)) return 0;
25. value = wrapper.value;
26. return 1;
27. endfunction

28. static function bit get_config_object(uvm_component cntxt,
29. string field,
30. inout T value, bit clone=0);
31. uvm_object obj;
32. T tmp;
33. if(cntxt == null) cntxt = uvm_root::get();
34. if(!cntxt.get_config_ojbect(field, obj, clone)) return 0;
35. if(!$cast(tmp, obj)) return 0;
36. value = tmp;
37. return 1;
38. endfunction
39. endclass
40. endpackage

Line 3: Wrapper class for configuring a single standalone object. The object can be any type that can be passed as an input to and output from a function. This allows things like virtual interfaces, dynamic arrays, and so on to be used as configuration properties. The setter and the getter must agree on the type being passed, and the type must match exactly. There are two static functions.
Line 9: The set_config() function has the same signature as the various set_config_* functions (an option context is available if the method is being used from inside of a component context). This is needed to enable a higher level component to override a sub-component settings.
Line 17: The get_config() function has a similar signature to the get_config_* functions, but requires that a context e provided. The context is the component fetching the value from the configuration table.
Line 28: The wrapper also provides a simplified get_config_object interface so that the user doesn’t have to recreate a temporary object and do a cast in order to get a configuration object.
The following code shows the usage of the uvm_config_prop_pkg in the X_DUT VIP:
1. class x_dut_apb_vif_bdl extends uvm_object;
2. virtual apb_if apb_vif;
3. virtual p_bus_if p_bus_vif;
4. endclass

5. class x_dut_ahb_vif_bdl extends uvm_object;
6. virtual ahb_if ahb_vif;
7. virtual h_bus_if h_bus_vif;
8. endclass

9. class x_dut_axi_vif_bdl extends uvm_object;
10. virtual axi_if axb_vif;
11. virtual x_bus_if x_bus_vif;
12. endclass

// Bundle class that holds all the virtual interfaces
// for x_dut I/O ports
13. class x_dut_io_vif_bdl extends uvm_object;
14. virtual apb_if apb_vif;
15. virtual p_bus_if p_bus_vif;

16. virtual ahb_if ahb_vif;
17. virtual h_bus_if h_bus_vif;

18. virtual axi_if axb_vif;
19. virtual x_bus_if x_bus_vif;
20. endclass

21. module x_dut_tb_top; // X_DUT Testbench Top Module
22. import uvm_config_prop_pkg::*;
23. …
24. apb_if apb_if0(p_clock, reset); // interfafce instance
25. p_bus_if p_bus_if0;

26. ahb_if ahb_if0(h_clock, reset);
27. h_bus_if h_bus_if0;

28. axi_if axi_if0(x_clock, reset);
29. x_bus_if x_bus_if0;

30. x_dut_io_vif_bdl io_vif_bdl

31. X_DUT u_x_dut ( … );// assign interfaces to DUT IO

32. …
33. initial begin
// assign interfaces to the vif bundle object
34. io_vif_bdl = new();

35. io_vif_bdl.apb_if0 = apb_if0;
36. io_vif_bdl.p_bus_if0 = p_bus_if0;

37. io_vif_bdl.ahb_if0 = ahb_if0;
38. io_vif_bdl.h_bus_if0 = h_bus_if0;

39. io_vif_bdl.axi_if0 = axb_if0;
40. io_vif_bdl.x_bus_if0 = x_bus_if0;

// set_config the vif bundle object to x_dut_env
41. uvm_config_prop#(x_dut_io_intf_bdl)::
set_config(“uvm_test_top.x_dut_tb.x_dut_env”, “x_dut_io_vif_bdl”, io_vif_bdl);

42. end

43. initial begin
44. #1 run_test();
45. end
46. endmodule: x_dut_tb_top


47. // x_dut_env: build() method
48. function void x_dut_env::build();
49. super.build();
50. void`(uvm_config_prop #(x_dut_io_vif_bdl)::get_config(this,”x_dut_io_vif_bdl”, io_vif_bdl));
51. // Call get_config() to unwrap the container, and assign the
52. // io_vif_bdl in x_dut_tb_top to the io_vif_bdl in x_dut_env.

53. // allocate virtual interfaces to sub-boundles.
54. apb_vif_bdl.apb_vif = io_vif_bdl.apb_vif;
55. apb_vif_bdl.p_bus_vif = io_vif_bdl.p_bus_vif;

56. ahb_vif_bdl.ahb_vif = io_vif_bdl.ahb_vif;
57. ahb_vif_bdl.h_bus_vif = io_vif_bdl.h_bus_vif;

58. axi_vif_bdl.axi_vif = io_vif_bdl.axi_vif;
59. axi_vif_bdl.x_bus_vif = io_vif_bdl.x_bus_vif;


60. if(io_vif_bdl != null)begin
61. uvm_config_prop #(apb_vif_bdl)::set_config(“apb_agent”,”apb_vif_bdl”, apb_vif_bdl, this);
62. // This static function call creates a wrapper class and
63. // set_config that class to
64. // uvm_test_top.x_dut_tb.x_dut_env.apb_agent.

65. uvm_config_prop #(ahb_vif_bdl)::set_config(“ahb_agent”,”ahb_vif_bdl”, ahb_vif_bdl, this);
66. uvm_config_prop #(axi_vif_bdl)::set_config(“axi_agent”,”axi_vif_bdl”, axi_vif_bdl, this);
67. end
68. endfunction: build

69. // x_dut_env: run() task (OPTIONAL)
70. function void x_dut_env::run();
71. if(io_vif_bdl == null) `uvm_fatal (“NOVIF”, “Virtual interfaces have not been set!”)
72. endtask: run


73. // apb_agent: build() method
74. function void apb_master_agent::build();
75. super.build();
76. void`(uvm_config_prop #(apb_vif_bdl)::get_config(this, “apb_vif_bdl”, apb_vif_bdl));
77. // Call get_config() to unwrap the container, and assign the
78. // apb_vif_bdl to the apb_vif_bdl in x_dut_env.apb_agent.


79. if(apb_vif_bdl != null)
80. uvm_config_prop #(virtual apb_if)::set_config(“apb_drv”, “apb_vif”, apb_vif_bdl.apb_vif, this);
81. // This static function call creates a wrapper class and
82. // set_config that class to
83. // uvm_test_top.x_dut_tb.x_dut_env.apb_agent.apb_drv.

84. …
85. endfunction: build

86. // apb_drv: build() method
87. function void apb_master_driver::build();
88. super.build();
89. void`(uvm_config_prop #(virtual apb_if)::get_config(this, “apb_vif”, apb_vif));
90. // Call get_config() to unwrap the container, and assign the
91. // apb_vif to the apb_vif in x_dut_env.apb_agent.apb_drv.

92. endfunction: build

93. // ahb_agent: build() method
94. function void ahb_master_agent::build();
95. super.build();
96. void`(uvm_config_prop #(ahb_vif_bdl)::get_config(this, “ahb_vif_bdl”, ahb_vif_bdl));
97. if(ahb_vif_bdl != null)
98. uvm_config_prop #(virtual ahb_if)::set_config(“ahb_drv”, “ahb_vif”, ahb_vif_bdl.ahb_vif, this);
99. …
100. endfunction: build

101. // ahb_drv: build() method
102. function void ahb_master_driver::build();
103. super.build();
104. void`(uvm_config_prop #(virtual ahb_if)::get_config(this, “ahb_vif”, ahb_vif));
105. endfunction: build

106. // axi_agent
107. …
108. // axi_drv
109. …


1.1.2 DUT Internal Interface Connection

When a VIP is reused at different hierarchical environment, especially when integrating a module VIP into a subsystem or chip level environment, we expect the signal connection to the DUT internal singal can be done by simply prepending HDL path to signal names instead of rewriting all the signal connection code.
As for signal connection between VIP and DUT’s in/out ports, we would not do this because we should check the signal connection in a “higher level DUT” by reconnecting the VIP’s interface signal to the internal signals in this “higher level DUT”. This is to make sure the DUT’s in/out ports are connected correctly when instantiated.

Let’s consider the following example:

Module PCE is the DUT. It has an internal interface pce_intf_c, which is defined as follows (in PCE block level verification environment):

interface pce_intf_c(input bit clk);
logic sig0;
logic sig1;

clocking aclk @(posedge clk);
output sig0;
input sig1;
endclocking: aclk

clocking pclk @(posedge clk);
output sig0;
input sig1;
endclocking: pclk

modport drv(clocking aclk);
modport mon(clocking pclk);

endinterface: pce_intf_c



Figure 7 Block Level Interface Signal Connection

Figure 7 shows the PCE verification environment. The top module is pce_tb_top, which instances DUT PCE (as u_pce) and interface pce_intf_c .
First we need to connect this interface instance to u_pce’s internal interface pce_intf_c.
Then connect this interface instance to the virtual interface pce_vif_c in the module level VIP pce_env(uvm_env) instanced in pce_tb(uvm_env).
We use the following macro to do the first step connection:
// For each internal interface, define a *_conn macro
`define pce_intf_c_conn(intf_name, hdl_path) \
pce_intf_c intf_name(hdl_path.clk) ; \
assign intf_name.sig0 = hdl_path.sig0; \
assign intf_name.sig1 = hdl_path.sig1;

// Provide a single macro that contains all internal interface
// connection macros.
`define pce_intf_conn(module_name, hdl_path) \
`pce_intf_c_conn( module_name``_intf_c, hdl_path)
// other types of PCE internal interface connect

The above macro are used in pce_tb_top as follows:
module pce_tb_top();
logic intfa_in, intfa_out, intfb_in, intfb_out;
logic clk;
pce_intf_c pce_intf_c_inst(clk);
…….
PCE u_pce(…);

`pce_intf_conn( pce , u_pce )
// at this point, we have u_pce’s internal interface pce_intf_c
// is connected to interface instance “pce_intf_c

endmodule

Now suppose we have Module DBM as the DUT, and it instances two PCEs: u_pce0 and u_pce1. Figure 8 shows the top module (dbm_tb_top) of DBM level verification environment. dbm_tb(uvm_env) has two pce_env(uvm_env) instances.

Figure 8 Interface Signal Connection when Block is Integrated into a Higher Level

We need to connect the two pce_intf_c instances in dbm_tb_top module to the pce_intf_c interface in each u_pce. We would like to reuse the PCE interface signal connection definition in PCE verification environment. Below is the interface signal connection macro at DBM level and how the macro is used in dbm_tb_top module:

`define dbm_intf_conn(module_name, hdl_path) \
`pce_intf_conn(module_name``_pce0, hdl_path.u_pce0) \
`pce_intf_conn(module_name``_pce1, hdl_path.u_pce1) \
// other dbm level internal interface definition

module dbm_tb_top();
// signal definitions

// interfaces
pce_intf_c dbm_pce0_intf_c, dbm_pce1_intf_c;


DBM u_dbm(…);

`dbm_intf_conn(dbm, u_dbm)
// other dbm external interface definition
// dbm external interface connection

// at this point, we have u_dbm.u_pce0’s pce_intf_c connected
// to interface instance “dbm_pce0_intf_c”, and u_dbm.u_pce1’s
// pce_intf_c connected to interface instance “dbm_pce1_intf_c”.
// “dbm_pce0_intf_c” and “dbm_pce1_intf_c” can be passed
// (as virtual interface parameters) to pce_env0 and pce_env1
// respectively

endmodule

With the interface instanced in the testbench top module connected to DUT internal signals, next we will need to connect/assign the interface to the virtual interface inside the env. In the above DBM example, we have two interfaces (dbm_pce0_intf_c and dbm_pce1_intf_c) need to be passed down to dbm_env and further down to pce_env0 and pce_env1 respectively.
But, suppose we have a large number of interfaces at DBM level need to be connected to the virtual interfaces in dbm_env, we may pass these interfaces as virtual interface parameters to dbm_env. OR, we can define a virtual interface bundle class first, assign those interfaces at dbm_tb_top to the virtual interface bundle object first, then pass the virtual interface bundle object as parameters to dbm_env using set_config/get_config approach, which is similar to what described in “6.10.1 DUT I/O Interfafce Connection”.
In PCE block level environment, suppose we need to pass down virtual interfaces to monitor and driver respectively. We define the following class to include all pce_env required virtual interface.
class pce_vif_bundle;
virtual pce_intf_c.mon pce_vif_c_mon;
virtual pce_intf_c.drv pce_vif_c_drv;
virtual pce_intf_b.mon pce_vif_b_mon;
virtual pce_intf_b.drv pce_vif_b_drv;
endclass


In the DBM level where PCE is instanced twice. Suppose pce_intf_a is the PCE external interface and is internal to DBM. In addition to pce_intf_a at DBM level, we need to include the PCE internal interface pce_intf_c in the DBM level interface bundle class. Here we list all the interface and/or bundles required for DBM env in dbm_vif_bundle class:
class dbm_vif_bundle;
virtual pce_intf_a.mon dbm_pce0_intfa_mon;
virtual pce_intf_a.mon dbm_pce1_intfa_mon;

pce_vif_bundle pce0_vif_bdl;
pce_vif_bundle pce1_vif_bdl;

function new();
pce0_vif_bdl = new();
pce1_vif_bdl = new();
endfunction
endclass

When dbm_env get_config the virtual interface bundle object, it assigns the PCE internal virtual interface bundle and set_config it to pce_env0 and pce_env1.