// I hope it helps. put it all in a file and run it.
package tb_env;
import uvm_pkg::*;
`include "uvm_macros.svh"
// Basic sequence item
class shift_reg_item extends uvm_sequence_item;
rand bit [7:0] data;
rand bit [2:0] shift;
`uvm_object_utils_begin(shift_reg_item)
`uvm_field_int(data, UVM_ALL_ON)
`uvm_field_int(shift, UVM_ALL_ON)
`uvm_object_utils_end
function new (string name="shift_reg_item");
super.new(name);
endfunction
endclass
// Basic sequence
class shift_reg_seq extends uvm_sequence #(shift_reg_item);
`uvm_object_utils(shift_reg_seq)
shift_reg_item req;
function new(string name="shift_req_seq");
super.new(name);
endfunction
task body();
req=shift_reg_item::type_id::create("req");
start_item(req);
if(!req.randomize())
`uvm_fatal("shift_reg_seq","Failed to randomize shift_reg item")
finish_item(req);
// `uvm_do(req)
// `uvm_do_with(req, {req.data==8'hAA; req.shift==3'b101;})
endtask
endclass
// Sequencer
class shift_reg_sqr extends uvm_sequencer #(shift_reg_item);
`uvm_component_utils(shift_reg_sqr)
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
typedef class shift_reg_drv;
// Callback parent class
// here you define the method that will change the sequence
// Implementation will be done in child class
class driver_cb extends uvm_callback;
`uvm_object_utils (driver_cb)
function new (string name = "driver_cb");
super.new(name);
endfunction
virtual function void set_seq_item_value (shift_reg_drv drv, shift_reg_item item);
endfunction : set_seq_item_value
endclass : driver_cb
// Driver
class shift_reg_drv extends uvm_driver #(shift_reg_item);
`uvm_component_utils(shift_reg_drv)
// Register the callback class with this driver class
`uvm_register_cb (shift_reg_drv, driver_cb)
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
// If the callback is added to this driver, this method
// will call the method defined in the callback class (child callback class)
virtual function void set_seq_item_value (shift_reg_item item);
`uvm_do_callbacks(shift_reg_drv, driver_cb, set_seq_item_value(this, item))
endfunction : set_seq_item_value
task run_phase (uvm_phase phase);
forever begin
seq_item_port.get_next_item(req);
// Call the callback method
set_seq_item_value(req);
req.print();
seq_item_port.item_done();
end
endtask
endclass
// This class set data bit to ones
// You can have many of this classes, each can do something else
// make sure that they are all extend driver cb
class set_seq_item_all_ones_cb extends driver_cb;
`uvm_object_utils(set_seq_item_all_ones_cb)
function new (string name = "set_seq_item_all_ones_cb");
super.new(name);
endfunction
// Override the the method that was declared in driver_cb
virtual function void set_seq_item_value (shift_reg_drv drv, shift_reg_item item);
item.data = 8'hFF;
item.shift = 3'h3;
endfunction : set_seq_item_value
endclass : set_seq_item_all_ones_cb
class shift_reg_test extends uvm_test;
shift_reg_seq seq;
shift_reg_drv drv;
shift_reg_sqr sqr;
set_seq_item_all_ones_cb cb;
`uvm_component_utils(shift_reg_test)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase (uvm_phase phase);
super.build_phase(phase);
sqr=shift_reg_sqr::type_id::create("sqr", this);
drv=shift_reg_drv::type_id::create("drv", this);
seq=shift_reg_seq::type_id::create("seq");
cb=set_seq_item_all_ones_cb::type_id::create("cb");
endfunction
function void connect_phase (uvm_phase phase);
super.connect_phase(phase);
drv.seq_item_port.connect(sqr.seq_item_export);
endfunction
task run_phase (uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
// Start sequence with out callback
seq.start(sqr);
// Here is where you add the callback functionality to the driver
// if you want to change is behaviour
uvm_callbacks #(shift_reg_drv, driver_cb)::add(drv, cb);
// Start the sequence with add callback functionality to the driver
seq.start(sqr);
// If you want you can remove to callback functionality fro the driver
uvm_callbacks #(shift_reg_drv, driver_cb)::delete(drv, cb);
// Start sequence without callback
seq.start(sqr);
phase.drop_objection(this);
endtask
endclass
endpackage : tb_env
module top;
import uvm_pkg::*;
`include "uvm_macros.svh"
import tb_env::*;
initial run_test("shift_reg_test");
endmodule