Easier UVM Code Generator Part 2:添加用户定义的代码

在本文中,我们将进一步实现monitor和coverage collector components,以便在仿真期间收集功能覆盖信息。
实现monitor
为了在验证环境中进行检查或覆盖率收集,我们首先需要完成monitor的实现。与前文driver代码的生成实现类似,我们使用template files指示uvm代码生成器包含我们的任务。
filename include/clkndata_do_mon.svtask clkndata_monitor::do_mon(); forever @(posedge vif.clk) begin m_trans = data_tx::create(m_trans); m_trans.data = vif.data; analysis_port.write(m_trans); endendtask  
和driver一样,任务的命名需要以agent接口为前缀。do_mon任务应monitor dut 接口,然后组装成一个事务m_trans,最后通过analysis_port发送出去。
filename clkndata.tpl...driver_inc = clkndata_do_drive.svmonitor_inc = clkndata_do_mon.sv...  
实现covergroup
uvm代码生成器将生成一个subscriber component,该组件连接到monitor的analysis_port。默认情况下,此subscriber 将使用covergroup对任何接收到的事务值进行采样。自动生成的代码如下所示:
filename clkndata_coverage.svclass clkndata_coverage extends uvm_subscriber #(data_tx); `uvm_component_utils(clkndata_coverage) bit m_is_covered; data_tx m_item; covergroup m_cov; option.per_instance = 1; cp_data: coverpoint m_item.data; endgroup extern function new(string name, uvm_component_parent); extern function void write(input data_tx t);endclassfunction clkndata_coverage::new(string name, uvm_component_parent); super.new(name, parent); m_is_covered = 0; m_cov = new;endfunctionfunction void clkndata_coverage::write(input data_tx t); m_item = t; m_cov.sample(); if (m_cov.get_inst_coverage() >= 100) m_is_covered = 1;endfunction...  
为了完成覆盖模型,可以在include文件中提供一组用户定义的coverpoints,例如:
filename include/clkndata_cover_inc.svcovergroup m_cov; option.per_instance = 1; cp_data: coverpoint m_item.data { bins zero = {0}; bins one = {1}; bins negative = { [-128:-1] }; bins positive = { [1:127] }; option.at_least = 16; }endgroup  
同样,必须使用正确的命名约定。文件名前缀为agent interface,必须将covergroup 命名为 m_cov,并且引用输入事务的变量名称必须为m_item。
filename clkndata.tpl...driver_inc = clkndata_do_drive.svmonitor_inc = clkndata_do_mon.svagent_cover_inc = clkndata_cover_inc.sv...  
生成的subscriber component现在包括刚刚提供的covergroup:
filename clkndata_coverage.svclass clkndata_coverage extends uvm_subscriber #(data_tx); ... data_tx m_item; `include clkndata_cover_inc.sv ... extern function void write(input data_tx t); ...endclass  
进一步扩展生成的代码
上述文件 clkndata_cover_inc.sv 仅包含一个covergroup。生成的代码实例化该covergroup,并包含一个用于对covergroup进行sample的write方法。但是,如果你需要subscriber 采取除sample covergroup之外或而不是采样的其他操作怎么办?答案是,不仅可以include covergroup,还可以从一组include文件中提取类的所有内容。如果要自己提供 new 和 write 方法,则还需要禁止自动生成它们。为此,你需要更改 interface template file,如下所示:
filename clkndata.tpl...#agent_cover_inc = clkndata_cover_inc.svagent_cover_inc_inside_class = clkndata_cover_inc_inside.svagent_cover_inc_after_class = clkndata_cover_inc_after.svagent_cover_generate_methods_inside_class = noagent_cover_generate_methods_after_class = no...  
生成的subscriber 组件现在如下所示:
class clkndata_coverage extends uvm_subscriber #(data_tx);  `uvm_component(clkndata_coverage)  `include clkndata_cover_inc_inside.svendclass`include clkndata_cover_inc_after.sv  
然后,可以提供以下两个include文件:
filename include/clkndata_cover_inc_inside.svcovergroup m_cov; option.per_instance = 1; cp_data: coverpoint m_item.data { bins zero = {0}; bins one = {1}; bins negative = { [-128:-1] }; bins positive = { [1:127] }; option.at_least = 16; }endgroupextern function new(string name, uvm_component_parent);extern function void write(input data_tx t);filename include/clkndata_cover_inc_after.svfunction clkndata_coverage::new(string name, uvm_component_parent); super.new(name, parent); m_cov = new;endfunctionfunction void clkndata_coverage::write(input data_tx t); m_item = t; m_cov.sample();endfunction: write  
你现在可以灵活地在这两个include文件中提供任何代码。你可以让用户定义的代码插入到生成的代码中,而不是代码生成器写出 'include 指令,如下所示:
filename clkndata.tpl...agent_cover_inc_inside_class = clkndata_cover_inc_inside.sv inlineagent_cover_inc_after_class = clkndata_cover_inc_after.sv inline...  
override a sequence
正如我们在前面的文章中看到的,生成的代码包含一个top-level virtual sequence:
文件名 top_seq_lib.sv
filename top_seq_lib.sv...task top_default_seq::body(); super.body(); ... clkndata_default_seq seq; seq = clkndata_default_seq::create(seq); seq.randomize(); seq.start(m_clkndata_agent.m_sequencer, this);endtask...  
可以通过扩展创建和启动的任何default sequence,例如
filename my_clkndata_seq.svclass my_clkndata_seq extends clkndata_default_seq; ... task body(); ... for (int i = 0; i < 16; i++) begin req = data_tx::create(req); start_item(req); if ( !req.randomize() with { data == i; }) ... finish_item(req); end endtaskendclass  
然后,需要在interface template file中标识该文件,并将用户定义的sequence作为default sequence:
filename clkndata.tpl...agent_cover_inc = clkndata_cover_inc.svagent_seq_inc = myclkndata_seq.svagent_factory_set = clkndata_default_seq my_clkndata_seq  
然后,uvm代码生成器会使用工厂机制覆盖整个default sequence:
filename top_test.svfunction void top_test::build_phase(uvm_phase phase); ... clkndata_default_seq::get_type()); ...endfunction


欧洲税务局采用了虚拟助理和其他额外的客户体验创新
联想K10 Plus高清渲染图和配置发布,将于9月22日亮相印度市场
电源控制芯片中的过流保护设计
腾讯云在北京举行大数据AI新品发布会
贸泽电子宣布与Sigfox签订全球分销协议 即日起开售Sigfox物联网产品
Easier UVM Code Generator Part 2:添加用户定义的代码
韩国芯片出口额下降了40%
疫情有效控制促进我国互联网汽车租赁市场回暖
索尼两款紧凑型3LCD高清激光投影机VPL-P630HZ和VPL-P530HZ11月上市
深度学习中最常见的10个方法盘点
上海世博探秘未来汽车怎么开?航天电池
FD系列真菌毒素检测仪的特点
wifi6什么时候来 为5G时代而生
后疫情时代,互联网医疗的几大趋势分析
安卓8.0配8G运存!地表最强谷歌Pixel2,将对iphone8形成最强阻击!
华为云全流程等保服务,帮助企业守护信息安全
手机相关技术
传统燃油汽车工程师的内卷焦虑
编程也要从娃娃抓起?
安全挂锁设计的目地以及安全系数的介绍