【IC验证】UVM实验lab05

1. 寄存器建模的要点和顺序

1.1 寄存器创建

定义单个uvm_reg,各个域的确定,并利用configure函数来配置属性;

class ctrl_reg extends uvm_reg;'uvm_object_utils(ctrl_reg)/*uvm_reg;uvm_mem;uvm_reg_map;uvm_reg_block都继承于uvm_object类*/uvm_reg_field reserved;rand uvm_reg_field pkt_len;rand uvm_reg_field prio_level;rand uvm_reg_field chnl_en;function new(string name = "ctrl_reg");super.name(name, 32, UVM_NO_COVERAGE);endfunction virtual function void build();reserved   = uvm_reg_field::type_id::create("reserved"  );pkt_len    = uvm_reg_field::type_id::create("pkt_len   ");prio_level = uvm_reg_field::type_id::create("prio_level");chnl_en    = uvm_reg_field::type_id::create("chnl_en   ");reserved  .configure(this, 26, 6, "RO", 0, 26'h0, 1, 0, 0);pkt_len   .configure(this, 3 , 2, "RW", 0, 3'h0,  1, 1, 0);prio_level.configure(this, 2 , 1, "RW", 0, 2'h3,  1, 1, 0);chnl_en   .configure(this, 1 , 0, "RW", 0, 1'h1,  1, 1, 0);endfunction
endclass
  • 在new()函数中,第二个参数是寄存器的宽度,一般为32位,第三个参数用于指定是否需要进行覆盖率收集。不需要则写为UVM_NO_COVERAGE, 需要则写为UVM_CVR_ALL
  • uvm_reg;uvm_mem;uvm_reg_map;uvm_reg_block都继承于uvm_object类
  • uvm_reg类中的build()函数,不同于UVM_component的bulid_phase,不会自动执行,需要手动调用
  • configure配置所需要的参数如下

field_name.configure( .parent          ( this ),          // 参数一是此域的父辈,也就是此域位于哪个寄存器中,即是this;
                                   .size              ( 1    ),          // 参数二是此域的宽度;
                                   .lsb_position ( 0    ),          // 参数三是此域的最低位在整个寄存器的位置,从0开始计数;
                                   .access        ( "RW" ),       // 参数四表示此域段的存取方式(属性);
                                   .volatile        ( 0    ),          // 参数五表示是否是易失的(volatile),这个参数一般不会使用;
                                  .reset            ( 0    ),          // 参数六表示此域上电复位后的默认值;
                                 .has_reset     ( 1    ),          // 参数七表示此域可复位;
                                 .is_randomize   ( 1 ),          // 参数八表示这个域是否可以随机化;
                                 .individually_accessible( 0    )      // 参数九表示这个域是否可以单独存取。

);

1.2 寄存器映射

定义uvm_reg_block,在里面例化定义的uvm_reg,使用configure做配置;通过add_reg()函数添加各个uvm_reg对应的偏移地址和访问属性。

class mcdf_rgm extends uvm_reg_block;'uvm_object_utils(uvm_rgm)ctrl_reg chnl0_ctrl_reg;ctrl_reg chnl1_ctrl_reg;	ctrl_reg chnl2_ctrl_reg;	function new(string name = "mcdf_rgm");super.new(name, UVM_NO_COVERAGE);endfunctionvirtual function void build();chnl0_ctrl_reg = ctrl_reg::type_id::create("chnl0_ctrl_reg");chnl0_ctrl_reg.configure(this);chnl0_ctrl_reg.build();chnl1_ctrl_reg = ctrl_reg::type_id::create("chnl1_ctrl_reg");chnl1_ctrl_reg.configure(this);chnl1_ctrl_reg.build();		chnl2_ctrl_reg = ctrl_reg::type_id::create("chnl2_ctrl_reg");chnl2_ctrl_reg.configure(this);chnl2_ctrl_reg.build();		map = create_map("map", 'h0, 4, UVM_LITTLE_ENDING);//给基地址map.add_reg(chnl0_ctrl_reg, 32'h0000 0000, "RW");//给偏移地址map.add_reg(chnl1_ctrl_reg, 32'h0000 0000, "RW");		map.add_reg(chnl2_ctrl_reg, 32'h0000 0000, "RW");		chnl0_ctrl_reg.add_hdl_path_slice($sformatf("mem[%0d]", 'SLV0_RW_REG), 0, 32);chnl1_ctrl_reg.add_hdl_path_slice($sformatf("mem[%0d]", 'SLV0_RW_REG), 0, 32);		chnl2_ctrl_reg.add_hdl_path_slice($sformatf("mem[%0d]", 'SLV0_RW_REG), 0, 32);		add_hdl_path("tb.dut.ctrl_regs_inst");lock_model();endfunction
endclass

在build函数中需要做以下几步,

  • 创建各个寄存器,配置寄存器实例的属性
  • 并调用寄存器的build()函数,实现对各个域的配置
  • 创建map,create_map第一个参数是名字,第二个参数是该reg block的基地址,第三个参数是寄存器所映射到的总线宽度(单位是byte),第四个参数是大小端,用于指定字节排序,一般有大端序(UVM_BIG_ENDING,高位字节存储在低地址处,低位字节存储在高地址处)和小端序(UVM_LITTLE_ENDING,低位字节存储在低地址处,高位字节存储在高地址处 )第五个参数指定连续地址是否相隔1个字节 (TRUE; 默认值) 或n_bytes (FALSE)。,一般为默认值1。
  • 通过add_reg来添加各个reg的偏移地址和访问属性。第一个参数是要添加的寄存器名,第二个是地址,第三个是寄存器的读写属性。
  • 关联寄存器模型和HDL硬件,用于将寄存器字段的一部分(即切片)与HDL路径绑定。从而使得UVM寄存器模型能够访问和操纵实际的硬件寄存器。第一个参数是hdl的地址,第二个参数是寄存器字段中切片的起始位,第三个参数是寄存器字段切片的大小。
  • lock_model()锁定该寄存器模型,不能进行诸如添加寄存器或存储器之类的结构改变。因此必须确保在调用lock_model之前已经创建了所有子块、映射和寄存器。

1.3 Adapter实现

adapter具有桥接功能,实现uvm_reg_bus_op和transaction之间的转换,实现前门访问和DUT返回值对寄存器模型的修改.

class reg2mcdf_adapter extends uvm_reg_adapter;'uvm_object_utils(reg2mcdf_adapter)function new(string name = "reg2mcdf_adapter");super.new(name);provides_response = 1;endfunctionfunction uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);reg_trans t = reg_trans::type_id::create("t");t.cmd  = (rw.kind == UVM_WRITE)? UVM_WRITE: UVM_READ;t.addr = rw.addr;t.data = rw.data;return t;endfunctionfunction void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);reg_trans t;if(!$cast(t,bus_item))begin'uvm_fatal("CASTFALL","provide bus_item is not of the correct type")return;endrw.kind = (t.cmd == 'WRITE)? UVM_WRITE: UVM_READ;rw.addr= t.addr;rw.data = t.data;rw.status = UVM_IS_OK;endfunction
endclass

通过reg2bus和bus2reg函数来实现数据类型的转换。

bus2reg()函数将收集到的transaction转换成寄存器模型使用的uvm_reg_bus_op类型变量,用以更新寄存器模型中相应寄存器的值;

virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

1.4 顶层集成block, adapter和predictor

1.4.1 例化并创建

class mcdf_env extends uvm_env;chnl_agent chnl_agts[3];reg_agent reg_agt;fmt_agent fmt_agt;mcdf_checker chker;mcdf_coverage cvrg;mcdf_virtual_sequencer virt_sqr;//例化adapter,predictor和register model句柄mcdf_rgm rgm;reg2mcdf_adapter adapter;uvm_reg_predictor #(reg_trans) predictor;'uvm_component_ultis(mcdf_env)function new(string name = "mcdf_env", uvm_component parent);super.new(name);endfunction	function void build_phase(uvm_phase phase)...//创建adapter,predictor和register model句柄rgm = mcdf_rgm::type_id::create("rgm", this);rgm.build();adapter = reg2mcdf_adapter::type_id::create("adapter", this);predictor = uvm_reg_predictor#(reg_trans)::type_id::create("predictor", this);endfunction...endclass

1.4.2 句柄连接

	/*将 reg_agt.sequencer 关联到 rgm.map,并使用 adapter 进行适配*/rgm.map.set_sequencer(reg_agt.sequencer, adapter);/*将monitor的analysis_port连接到predictor的输入端口,使predictor能够接收monitor捕获的总线事务。*/reg_agt.monitor.mon_ana_port.connect(predictor.bus_in);predictor.map = rgm.map;predictor.adapter = adapter;virt_sqr.rgm = rgm;

1.4.2 在test层运行

top_seq.start(env.virt_sqr);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37803.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

八、浏览器同源策略

上一篇👉: 浏览器垃圾回收机制 文章目录 浏览器同源策略1.同源策略的定义2.同源策略的作用3.同源策略的限制范围4.解决跨域方案汇总1.CORS(跨源资源共享)2.JSONP3.postMessage 跨域4.Nginx代理跨域5.Node.js中间件代理跨域6.document.domain…

【教学类65-04】20240625秘密花园涂色书04(通义万相)(图纸16:9,A4横板1张,一大168张纸168份)

背景需求 【教学类65-01】20240622秘密花园涂色书01(通义万相)(A4横版2张,一大3小 38张纸76份)-CSDN博客文章浏览阅读118次。【教学类65-01】20240622秘密花园涂色书01(通义万相)(A…

老年人能力评估系统:在居家养老中的作用

随着人口老龄化趋势的加剧,居家养老成为了许多老年人的首选。为了满足居家养老中老年人能力评估的需求,提高评估质量和效果,老年人能力评估系统应运而生。本文将为您介绍老年人能力评估系统在居家养老中的作用,让您了解这个在居家…

Ubuntu 截图shutter,图像编辑 gimp,录屏kazam

1.截图: Shutter 安装shutter命令: sudo add-apt-repository ppa:shutter/ppasudo apt-get updatesudo apt-get install shutter 2.图片编辑:Gimp, Kolourpaint, Pinta gimp全名为:GNU Image Manipulation Program&#xff0c…

操作系统-文件的物理结构(文件分配方式)

文章目录 总览文件块和磁盘块连续分配顺序访问直接访问(随机访问)为什么连续分配同时支持这两种访问模式? 链接分配隐式链接显示链接小结索引分配链接方案多层索引混合索引小结 总结 总览 文件数据存放在外存中 文件块和磁盘块 文件内通过逻…

万字长文详解数据结构:树 | 第6章 | Java版大话数据结构 | 二叉树 | 哈夫曼树 | 二叉树遍历 | 构造二叉树 | LeetCode练习

📌本篇分享的大话数据结构中🎄树🎄这一章的知识点,在此基础上,增加了练习题帮助大家理解一些重要的概念✅;同时,由于原文使用的C语言代码,不利于学习Java语言的同学实践,…

Linux中使用网络文件系统NFS挂载远程目录,对远程文件的本地化操作

目录 一、NFS及其在linux系统中的挂载 1、NFS概述 2、NFS挂载及其作用 (1)资源共享 (2)简化数据管理 (3)提高数据可用性 (4)灵活性 (5)访问控制 &am…

Elasticsearch 避免常见查询错误和陷阱

Elasticsearch 作为一款强大的搜索引擎和分析工具,已经被广泛应用于各种场景中。然而,在使用 Elasticsearch 进行查询时,如果不注意一些常见的错误和陷阱,可能会导致查询效率低下、结果不准确甚至系统性能下降。本文旨在总结一些常…

web刷题记录(7)

[HDCTF 2023]SearchMaster 打开环境,首先的提示信息就是告诉我们,可以用post传参的方式来传入参数data 首先考虑的还是rce,但是这里发现,不管输入那种命令,它都会直接显示在中间的那一小行里面,而实际的命令…

工业自动化控制中心

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms;namespace 工业自动化控制中心 {public partial class Form1 : Form{public Form1(){InitializeComponent();}pri…

数据结构与算法笔记:高级篇 - 搜索:如何用 A* 搜索算法实现游戏中的寻路功能?

概述 魔兽世界、仙剑奇侠传这类 MMRPG 游戏,不知道你玩过没有?在这些游戏中,有一个非常重要的功能,那就是任务角色自动寻路。当任务处于游戏地图中的某个位置时,我们用鼠标点击另外一个相对较远的位置,任务…

无线WiFi毫米波雷达传感器成品,智能照明人体感应开关,飞睿智能点亮智慧生活

在智能科技飞速发展的今天,我们的生活正被各种智能设备所包围,其中智能照明作为智能家居的重要组成部分,正逐渐改变着我们的生活方式。而在这背后,有一个默默工作的“小助手”——飞睿智能毫米波雷达传感器,它就像智能…

面试官:10W QPS高并发下,如何防止重复下单?

核心问题 10W QPS:每秒10万次请求,高并发场景。重复下单:用户因网络问题、系统重试、误操作等原因提交多次相同订单。 电商订单支付核心流程 用户下单:选择商品,提交订单。订单确认:系统生成订单号&…

考后热门三件套 国漫年番加点料

学生时代,最开心的莫过于寒暑假,而比寒暑假更开心的必须是升学考后的假期!很多同学的考后三件套:聚餐、旅游和学车!同样有许多同学开启了补番计划,今天就给大家推荐4部暑期必看的年番,各种类型兼…

PICO 4S泄露信息更新,配备骁龙XR2 Gen 2,单眼分辨率2160×2160

根据最新的泄露信息汇总,PICO 4S确实有望成为一款高性能的VR头显,其核心规格和特性包括: 处理器与内存:搭载了高通骁龙XR2 Gen 2芯片组,这是针对VR/AR设备优化的高端处理器,能提供更强大的计算能力和效率。…

mwwz库添加对多模板匹配的支持:find_shape_models

多模板匹配的实现只需要对单模板匹配做一些扩展,传入的模板由不同的id表示,在金字塔顶层完成模板的分类,在剩下的金字塔完成对每一类模板的匹配,匹配结果由id标识。测试程序已集成该方法,清除模板后所创建的模板被看作…

Vue 鼠标滑入元素改变其背景颜色,且鼠标划入另一块区域,背景颜色保持不变

如上图所示:鼠标划入"条件区域",对应ul元素改变背景颜色,且划入内容区域时,ul元素的背景颜色保持不变。只有当鼠标划出"内容区域",或者切换到"条件区域"的其他ul元素上时,背景颜色才恢复…

二叉树的层序遍历/后序遍历(leetcode104二叉树的最大深度、111二叉树的最小深度)(华为OD悄悄话、数组二叉树)

104二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 本题可以使用前序(中左右),也可以使用后序遍历(左右中),…

基于SpringBoot学生信息管理系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟感兴趣的可以先收藏起来,还…

qt QTreeWidget文件管理器拖入应用,从应用拖入文件管理器拷贝

我用QT实现了一个文件管理的软件,能够实现从桌面或其他路径拖拽文件到软件,软件获取拖拽文件的路径。但是当我想实现反向操作时遇到了问题。在网上搜索和阅读文档一天多都未能解决该问题。 下面给出我的实现: Qt开发中经常会用QTreeWidget去…