How do I instantiate a UVM Monitor Environment in a Traditio

  • Thread starter rajatkmitra@gmail.com
  • Start date
R

rajatkmitra@gmail.com

Guest
Hello all,

I have a traditional testbench that instantiates a Stimulus Generator and a DUT. Looks like this

//in module tb.v

module tb;

driver i_driver(...);

dut i_dut(..);

endmodule

The stimulus generation occurs within the driver.

I would like to add an UVM Environment with only a Monitor, Scoreboard and Functional Coverage to this testbench. I created a wrapper called "svid_packet_monitor" and instantiated that in the tb.

module tb;

driver i_driver(...);

dut i_dut(..);

svid_packet_mon_wrapper i_svid_packet_mon_wrapper();

endmodule

I am new to the whole UVM thing and am not sure how the code inside the monitor wrapper should look like. I took a first stab at creating a package with the monitor and associated class items and imported this inside the svid_packet_mon_wrapper. Then I created my_test inside the wrapper that extends uvm_test but I am not sure how to start this up. I am attaching the code for the monitor package and the monitor wrapper( with questions inside the monitor_wrapper code ). Any help to put this together would be highly appreciated...

Best

Raj
---------------------------------------------------------------------------
The following is the code for the wrapper
==========================================================================itor;

function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new

function void build_phase( uvm_phase phase );
super.build_phase( phase );

svid_ap = new( .name( "svid_ap" ), .parent( this ) );
packet_monitor = svid_transmit_packet_monitor::type_id::create(
..name( "packet_monitor" ), .parent( this ) );

endfunction // build_phase


function void connect_phase(uvm_phase phase);
super.connect_phase( phase );
packet_monitor.ingress_intf = ingress_intf;
packet_monitor.svid_ap.connect(svid_ap);
endfunction // connect_phase

endclass // svid_transmit_packet_agent
//-------------------------------------------------------------
//svid_functional_coverage_subscriber
//-------------------------------------------------------------
class svid_functional_coverage_subscriber extends
uvm_subscriber#(svid_transmit_packet);
`uvm_component_utils(svid_functional_coverage_subscriber)

svid_transmit_packet svid_packet;

covergroup svid_packet_cg;
start_frame_cp: coverpoint svid_packet.start_frame;
addr_cp: coverpoint svid_packet.addr;
command_cp: coverpoint svid_packet.command;
end_frame_cp: coverpoint svid_packet.end_frame;
endgroup // svid_packet_cg

function new( string name, uvm_component parent );
super.new( name, parent );
svid_packet_cg = new;
endfunction // new

function void write(svid_transmit_packet t);
svid_packet = t;
svid_packet_cg.sample();
endfunction // write

endclass // svid_functional_coverage_subscriber
//------------------------------------------------------------



---------------------------------------------------------------------------
The following is the code for the environment
==========================================================================`include "uvm_macros.svh"


package uvm_svid_monitor_package;
import uvm_pkg::*;
//----------------------------------------------------------
//svid_transmit_packet_configuration
//----------------------------------------------------------
class svid_transmit_packet_configuration extends uvm_object;
`uvm_object_utils( svid_transmit_packet_configuration )

function new( string name = "" );
super.new( name );
endfunction: new
endclass // svid_transmit_packet_configuration


//-----------------------------------------------------------
//svid transmit packet class;
//-----------------------------------------------------------
class svid_transmit_packet extends uvm_sequence_item;

typedef enum bit [2:0] {IDLE,SET_VID_FAST, SET_VID_SLOW,
SET_VID_DECAY, SET_PS, GET_REG} svid_cmd;
typedef enum int {LOOP0, LOOP1} svid_loop;
typedef enum bit [2:0] {INVALID0, INVALID1, START_FRAME, END_FRAME,
INVALID2, INVALID3, INVALID4, INVALID5
} frame_limiter;

//Frame specific parmeters
frame_limiter start_frame;
svid_loop addr;
svid_cmd command;
bit [7:0] payload;
bit parity;
frame_limiter end_frame;

function new(string name=" ");
super.new(name);
endfunction // new

`uvm_object_utils_begin(svid_transmit_packet)
`uvm_field_enum( frame_limiter, start_frame, UVM_ALL_ON )
`uvm_field_enum( svid_cmd, command, UVM_ALL_ON )
`uvm_field_enum( svid_loop, addr, UVM_ALL_ON )
`uvm_field_int( payload, UVM_ALL_ON )
`uvm_field_int( parity, UVM_ALL_ON )
`uvm_field_enum( frame_limiter, end_frame, UVM_ALL_ON )
`uvm_object_utils_end



endclass // svid_transmit_packet



//-----------------------------------------------------------
//svid transmission monitor; this monitor retrives the packet
//from the ingress interface and put it to the analysis port
//-----------------------------------------------------------
class svid_transmit_packet_monitor extends uvm_monitor;
`uvm_component_utils(svid_transmit_packet_monitor)

uvm_analysis_port #(svid_transmit_packet) svid_ap;
virtual svid_packet_intf ingress_intf; //from wired interface

function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new

function void build_phase(uvm_phase phase);
super.build_phase( phase );
void'(uvm_resource_db#(virtual svid_packet_intf
)::read_by_name(.scope("ifs"), .name("svid_packet_intf_ingress"),
..val(ingress_intf)));
svid_ap = new( .name( "svid_ap" ), .parent( this ) );
endfunction // build_phase

task run_phase(uvm_phase phase);
forever begin
svid_transmit_packet svid_packet;
@ingress_intf.cb_out;
if(ingress_intf.cb_out.command != svid_transmit_packet::IDLE)begin
svid_packet =
svid_transmit_packet::type_id::create(.name("svid_packet"));
svid_packet.start_frame =
svid_transmit_packet::frame_limiter'(ingress_intf.cb_out.start_frame);
svid_packet.addr =
svid_transmit_packet::svid_loop'(ingress_intf.cb_out.addr);
svid_packet.command =
svid_transmit_packet::svid_cmd'(ingress_intf.cb_out.command);
svid_packet.payload = ingress_intf.cb_out.payload;
svid_packet.parity = ingress_intf.cb_out.parity;
svid_packet.end_frame =
svid_transmit_packet::frame_limiter'(ingress_intf.cb_out.end_frame);
svid_ap.write(svid_packet);
end
end // forever begin
endtask // run_phase

endclass // svid_transmit_packet_monitor
//-----------------------------------------------------------
//svid agent; instantiates sequencer (NOT), monitor and driver
//-----------------------------------------------------------
class svid_transmit_packet_agent extends uvm_agent;
`uvm_component_utils(svid_transmit_packet_agent)

uvm_analysis_port#(svid_transmit_packet) svid_ap;
virtual svid_packet_intf ingress_intf; //from DUT svid_transmit_packet_monitor packet_monitor;

function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new

function void build_phase( uvm_phase phase );
super.build_phase( phase );

svid_ap = new( .name( "svid_ap" ), .parent( this ) );
packet_monitor = svid_transmit_packet_monitor::type_id::create(
..name( "packet_monitor" ), .parent( this ) );

endfunction // build_phase


function void connect_phase(uvm_phase phase);
super.connect_phase( phase );
packet_monitor.ingress_intf = ingress_intf;
packet_monitor.svid_ap.connect(svid_ap);
endfunction // connect_phase

endclass // svid_transmit_packet_agent
//-------------------------------------------------------------
//svid_functional_coverage_subscriber
//-------------------------------------------------------------
class svid_functional_coverage_subscriber extends
uvm_subscriber#(svid_transmit_packet);
`uvm_component_utils(svid_functional_coverage_subscriber)

svid_transmit_packet svid_packet;

covergroup svid_packet_cg;
start_frame_cp: coverpoint svid_packet.start_frame;
addr_cp: coverpoint svid_packet.addr;
command_cp: coverpoint svid_packet.command;
end_frame_cp: coverpoint svid_packet.end_frame;
endgroup // svid_packet_cg

function new( string name, uvm_component parent );
super.new( name, parent );
svid_packet_cg = new;
endfunction // new

function void write(svid_transmit_packet t);
svid_packet = t;
svid_packet_cg.sample();
endfunction // write

endclass // svid_functional_coverage_subscriber
//------------------------------------------------------------

itor;

function new( string name, uvm_component parent );
super.new( name, parent );
endfunction: new

function void build_phase( uvm_phase phase );
super.build_phase( phase );

svid_ap = new( .name( "svid_ap" ), .parent( this ) );
packet_monitor = svid_transmit_packet_monitor::type_id::create(
..name( "packet_monitor" ), .parent( this ) );

endfunction // build_phase


function void connect_phase(uvm_phase phase);
super.connect_phase( phase );
packet_monitor.ingress_intf = ingress_intf;
packet_monitor.svid_ap.connect(svid_ap);
endfunction // connect_phase

endclass // svid_transmit_packet_agent
//-------------------------------------------------------------
//svid_functional_coverage_subscriber
//-------------------------------------------------------------
class svid_functional_coverage_subscriber extends
uvm_subscriber#(svid_transmit_packet);
`uvm_component_utils(svid_functional_coverage_subscriber)

svid_transmit_packet svid_packet;

covergroup svid_packet_cg;
start_frame_cp: coverpoint svid_packet.start_frame;
addr_cp: coverpoint svid_packet.addr;
command_cp: coverpoint svid_packet.command;
end_frame_cp: coverpoint svid_packet.end_frame;
endgroup // svid_packet_cg

function new( string name, uvm_component parent );
super.new( name, parent );
svid_packet_cg = new;
endfunction // new

function void write(svid_transmit_packet t);
svid_packet = t;
svid_packet_cg.sample();
endfunction // write

endclass // svid_functional_coverage_subscriber
//------------------------------------------------------------
 

Welcome to EDABoard.com

Sponsor

Back
Top