Migration EUVM to VCS Simulator

Hi All,

This is how to run EUVM testbench on VCS Simulator
VCS doesn’t support VPI between Verilog and D-language officially.
To resolve this issue, VCS simulator will call C-function and then this C-function will call VPI initialize routine made by D-language

1.Modify makefile

#!/bin/csh -f
CC = gcc
CFLAGS = -Wall -O3 -fPIC
INCLUDES = -I …/testbench/tiny_sha3

EDEBUG = NONE
DFLAGS = -relocation-model=pic -w -O3 -lowmem -release -boundscheck=off

clean:
rm -rf simv *.o *.a 64/ AN.DB/ *.log partitionlib/ simv.daidir/ vhdl_objs_dir/ work.lib++/ csrc/ *.fsdb *.so

all: comp run

run:
./simv +vpi
-sv_lib avmm_sha3 \
+warn=noFCDCI \
+vmm_log_nowarn_at_200 \
+vmm_log_nofatal_at_1000 \
+vcs+lic+wait \
+ntb_solver_array_size_warn=20000 \
+UVM_VERBOSITY=UVM_DEBUG \
+UVM_TESTNAME=avmm_sha3.random_test -l simv.log | tee simv_tee.log

comp: clean avmm_sha3.so
vcs -full64 \
-timescale=1ps/1ps \
-sverilog \
-kdb -lca \
-reportstats -l vcs.ct.log \
-debug_access+all \
+vpi \
-P test.tab \
…/src/rtl/avalon_sha3_wrapper.v \
…/testbench/avmm_sha3.v \
…/src/rtl/sha3.v \
…/src/rtl/sha3_wrapper.v

avmm_sha3.so: …/testbench/avmm_sha3.d libsha3.a
ldc2 $(DFLAGS) -shared -of$@ -L-luvm-ldc-shared -L-lesdl-ldc-shared \
-L-lphobos2-ldc-shared -L-lz3 -L-ldl $^

libsha3.a: sha3.o
ar r $@ $^

sha3.o:
$(CC) $(CFLAGS) $(INCLUDES) -c …/testbench/tiny_sha3/sha3.c -o sha3.o

When elaborate testbench and simulation, you should load .tab file and shared library
avmm_sha3.so : d shared library include c library which included sha3 c-model and c-function which can call d-function

2.Prepare .tab file.
create test.tab file
$initialize_c call=initialize_c
$avl_item_done call=vpi_item_done_calltf size=32
$avl_try_next_item call=vpi_try_next_item_calltf size=32
$avl_put call=vpi_task_calltf size=32

Explain -
$initialize_c call=initialize_c ## verilog <-> c-language : Didn’t register User VPI function, this function just use call D-function which include VPI registration functions.
Following 3 functions are User VPI functions will be registered by Vpi.initialize()
$avl_item_done call=vpi_item_done_calltf size=32
$avl_try_next_item call=vpi_try_next_item_calltf size=32
$avl_put call=vpi_task_calltf size=32

3.Modify sha3.c
To call initializeESDL(), make initialize_c function as following code.

#include “sha3.h”

extern void initialize_c(void);

void initializeESDL ();
void initialize_c(void) {
initializeESDL();
}

// update the state with given number of rounds

4.Modify avmm_sha3.d
// original code
void initializeESDL() {
Vpi.initialize();
auto test = new uvm_tb;
test.multicore(0, 4);
test.elaborate(“test”);
test.set_seed(1);
test.setVpiMode();
test.start_bg();
}
alias funcType = void function();
shared extern ( C) funcType[2] vlog_startup_routines = [&initializeESDL, null];
// modified code
// To called by C-function, declare extern ( C)
//Loading shared library case, you can’t use vlog_startup_routines, comment vlog_startup_routines

5.Modify avmm_sha3.v
// original code
initial
begin
$dumpfile(“avmm_sha3.vcd”);
$dumpvars(0, sha3_tb);
end // initial begin
// modified code
image

6.run simulation and check waveform
simulation log and waveform is as following picture
UVM_INFO uvm/base/uvm_phase.d(1939) @ 798480000: reporter [PH/TRC/EXE/ALLDROP] Phase ‘common.run’ (id=85) PHASE EXIT ALL_DROPPED
UVM_INFO uvm/base/uvm_phase.d(1958) @ 798480000: reporter [PH_READY_TO_END] Phase ‘common.run’ (id=85) PHASE READY TO END
UVM_INFO uvm/base/uvm_phase.d(1958) @ 798480000: reporter [PH_READY_TO_END] Phase ‘uvm.uvm_sched.post_shutdown’ (id=56) PHASE READY TO END
UVM_INFO uvm/seq/uvm_sequencer_base.d(460) @ 798480000: uvm_test_top.env.agent.sequencer [PHASESEQ] No default sequence to kill for phase ‘run’
UVM_INFO uvm/seq/uvm_sequencer_base.d(460) @ 798480000: uvm_test_top.env.phrase_agent.sequencer [PHASESEQ] No default sequence to kill for phase ‘run’
UVM_INFO uvm/seq/uvm_sequencer_base.d(460) @ 798480000: uvm_test_top.env.agent.sequencer [PHASESEQ] No default sequence to kill for phase ‘post_shutdown’
UVM_INFO uvm/seq/uvm_sequencer_base.d(460) @ 798480000: uvm_test_top.env.phrase_agent.sequencer [PHASESEQ] No default sequence to kill for phase ‘post_shutdown’
UVM_INFO uvm/base/uvm_report_catcher.d(749) @ 798480000: reporter [UVM/REPORT/CATCHER]
— UVM Report catcher Summary —

Number of demoted UVM_FATAL reports : 0
Number of demoted UVM_ERROR reports : 0
Number of demoted UVM_WARNING reports: 0
Number of caught UVM_FATAL reports : 0
Number of caught UVM_ERROR reports : 0
Number of caught UVM_WARNING reports : 0

UVM_INFO uvm/base/uvm_report_server.d(961) @ 798480000: reporter [UVM/REPORT/SERVER]
— UVM Report Summary —

** Report counts by severity
UVM_INFO : 569
UVM_FATAL : 0
UVM_ERROR : 0
UVM_WARNING : 0
** Report counts by id
[MATCHED] 99
[READ] 99
[UVM/RELNOTES] 1
[PH/TRC/EXE/ALLDROP] 1
[VPIREG] 3
[PRINTREQUEST] 100
[WRITE] 99
[PH_READY_TO_END] 13
[PHASESEQ] 52
[UVM/REPORT/CATCHER] 1
[RNTST] 1

[ESDL!test] Shutting down all the Routine threads
[ESDL!test] Shutting down all the active Tasks
[ESDL!test] Simulation Complete

Sending vpiFinish signal to the Verilog Simulator
$finish called from file “…/testbench/avmm_sha3.v”, line 93.
$finish at simulation time 799090000
V C S S i m u l a t i o n R e p o r t
Time: 799090000 ps

>verdi dump.fsdb &

Thanks.