I want to impliment a layer driver to connect a sqr.
find in sequencer use the below function to write sequencer req fifo
// send_request
// ------------
function void uvm_sequencer_param_base::send_request(uvm_sequence_base sequence_ptr,
uvm_sequence_item t,
bit rerandomize = 0);
REQ param_t;
if (sequence_ptr == null) begin
uvm_report_fatal("SNDREQ", "Send request sequence_ptr is null", UVM_NONE);
end
if (sequence_ptr.m_wait_for_grant_semaphore < 1) begin
uvm_report_fatal("SNDREQ", "Send request called without wait_for_grant", UVM_NONE);
end
sequence_ptr.m_wait_for_grant_semaphore--;
if ($cast(param_t, t)) begin
if (rerandomize == 1) begin
if (!param_t.randomize()) begin
uvm_report_warning("SQRSNDREQ", "Failed to rerandomize sequence item in send_request");
end
end
if (param_t.get_transaction_id() == -1) begin
param_t.set_transaction_id(sequence_ptr.m_next_transaction_id++);
end
m_last_req_push_front(param_t);
end else begin
uvm_report_fatal(get_name(),$sformatf("send_request failed to cast sequence item"), UVM_NONE);
end
param_t.set_sequence_id(sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1));
t.set_sequencer(this);
// uvm_tlm_fifo #(REQ) m_req_fifo; 是uvm_sequencer_param_base 的member
if (m_req_fifo.try_put(param_t) != 1) begin //这个是放入m_req_fifo
uvm_report_fatal(get_full_name(), "Concurrent calls to get_next_item() not supported. Consider using a semaphore to ensure that concurrent processes take turns in the driver", UVM_NONE);
end
m_num_reqs_sent++;
// Grant any locks as soon as possible
grant_queued_locks();
endfunction
I code like the following;
It seems no error comes out except
UVM_ERROR @ 0: run [TEST_DONE_NOHIER] A non-hierarchical object, ‘common.run’ () was used in a call to uvm_test_done.raise_objection(). For this objection, a sequence or component is required.,
I can use try_put to write req_fifo
but I use get_next_item, get nothing;
can anyone give some comments.
package my_pkg;
import uvm_pkg::*;
`include "uvm_macros.svh"
class a_item extends uvm_sequence_item;
rand bit [7:0] a_data;
`uvm_object_utils_begin(a_item)
`uvm_field_int(a_data,UVM_ALL_ON)
`uvm_object_utils_end
function new(string name="a_item");
super.new(name);
endfunction
endclass
class a_seq extends uvm_sequence;
`uvm_object_utils(a_seq)
a_item a_item_h;
function new(string name="a_seq");
super.new(name);
endfunction
virtual task body();
a_item a_item_h;
uvm_sequence_item tmp;
tmp =create_item(a_item::get_type(),m_sequencer,"req");
$cast(a_item_h,tmp);
start_item(a_item_h);
a_item_h.randomize();
finish_item(a_item_h);
endtask
endclass
////class b_seq(uvm_sequence_item t) extends uvm_sequence;
// `uvm_object_utils(a_seq)
// a_item a_item_h;
// function new(string name="b_seq");
// super.new(name);
// endfunction
//
// virtual task body();
// a_item a_item_h;
// uvm_sequence_item tmp;
// tmp =create_item(a_item::get_type(),m_sequencer,"req");
//
// $cast(a_item_h,t);
// start_item(a_item_h);
// a_item_h.randomize();
// finish_item(a_item_h);
//
// endtask
//endclass
////////////////////////sequencer
class a_sequencer extends uvm_sequencer;
`uvm_component_utils(a_sequencer)
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction
endclass
class b_sequencer extends uvm_sequencer;
`uvm_component_utils(b_sequencer)
uvm_analysis_imp#(uvm_sequence_item, b_sequencer) b_imp;
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
b_imp=new("b_imp",this);
endfunction
function write(uvm_sequence_item t);
//t.try_put
// m_req_fifo.
// send_request(null,t);
REQ param_t;
$cast(param_t,t);
t.set_sequencer(this);
$display("b_sequencer write $$$$$$$$$");
if (m_req_fifo.try_put(param_t) != 1) begin
$display("-----#############");
`uvm_info(get_full_name(), "Concurrent . $$$$$$$$$$", UVM_LOW);
end
`uvm_info(get_name(),$sformatf("%s",t.sprint()),UVM_LOW)
$display("b_sequencer write end$$$$$$$$");
endfunction
endclass
//////////////////////////driver
class a_driver extends uvm_driver;
`uvm_component_utils(a_driver)
b_sequencer b_sequencer_h;
uvm_analysis_port#(uvm_sequence_item) ap;
function new(string name, uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
ap=new("ap",this);
endfunction
task run_phase(uvm_phase phase);
REQ tmp;
a_item a_item_h;
// b_seq b_seq_h;
forever begin
$display("--a_driver_h run----$$$$$");
seq_item_port.get_next_item(tmp);
$cast(a_item_h,tmp);
`uvm_info(get_name(),$sformatf("%s",a_item_h.sprint()),UVM_LOW)
// b_seq_h=new();
// b_seq_h.start(b_sequencer_h);
//ap.write(a_item_h);
ap.write(tmp);
seq_item_port.item_done();
end
endtask
endclass
class b_driver extends uvm_driver;
`uvm_component_utils(b_driver)
function new(string name, uvm_component parent);
super.new(name,parent);
$display("--b_driver_h new----$$$$$");
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
$display("--b_driver_h-build---$$$$$");
endfunction
task run_phase(uvm_phase phase);
REQ tmp;
a_item a_item_h;
forever begin
phase.raise_objection(phase);
$display("--b_driver_h---run0-$$$$$");
seq_item_port.get_next_item(tmp);
$display("--b_driver_h---run1-$$$$$");
$cast(a_item_h,tmp);
$display("--b_driver_h---run-######");
`uvm_info(get_full_name(),$sformatf("%s",a_item_h.sprint()),UVM_LOW)
seq_item_port.item_done();
phase.drop_objection(phase);
end
endtask
endclass
class a_env extends uvm_env;
`uvm_component_utils(a_env)
a_driver a_driver_h;
a_sequencer a_sequencer_h;
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
a_driver_h=a_driver::type_id::create("a_driver_h",this);
a_sequencer_h = a_sequencer::type_id::create("a_sequencer_h",this);
endfunction
function void connect_phase(uvm_phase phase);
a_driver_h.seq_item_port.connect(a_sequencer_h.seq_item_export);
endfunction
endclass
class b_env extends uvm_env;
`uvm_component_utils(b_env)
b_driver b_driver_h;
b_sequencer b_sequencer_h;
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
b_driver_h=b_driver::type_id::create("b_driver_h",this);
b_sequencer_h = b_sequencer::type_id::create("b_sequencer_h",this);
endfunction
function void connect_phase(uvm_phase phase);
b_driver_h.seq_item_port.connect(b_sequencer_h.seq_item_export);
endfunction
endclass
class a_test extends uvm_test;
`uvm_component_utils(a_test)
a_env a_env_h;
b_env b_env_h;
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
a_env_h=a_env::type_id::create("a_env_h",this);
b_env_h=b_env::type_id::create("b_env_h",this);
//a_sequencer_h = a_sequencer::type_id::create("a_sequencer_h",this);
endfunction
function void connect_phase(uvm_phase phase);
// a_env_h.a_driver_h.ap.connect(b_env_h.b_sequencer_h.m_req_fifo.put_export);
a_env_h.a_driver_h.ap.connect(b_env_h.b_sequencer_h.b_imp);
// a_env_h.a_driver_h.b_sequencer_h = b_env_h.b_sequencer_h;
endfunction
task run_phase(uvm_phase phase);
a_seq a_seq_h;
phase.raise_objection(phase);
a_seq_h =new();
a_seq_h.start(a_env_h.a_sequencer_h);
#10ns;
phase.drop_objection(phase);
endtask
endclass
endpackage
module top_tb();
import uvm_pkg::*;
`include "uvm_macros.svh"
import my_pkg::*;
initial begin
run_test();
end
endmodule