Post on 19-Jun-2020
transcript
Dr. Mike Bartley, Test and Verification
Solutions
Easy migration between
frameworks using UVM Multi-
Language (UVM-ML)
Agenda
The need for UVM-ML
UVM-ML : A background
TVS Test Environment
UVM-ML Use Cases
Benefits of using UVM-ML
Top Verification Challenges from Verification Futures
Complexity 7
Integrating Languages, Views and Techniques 7
Completeness 5
Productivity 5
Requirements Driven Verif (ISO 26262) 5
Scalability 4
Reuse 4
System 4
Mixed Signal 4
The challenges in multi-framework testbenches
• The types of challenges embodied in multi-framework testbenches include, but are not limited to: – Specifying the construction order of multi-framework components
– Referencing and configuring multi-framework components
– Connecting component ports between frameworks
– Transmitting transactions and other data between multi-framework components
– Specifying equivalent transaction data types between multiple frameworks
– Coordinating and synchronizing multi-framework component activity
– Coordinating reset and other key phases across multi-framework components
– Reporting errors and messages between frameworks
– Initializing the system, and enabling shutdown coordination across frameworks
The need for UVM-ML
• Many SoC level testbenches have a mixture of legacy Specman/e
environment along with SystemVerilog-UVM, SystemC etc. environments
• Multi-framework integration is a challenge (see previous slide)
• Need for a solution that can integrate verification components written in
different languages
• Solution needs to support additional languages and methodologies
• A standard solution will enable verification engineers to select verification
collateral based on its merits and quality, rather than its availability in a
given language or framework.
• VIPs can be reused as is and without modifications with other
frameworks. • Seamless interoperability of components in different frameworks
is preserved.
UVM-ML : A background
Collaboration between Cadence and AMD
Open source library
Enables hierarchical integration of frameworks
Provides seamless phasing and configuration
Supports multiple simulators
TVS Environment
E environment
env
Virtual
sequencer
Proxy
sequencer
AgentSequencer
Driver
Proxy
stube env
SV svtop Propagate items
and sequences to target
send_request_p
wait_for_grant_pwait_for_item_done_pinvoke_sequence_p
SV_SERVICE_SEQ
Layering Sequence
do_ml_sequence()
convert_item()
TVS Environment
env
Virtual
sequencer
Proxy
sequencer
AgentSequencer
Driver
Proxy
stube env
SV svtop
Monitor
Protocol
Checker
Coverage
Dummy
Monitor
Creating a remote child using UVM-SV adapter API
Maintaining relationship between UVM-e child proxy and UVM-SV parent proxy
UVM-SV UVM-e
UVM-SV UVM-e
ML Parent proxy ML Child proxy
UVM-ML Backplane
The backplane will record and maintain connections
between parent and foreign child frameworks
UVM-ML Use Case
• Instantiating parent UVM-SV adapter in SV
• Creating a remote child using UVM-SV adapter API
• Registering ML connections
• Binding ML connections
• Starting simulation using procedural interface
• Synchronization
Instantiating UVM-SV adapter in SV
package proxy_pkg;
import uvm_pkg::*;import uvm_ml::*;`include "uvm_macros.svh“
`include "proxy_sequence_item.svh"`include "proxy_sequence.svh"`include "proxy_driver.svh"`include "proxy_sequencer.svh"`include "proxy_agent.svh" `include "proxy_env.svh”endpackage
• Only the UVM-SV adapter is used
• We do not use the UVM-e adapter since the version of
UVM-ML we are using supports this adapter by default.
Creating a remote child using UVM-SV adapter API
• The uvm_ml_create_component function is used in the build phase to
create the remote child in our UVM-SV environment file
class proxy_env extends uvm_env;////////////////////////Registration of the Component /////////////////////////`uvm_component_utils(proxy_env)// handle of agentproxy_agent agent; uvm_component etop1;
//Constructorfunction new (string name, uvm_component parent);super.new(name, parent);
endfunction : new///////////////////Build Phase //////////////////////////////////virtual function void build_phase(uvm_phase phase);super.build_phase(phase);// To build the driver agent = proxy_agent::type_id::create("agent",this); etop1 = uvm_ml_create_component("e", “etop", “e", this);
endfunction: build_phaseendclass : proxy_env
Starting simulation using procedural interface
module top();import uvm_pkg::*;import proxy_pkg::*;import uvm_ml::*;initialbeginstring tops[1];tops[0] = "sv:proxy_testbase";uvm_ml_run_test(tops, “test_name");//run_test();
endendmodule
• For starting simulation, we use the UVM-SV API uvm_ml_run_test()
tops is a dynamic
array of top
component
identifiers
Registering ML connections
• Using the UVM ML API for registering ML connections, we were able to
create a channel between UVM-SV and UVM-eUVM-SV UVM-SV
class proxy_testbase extends uvm_test;
//Registration of the Component /////////////////////////
`uvm_component_utils(proxy_testbase) proxy_env env;
// Constructor
…..
endfunction : new
////////////////////Build Phase//////////////////////////////////
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// creating the env
env = proxy_env::type_id::create("env",this);
endfunction: build_phase
///////////////////////////////////////////////////////////////
function void phase_ended(uvm_phase phase);
if (phase.get_name() == "build") begin
uvm_ml::ml_tlm1#(proxy_sequence_item)::
register(env.agent.sequencer.a_port);
end
endfunction
endclass
class proxy_sequencer extends uvm_sequencer#(proxy_sequence_item);
////////////////Registration of the Component /////////////////////////
`uvm_sequencer_utils(proxy_sequencer)
// analysis port
uvm_analysis_port
#(proxy_sequence_item) a_port; // constructor for proxy_sequencer
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new
/////////////////////Build Phase////////////////////////////////////
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
a_port = new ("a_port",this);
endfunction: build_phase
////////////////////////////////////////////////////////////////////////////
Binding ML connections
The connect API is used to bind ML connectionsUVM-SV UVM-e
class proxy_testbase extends uvm_test;
//Registration of the Component /////////////////////////`uvm_component_utils(proxy_testbase)
proxy_env env;
// Constructor function new (string name, uvm_component parent);
super.new(name, parent);endfunction : new
---
function void connect_phase(uvm_phase phase);bit result;
super.connect_phase(phase);
result = uvm_ml::connect(env.agent.sequencer.a_port.
get_full_name(), "proxy_testbase.env.tvs_driver.in_port");
endfunction
extend tvs_driver {
keep agent() == "SV";
in_port : in interface_port of tlm_analysis of
tvs_item using prefix=imp_ is instance;keep bind(in_port,external);imp_write(p: tvs_item) is {
print p using hex;};
pre_generate() is also {
out("[SN] pre_generate()");print me.e_path();
print me.get_parent_unit();};
post_generate() is also {
out("[SN] post_generate()");print me.e_path();
print me.get_parent_unit();};
connect_ports() is also {out("[SN] connect_ports()");
}; //env_name: tvs_env_t;
//agent_name: tvs_agent_t;
seq: tvs_sequence; keep seq.driver == me;
run() is also {}; };
Synchronization
• The synchronize() API in the run_phase task is used for synchronizing
simulators
class proxy_testbase extends uvm_test;
////////////////////////Registration of the Component /////////////////////////
`uvm_component_utils(proxy_testbase)
proxy_env env;
//Constructor
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new
endfunction
--
--
--
task run_phase(uvm_phase phase);
proxy_sequence seq;
uvm_top.print_topology();
uvm_ml::synchronize();seq = new("seq");
assert(seq.randomize() with {no_of_seq == 5;});
seq.start(env.agent.sequencer);
endtask
Benefits of UVM-ML
Easy VIP integration in multi-language environment
Focus on testing new product features
Preserve user’s native-language experience
Re-use of golden VIP