APB的层次关系
实现APB master driver的drive_transfer()方法
task apb_master_driver::get_and_drive();
forever begin
seq_item_port.get_next_item(req);
`uvm_info(get_type_name(), "sequencer got next item", UVM_HIGH)
drive_transfer(req);
void'($cast(rsp, req.clone()));
rsp.set_sequence_id(req.get_sequence_id());
seq_item_port.item_done(rsp);
`uvm_info(get_type_name(), "sequencer item_done_triggered", UVM_HIGH)
end
endtask: get_and_drive
task apb_master_driver::drive_transfer (apb_transfer t);
`uvm_info(get_type_name(), "drive_transfer", UVM_HIGH)
case(t.trans_kind)
IDLE : this.do_idle();
WRITE : this.do_write(t);
READ : this.do_read(t);
default : `uvm_error("ERRTYPE", "unrecognized transaction type")
endcase
endtask: drive_transfer
task apb_master_driver::do_write(apb_transfer t);
`uvm_info(get_type_name(), "do_write ...", UVM_HIGH)
@(vif.cb_mst);
vif.cb_mst.paddr <= t.addr;
vif.cb_mst.pwrite <= 1;
vif.cb_mst.psel <= 1;
vif.cb_mst.penable <= 0;
vif.cb_mst.pwdata <= t.data;
@(vif.cb_mst);
vif.cb_mst.penable <= 1;
repeat(t.idle_cycles) this.do_idle();
endtask: do_write
task apb_master_driver::do_read(apb_transfer t);
`uvm_info(get_type_name(), "do_read ...", UVM_HIGH)
@(vif.cb_mst);
vif.cb_mst.paddr <= t.addr;
vif.cb_mst.pwrite <= 0;
vif.cb_mst.psel <= 1;
vif.cb_mst.penable <= 0;
@(vif.cb_mst);
vif.cb_mst.penable <= 1;
#100ps;
t.data = vif.prdata;
repeat(t.idle_cycles) this.do_idle();
endtask: do_read
task apb_master_driver::do_idle();
`uvm_info