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


    目录

    实验目标

     chnl_pkg的变化

    arb_pkg的变化

    mcdf_pkg的变化

    其他文件也是类似

    tb的变化


    实验目标

    完成SV到UVM的移植转化

     chnl_pkg的变化

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

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

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

    1. class chnl_trans extends uvm_sequence_item;
    2. class chnl_driver extends uvm_driver #(chnl_trans);
    3. class chnl_generator extends uvm_component;
    4. class chnl_monitor extends uvm_monitor;
    5. class chnl_agent extends uvm_agent;

    每个组件都要进行注册

    1. `uvm_component_utils(chnl_driver)
    2. `uvm_component_utils(chnl_monitor)
    3. `uvm_component_utils(chnl_agent)

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

    1. `uvm_object_utils_begin(chnl_trans)
    2. `uvm_field_array_int(data, UVM_ALL_ON)
    3. `uvm_field_int(ch_id, UVM_ALL_ON)
    4. `uvm_field_int(pkt_id, UVM_ALL_ON)
    5. `uvm_field_int(data_nidles, UVM_ALL_ON)
    6. `uvm_field_int(pkt_nidles, UVM_ALL_ON)
    7. `uvm_field_int(rsp, UVM_ALL_ON)
    8. `uvm_object_utils_end
    9. `uvm_component_utils_begin(chnl_generator)
    10. `uvm_field_int(pkt_id, UVM_ALL_ON)
    11. `uvm_field_int(ch_id, UVM_ALL_ON)
    12. `uvm_field_int(data_nidles, UVM_ALL_ON)
    13. `uvm_field_int(pkt_nidles, UVM_ALL_ON)
    14. `uvm_field_int(data_size, UVM_ALL_ON)
    15. `uvm_field_int(ntrans, UVM_ALL_ON)
    16. `uvm_component_utils_end

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

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

    1. task do_drive();
    2. chnl_trans req, rsp;
    3. @(posedge intf.rstn);
    4. forever begin
    5. this.req_mb.get(req);
    6. this.chnl_write(req);
    7. void'($cast(rsp, req.clone()));//clone返回的是uvm object类型(父类句柄)
    8. rsp.rsp = 1;
    9. this.rsp_mb.put(rsp);
    10. end
    11. endtask
    12. task chnl_write(input chnl_trans t);
    13. foreach(t.data[i]) begin
    14. @(posedge intf.clk);
    15. intf.drv_ck.ch_valid <= 1;
    16. intf.drv_ck.ch_data <= t.data[i];
    17. @(negedge intf.clk);
    18. wait(intf.ch_ready === 'b1);
    19. `uvm_info(get_type_name(), $sformatf("sent data 'h%8x", t.data[i]), UVM_HIGH)
    20. repeat(t.data_nidles) chnl_idle();
    21. end
    22. repeat(t.pkt_nidles) chnl_idle();
    23. endtask

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

    1. task run_phase(uvm_phase phase);
    2. fork
    3. this.do_drive();
    4. this.do_reset();
    5. join
    6. endtask

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

    1. function new (string name = "chnl_trans");
    2. super.new(name);
    3. endfunction
    4. function new (string name = "chnl_driver", uvm_component parent);
    5. super.new(name, parent);
    6. endfunction
    7. function new (string name = "chnl_generator", uvm_component parent);
    8. super.new(name, parent);
    9. this.req_mb = new();
    10. this.rsp_mb = new();
    11. endfunction
    12. function new(string name="chnl_monitor", uvm_component parent);
    13. super.new(name, parent);
    14. endfunction
    15. function new(string name = "chnl_agent", uvm_component parent);
    16. super.new(name, parent);
    17. endfunction

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

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

    arb_pkg的变化

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

    mcdf_pkg的变化

    例化refmod用工厂的方法

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

    其他文件也是类似

    tb的变化

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

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

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

  • 相关阅读:
    算法(三)
    OpenGL - Gamma Correction
    C++友元(friend)
    Oracle "脑残" CBO 优化案例
    球谐函数实现环境光照漫反射实践
    Jenkins服务开机自启动
    openGauss学习笔记-101 openGauss 数据库管理-管理数据库安全-客户端接入之用SSH隧道进行安全的TCP/IP连接
    基于盛科芯片的PTP功能总结
    大话设计模式之抽象工厂模式
    docker搭建jenkins
  • 原文地址:https://blog.csdn.net/weixin_39668316/article/details/126355226