0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在生成的代码中使用UVM Register Layer?

芯片验证工程师 来源:芯片验证工程师 2023-06-05 14:14 次阅读

Acquire a Register Model

寄存器模型一般可以使用工具生成或者从头开始编写,寄存器模型示例如下:

Filename regmodel.sv
class dummy_reg extends uvm_reg;
`uvm_object_utils(dummy_reg)


rand uvm_reg_field F;
...
virtual function void build();
F = uvm_reg_field::create("F");
F.configure(this, 8, 0, "RW", 1, 8'h00, 1, 1, 1);
endfunction
endclass




class bus_reg_block extends uvm_reg_block;
`uvm_object_utils(bus_reg_block)


rand dummy_reg reg0;
uvm_reg_map bus_map;
...
virtual function void build();
reg0 = dummy_reg::create("reg0");
reg0.configure(this);
reg0.build();


bus_map = create_map("bus_map", 'h0, 1, UVM_LITTLE_ENDIAN);
default_map = bus_map;
bus_map.add_reg(reg0, 'h0, "RW");
lock_model();
endfunction
endclass




class top_reg_block extends uvm_reg_block;
`uvm_object_utils(top_reg_block)


bus_reg_block bus;
uvm_reg_map bus_map;
...
virtual function void build();
bus = bus_reg_block::create("bus");
bus.configure(this);
bus.build();


bus_map = create_map("bus_map", 'h0, 1, UVM_LITTLE_ENDIAN);
default_map = bus_map;
bus_map.add_submap(bus.bus_map, 'h0);
lock_model();
endfunction
endclass

Add Register Access to the Interface Template File

我们从interface template file的主要部分开始,其中指定了事务接口中的变量。为了使示例简单,我们省略monitor和focv,只包含driver。


Filename bus.tpl
agent_name = bus
trans_item = bus_tx
trans_var  = rand bit cmd;
trans_var  = rand byte addr;
trans_var  = rand byte data;


driver_inc = bus_do_drive.sv


if_port  = logic clk;
if_port  = bit  cmd;
if_port  = byte addr;
if_port  = byte data;
if_clock = clk

现在,我们通过指定register layer具有的访问类型以及寄存器层和agent之间的映射来扩展interface template file。这是通过标识register layer用于读取和写入 DUT 中的寄存器的command, address和data:

reg_access_mode       = WR
reg_access_block_type = bus_reg_block


uvm_reg_kind    = cmd
uvm_reg_addr    = addr
uvm_reg_data    = data


reg_access_mode指定是否允许register layer对寄存器进行写/读(WR)、只写 (WO) 或只读 (RO) 访问。

reg_access_block_type在寄存器模型文件中指定 uvm_reg_block 类型,该文件包含要读取或写入的寄存器。

Add Register Access to the Common Template File

top-level register model必须在common template file中向uvm代码生成器描述:

Filename common.tpl
regmodel_file      = regmodel.sv
top_reg_block_type = top_reg_block

top_reg_block_type参数必须为top-level register model的类名。

Generate and Run

uvm代码生成器将创建以下结构:

top_tb (module)
 ↳ top_th (module instance)
   ↳ bus_if (interface instance)
     mydut (module instance)


 ↳ top_test (object, class uvm_test)
    ↳ top_config (created in build_phase, class uvm_object)
      top_env (uvm_env)
       ↳ bus_env_config (uvm_object)
         top_reg_block (uvm_reg_block)
         bus_env (uvm_env)
          ↳ bus_config (uvm_object)
            bus_reg_block (uvm_reg_block)
            reg2bus_adapter
            uvm_reg_predictor
            bus_agent (uvm_agent)
             ↳ bus_sequencer
               bus_driver (uvm_driver)
               bus_monitor (uvm_monitor)
            bus_coverage (uvm_subscriber)
            bus_env_coverage (uvm_subscriber)


       ↳ top_default_seq (created in run_phase, class uvm_sequence)
          ↳ bus_env_default_seq (uvm_sequence)
             ↳ registers.update()

实例化register model时,使用register model的每个agent都在其自己的 env 中实例化。在上面的结构中,可以看到:

top_test
  instantiates top_env
    instantiates bus_env
      instantiates bus_agent

top_env具有对top-level register blocktop_reg_block的引用,registermodel就是在这个层次实例化的。

bus_env引用该agent的register modelbus_reg_block,并实例化adapter和predictor,该adapter和predictor将该registermodel连接到agent。

uvm代码生成器在使用registermodel的default sequence中向相应registermodel中的每个寄存器写入一个随机值。

Filenamebus_env_seq_lib.sv


task bus_env_default_seq::body();
  super.body();
  `uvm_info(get_type_name(), "default sequence starting", UVM_HIGH)
  regmodel.get_registers(data_regs);
  data_regs.shuffle();
  foreach(data_regs[i])
    begin
      // Randomize register content and then update
      if(!data_regs[i].randomize())
        `uvm_error(get_type_name(), $sformatf("Randomization error for data_regs[%0d]", i))
      data_regs[i].update(status, .path(UVM_FRONTDOOR), .parent(this));
    end
  `uvm_info(get_type_name(), "default sequence completed", UVM_HIGH)
endtask : body

添加用户定义的寄存器sequence

与前面的文章一样,可以通过扩展uvm代码生成器创建的default sequence来创建自己的sequence。这次它是一个专门的register sequence:

Filenamebus_env_reg_seq.sv


class bus_env_reg_seq extends bus_env_default_seq;
  `uvm_object_utils(bus_env_reg_seq)
  ...
  task body();
     regmodel.reg0.write(status, .value('hab), .parent(this));
     assert(status == UVM_IS_OK);


     regmodel.reg0.write(status, .value('hcd), .parent(this));
     assert(status == UVM_IS_OK);


     regmodel.reg0.write(status, .value('hef), .parent(this));
     assert(status == UVM_IS_OK);


     regmodel.reg0.read(status, .value(data), .parent(this));
     assert(status == UVM_IS_OK);
  endtask: body
endclass : bus_env_reg_seq

同样需要在interface template file添加factory override:

Filenamebus.tpl
...
reg_seq_inc       = bus_env_reg_seq.sv
agent_factory_set = bus_env_default_seq  bus_env_reg_seq

然后可以对生成的现成代码运行仿真,应该看到仿真日志中包含以下打印信息

# @10000 mydut bus_cmd = W, bus_addr = 00, bus_data = ab
# @30000 mydut bus_cmd = W, bus_addr = 00, bus_data = cd
# @50000 mydut bus_cmd = W, bus_addr = 00, bus_data = ef
# @70000 mydut bus_cmd = R, bus_addr = 00, bus_data = 00





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5307

    浏览量

    119928
  • UVM
    UVM
    +关注

    关注

    0

    文章

    181

    浏览量

    19126
  • 生成器
    +关注

    关注

    7

    文章

    313

    浏览量

    20966
  • DUT
    DUT
    +关注

    关注

    0

    文章

    189

    浏览量

    12320

原文标题:Easier UVM Code Generator Part 3:添加Register Layer

文章出处:【微信号:芯片验证工程师,微信公众号:芯片验证工程师】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    IC验证之UVM常用宏汇总分析(四)

    UVM_REG_ADDR_WIDTH 64源代码 :`ifndef UVM_REG_DATA_WIDTH`define UVM_REG_DATA_WIDTH 64`endif自定义字
    发表于 12-02 15:24

    UVM ral register在UVC中使用注意事项

    在UVC中使用RAL中的register
    发表于 12-18 06:35

    何在simv sim_opts中使uvm_set_verbosity

    -uvm_set_verbosity本文只介绍如何在simv sim_opts中使uvm_set_verbosity。
    发表于 12-18 06:42

    UVM sequence分层有哪几种方式呢

    ,我们随机生成了包含多个lower_env_item的数组upper_env_item_seq,然后分别进行发送。同样一个例子,我们也可以使用多个sequencer(high-layer
    发表于 04-11 16:37

    UVM sequence分层的几种体现

    的例子中,我们随机生成了包含多个lower_env_item的数组upper_env_item_seq,然后分别进行发送。同样一个例子,我们也可以使用多个sequencer(high-layer
    发表于 04-14 11:08

    基于UVM代码生成器的开发设计

    不一相互矛盾的UVM代码。对于这些问题UVM 代码生成器基本都可以解决,更为关键的是,这对于项目的开发效率提高也是一件极有意义的事情。 简单
    发表于 09-15 17:18 22次下载
    基于<b class='flag-5'>UVM</b>的<b class='flag-5'>代码</b><b class='flag-5'>生成</b>器的开发设计

    何在生产时防止代码泄漏

    的,本文将介绍如何在生产时防止代码泄漏。 有很多企业在产品研发完成后,一般选择代工厂进行批量生产,代码的安全性尤为重要。为了避免工厂直接接触代码,一般会在编程器上建立加密工程,对烧录文
    发表于 01-26 01:05 386次阅读
    如<b class='flag-5'>何在生</b>产时防止<b class='flag-5'>代码</b>泄漏

    何在java代码中使用HTTP代理IP

    何在java代码中使用HTTP代理IP。
    的头像 发表于 08-04 15:38 2183次阅读

    何在python代码中使用HTTP代理IP

    何在python代码中使用HTTP代理IP。
    的头像 发表于 08-04 15:46 1246次阅读

    何在PHP代码中使用HTTP代理IP

    何在PHP代码中使用HTTP代理IP。
    的头像 发表于 08-04 16:08 2403次阅读

    何在易e语言代码中使用HTTP代理IP

    何在易e语言代码中使用HTTP代理IP,示例代码demo直接可用(步骤注释清晰)
    的头像 发表于 08-05 16:29 6818次阅读

    何在c语言代码中使用HTTP代理IP

    何在c语言代码中使用HTTP代理IP,示例代码demo直接可用(步骤注释清晰)
    的头像 发表于 08-05 16:31 2307次阅读

    何在c#语言代码中使用HTTP代理IP

    何在c#语言代码中使用HTTP代理IP,示例代码demo直接可用(步骤注释清晰)
    的头像 发表于 08-05 16:33 2558次阅读

    何在python代码中使用HTTP代理IP

    如何再python代码中使用HTTP代理IP。
    的头像 发表于 09-13 09:25 972次阅读

    个性化地定制自己的uvm代码生成器模板和脚本

    使用uvm代码生成器创建基本的uvm验证环境框架,然后丢弃代码生成器模板并扩展和维护
    的头像 发表于 05-14 16:51 1989次阅读
    个性化地定制自己的<b class='flag-5'>uvm</b><b class='flag-5'>代码</b><b class='flag-5'>生成</b>器模板和脚本