-------------- burst_test:与single_test不同的是,需要在run_phase中使用fork join 让AHB侧和APB侧同时工作(不能等AHB都发完APB才工作);num_apb_seq为APB已传输的个数,当APB侧传输数据的个数,大于或等于AHB侧的总数据个数后,跳出循环;
class ahbl_mst_burst extends ahb2apb_base_test;ahbl_mst_burst_seq ahbl_mst_seq_i;apb_slv_nrdy_seq apb_slv_seq_i;`uvm_component_utils(ahbl_mst_burst)function new(string name,uvm_component parent=null);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);ahbl_mst_seq_i = ahbl_mst_burst_seq::type_id::create("ahbl_mst_seq_i",this);apb_slv_seq_i = apb_slv_nrdy_seq::type_id::create("apb_slv_seq_i",this);endfunctionvirtual task run_phase(uvm_phase phase);int num_apb_seq;phase.raise_objection(this);super.run_phase(phase);#100us;fork//使用fork join 让AHB侧和APB侧同时工作(不能等AHB都发完APB才工作)beginahbl_mst_seq_i.start(env_i.ahbl_mst_agt_i.sqr_i);endbeginnum_apb_seq = 0;while(1)beginapb_slv_seq_i.start(env_i.apb_slv_agt_i.sqr_i);num_apb_seq++;if(num_apb_seq >= ahbl_mst_seq_i.req.get_bst_beats())beginbreak;//APB侧传输数据的个数,大于或等于AHB侧的数据个数后,跳出循环endendendjoinphase.drop_objection(this);endtaskendclass
burst_seq中:将htrans、hsize、hburst、hwrite注释掉(全部随机)
class ahbl_mst_burst_seq extends ahbl_mst_basic_seq;function new(string name="ahbl_mst_burst_seq");super.new(name);endfunction`uvm_object_utils(ahbl_mst_burst_seq)virtual task body();`uvm_do_with(req,{hsel == 1'b1;//htrans == ahbl_mst_pkg::NSEQ;// hsize == ahbl_mst_pkg::WORD;//hburst == ahbl_mst_pkg::SINGLE;//hwrite == 1'b1;})endtask
endclass
---------- burst_test_slverr:每次传输slv侧slverr为1,随机1:5个周期的nready:
class apb_slv_slverr_seq extends apb_slv_basic_seq;function new(string name = "apb_slv_slverr_seq");super.new(name);endfunction`uvm_object_utils(apb_slv_slverr_seq)virtual task body();`uvm_do_with(req,{slverr == 1'b1;nready_num inside {[1:5]};})endtask
endclass
AHB侧收到SLVERR的波形为第一个周期HRESP为高,HREADYOUT为低;第二个周期都为高;
对于AHB协议中所讲,遇到ERRO可以立即停掉或者传输完毕给IDLE;
--------------burst_tight_transfer(紧密传输两个burst):基本相同,例化两个相同的burst_seq,再run_phase中先后使用,并先后分别判断传输数量后跳出循环;
class ahbl_mst_tight_transfer extends ahb2apb_base_test;ahbl_mst_burst_seq ahbl_mst_seq_0;ahbl_mst_burst_seq ahbl_mst_seq_1;apb_slv_nrdy_seq apb_slv_seq_i;`uvm_component_utils(ahbl_mst_tight_transfer)function new(string name,uvm_component parent=null);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);ahbl_mst_seq_0 = ahbl_mst_burst_seq::type_id::create("ahbl_mst_seq_0",this);ahbl_mst_seq_1 = ahbl_mst_burst_seq::type_id::create("ahbl_mst_seq_1",this);apb_slv_seq_i = apb_slv_nrdy_seq::type_id::create("apb_slv_seq_i",this);endfunctionvirtual task run_phase(uvm_phase phase);int num_apb_seq;phase.raise_objection(this);super.run_phase(phase);#100us;forkbeginahbl_mst_seq_0.start(env_i.ahbl_mst_agt_i.sqr_i);ahbl_mst_seq_1.start(env_i.ahbl_mst_agt_i.sqr_i);endbeginnum_apb_seq = 0;while(1)beginapb_slv_seq_i.start(env_i.apb_slv_agt_i.sqr_i);num_apb_seq++;if(num_apb_seq >= ahbl_mst_seq_0.req.get_bst_beats())beginbreak;endendwhile(1)beginapb_slv_seq_i.start(env_i.apb_slv_agt_i.sqr_i);num_apb_seq++;if(num_apb_seq >= ahbl_mst_seq_1.req.get_bst_beats())beginbreak;endendendjoinphase.drop_objection(this);endtaskendclass
第一个随机burst是WORD读操作,第二个是HALFWORD写操作;
AHB写操作第一个5666说明写入高两个字节有效为AB6C3EE5;第二个5668说明低两个字节有效为477EF246;APB端地址总是一次加4,PSTRB信号代表了地址是高有效还是低有效,C为1100说明高有效,3为0011说明低有效;(PSTRB仅用于写,说明了哪个字节数据是有效)
-------------------------------地址解读:32位一次传4字节,地址0、4、8、C变化;
16位一次传2字节HalfWord,地址0、2、4、6、8、A…变化;
如地址0X42,HWORD传输,随机出来的32位数据只有高两个字节有效;低两个字节无效;