Monday, July 15, 2019

UVM Notes

This article is to list down the most used constructions of UVM to my personal understanding.

UVM simulator steps

  • VCS(Synopsys)
  • IUS(Cadence)
  • Questa(Mentor)
1. set $UVMHOME to instal dir of required UVM library
2. Use irun option -uvmhome to reference $UVMHOME
3. Use incdir to reference any included file directories
%irun -f run.f

run.f:
-uvmhome $UVMHOME
-incdir .../sv
.../sv/tb_pkg.sv
top.sv

top.sv:
module top();
    import uvm_pkg::*;
    import tb_pkg::*;
    initial begin
        //run test
        ...
    end
endmodule: top

Debugging case: 
when using 3 step compile on vcs, vlogan and elab must both add uvm_dpi.cc to actually compile the c. add the file in file list does not work. 
if using 1 step compile, then just need to include the file in filelist. 


UVM Directory Structure

contains two kinds of code:

UVM_ROOT UVM_TOP

Tips: (1) debug features
uvm_top.print_topology();  //advised to be called from end_of_elaboration_phase

=======================================
If you look into the uvm source code, run_test() task is actually a task defined in the class uvm_root. it's the implicit top-level and phase controller for all UVM components. the UVM automatically creates a single instance of <uvm_root> that users can access via the global (uvm_pkg-scope) variable uvm_top. 
  • long time confusion solved: the run_test() called in top tb module is defined in uvm_globals.svh which actually calls the run_test() in uvm_root.
  • uvm_test_top is not a variable in uvm_root, how can you access that with uvm_root?
  • class uvm_root extends uvm_component
  • const uvm_root uvm_top = uvm_root::get();
  • uvm_top is the top-level component, and any component whose parent is specified as NULL becomes a child of uvm_top.
  • uvm top manages the phasing for all components.
  • set globally the report verbosity, log files, and actions(?).
  • Because uvm_top is globally accessible (in uvm_pkg scope(?)), UVM's reporting mechanism is accessible from anywhere outside uvm_component, such as in modules and sequences.

UVM Configuration

1) uvm_config_db

  • uvm_config_db#(int)::set(this, "env.agent", "is_active", UVM_PASSIVE);
  • uvm_config_db#(int)::set(null, "uvm_test_top.env.agent", "is_active", UVM_PASSIVE);
  • uvm_config_db#(int)::set(uvm_root::get(), "uvm_test_top.env.agent", "is_active", UVM_PASSIVE);//equivalent to using null
  • uvm_config_db#(int)::set(null, "*.env.agent", "is_active", UVM_PASSIVE);
  • uvm_config_db#(int)::set(null, "uvm_test_top.env*", "is_active", UVM_PASSIVE);
  • Database must be type parameterized. this allows config db to be created for any standard or user-defined type; and allows better compile time checking.
  • Methods are static
  • Methods use a specific contxt argument, whi is usually this; unless the set is called from the top module, in which case it must be assigned to null
  • syntax: static function void set(uvm_component cntxt, string inst_name, string field_name, ref T value)
  • syntax: static function void get(uvm_component cntxt, string inst_name, string field_name, ref T value)
    • get is only required when set is called from the top level module or outside the build phase
  • syntax: static function bit exists(uvm_component cntxt, string inst_name, string field_name, bit spell_chk = 0)
  • syntax: static task wait_modified(uvm_component cntxt, string inst_name, string field_name)
  • inst_name may contain wildcards or regular expression syntax
  • for object, interfaces or user-defined types, use uvc_config_db
  • for run-time configuration, use uvc_config_db


2) a specialized cfg task is set_config_* for uvm_component class, where * can be int, string or object, depending on type of config property:

  • config settings are automatically resolved in UVM build phase; that is because apply_config_settings() is executed in the build phase (when super.build_phase() is called in any uvm_component class). settings are applied only when match is found, if not found, field names will be unset, and mismatched configuration set's should be listed at end of simulation.
  • syntax: virtual function void set_config_in (string inst_name, string field, bitstream_t value)
    • inst_name is relative pathname to a specific component instance from the component where the method is called
    • field is a string containing a config property name of the instance class
    • set build options before calling super.build_phase; this is also why the parameters are strings, because the components and fields does not exist yet.
    • set_config_int("env.agent", "is_active", UVM_PASSIVE);
    • set_config_int("*", "recording_detail", 1);//default is 0, by enabling the recording details for every component, transactions can be viewed in the waveform window(?)
  • the creation of the agent instance in the parent build_phase() triggers the execution of the build_phase() of the agent instance.
  • config property must be automated in the component where declared (field registered)
  • Config settings in higher scope take precedence over lower scopes.
  • Config settings in the same scope conform to "last one in wins"

UVM Field Automation

#Non-array
1) `uvm_field_int (<field_name>, <flags>)
2) `uvm_field_object (<field_name>, <flags>)
3) `uvm_field_string (<field_name>, <flags>)
4) `uvm_field_event (<field_name>, <flags>)

#static Array:
1) `uvm_field_sarray_enum (<enum_type>, <field_name>, <flags>)
2) `uvm_field_sarray_int (<field_name>, <flags>)
3) `uvm_field_sarray_object (<field_name>, <flags>)
4) `uvm_field_sarray_string (<field_name>, <flags>)
#dynamic Array:
1) `uvm_field_array_enum (<enum_type>, <field_name>, <flags>)
2) `uvm_field_array_int (<field_name>, <flags>)
3) `uvm_field_array_object (<field_name>, <flags>)
4) `uvm_field_array_string (<field_name>, <flags>)
#dynamic Array:
1) `uvm_field_queue_enum (<enum_type>, <field_name>, <flags>)
2) `uvm_field_queue_int (<field_name>, <flags>)
3) `uvm_field_queue_object (<field_name>, <flags>)
4) `uvm_field_queue_string (<field_name>, <flags>)

#associative Array:
1) `uvm_field_aa_<d_type>_<ix_type>

#flags
UVM_NOVOMPARE

#the do_* functions are worth more discussion later. 

uvm_factory

b extends a, c extends a, override(a,c)
will b be affected?
Tips: (1) how to use factory debug features. 
uvm_factory::get().print(); //prints the uvm_factory details like registration and override. can be called from build phase, connect phase or mostly likely end_of_elaboration_phase. 

UVM Phasing

Tips:(1) phasing debug features (not very useful)
sim option +UVM_PHASE_TRACE
(2) objection debugging 
sim option +UVM_OBJECTION_TRACE

UVM_sequence

start_item()
finish_item()
get_response()
driver: 
seq_item_port.get_next_item(), 
seq_item_port.item_done(), 
seq_item_port. put(resp)

UVM_POOL

uvm_object_string_pool #(T)
pool.get(string) #get object by a name

Scoreboard

A scoreboard normally consists of 3 components of functions:
1) reference model/transfer function
     c++, systemC or systemverilog: a) existing C model; b) create model, not in collaboration with design team( duplication of errors)
2) Data Storage
     model output instant, DUT takes time to output. Need to store data (and synchronization)
    Queue: output data in same order as input order
    Associative Array: out of order output. Key unique and knonw for input and output. herefore, key is either: a) untransformed port of data, or b) can be generated from data
3) comparison/check logic

Scoreboard internals:
    update counter, tracking received, dropped, matched, and mismatched
    report_phase, print summary of statistics
    end of simulation: check scoreboard queues are empty

Scoreboard must create a new copy of received data item by cloning, before writing the cloned packet to the queue.

UVM TLM Communication bwtween Components

TLM concepts: Port and Imp
    Data Flow: producer create data, consumer consume data
            Producer ---data---> Cosumer
    Control Flow: Initiator sends request to Target
            Initiator ---request---> Target
    producer is initiator: write operation, also called push/put: e.g. analysis connections
    producer is target: read operation, also called pull/get

Port: TLM connection object for Initiator
Imp (implementation): TLM connection object for target.
Export:
symbols: square(port), circle(imp), triangle(export)
port.connect(Imp)
port.connect(Export)

TLM Analysis Interface
uvm_analysis_port #(data type) ap_out
ap_out = new("ap_out", this);

`uvm_analysis_imp_decl(_foo)
uvm_analysis_imp_foo #(data type) foo_in
`uvm_analysis_imp_decl(_bar)
uvm_analysis_imp_foo #(data type) bar_in

function void write_foo(input ---);
endfunction
function void write_bar(input---);
endfunction

...ap_out.connect(...ap_in)


Complex Module UVC connection(external to intermal)
two ways:
1. Module monitor: all external connections are made to this monitor and monitor is responsible for routing connections to other component in the UVC.
the good:  Single, central location for connecting external TLM interfaces.
the bad: at the expense of additional internal interface connections to other components.

2. Module connections: external TLM interfaces are placed on UVC itself, then routed using hierarchical connections and not separate TLM interface. use of TLM export object
the good: fewer TLM connections
the bad: losing some readability

Port initiators can be connected to port, export, or imp targets.
Export initiators can be connected to export or imp targets.
Imp cannot be a connection initiator. Imp is a target only, and is always the last connections object on a route.

TLM FIFO

Analysis FIFO
uvm_tlm_analysis_fifo is a specialization of uvm_tlm_fifo:
unbounded (size=0)
analysis_export replaces put export, support analysis write method.

uvm_analysis_port ---> analysis_export---analysis_fifo---get_peek_export <---scoreboard_get_port

uvm_tlm_analysis_fifo #(data type) tb_fifo = new("...", this);
uvm_get_port $(data type) sb_in = new("...", this);
function void connect_phase();
    sb_in.connect(tb_fifo.get_peek_export)
endfunction

by the way, analysis fifo's blocking_get_export is just an alias to get_peek_export










No comments:

Post a Comment

C Programming

Header Files and Includes https://cplusplus.com/forum/articles/10627/ https://stackoverflow.com/questions/2762568/c-c-include-header-file-or...