电力电子转战数字IC20220815day60——uvm入门实验2

目录

实验目标

 chnl_pkg的变化

arb_pkg的变化

mcdf_pkg的变化

其他文件也是类似

tb的变化


实验目标

完成SV到UVM的移植转化

 chnl_pkg的变化

首先在package下面要植入uvm_pkg和uvm_macros.svh

  import uvm_pkg::*;
  `include "uvm_macros.svh"

每个class都有对应的继承的父类,driver是参数类,需要标明发送的是chnl_trans

  class chnl_trans extends uvm_sequence_item;
  class chnl_driver extends uvm_driver #(chnl_trans);
  class chnl_generator extends uvm_component;
  class chnl_monitor extends uvm_monitor;
  class chnl_agent extends uvm_agent;

每个组件都要进行注册

    `uvm_component_utils(chnl_driver)

    `uvm_component_utils(chnl_monitor)

    `uvm_component_utils(chnl_agent)

sequence item由于经常要对数据进行拷贝等操作,在注册时要有域的自动化。SV中对数据进行克隆和打印等函数被uvm提供的数据处理和消息管理替代替代。

    `uvm_object_utils_begin(chnl_trans)
      `uvm_field_array_int(data, UVM_ALL_ON)
      `uvm_field_int(ch_id, UVM_ALL_ON)
      `uvm_field_int(pkt_id, UVM_ALL_ON)
      `uvm_field_int(data_nidles, UVM_ALL_ON)
      `uvm_field_int(pkt_nidles, UVM_ALL_ON)
      `uvm_field_int(rsp, UVM_ALL_ON)
    `uvm_object_utils_end

    `uvm_component_utils_begin(chnl_generator)
      `uvm_field_int(pkt_id, UVM_ALL_ON)
      `uvm_field_int(ch_id, UVM_ALL_ON)
      `uvm_field_int(data_nidles, UVM_ALL_ON)
      `uvm_field_int(pkt_nidles, UVM_ALL_ON)
      `uvm_field_int(data_size, UVM_ALL_ON)
      `uvm_field_int(ntrans, UVM_ALL_ON)
    `uvm_component_utils_end

driver中的方法,由于clone()返回的是uvm_object类型,而rsp是chnl_trans的句柄,类型是sequence_item,需要进行动态转换$cast。

打印消息由$display变成uvm的消息管理`uvm_info

    task do_drive();
      chnl_trans req, rsp;
      @(posedge intf.rstn);
      forever begin
        this.req_mb.get(req);
        this.chnl_write(req);
        void'($cast(rsp, req.clone()));//clone返回的是uvm object类型(父类句柄)
        rsp.rsp = 1;
        this.rsp_mb.put(rsp);
      end
    endtask

    task chnl_write(input chnl_trans t);
      foreach(t.data[i]) begin
        @(posedge intf.clk);
        intf.drv_ck.ch_valid <= 1;
        intf.drv_ck.ch_data <= t.data[i];
        @(negedge intf.clk);
        wait(intf.ch_ready === 'b1);
        `uvm_info(get_type_name(), $sformatf("sent data 'h%8x", t.data[i]), UVM_HIGH)
        repeat(t.data_nidles) chnl_idle();
      end
      repeat(t.pkt_nidles) chnl_idle();
    endtask

根据uvm的phase机制,driver中响应的run任务也要变成run_phase(uvm_phase phase)

    task run_phase(uvm_phase phase);
      fork
       this.do_drive();
       this.do_reset();
      join
    endtask

由于有了继承关系,new函数中都要调用父类的new函数。继承于component的要多一个parent参数,继承于object的则没有。

    function new (string name = "chnl_trans");
      super.new(name);
    endfunction

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

    function new (string name = "chnl_generator", uvm_component parent);
      super.new(name, parent);
      this.req_mb = new();
      this.rsp_mb = new();
    endfunction

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

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

agent中多了build_phase,例化了driver和monitor。在SV中这部分是放在new函数中

    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      driver = chnl_driver::type_id::create("driver", this);
      monitor = chnl_monitor::type_id::create("monitor", this);
    endfunction

arb_pkg的变化

和上面的一样,由于本身就是空的,所以各个组件加上继承、注册、new函数即可

mcdf_pkg的变化

例化refmod用工厂的方法

    function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      foreach(this.chnl_mbs[i]) this.chnl_mbs[i] = new();
      this.fmt_mb = new();
      this.reg_mb = new();
      this.refmod = mcdf_refmod::type_id::create("refmod", this);
    endfunction

其他文件也是类似

tb的变化

通过uvm的配置完成接口在硬件tb到软件验证环境mcdf_env的传递

    uvm_config_db#(virtual chnl_intf)::set(uvm_root::get(), "uvm_test_top", "ch0_vif", chnl0_if);
    uvm_config_db#(virtual chnl_intf)::set(uvm_root::get(), "uvm_test_top", "ch1_vif", chnl1_if);
    uvm_config_db#(virtual chnl_intf)::set(uvm_root::get(), "uvm_test_top", "ch2_vif", chnl2_if);
    uvm_config_db#(virtual reg_intf)::set(uvm_root::get(), "uvm_test_top", "reg_vif", reg_if);
    uvm_config_db#(virtual arb_intf)::set(uvm_root::get(), "uvm_test_top", "arb_vif", arb_if);
    uvm_config_db#(virtual fmt_intf)::set(uvm_root::get(), "uvm_test_top", "fmt_vif", fmt_if);
    uvm_config_db#(virtual mcdf_intf)::set(uvm_root::get(), "uvm_test_top", "mcdf_vif", mcdf_if);

原来在tb中的test已经被UVM的run_test()替代了,不需要再调用test中的run

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值