IC验证学习笔记(AHB-RAM)03更新ahb_driver

更新driver的run_phase以及get_and_drive任务:

task run_phase(uvm_phase phase);
    super.run_phase(phase);
    fork
     get_and_drive();
     reset_listener();
    join_none
  endtask

  virtual task 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());
      rsp.set_transaction_id(req.get_transaction_id());
      seq_item_port.item_done(rsp);
      `uvm_info(get_type_name(), "sequencer item_done_triggered", UVM_HIGH)
    end
  endtask : get_and_drive

  virtual task drive_transfer(REQ t);
    // TODO implementation in child class 在子类实现
  endtask

  virtual task reset_listener();
    // TODO implementation in child class
  endtask

 在ahb_if中定义一些enum的debug方便我们后续观察:

  response_type_enum                      debug_hresp;
  trans_type_enum                         debug_htrans;
  burst_size_enum                         debug_hsize;
  burst_type_enum                         debug_hburst;
  xact_type_enum                          debug_xact;
  status_enum                             debug_status;

  // debug signals assignment
  assign debug_hresp    = response_type_enum'(hresp);
  assign debug_htrans   = trans_type_enum'(htrans);
  assign debug_hsize    = burst_size_enum'(hsize);
  assign debug_hburst   = burst_type_enum'(hburst);
  // the below signals to be assigned by monitor
  // debug_xact ..
  // debug_status ..

以及ahb_if 中的时钟块:

  clocking cb_mst @(posedge hclk);
    // USER: Add clocking block detail
    default input #1ps output #1ps;
    output haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite; 
    input hready, hgrant, hrdata;
  endclocking : cb_mst

  clocking cb_slv @(posedge hclk);
   // USER: Add clocking block detail
    default input #1ps output #1ps;
    input haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite; 
    output hready, hgrant, hrdata;
  endclocking : cb_slv

  clocking cb_mon @(posedge hclk);
   // USER: Add clocking block detail
    default input #1ps output #1ps;
    input haddr, hburst, hbusreq, hlock, hprot, hsize, htrans, hwdata, hwrite; 
    input hready, hgrant, hrdata;
  endclocking : cb_mon

子类master_driver:

父类get and drive的drive_transfer在master_driver中实现

先判断传输类型(只有SINGLE),再判断read或write实现对应读写任务

`ifndef LVC_AHB_MASTER_DRIVER_SV
`define LVC_AHB_MASTER_DRIVER_SV

class lvc_ahb_master_driver extends lvc_ahb_driver;
  lvc_ahb_agent_configuration cfg;
  virtual lvc_ahb_if vif;
  `uvm_component_utils(lvc_ahb_master_driver)

  function new(string name = "lvc_ahb_master_driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
  endfunction

  task run_phase(uvm_phase phase);
    super.run_phase(phase);
  endtask

  virtual task drive_transfer(REQ t);
    // TODO implementation in child class
    case(t.burst_type)
      SINGLE: begin do_atomic_trans(t); end
      INCR  : begin `uvm_error("TYPEERR", "burst type not supported yet") end
      WRAP4 : begin `uvm_error("TYPEERR", "burst type not supported yet") end
      INCR4 : begin `uvm_error("TYPEERR", "burst type not supported yet") end
      WRAP8 : begin `uvm_error("TYPEERR", "burst type not supported yet") end
      INCR8 : begin `uvm_error("TYPEERR", "burst type not supported yet") end
      WRAP16: begin `uvm_error("TYPEERR", "burst type not supported yet") end
      INCR16: begin `uvm_error("TYPEERR", "burst type not supported yet") end
      default: begin `uvm_error("TYPEERR", "burst type not defined") end
    endcase
  endtask

  virtual task do_atomic_trans(REQ t);
    case(t.trans_type)							//??
      READ      : do_read(t);
      WRITE     : do_write(t);
      IDLE_XACT : begin `uvm_error("TYPEERR", "trans type not supported yet") end
      default: begin `uvm_error("TYPEERR", "trans type not defined") end
    endcase
  endtask

  virtual task wait_for_bus_grant();
    @(vif.cb_mst iff vif.cb_mst.hgrant === 1'b1);
  endtask

  virtual task do_write(REQ t);
    do_init_write(t);
    do_proc_write(t);
  endtask

  virtual task do_read(REQ t);
    do_init_read(t);
    do_proc_read(t);
  endtask

  virtual task do_init_write(REQ t);
    wait_for_bus_grant();//等待grant信号
    @(vif.cb_mst);
    vif.cb_mst.htrans <= NSEQ;//trans_type_enum 类型为NSEQ 代表第一个数据
    vif.cb_mst.haddr  <= t.addr;
    vif.cb_mst.hburst <= t.burst_type;
    vif.cb_mst.hsize  <= t.burst_size;//固定hsize
    vif.cb_mst.hwrite <= 1'b1;//驱动write
    @(vif.cb_mst);				//传入数据,等待第二拍ready信号为高,
    vif.cb_mst.hwdata <= t.data[0];
    // check ready with delay in current cycle
    forever begin
      @(negedge vif.hclk);//需要检测第二拍时的ready,检测下降沿最准确
      if(vif.hready === 1'b1) begin
        break;
      end
      else
        @(vif.cb_mst);//如果为低则需要再等一拍
    end

    // update current trans status
    t.trans_type = NSEQ;
    t.current_data_beat_num = 0; // start beat from 0 to make consistence with data array index
    t.all_beat_response[t.current_data_beat_num] = response_type_enum'(vif.hresp);
	//记录下每一位的response OKAY、ERROR、RETRY、SPLIT 
  endtask

  virtual task do_init_read(REQ t);
    wait_for_bus_grant();
    @(vif.cb_mst);
    vif.cb_mst.htrans <= NSEQ;
    vif.cb_mst.haddr  <= t.addr;
    vif.cb_mst.hburst <= t.burst_type;
    vif.cb_mst.hsize  <= t.burst_size;
    vif.cb_mst.hwrite <= 1'b0;	//读操作
    @(vif.cb_mst);
    // check ready with delay in current cycle
    forever begin
      @(negedge vif.hclk);
      if(vif.hready === 1'b1) begin	//同样在negedge时检查ready是否为高
        break;
      end
      else
        @(vif.cb_mst);
    end
    t.data = new[t.current_data_beat_num+1](t.data);//重置一下data,new一位并加上之前的data
    t.data[0] = vif.hrdata;//等待第二拍ready信号为高,读进数据,
    
    // update current trans status
    t.trans_type = NSEQ;
    t.current_data_beat_num = 0; // start beat from 0 to make consistence with data array index
    t.all_beat_response[t.current_data_beat_num] = response_type_enum'(vif.hresp);
  endtask

  virtual task do_proc_write(REQ t);
    // TODO implement for SEQ operations of other BURST types
    do_init_idle(t);
  endtask

  virtual task do_proc_read(REQ t);
    // TODO implement for SEQ operations of other BURST types
    do_init_idle(t);
  endtask

  virtual protected task do_init_idle(REQ t);//写了以后不再写了需要置为IDLE状态
    @(vif.cb_mst);
    _do_drive_idle();
  endtask

  virtual protected task _do_drive_idle();
    vif.cb_mst.haddr     <= 0;
    vif.cb_mst.hburst    <= 0;
    vif.cb_mst.hbusreq   <= 0;
    vif.cb_mst.hlock     <= 0;
    vif.cb_mst.hprot     <= 0;
    vif.cb_mst.hsize     <= 0;
    vif.cb_mst.htrans    <= 0;
    vif.cb_mst.hwdata    <= 0;
    vif.cb_mst.hwrite    <= 0;
  endtask

  virtual protected task reset_listener();
    `uvm_info(get_type_name(), "reset_listener ...", UVM_HIGH)
    fork
      forever begin
        @(negedge vif.hresetn); // ASYNC reset
        _do_drive_idle();
      end
    join_none
  endtask

endclass


`endif // LVC_AHB_MASTER_DRIVER_SV

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值