• 电力电子转战数字IC20220816day61——uvm入门实验3


    目录

    实验目标

    实验任务

    1.1将monitor中用来与checker中的mailbox通信的mon_mb句柄换成对应的uvm_blocking_put_port类型

    1.2在checker中声明和monitor通信的imp端口,与refmod通信的imp端口

    1.3对上面声明的imp实现对应的方法

    1.4在mcdf_refmod中声明与checker连接的imp端口,例化

    1.5在mcdf_env的connect_phase()完成monitor的port连接到mcdf_checker imp

    1.6在mcdf_checker中完成mcdf_refmod的port连接到mcdf_checker的imp

    2.1将mcdf_refmod中的out_mb替换成uvm_tlm_fifo

    2.2同样的,mcdf_checker中的exp_mb[3]替换成uvm_blocking_get_port类型句柄数组。将mcdf_checker中的port连接到mcdf_refmod中uvm_tlm_fifo自带的blocking_get_export

    3.1利用回调函数完成类的复用,先预定义几个虚方法

    3.2关联回调类型和对应的test

    3.3回调指定,也就是连接

    3.4定义继承于base test的两个test的两个回调函数cb_*********,这两个回调函数都继承于base test的回调函数

    4在mcdf_base_test中添加新的end_of_elaboration_phase函数;利用uvm_root类设置信息冗余度为UVM_high;利用uvm_root::set_report_max_quit_count()函数设置仿真退出的最大数值;利用uvm_root::set_timeout()设置仿真的最大时间长度


    实验目标

    实验任务

    1.1将monitor中用来与checker中的mailbox通信的mon_mb句柄换成对应的uvm_blocking_put_port类型

    首先在monitor中(这里以chnl_monitor为例),声明端口

        uvm_blocking_put_port #(mon_data_t) mon_bp_port;

    然后在new函数中例化这个PORT

    1. function new(string name="chnl_monitor", uvm_component parent);
    2. super.new(name, parent);
    3. //TODO-1.1 instantiate the TLM port
    4. mon_bp_port = new("mon_bp_port", this);
    5. endfunction

    将原来存放句柄的方式由mailbox改为端口

    1. mon_mb.put(m);
    2. mon_bp_port.put(m);

    1.2在checker中声明和monitor通信的imp端口,与refmod通信的imp端口

    checker对多个agent中的monitor,是一对多的多方向通信类型,需要使用宏声明

    1. //在mcdf_checker前进行宏声明
    2. `uvm_blocking_put_imp_decl(_chnl0)
    3. `uvm_blocking_put_imp_decl(_chnl1)
    4. `uvm_blocking_put_imp_decl(_chnl2)
    5. `uvm_blocking_put_imp_decl(_fmt)
    6. `uvm_blocking_put_imp_decl(_reg)
    7. `uvm_blocking_get_peek_imp_decl(_chnl0)
    8. `uvm_blocking_get_peek_imp_decl(_chnl1)
    9. `uvm_blocking_get_peek_imp_decl(_chnl2)
    10. `uvm_blocking_get_imp_decl(_reg)
    11. //在mcdf_checker中进行端口声明
    12. uvm_blocking_put_imp_chnl0 #(mon_data_t, mcdf_checker) chnl0_bp_imp;
    13. uvm_blocking_put_imp_chnl1 #(mon_data_t, mcdf_checker) chnl1_bp_imp;
    14. uvm_blocking_put_imp_chnl2 #(mon_data_t, mcdf_checker) chnl2_bp_imp;
    15. uvm_blocking_put_imp_fmt #(fmt_trans , mcdf_checker) fmt_bp_imp ;
    16. uvm_blocking_put_imp_reg #(reg_trans , mcdf_checker) reg_bp_imp ;
    17. //
    18. uvm_blocking_get_peek_imp_chnl0 #(mon_data_t, mcdf_checker) chnl0_bgpk_imp;
    19. uvm_blocking_get_peek_imp_chnl1 #(mon_data_t, mcdf_checker) chnl1_bgpk_imp;
    20. uvm_blocking_get_peek_imp_chnl2 #(mon_data_t, mcdf_checker) chnl2_bgpk_imp;
    21. uvm_blocking_get_imp_reg #(reg_trans , mcdf_checker) reg_bg_imp ;
    22. //在new函数中例化
    23. chnl0_bp_imp = new("chnl0_bp_imp", this);
    24. chnl1_bp_imp = new("chnl1_bp_imp", this);
    25. chnl2_bp_imp = new("chnl2_bp_imp", this);
    26. fmt_bp_imp = new("fmt_bp_imp", this);
    27. reg_bp_imp = new("reg_bp_imp", this);
    28. chnl0_bgpk_imp = new("chnl0_bgpk_imp", this);
    29. chnl1_bgpk_imp = new("chnl1_bgpk_imp", this);
    30. chnl2_bgpk_imp = new("chnl2_bgpk_imp", this);
    31. reg_bg_imp = new("reg_bg_imp", this);

    1.3对上面声明的imp实现对应的方法

    1. task put_chnl0(mon_data_t t);
    2. chnl_mbs[0].put(t);
    3. endtask
    4. task put_chnl1(mon_data_t t);
    5. chnl_mbs[1].put(t);
    6. endtask
    7. task put_chnl2(mon_data_t t);
    8. chnl_mbs[2].put(t);
    9. endtask
    10. task put_fmt(fmt_trans t);
    11. fmt_mb.put(t);
    12. endtask
    13. task put_reg(reg_trans t);
    14. reg_mb.put(t);
    15. endtask
    16. task peek_chnl0(output mon_data_t t);
    17. chnl_mbs[0].peek(t);
    18. endtask
    19. task peek_chnl1(output mon_data_t t);
    20. chnl_mbs[1].peek(t);
    21. endtask
    22. task peek_chnl2(output mon_data_t t);
    23. chnl_mbs[2].peek(t);
    24. endtask
    25. task get_chnl0(output mon_data_t t);
    26. chnl_mbs[0].get(t);
    27. endtask
    28. task get_chnl1(output mon_data_t t);
    29. chnl_mbs[1].get(t);
    30. endtask
    31. task get_chnl2(output mon_data_t t);
    32. chnl_mbs[2].get(t);
    33. endtask
    34. task get_reg(output reg_trans t);
    35. reg_mb.get(t);
    36. endtask

    1.4在mcdf_refmod中声明与checker连接的imp端口,例化

    1. //在mcdf_refmod类中声明
    2. uvm_blocking_get_port #(reg_trans) reg_bg_port;
    3. uvm_blocking_get_peek_port #(mon_data_t) in_bgpk_ports[3];
    4. //在new函数中例化
    5. reg_bg_port = new("reg_bg_port", this);
    6. foreach(in_bgpk_ports[i]) in_bgpk_ports[i] = new($sformatf("in_bgpk_ports[%0d]", i), this);
    7. //将mailbox换成PORT
    8. this.reg_mb.get(t);
    9. this.reg_bg_port.get(t);
    1. this.in_mbs[id].peek(it);
    2. this.in_bgpk_ports[id].get(it);
    3. this.in_mbs[id].get(it);
    4. this.in_bgpk_ports[id].get(it);

    1.5在mcdf_env的connect_phase()完成monitor的port连接到mcdf_checker imp

    1. function void connect_phase(uvm_phase phase);
    2. super.connect_phase(phase);
    3. //TODO-1.5 connect TLM ports between monitors and the checker
    4. chnl_agts[0].monitor.mon_bp_port.connect(chker.chnl0_bp_imp);
    5. chnl_agts[1].monitor.mon_bp_port.connect(chker.chnl1_bp_imp);
    6. chnl_agts[2].monitor.mon_bp_port.connect(chker.chnl2_bp_imp);
    7. reg_agt.monitor.mon_bp_port.connect(chker.reg_bp_imp);
    8. fmt_agt.monitor.mon_bp_port.connect(chker.fmt_bp_imp);
    9. endfunction

    1.6在mcdf_checker中完成mcdf_refmod的port连接到mcdf_checker的imp

    1. function void connect_phase(uvm_phase phase);
    2. super.connect_phase(phase);
    3. //TODO-1.6 connect checker TLM ports with the ones of reference model
    4. refmod.in_bgpk_ports[0].connect(chnl0_bgpk_imp);
    5. refmod.in_bgpk_ports[1].connect(chnl1_bgpk_imp);
    6. refmod.in_bgpk_ports[2].connect(chnl2_bgpk_imp);
    7. refmod.reg_bg_port.connect(reg_bg_imp);

    2.1将mcdf_refmod中的out_mb替换成uvm_tlm_fifo

    1. //先声明
    2. uvm_tlm_fifo #(fmt_trans) out_tlm_fifos[3];
    3. //new函数中例化
    4. foreach(out_tlm_fifos[i]) out_tlm_fifos[i] = new($sformatf("out_tlm_fifos[%0d]", i), this);
    5. //替代原来的mailbox
    6. this.out_mbs[id].put(ot);
    7. this.out_tlm_fifos[id].put(ot);

    2.2同样的,mcdf_checker中的exp_mb[3]替换成uvm_blocking_get_port类型句柄数组。将mcdf_checker中的port连接到mcdf_refmod中uvm_tlm_fifo自带的blocking_get_export

    1. uvm_blocking_get_port #(fmt_trans) exp_bg_ports[3];
    2. foreach(exp_bg_ports[i]) exp_bg_ports[i] = new($sformatf("exp_bg_ports[%0d]", i), this);
    3. // this.exp_mbs[mont.ch_id].get(expt);
    4. this.exp_bg_ports[mont.ch_id].get(expt);
    5. foreach(exp_bg_ports[i]) begin
    6. exp_bg_ports[i].connect(refmod.out_tlm_fifos[i].blocking_get_export);
    7. end

    使用uvm_tlm_fifo就可以既使用tlm端口又不用自己实现具体的方法

    3.1利用回调函数完成类的复用,先预定义几个虚方法

    1. typedef class mcdf_base_test;
    2. class cb_mcdf_base extends uvm_callback;
    3. `uvm_object_utils(cb_mcdf_base)
    4. mcdf_base_test test;
    5. function new (string name = "cb_mcdf_base");
    6. super.new(name);
    7. endfunction
    8. virtual task cb_do_reg();
    9. // User to define the content
    10. endtask
    11. virtual task cb_do_formatter();
    12. // User to define the content
    13. endtask
    14. virtual task cb_do_data();
    15. // User to define the content
    16. endtask
    17. endclass

    3.2关联回调类型和对应的test

    在对应的test注册时使用callback对应的宏

        `uvm_register_cb(mcdf_base_test, cb_mcdf_base)

    3.3回调指定,也就是连接

    在对应的test中的虚方法用回调指定宏,参数多了虚方法

    1. virtual task do_reg();
    2. //TODO-3.3 Use callback macro to link the callback method
    3. `uvm_do_callbacks(mcdf_base_test, cb_mcdf_base, cb_do_reg())
    4. endtask
    5. // do external formatter down stream slave configuration
    6. virtual task do_formatter();
    7. //TODO-3.3 Use callback macro to link the callback method
    8. `uvm_do_callbacks(mcdf_base_test, cb_mcdf_base, cb_do_formatter())
    9. endtask
    10. // do data transition from 3 channel slaves
    11. virtual task do_data();
    12. //TODO-3.3 Use callback macro to link the callback method
    13. `uvm_do_callbacks(mcdf_base_test, cb_mcdf_base, cb_do_data())
    14. endtask

    3.4定义继承于base test的两个test的两个回调函数cb_*********,这两个回调函数都继承于base test的回调函数

    把原来mcdf_data_consistence_basic_test完全复制到回调函数cb_mcdf_data_consistence_basic_test中,全部方法前面加上cb_前缀,相当于做了两次相同的mcdf_data_consistence_basic_test。也可以定义新的方法或修改原有方法,作为test的扩展

    1. class cb_mcdf_data_consistence_basic extends cb_mcdf_base;
    2. `uvm_object_utils(cb_mcdf_data_consistence_basic)
    3. function new (string name = "cb_mcdf_data_consistence_basic");
    4. super.new(name);
    5. endfunction
    6. task cb_do_reg();
    7. bit[31:0] wr_val, rd_val;
    8. super.cb_do_reg();
    9. // slv0 with len=8, prio=0, en=1
    10. wr_val = (1<<3)+(0<<1)+1;
    11. test.write_reg(`SLV0_RW_ADDR, wr_val);
    12. test.read_reg(`SLV0_RW_ADDR, rd_val);
    13. void'(test.diff_value(wr_val, rd_val, "SLV0_WR_REG"));
    14. // slv1 with len=16, prio=1, en=1
    15. wr_val = (2<<3)+(1<<1)+1;
    16. test.write_reg(`SLV1_RW_ADDR, wr_val);
    17. test.read_reg(`SLV1_RW_ADDR, rd_val);
    18. void'(test.diff_value(wr_val, rd_val, "SLV1_WR_REG"));
    19. // slv2 with len=32, prio=2, en=1
    20. wr_val = (3<<3)+(2<<1)+1;
    21. test.write_reg(`SLV2_RW_ADDR, wr_val);
    22. test.read_reg(`SLV2_RW_ADDR, rd_val);
    23. void'(test.diff_value(wr_val, rd_val, "SLV2_WR_REG"));
    24. // send IDLE command
    25. test.idle_reg();
    26. endtask
    27. task cb_do_formatter();
    28. super.cb_do_formatter();
    29. void'(test.fmt_gen.randomize() with {fifo == LONG_FIFO; bandwidth == HIGH_WIDTH;});
    30. test.fmt_gen.start();
    31. endtask
    32. task cb_do_data();
    33. super.cb_do_data();
    34. void'(test.chnl_gens[0].randomize() with {ntrans==100; ch_id==0; data_nidles==0; pkt_nidles==1; data_size==8; });
    35. void'(test.chnl_gens[1].randomize() with {ntrans==100; ch_id==1; data_nidles==1; pkt_nidles==4; data_size==16;});
    36. void'(test.chnl_gens[2].randomize() with {ntrans==100; ch_id==2; data_nidles==2; pkt_nidles==8; data_size==32;});
    37. fork
    38. test.chnl_gens[0].start();
    39. test.chnl_gens[1].start();
    40. test.chnl_gens[2].start();
    41. join
    42. #10us; // wait until all data haven been transfered through MCDF
    43. endtask
    44. endclass: cb_mcdf_data_consistence_basic

    注意:原来test中用this.的地方表示当前类,在回调函数中改成test.1

    4在mcdf_base_test中添加新的end_of_elaboration_phase函数;利用uvm_root类设置信息冗余度为UVM_high;利用uvm_root::set_report_max_quit_count()函数设置仿真退出的最大数值;利用uvm_root::set_timeout()设置仿真的最大时间长度

    1. function void end_of_elaboration_phase(uvm_phase phase);
    2. super.end_of_elaboration_phase(phase);
    3. uvm_root::get().set_report_verbosity_level_hier(UVM_HIGH);
    4. uvm_root::get().set_report_max_quit_count(1);
    5. uvm_root::get().set_timeout(10ms);
    6. endfunction

  • 相关阅读:
    Timer和ScheduledThreadPoolExecutor的区别及源码分析
    云原生:从基本概念到实践,解析演进与现状
    数据结构 并查集
    17.linuxGPIO应用编程
    Spring Framework 简介与起源
    鸿蒙HarmonyOS实战-Web组件(基本使用和属性)
    【夜读】你和高手的差距,就在于处理问题的能力
    shell 实例:检查default路由的存在
    ubuntu18.04平台上基于xenomai3.2对Linux内核的实时化改造
    Java-基于SSM的人事管理系统
  • 原文地址:https://blog.csdn.net/weixin_39668316/article/details/126365299