Skip to content

Commit

Permalink
Add template for uvm_agent files and package
Browse files Browse the repository at this point in the history
  • Loading branch information
gmlarumbe committed May 10, 2023
1 parent 926ad92 commit d872717
Show file tree
Hide file tree
Showing 12 changed files with 423 additions and 9 deletions.
48 changes: 48 additions & 0 deletions snippets/uvm_agent/uvm_agent.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class <uvm_name>_agent extends uvm_component;
`uvm_component_utils(<uvm_name>_agent)

<uvm_name>_monitor m_monitor;
<uvm_name>_sequencer m_sequencer;
<uvm_name>_driver m_driver;

<uvm_name>_agent_config m_cfg;
uvm_analysis_port #(<uvm_name>_seq_item) ap;

// Methods
extern function new(string name = "<uvm_name>_agent", uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern function void connect_phase(uvm_phase phase);

endclass : <uvm_name>_agent


// ------------------------------
// External method definitions
// ------------------------------
function <uvm_name>_agent::new(string name = "<uvm_name>_agent", uvm_component parent = null);
super.new(name, parent);
endfunction


function void <uvm_name>_agent::build_phase(uvm_phase phase);
if (!uvm_config_db #(<uvm_name>_agent_config)::get(this, "", "<uvm_name>_agent_config", m_cfg)) begin
`uvm_fatal("CONFIG_LOAD", $sformatf("Cannot get <uvm_name>_agent_config from uvm_config_db."))
end
m_monitor = <uvm_name>_monitor::type_id::create("m_monitor", this);
m_monitor.m_cfg = m_cfg;

if(m_cfg.active == UVM_ACTIVE) begin
m_driver = <uvm_name>_driver::type_id::create("m_driver", this);
m_driver.m_cfg = m_cfg;
m_sequencer = <uvm_name>_sequencer::type_id::create("m_sequencer", this);
end
endfunction : build_phase


function void <uvm_name>_agent::connect_phase(uvm_phase phase);
ap = m_monitor.ap;

if(m_cfg.active == UVM_ACTIVE) begin
m_driver.seq_item_port.connect(m_sequencer.seq_item_export);
end
endfunction : connect_phase
34 changes: 34 additions & 0 deletions snippets/uvm_agent/uvm_agent_config.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class <uvm_name>_agent_config extends uvm_object;
`uvm_object_utils(<uvm_name>_agent_config)

// BFM Virtual Interfaces
virtual <uvm_name>_monitor_bfm mon_bfm;
virtual <uvm_name>_driver_bfm drv_bfm;

// Data Members
uvm_active_passive_enum active = UVM_ACTIVE;

// Methods
extern function new(string name = "<uvm_name>_agent_config");
extern static function <uvm_name>_agent_config get_config(uvm_component c);

endclass : <uvm_name>_agent_config


// ------------------------------
// External method definitions
// ------------------------------
function <uvm_name>_agent_config::new(string name = "<uvm_name>_agent_config");
super.new(name);
endfunction


function <uvm_name>_agent_config <uvm_name>_agent_config::get_config(uvm_component c);
<uvm_name>_agent_config t;

if (!uvm_config_db #(<uvm_name>_agent_config)::get(c, "", "<uvm_name>_agent_config", t)) begin
`uvm_fatal("CONFIG_LOAD", $sformatf("Cannot get() configuration <uvm_name>_agent_config from uvm_config_db."))
end

return t;
endfunction
17 changes: 17 additions & 0 deletions snippets/uvm_agent/uvm_agent_pkg.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package <uvm_name>_agent_pkg;

import uvm_pkg::*;
`include "uvm_macros.svh"

`include "<uvm_name>_types.svh"
`include "<uvm_name>_seq_item.svh"
`include "<uvm_name>_agent_config.svh"
`include "<uvm_name>_driver.svh"
`include "<uvm_name>_monitor.svh"
typedef uvm_sequencer#(<uvm_name>_seq_item) <uvm_name>_sequencer;
`include "<uvm_name>_agent.svh"

// Utility Sequences
`include "<uvm_name>_seq_lib.svh"

endpackage : <uvm_name>_agent_pkg
44 changes: 44 additions & 0 deletions snippets/uvm_agent/uvm_driver.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class <uvm_name>_driver extends uvm_driver #(<uvm_name>_seq_item, <uvm_name>_seq_item);
`uvm_component_utils(<uvm_name>_driver)

// Data Members
local virtual <uvm_name>_driver_bfm m_bfm;
<uvm_name>_agent_config m_cfg;

// Methods
extern function new(string name = "<uvm_name>_driver", uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);

endclass : <uvm_name>_driver


// ------------------------------
// External method definitions
// ------------------------------
function <uvm_name>_driver::new(string name = "<uvm_name>_driver", uvm_component parent = null);
super.new(name, parent);
endfunction


function void <uvm_name>_driver::build_phase(uvm_phase phase);
super.build_phase(phase);
if (!uvm_config_db #(<uvm_name>_agent_config)::get(this, "", "<uvm_name>_agent_config", m_cfg)) begin
`uvm_fatal("CONFIG_LOAD", $sformatf("Cannot get <uvm_name>_agent_config from uvm_config_db."))
end
m_bfm = m_cfg.drv_bfm;
endfunction : build_phase


task <uvm_name>_driver::run_phase(uvm_phase phase);
<uvm_name>_seq_item req;
<uvm_name>_seq_item rsp;

m_bfm.init_values();

forever begin
seq_item_port.get_next_item(req);
m_bfm.drive(req);
seq_item_port.item_done();
end
endtask : run_phase
27 changes: 27 additions & 0 deletions snippets/uvm_agent/uvm_driver_bfm.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
interface <uvm_name>_driver_bfm # (
// ...
) (
input logic clk,
input logic resetn,
// ...
);

timeprecision 1ps;
timeunit 1ns;

`include "uvm_macros.svh"
import uvm_pkg::*;
import <uvm_name>_agent_pkg::*;

// Methods
task init_values ();
// ...
endtask : init_values


task drive (<uvm_name>_seq_item req);
// ...
endtask : drive


endinterface : <uvm_name>_driver_bfm
11 changes: 11 additions & 0 deletions snippets/uvm_agent/uvm_if.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
interface <uvm_name>_if #(
// ...
) ();

logic clk;
logic resetn;

// ...

endinterface

43 changes: 43 additions & 0 deletions snippets/uvm_agent/uvm_monitor.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class <uvm_name>_monitor extends uvm_component;
`uvm_component_utils(<uvm_name>_monitor);

local virtual <uvm_name>_monitor_bfm m_bfm;
<uvm_name>_agent_config m_cfg;
uvm_analysis_port #(<uvm_name>_seq_item) ap;

// Methods
extern function new(string name = "<uvm_name>_monitor", uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern function void notify_transaction(<uvm_name>_seq_item item);

endclass : <uvm_name>_monitor


// ------------------------------
// External method definitions
// ------------------------------
function <uvm_name>_monitor::new(string name = "<uvm_name>_monitor", uvm_component parent = null);
super.new(name, parent);
endfunction


function void <uvm_name>_monitor::build_phase(uvm_phase phase);
if (!uvm_config_db #(<uvm_name>_agent_config)::get(this, "", "<uvm_name>_agent_config", m_cfg)) begin
`uvm_fatal("CONFIG_LOAD", $sformatf("Cannot get <uvm_name>_agent_config from uvm_config_db."))
end
m_bfm = m_cfg.mon_bfm;
m_bfm.proxy = this;
ap = new("ap", this);
endfunction : build_phase


task <uvm_name>_monitor::run_phase(uvm_phase phase);
m_bfm.run();
endtask : run_phase


function void <uvm_name>_monitor::notify_transaction(<uvm_name>_seq_item item);
ap.write(item);
endfunction : notify_transaction

32 changes: 32 additions & 0 deletions snippets/uvm_agent/uvm_monitor_bfm.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
interface <uvm_name>_monitor_bfm # (
// ...
) (
input logic clk,
input logic resetn,
// ...
);

`include "uvm_macros.svh"
import uvm_pkg::*;
import <uvm_name>_agent_pkg::*;

// Members
<uvm_name>_monitor proxy;

// Methods
task run();
<uvm_name>_seq_item item;
<uvm_name>_seq_item cloned_item;

forever begin
// ...
wait(...);
item = <uvm_name>_seq_item::type_id::create("item");

// Clone and publish the cloned item to the subscribers
$cast(cloned_item, item.clone());
proxy.notify_transaction(cloned_item);
end
endtask : run

endinterface : <uvm_name>_monitor_bfm
86 changes: 86 additions & 0 deletions snippets/uvm_agent/uvm_seq_item.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class <uvm_name>_seq_item extends uvm_sequence_item;
`uvm_object_utils(<uvm_name>_seq_item)

// Data Members
logic [31:0] data;

// Methods
extern function new(string name = "<uvm_name>_seq_item");
extern function void do_copy(uvm_object rhs);
extern function bit do_compare(uvm_object rhs, uvm_comparer comparer);
extern function string convert2string();
extern function void do_print(uvm_printer printer);
extern function void do_record(uvm_recorder recorder);
// ModelSim randomize equivalent
extern function int my_randomize();

endclass : <uvm_name>_seq_item


// ------------------------------
// External method definitions
// ------------------------------
function <uvm_name>_seq_item::new(string name = "<uvm_name>_seq_item");
super.new(name);
endfunction


function void <uvm_name>_seq_item::do_copy(uvm_object rhs);
<uvm_name>_seq_item rhs_;

if(!$cast(rhs_, rhs)) begin
`uvm_fatal("do_copy", "cast of rhs object failed")
end
super.do_copy(rhs);
data = rhs_.data;
// ...

endfunction : do_copy


function bit <uvm_name>_seq_item::do_compare(uvm_object rhs, uvm_comparer comparer);
<uvm_name>_seq_item rhs_;

if(!$cast(rhs_, rhs)) begin
`uvm_error("do_compare", "cast of rhs object failed")
return 0;
end
return super.do_compare(rhs, comparer) &&
data == rhs_.data;
// ...

endfunction : do_compare


function string <uvm_name>_seq_item::convert2string();
string s;

$sformat(s, "%s----------------------------\n", s);
$sformat(s, "%s| <uvm_name> transaction:\n", s);
$sformat(s, "%s----------------------------\n", s);
$sformat(s, "%s| data = 0x%0h\n", s, data);
$sformat(s, "%s----------------------------", s);

return s;

endfunction : convert2string


function void <uvm_name>_seq_item::do_print(uvm_printer printer);
printer.m_string = convert2string();
endfunction : do_print


function void <uvm_name>_seq_item::do_record(uvm_recorder recorder);
super.do_record(recorder);
`uvm_record_field("data", data)
// ...
endfunction : do_record


function int <uvm_name>_seq_item::my_randomize ();
// ...

return 1; // Always successful

endfunction : my_randomize
34 changes: 34 additions & 0 deletions snippets/uvm_agent/uvm_seq_lib.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class <uvm_name>_seq_base extends uvm_sequence #(<uvm_name>_seq_item);
`uvm_object_utils(<uvm_name>_seq_base)

// Data members
logic [31:0] data = 0;

// Knobs
bool_t do_randomize = TRUE;

// Methods
function new(string name = "<uvm_name>_seq_base");
super.new(name);
endfunction

task body();
<uvm_name>_seq_item req;

begin
req = <uvm_name>_seq_item::type_id::create("req");
// UVM sequence_item operation
start_item(req);
if (do_randomize == TRUE) begin
if(!req.my_randomize()) begin
`uvm_error("body", "req randomization failure")
end
end
finish_item(req);
end

endtask : body

endclass : <uvm_name>_seq_base


6 changes: 6 additions & 0 deletions snippets/uvm_agent/uvm_types.svh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
`ifndef <UVM_NAME>_TYPES
`define <UVM_NAME>_TYPES

typedef enum bit {FALSE=0, TRUE=1} bool_t;

`endif // <UVM_NAME>_TYPES
Loading

0 comments on commit d872717

Please sign in to comment.