AHB-to-APB Bridge——08burst_test(rdy、nrdy、slverr、tight)、地址

-------------- 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);
  endfunction

  virtual 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);
  endfunction
  
  virtual 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才工作)
      begin
        ahbl_mst_seq_i.start(env_i.ahbl_mst_agt_i.sqr_i);
      end
      begin
        num_apb_seq = 0;
        while(1)begin
          apb_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())begin
            break;//APB侧传输数据的个数,大于或等于AHB侧的数据个数后,跳出循环
          end
        end
      end
    join
    phase.drop_objection(this);
  endtask

endclass

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;AHB-to-APB Bridge——08burst_test(rdy、nrdy、slverr、tight)、地址_第1张图片

 --------------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);
  endfunction

  virtual 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);
  endfunction
  
  virtual task run_phase(uvm_phase phase);
    int num_apb_seq;
    phase.raise_objection(this);
    super.run_phase(phase);

    #100us;
    fork
      begin
        ahbl_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);
      end
      begin
        num_apb_seq = 0;
        while(1)begin
          apb_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())begin
            break;
          end
        end
        while(1)begin
          apb_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())begin
            break;
          end
        end
      end
    join
    phase.drop_objection(this);
  endtask

endclass

 第一个随机burst是WORD读操作,第二个是HALFWORD写操作;

AHB写操作第一个5666说明写入高两个字节有效为AB6C3EE5;第二个5668说明低两个字节有效为477EF246;APB端地址总是一次加4,PSTRB信号代表了地址是高有效还是低有效,C为1100说明高有效,3为0011说明低有效;(PSTRB仅用于写,说明了哪个字节数据是有效)

 

-------------------------------地址解读:32位一次传4字节,地址0、4、8、C变化;

AHB-to-APB Bridge——08burst_test(rdy、nrdy、slverr、tight)、地址_第2张图片

 16位一次传2字节HalfWord,地址0、2、4、6、8、A…变化;

AHB-to-APB Bridge——08burst_test(rdy、nrdy、slverr、tight)、地址_第3张图片

 如地址0X42,HWORD传输,随机出来的32位数据只有高两个字节有效;低两个字节无效;

AHB-to-APB Bridge——08burst_test(rdy、nrdy、slverr、tight)、地址_第4张图片

 

你可能感兴趣的:(fpga开发)