there are many means to solve this question in forum, but i dont find the answer suit for me! below is my code :
class ahbl_trans extends uvm_sequence_item;
rand logic hsel;
rand logic [31:0] haddr = 32’b0;
rand htrans_t htrans = NSEQ;
rand hsize_t hsize = BYTE;
rand hburst_t hburst = WRAP4;
rand logic [3:0] hprot = 4’b0;
rand logic hwrite = 1’b0;
rand logic [31:0] hrwdata = 32’b0;
rand logic hresp = 1’b0;
rand logic hreadyout = 1’b1;
rand logic [3:0] clk_ratio = 4'h1;
protected rand int unsigned bst_beats;
protected rand logic [31:0] haddr_q[$];
protected rand logic [31:0] hrwdata_q[$];
protected rand htrans_t htrans_q[$];
protected int unsigned haddr_idx = 0;
protected int unsigned hrwdata_idx = 0;
protected int unsigned htrans_idx = 0;
//Factory Registration
`uvm_object_utils_begin(ahbl_trans)
`uvm_field_int (hsel, UVM_ALL_ON)
`uvm_field_int (haddr, UVM_ALL_ON)
`uvm_field_enum (htrans_t, htrans, UVM_ALL_ON)
`uvm_field_enum (hsize_t, hsize, UVM_ALL_ON)
`uvm_field_enum (hburst_t, hburst, UVM_ALL_ON)
`uvm_field_int (hprot, UVM_ALL_ON)
`uvm_field_int (hwrite, UVM_ALL_ON)
`uvm_field_int (hrwdata, UVM_ALL_ON)
`uvm_field_int (hreadyout, UVM_ALL_ON)
`uvm_field_int (clk_ratio, UVM_ALL_ON)
`uvm_field_int (hresp, UVM_ALL_ON)
`uvm_field_int (bst_beats, UVM_ALL_ON)
`uvm_field_queue_int (haddr_q, UVM_ALL_ON)
`uvm_field_queue_int (hrwdata_q, UVM_ALL_ON)
`uvm_field_queue_enum (htrans_t, htrans_q, UVM_ALL_ON)
`uvm_field_int (haddr_idx, UVM_ALL_ON)
`uvm_field_int (hrwdata_idx, UVM_ALL_ON)
`uvm_field_int (htrans_idx, UVM_ALL_ON)
`uvm_object_utils_end
//------------------------------------------
// Constraints
//------------------------------------------
constraint haddr_constr{
(hsize == HWORD)-> (haddr[0] == 1'b0);
(hsize == WORD) -> (haddr[1:0] == 2'b0);
solve hsize before haddr;
}
constraint hsize_constr{
(hsize <= 2); //Bit-width == 32, so hsize == BYTE/HWORD/WORD
}
constraint htrans_constr{
htrans == IDLE -> (hburst == SINGLE);
solve htrans before hburst;
}
constraint hburst_constr{
(hburst == SINGLE) -> (bst_beats == 1);
(hburst == WRAP4 ) -> (bst_beats == 4);
(hburst == WRAP8 ) -> (bst_beats == 8);
(hburst == WRAP16) -> (bst_beats == 16);
(hburst == INCR4 ) -> (bst_beats == 4);
(hburst == INCR8 ) -> (bst_beats == 8);
(hburst == INCR16) -> (bst_beats == 16);
solve hburst before bst_beats;
}
constraint queue_constr{
haddr_q.size() == bst_beats;
hrwdata_q.size() == bst_beats;
htrans_q.size() == bst_beats;
solve bst_beats before haddr_q;
solve bst_beats before hrwdata_q;
solve bst_beats before htrans_q;
}
logic [3:0] array_ratio[] ='{4'h1,4'h2,4'h4,4'h8};
constraint clk_ratio_constr{
clk_ratio inside {array_ratio};
}
//----------------------------------------------
// Methods
// ---------------------------------------------
// Standard UVM Methods:
function new(string name = "ahbl_tran");
super.new(name);
endfunction
function void post_randomize();
int i;
haddr_q[0] = haddr;
htrans_q[0] = NSEQ;
hrwdata_q[0] = hrwdata;
for (i = 1; i < bst_beats; i++) begin
haddr_q[i] = haddr_q[i-1] + (2**hsize);
htrans_q[i] = SEQ;
end
endfunction
// User Defined Methods:
virtual function logic [31:0] nxt_haddr();
haddr_idx++;
return haddr_q[haddr_idx - 1];
endfunction
virtual function logic [31:0] nxt_hrwdata();
hrwdata_idx++;
return hrwdata_q[hrwdata_idx - 1];
endfunction
virtual function logic [31:0] nxt_htrans();
htrans_idx++;
return htrans_q[htrans_idx - 1];
endfunction
virtual function logic [31:0] htrans_ro();
htrans_ro = htrans_q[htrans_idx];
return htrans_ro;
endfunction
virtual function bit last_beat();
return (htrans_idx == htrans_q.size());
endfunction
virtual function int get_bst_beats();
return(bst_beats);
endfunction
endclass
class ahbl_mst_basic_seq extends uvm_sequence#(ahbl_trans);
ahbl_trans req;
//Factory Registration
//
`uvm_object_utils(ahbl_mst_basic_seq)
//----------------------------------------------
// Methods
// ---------------------------------------------
// Standard UVM Methods:
function new(string name = "ahbl_mst_basic_seq");
super.new(name);
endfunction
virtual task pre_body();
if(starting_phase != null) begin
starting_phase.raise_objection(this);
end
endtask
virtual task post_body();
if(starting_phase != null) begin
starting_phase.drop_objection(this);
end
endtask
endclass
class ahbl_mst_burst_seq extends ahbl_mst_basic_seq;
//Factory Registration
//
`uvm_object_utils(ahbl_mst_burst_seq)
//----------------------------------------------
// Methods
// ---------------------------------------------
// Standard UVM Methods:
function new(string name = "ahbl_mst_burst_seq");
super.new(name);
endfunction
/*virtual task body();
ahbl_trans req;
`uvm_do_with(req, { req.hsel == 1'b1; req.hburst inside {[2:7]};})
endtask*/
virtual task body();
req = ahbl_trans::type_id::create("req");
`uvm_info(get_type_name(),"create complete",UVM_LOW)
wait_for_grant();
`uvm_info(get_type_name(),"GET GRANT",UVM_LOW)
assert(req.randomize() with { req.hsel == 1'b1; req.hburst inside {[2:7]};});
`uvm_info(get_type_name(),"RANDOMIZE SUCCESSFUL",UVM_LOW)
req.print();
send_request(req);
`uvm_info(get_type_name(),"SEND REQUEST",UVM_LOW)
wait_for_item_done();
get_response(rsp);
endtask
endclass
class ahbl_mst_sqr extends uvm_sequencer#(ahbl_trans);
//Factory Registration
//
`uvm_component_utils(ahbl_mst_sqr)
//----------------------------------------------
// Methods
// ---------------------------------------------
// Standard UVM Methods:
extern function new(string name = "ahbl_mst_sqr", uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
// User Defined Methods:
endclass
//Constructor
function ahbl_mst_sqr::new(string name = “ahbl_mst_sqr”, uvm_component parent);
super.new(name, parent);
endfunction
function void ahbl_mst_sqr::build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
class ahbl_mst_drv extends uvm_driver#(ahbl_trans);
//------------------------------------------
// Data, Interface, port Members
//------------------------------------------
virtual ahbl_if vif;
ahbl_trans pkt_apha = null; //packet address-phase
ahbl_trans pkt_dpha = null; //packet data-phase
uvm_sequence_item item;
//Factory Registration
//
`uvm_component_utils(ahbl_mst_drv)
//----------------------------------------------
// Methods
// ---------------------------------------------
// Standard UVM Methods:
extern function new(string name = "ahbl_mst_drv", uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
extern virtual task main_phase(uvm_phase phase);
// User Defined Methods:
extern task drive_lcyc_pkt_dpha(ref ahbl_trans pkt);
extern task drive_lcyc_pkt_apha(ref ahbl_trans pkt);
extern task drive_lcyc_pkt_idle();
endclass
class ahbl_mst_tight_transfer extends ahb2apb_base_test;
//------------------------------------------
// Data, Interface, port Members
//------------------------------------------
ahbl_mst_burst_seq ahbl_mst_burst_seq_0;
ahbl_mst_burst_seq ahbl_mst_burst_seq_1;
apb_slv_nrdy_seq apb_slv_nrdy_seq_i;
//Factory Registration
//
`uvm_component_utils(ahbl_mst_tight_transfer)
//----------------------------------------------
// Methods
//----------------------------------------------
// Standard UVM Methods:
extern function new(string name = "ahbl_mst_tight_transfer", uvm_component parent);
extern virtual function void build_phase(uvm_phase phase);
extern virtual task main_phase(uvm_phase phase);
// User Defined Methods:
endclass
//Constructor
function ahbl_mst_tight_transfer::new(string name = “ahbl_mst_tight_transfer”, uvm_component parent);
super.new(name, parent);
endfunction
//Build_Phase
function void ahbl_mst_tight_transfer::build_phase(uvm_phase phase);
super.build_phase(phase);
ahbl_mst_burst_seq_0 = ahbl_mst_burst_seq::type_id::create(“ahbl_mst_burst_seq_0”);
ahbl_mst_burst_seq_1 = ahbl_mst_burst_seq::type_id::create(“ahbl_mst_burst_seq_1”);
apb_slv_nrdy_seq_i = apb_slv_nrdy_seq::type_id::create(“apb_slv_nrdy_seq_i”);
endfunction
//Main_Phase
task ahbl_mst_tight_transfer::main_phase(uvm_phase phase);
int num_apb_seq;
phase.raise_objection(this);
super.main_phase(phase);
#100us;
fork
begin
ahbl_mst_burst_seq_0.start(env_i.ahbl_mst_agt_i.sqr_i);
ahbl_mst_burst_seq_1.start(env_i.ahbl_mst_agt_i.sqr_i);
end
begin
num_apb_seq = 0;
while(1) begin
apb_slv_nrdy_seq_i.start(env_i.apb_slv_agt_i.sqr_i);
num_apb_seq++;
if(num_apb_seq >= ahbl_mst_burst_seq_0.req.get_bst_beats()) begin
num_apb_seq = 0;
break;
end
end
while(1) begin
apb_slv_nrdy_seq_i.start(env_i.apb_slv_agt_i.sqr_i);
num_apb_seq++;
if(num_apb_seq >= ahbl_mst_burst_seq_1.req.get_bst_beats())
break;
end
end
join
phase.drop_objection(this);
endtask
//Constructor
function ahbl_mst_drv::new(string name = “ahbl_mst_drv”, uvm_component parent);
super.new(name, parent);
endfunction
//Build_Phase
function void ahbl_mst_drv::build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual ahbl_if)::get(this,“”,“vif”,vif))
`uvm_fatal(“my_driver”, “Error in Getting interface”)
endfunction
//Main_Phase
task ahbl_mst_drv::main_phase(uvm_phase phase);
while(1) begin
@(vif.mst_cb);
if(!vif.mst_cb.hresetn) begin
vif.mst_cb.hsel <= 1’b0;
vif.mst_cb.haddr <= 32’b0;
vif.mst_cb.htrans <= IDLE;
vif.mst_cb.hsize <= BYTE;
vif.mst_cb.hburst <= SINGLE;
vif.mst_cb.hprot <= 4’b0;
vif.mst_cb.hwrite <= 1’b0;
vif.mst_cb.hwdata <= 32’b0;
vif.mst_cb.clk_ratio<= 4’h1;
pkt_dpha = null;
pkt_apha = null;
end
else begin
//transfer data
if(pkt_dpha != null) begin
drive_lcyc_pkt_dpha(pkt_dpha);
if(vif.mst_cb.hready & (pkt_dpha.hburst == SINGLE | pkt_dpha.last_beat())) begin
seq_item_port.item_done();
pkt_dpha = null;
pkt_apha = null;
end
end
if(pkt_apha != null) begin
//transfer address
drive_lcyc_pkt_apha(pkt_apha);
end
else begin
`uvm_info(get_type_name(),"BEFORE get next item",UVM_LOW)
seq_item_port.get_next_item(pkt_apha);//(pkt_apha);
`uvm_info(get_type_name(),"AFTER get next item",UVM_LOW)
if(pkt_apha != null) begin
drive_lcyc_pkt_apha(pkt_apha);
pkt_apha.print();
`uvm_info(get_type_name(), "ahbl_mst_drv successfully get a new AddressPhase pkt", UVM_LOW)
end
else begin
drive_lcyc_pkt_idle();
//`uvm_info(get_type_name(), "ahbl_mst_drv didn't get a new AddressPhase pkt", UVM_LOW)
end
end
end
end
endtask
task ahbl_mst_drv::drive_lcyc_pkt_dpha(ref ahbl_trans pkt);
if(vif.mst_cb.hready)
vif.mst_cb.hwdata <= pkt.hwrite ? pkt.nxt_hrwdata() : 32’d0;
endtask
task ahbl_mst_drv::drive_lcyc_pkt_apha(ref ahbl_trans pkt);
if((vif.mst_cb.hready)) begin
vif.mst_cb.hsel <= pkt.hsel;
vif.mst_cb.haddr <= ((pkt.htrans_ro() != IDLE)&(pkt.htrans_ro() != BUSY)) ? pkt.nxt_haddr() : vif.haddr;
vif.mst_cb.htrans <= pkt.nxt_htrans();
vif.mst_cb.hsize <= pkt.hsize;
vif.mst_cb.hburst <= pkt.hburst;
vif.mst_cb.hprot <= pkt.hprot;
vif.mst_cb.hwrite <= pkt.hwrite;
vif.mst_cb.clk_ratio<= pkt.clk_ratio;
this.pkt_dpha <= this.pkt_apha;
end
endtask
task ahbl_mst_drv::drive_lcyc_pkt_idle();
vif.mst_cb.hsel <= 1’b0;
vif.mst_cb.haddr <= 32’b0;
vif.mst_cb.htrans <= IDLE;
vif.mst_cb.hsize <= BYTE;
vif.mst_cb.hburst <= SINGLE;
vif.mst_cb.hprot <= 4’b0;
vif.mst_cb.hwrite <= 1’b0;
vif.mst_cb.clk_ratio<= 4’h1;
endtask
UVM_INFO .\dv\vip\ahbl_mst\ahbl_mst_drv.svh(98) @ 50: uvm_test_top.env_i.ahbl_mst_agt_i.drv_i [ahbl_mst_drv] BEFORE get next item
UVM_INFO ./dv/seqlib/ahbl_mst_seqlib.sv(75) @ 100007: uvm_test_top.env_i.ahbl_mst_agt_i.sqr_i@@ahbl_mst_burst_seq_0 [ahbl_mst_burst_seq] create complete
UVM_INFO ./dv/seqlib/ahbl_mst_seqlib.sv(77) @ 100007: uvm_test_top.env_i.ahbl_mst_agt_i.sqr_i@@ahbl_mst_burst_seq_0 [ahbl_mst_burst_seq] GET GRANT
UVM_INFO ./dv/seqlib/ahbl_mst_seqlib.sv(79) @ 100007: uvm_test_top.env_i.ahbl_mst_agt_i.sqr_i@@ahbl_mst_burst_seq_0 [ahbl_mst_burst_seq] RANDOMIZE SUCCESSFUL
------------------------------------------------
Name Type Size Value
------------------------------------------------
req ahbl_trans - @1023
hsel integral 1 'h1
haddr integral 32 'hf04b3dfc
htrans htrans_t 2 SEQ
hsize hsize_t 3 HWORD
hburst hburst_t 3 INCR16
hprot integral 4 'h4
hwrite integral 1 'h1
hrwdata integral 32 'h87757203
hreadyout integral 1 'h0
clk_ratio integral 4 'h4
hresp integral 1 'h0
bst_beats integral 32 'h10
haddr_q da(integral) 16 -
[0] integral 32 'hf04b3dfc
[1] integral 32 'hf04b3dfe
[2] integral 32 'hf04b3e00
[3] integral 32 'hf04b3e02
[4] integral 32 'hf04b3e04
… … … …
[11] integral 32 'hf04b3e12
[12] integral 32 'hf04b3e14
[13] integral 32 'hf04b3e16
[14] integral 32 'hf04b3e18
[15] integral 32 'hf04b3e1a
hrwdata_q da(integral) 16 -
[0] integral 32 'h87757203
[1] integral 32 'hc465ecd5
[2] integral 32 'hfb163a14
[3] integral 32 'hd767f58d
[4] integral 32 'h3444859
… … … …
[11] integral 32 'h43b60bde
[12] integral 32 'h6599fa67
[13] integral 32 'h79662df7
[14] integral 32 'hf182cf2
[15] integral 32 'hfc82bda1
htrans_q array(htrans_t) 16 -
[0] htrans_t 2 NSEQ
[1] htrans_t 2 SEQ
[2] htrans_t 2 SEQ
[3] htrans_t 2 SEQ
[4] htrans_t 2 SEQ
… … … …
[11] htrans_t 2 SEQ
[12] htrans_t 2 SEQ
[13] htrans_t 2 SEQ
[14] htrans_t 2 SEQ
[15] htrans_t 2 SEQ
haddr_idx integral 32 'h0
hrwdata_idx integral 32 'h0
htrans_idx integral 32 'h0
------------------------------------------------
UVM_FATAL @ 100007: uvm_test_top.env_i.ahbl_mst_agt_i.sqr_i [sqr_i] send_request failed to cast sequence item
from the simulation information i know the mistake maybe is around get_next_item(),but i dont know how to fix it.