Created
March 23, 2017 10:20
-
-
Save sagar5258/a30c711ac030fc3c71b870189a46d3db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import uvm_pkg :: *; | |
class my_seq_item extends uvm_sequence_item; | |
rand logic [7:0] addr; | |
rand logic [7:0] data; | |
constraint addr_range_cn { | |
addr inside {[10:20]}; | |
} | |
constraint data_range_cn { | |
data inside {[100:200]}; | |
} | |
`uvm_object_utils_begin(my_seq_item) | |
`uvm_field_int(addr, UVM_ALL_ON| UVM_DEC) | |
`uvm_field_int(data, UVM_ALL_ON| UVM_DEC) | |
`uvm_object_utils_end | |
function new(string name="my_seq_item"); | |
super.new(name); | |
endfunction : new | |
virtual function string convert2string(); | |
convert2string = $sformatf("addr=%0d, data=%0d", addr, data); | |
endfunction : convert2string | |
endclass : my_seq_item | |
class my_sequencer extends uvm_sequencer #(my_seq_item); | |
`uvm_component_utils (my_sequencer) | |
function new (string name="my_sequencer", uvm_component parent=null); | |
super.new(name, parent); | |
endfunction : new | |
endclass : my_sequencer | |
class my_driver extends uvm_driver #(my_seq_item); | |
`uvm_component_utils (my_driver) | |
function new (string name="my_driver", uvm_component parent=null); | |
super.new(name, parent); | |
endfunction : new | |
function void build_phase (uvm_phase phase); | |
super.build_phase(phase); | |
endfunction : build_phase | |
task run_phase(uvm_phase phase); | |
forever begin | |
seq_item_port.get_next_item(req); | |
`uvm_info(get_name(), | |
$sformatf("in driver after get_next_item my_seq_item= %s", req.convert2string()), UVM_LOW); | |
#50; | |
`uvm_info(get_name(), $sformatf("item_done called"), UVM_LOW); | |
seq_item_port.item_done(); | |
end | |
endtask : run_phase | |
endclass : my_driver | |
class my_agent extends uvm_agent; | |
`uvm_component_utils (my_agent) | |
my_sequencer sqr; | |
my_driver drv; | |
function new (string name="my_agent", uvm_component parent=null); | |
super.new(name, parent); | |
endfunction : new | |
function void build_phase (uvm_phase phase); | |
super.build_phase(phase); | |
sqr = my_sequencer :: type_id :: create("sqr", this); | |
drv = my_driver :: type_id :: create("drv", this); | |
endfunction : build_phase | |
function void connect_phase (uvm_phase phase); | |
super.connect_phase(phase); | |
drv.seq_item_port.connect(sqr.seq_item_export); | |
endfunction : connect_phase | |
endclass : my_agent | |
class my_seq extends uvm_sequence #(my_seq_item); | |
`uvm_object_utils (my_seq) | |
function new(string name="my_seq"); | |
super.new(name); | |
// The most common interaction with the starting phase | |
// within a sequence is to simply ~raise~ the phase's objection | |
// prior to executing the sequence, and ~drop~ the objection | |
// after ending the sequence (either naturally, or | |
// via a call to <kill>). In order to | |
// simplify this interaction for the user, the UVM | |
// provides the ability to perform this functionality | |
// automatically. | |
// From a timeline point of view, the automatic phase objection | |
// looks like: | |
//| start() is executed | |
//| --! Objection is raised !-- | |
//| pre_start() is executed | |
//| pre_body() is optionally executed | |
//| body() is executed | |
//| post_body() is optionally executed | |
//| post_start() is executed | |
//| --! Objection is dropped !-- | |
//| start() unblocks | |
// NEVER set the automatic phase objection bit to 1 if your sequence | |
// runs with a forever loop inside of the body, as the objection will | |
// never get dropped! | |
set_automatic_phase_objection(1); | |
endfunction : new | |
task body (); | |
`uvm_create(req) | |
if(!req.randomize()) begin | |
`uvm_fatal(get_name(), $sformatf("Randomization failed")) | |
end | |
`uvm_info (get_name(), | |
$sformatf("After randomizating in my_seq my_seq_item= %s", | |
req.convert2string()), UVM_LOW) | |
`uvm_send(req) | |
endtask : body | |
endclass : my_seq | |
class my_test extends uvm_test; | |
`uvm_component_utils (my_test) | |
my_agent agent; | |
function new (string name="my_test", uvm_component parent=null); | |
super.new(name, parent); | |
endfunction : new | |
function void build_phase (uvm_phase phase); | |
super.build_phase(phase); | |
agent = my_agent::type_id::create("agent", this); | |
endfunction : build_phase | |
task run_phase(uvm_phase phase); | |
my_seq seq; | |
uvm_phase starting_phase; | |
bit automatic_phase_objection_status; | |
seq = my_seq::type_id::create ("seq"); | |
// Function: set_starting_phase | |
// Sets the 'starting phase'. | |
seq.set_starting_phase(phase); | |
// If set_automatic_phase_objection is not called in new (constructor) | |
// of sequence then can be calleb from test-case | |
// seq.set_automatic_phase_objection(1); | |
fork | |
begin | |
#30; | |
// Function: get_starting_phase | |
// Returns the 'starting phase'. | |
// If non-null, the starting phase specifies the phase in which this | |
// sequence was started. | |
starting_phase = seq.get_starting_phase(); | |
`uvm_info(get_name(), | |
$sformatf("starting_phase:%s", starting_phase.get_full_name()), UVM_LOW) | |
// Function: get_automatic_phase_objection | |
// Returns (and locks) the value of the 'automatically object to | |
// starting phase' bit. | |
// | |
// If 1, then the sequence will automatically raise an objection | |
// to the starting phase (if the starting phase is not ~null~) immediately | |
// prior to <pre_start> being called. The objection will be dropped | |
// after <post_start> has executed, or <kill> has been called. | |
automatic_phase_objection_status = seq.get_automatic_phase_objection(); | |
`uvm_info(get_name(), | |
$sformatf("during seq is running, get_automatic_phase_objection returns :%b", automatic_phase_objection_status), UVM_LOW) | |
end | |
join_none | |
seq.start(agent.sqr); | |
automatic_phase_objection_status = seq.get_automatic_phase_objection(); | |
`uvm_info(get_name(), | |
$sformatf("After seq finished, get_automatic_phase_objection returns :%b", automatic_phase_objection_status), UVM_LOW) | |
endtask : run_phase | |
endclass : my_test | |
module top(); | |
initial begin | |
run_test("my_test"); | |
end | |
endmodule : top | |
//Output: | |
// UVM_INFO @ 0: reporter [RNTST] Running test my_test... | |
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq raised 1 objection(s) (automatic phase objection): count=1 total=1 | |
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent.sqr added 1 objection(s) to its total (raised from source object , automatic phase objection): count=0 total=1 | |
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top.agent added 1 objection(s) to its total (raised from source object , automatic phase objection): count=0 total=1 | |
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_test_top added 1 objection(s) to its total (raised from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=1 | |
// UVM_INFO @ 0: run [OBJTN_TRC] Object uvm_top added 1 objection(s) to its total (raised from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=1 | |
// UVM_INFO testbench.sv(118) @ 0: uvm_test_top.agent.sqr@@seq [seq] After randomizating in my_seq my_seq_item= addr=19, data=140 | |
// UVM_INFO testbench.sv(50) @ 0: uvm_test_top.agent.drv [drv] in driver after get_next_item my_seq_item= addr=19, data=140 | |
// UVM_INFO testbench.sv(158) @ 30: uvm_test_top [uvm_test_top] starting_phase:common.run | |
// UVM_INFO testbench.sv(170) @ 30: uvm_test_top [uvm_test_top] during seq is running, get_automatic_phase_objection returns :1 | |
// UVM_INFO testbench.sv(52) @ 50: uvm_test_top.agent.drv [drv] item_done called | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq dropped 1 objection(s) (automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr.seq all_dropped 1 objection(s) (automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr subtracted 1 objection(s) from its total (dropped from source object , automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent.sqr subtracted 1 objection(s) from its total (all_dropped from source object , automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent subtracted 1 objection(s) from its total (dropped from source object , automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top.agent subtracted 1 objection(s) from its total (all_dropped from source object , automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_test_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0 | |
// UVM_INFO @ 50: run [OBJTN_TRC] Object uvm_top subtracted 1 objection(s) from its total (all_dropped from source object uvm_test_top.agent.sqr.seq, automatic phase objection): count=0 total=0 | |
// UVM_INFO uvm-1.2/src/base/uvm_objection.svh(1271) @ 50: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase | |
// UVM_INFO testbench.sv(176) @ 50: uvm_test_top [uvm_test_top] After seq finished, get_automatic_phase_objection returns :1 | |
// UVM_INFO uvm-1.2/src/base/uvm_report_server.svh(847) @ 50: reporter [UVM/REPORT/SERVER] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment