- using callback func to handle the trx that's much more beautiful than using the trx handler in the same block
this.trans_executed(tr); `uvm_do_callbacks(apb_master,apb_master_cbs,trans_executed(this,tr))- using get_parent() to fetch the parent's pp and populate it to sub blocks
apb_agent agent;
if ($cast(agent, get_parent()) && agent != null) begin
sigs = agent.vif;
end- using sequencer handler to sort/resort the sequence items by it's priority set, such as sorted([seq(0)->p(1), seq(1)->p(0)]) => [seq(1)->p(0), seq(0)->p(1)]
- register sub sequence to sequencer manager
class dut_reset_seq extends uvm_sequence;
function new(string name = "dut_reset_seq");
super.new(name);
endfunction
`uvm_object_utils(dut_reset_seq)
virtual task body();
dut_top.rst = 1;
repeat (5) @(negedge dut_top.clk);
dut_top.rst = 0;
endtask
endclass
....
dut_reset_seq rst_seq; rst_seq = dut_reset_seq::type_id::create("rst_seq", this);
rst_seq.start(null);
....
my_tx tx;
start_item(tx);
...// do something here
finish_item(tx);
- TLM interface (socket/package) it use like in "fifo" struct
- pull_port (slave side)
- querying the valuable trx from trx queue when the trx queue is not empty.
uvm_seq_item_pull_port #(reg_rw) seqr_port;
seqr_port.peek(rw); // aka 'get_next_rw
... // do trx handle
seqr_port.get(rw); // aka 'item_done'' - put_port(master side)
- push the valuable trx to trx queue when the trx queue is not full
- port/export TLM1
- A component can send out a transaction out through a port, or receive an incoming transaction through an export.
function void connect;
sqr2.seq_item_port.connect(sqr1.seq_item_export );
...
endfunction- blocking/non-blocking trx in TLM2
- non-blocking (return immediately) or blocking (suspend and wait for some event before returning)
- non-blocking // no delay
uvm_tlm_nb_target_socket#(device, usb_xfer, usb_tlm_phase) sock; // slave
function uvm_tlm_sync_e nb_transport_fw(usb_xfer xfer, ref usb_tlm_phase ph...)
uvm_tlm_nb_initiator_socket#(host, usb_xfer, usb_tlm_phase) sock; // master
function uvm_tlm_sync_e nb_transport_bw(usb_xfer xfer, ref usb_tlm_phase ph, ...) - // connect sub sockets in uvm_env connect phase
// master.sock.connect(slave.sock); - blocking // support delay
- uvm_tlm_b_target_socket #(target, apb_rw) sock; //slaveuvm_tlm_b_initiator_socket#(apb_rw) sock; // master
- // connect sub sockets in uvm_env connect phase
// master.sock.connect(slave.sock); - uvm_reg_field call back and sample
rand uvm_reg_field data;
virtual function void build();
data = uvm_reg_field::type_id::create("data");
data.configure(this, 32, 0, "RO", 0, `UVM_REG_DATA_WIDTH'h0>>0, 1, 1, 1);
endfunction
covergroup value_cg;
option.per_instance=1;
coverpoint data.value[31:0];
endgroup
virtual function void sample_values();
super.sample_values();
value_cg.sample();
endfunction
`uvm_register_cb(input_value_c, uvm_reg_cbs)
`uvm_set_super_type(input_value_c, uvm_reg)
`uvm_object_utils(input_value_c)
function new(input string name="unnamed-input_value_c");
super.new(name, 32, build_coverage(UVM_CVR_FIELD_VALS));
if(has_coverage(UVM_CVR_FIELD_VALS)) value_cg=new;
endfunction : new
endclass : input_value_c
- uvm_reg_block
- add sub classes "uvm_reg" to block set
virtual function void build();
// Now create all registers
bypass_mode = bypass_mode_c::type_id::create("bypass_mode", , get_full_name());
// Now build the registers. Set parent and hdl_paths
bypass_mode.configure(this, null, "bypass_mode_reg");
bypass_mode.build();
// Now build the registers. Set parent and hdl_paths
bypass_mode.configure(this, null, "bypass_mode_reg");
bypass_mode.build();
// Now define address mappings
default_map = create_map("default_map", 0, 4, UVM_LITTLE_ENDIAN);
default_map.add_reg(bypass_mode, `UVM_REG_ADDR_WIDTH'h0, "RW");
endclass
endclass
- uvm_report_server
- uvm_report_server svr;
svr = _global_reporter.get_report_server();
svr.set_max_quit_count(10);
沒有留言:
張貼留言