当前位置: 首页 > news >正文

IP验证学习之case编写

目录

前言

一:编写base_test

二.编写testcase

virtual_sequence:

reg_sequence:

数据流sequence:

总结


前言

读者阅读时要能够体会简单的case的控制过程。因为很多时候环境不需要你搭建,但case却要写很多。

整体的UVM环境读者可以使用脚本工具自行创建就好,不懂的地方 多问问前辈和AI~

参考:绿皮书,白皮书


一:编写base_test

在编写完env或者配置完成时,接下来的工作就是要编写testcase了,这一步分成了两类。

1.所有的驱动都会在在testcase里按照流程一步步的配置,即封装一些task ,如mem_write,mem_read等任务。

2.调用virtual sequence ,在virtual sequence中调度多个sequence进行工作。

从UVM的应用角度来说,更加推荐使用virtual sequence 调度多个sequence的方式编写自己的testcase。但是如果项目中用到了第三方的IP,那么大概率环境用的是第一种方式,其复用性上会差一点。

我以第二种方式开始介绍。

在此之前首先对UVM的顶层控制有一个了解,如图:virtual sequence里面例化了所有sequence,virtual sequencer里面例化了环境里的sequencer,这两个东西读者可以理解成容器。

virtual sequence里可以调度sequence的次序,产生次数等,同时可以指定其子sequence在哪个sequencer上运行。

virtual sequencer集成了多个sequencer的作用就是方便控制全局的sequencer,与virtual sequence相互作用。

可以说有virtual sequence 就会有 virtual sequencer,其中vritual sequence通常作为顶层控制器控制全局sequence,而virtual sequencer 一般而言就是集成sequencer。

下图展示了sequence作为顶层控制的思想和具体流程。

当有了env后,我们首先需要做的就是用一个或者多个base_test封装env,根据多个base_test的不同需求编写。

比如 DUT中存在两个通路,可以准备三个base_test分别验证其中一条通路或者两条通路都打开的场景。

class base_test extends uvm_test;......env_config    env_cfg;env            m_env;......function void build_phase(uvm_phase phase);......m_env = env::type_id::create("m_env",this);    //实例化envenv_cfg.config_env();env_cfg.has_xxx_scoreboard = 0 ;             //这里就是配置env以及内部的参数,仅供参考//如果有VIP的话,还需要配置一下VIP里的default_sequenceuvm_config_db#(uvm_object_wrapper)::set(this,"m_env.apb_env.apb_slave_env.slave*.sequencer.run_phase","default_sequence",svt_apb_slave_memory_sequence::type_id::get());uvm_config_db#(uvm_object_wrapper)::set(this,"m_env.apb_env.apb_master_env.sequencer.main_phase","default_sequence",null/*svt_apb_slave_memory_sequence::type_id::get()*/);endfunction:build_phasefunction void base_test::final_phase(uvm_phase phase);......//在仿真结束的最后阶段可以加入一个检查环境是否存在 UVM_ERROR 或者 UVM_WARNING 的语句err_num = server.get_severrity_count(UVM_ERROR)+  server.get_severrity_count(UVM_FATAL);+  server.get_severrity_count(UVM_WARNING);if(!err_num) `uvm_info("UVM_CASE_PASS", “******** UVM TEST PASSED *********",UVM_NONE)else `uvm_info("UVM_CASE_FAIL", “******** UVM TEST FAILED *********",UVM_NONE)endfunction:final_phaseendclass

由于base_test在这里的作用主要就是搭建一个个框架管道,所以可以不用添加各个run阶段的phase(但有时也不是绝对的,有的人也会给base_test添加一些基础激励类的配置)。

二.编写testcase

在编写testcase的时候,通常会继承于base_test。一般环境最先会先写一个smoke_test(冒烟测试),即不需要配置任何寄存器,以DUT默认的配置直接发起数据流操作。

不过这里还是以编写配置寄存器的case为例,介绍一下如何写case。

class register_test extends base_test;......task main_phase(uvm_phase phase);dut_register_vseq    u_reg_vseq;phase.raise_objection(this);u_reg_vseq = new();u_reg_vseq.start(m_env.reg_vseqr);        //启动一个虚拟序列,并将其运行在指定的sequencer上,这里就是启动寄存器虚拟序列,将其运行在reg_vseqr上。phase.drop_objection(this);endtaskendclass            

上面这个case十分简单,仅仅只是调用virtual sequence进行启动,所以代码量很小。下面来看一下 virtual sequence 以及其调用的各个sequence的具体内容。

virtual_sequence:

class dut_register_vseq extends uvm_sequencer;register_sequence    reg_seq;    //申明寄存器配置的sequence的句柄//其他sequence......task body();        //写sequence主要就是完成body任务,在virtual sequence里就是完成调配各个sequence的顺序或者功能等。`uvm_do(reg_seq) //在当前的sequencer上调用并启动寄存器配置的sequence。apb_rw_seq.mem_write_(32'h4000_0004,32'h1); //如果对于DUT而言是一些直连线访问,可以模拟一个寄存器访问操作直接访问寄存器。`uvm_do(input_seq, p_sequencer.input_seqr) ;  //启动input_seq这个序列,指定它在virtual_seuqnecer下面的input_seqr里面运行。endtaskendclass

可以看到virtual sequence里面就是配置子sequence,指定它们在哪个sequencer上运行,并做一些其他读写操作。

完成基本的sequence启动项配置后,再来看看其中的两个sequence是怎样写的。编写sequence主要是编写task_body。

reg_sequence:

class register_sequence extends uvm_sequence;......task_body();uvm_status_e    status;    //这是和寄存器有关的变量,用于检查是否寄存器操作是否成功。uvm_reg_data_t    data;    //用于存储寄存器读写操作的数据rgm.logic_sel.logic_sel.set(1);rgm.update(status,UVM_FRONTDOOR);    //前门访问endtaskendclass

数据流sequence:

class op_in_seq#(DATA_WIDTH = 4) extends uvm_sequence    //声明了一个带参数的sequence......task body();op_in_seq_item`PARAM_LIST req;        // `PARAM_LIST 是宏定义的参数列表,用于配置例化对象`uvm_info("TRACE",$sformatf("%m"),UVM_HIGH)`uvm_do(req)endtask
endclass

在上述例子里,在virtual_sequence中分别调用了寄存器配置的sequence和发送数据流的sequence,两者各司其职,为了灵活的配置顺序,通常还会用fork...join的方式并行执行一些sequence.

在面对一个全新的IP时,最初写case是比较慢的,但是当编写sequence到一定程度上后,接下来的testcase就是把原先编写好的sequence组合起来用于验证。


总结

UVM环境的环境搭建关键还是要看具体的DUT情况才可以,实际工作中写case就已经花费了很多时间,通常公司也会引入AI agent自动生成一些验证框架和sequence等,方便验证编写case。


文章转载自:

http://woLvN3Jj.zbjfq.cn
http://65jWUx2J.zbjfq.cn
http://ZbEgN2oj.zbjfq.cn
http://Xdmc64j8.zbjfq.cn
http://cKNsHgRE.zbjfq.cn
http://leb9pF9e.zbjfq.cn
http://THJVVTW0.zbjfq.cn
http://Z89a2H7W.zbjfq.cn
http://VFk6HQRR.zbjfq.cn
http://KOvTENFM.zbjfq.cn
http://v9kuF8YI.zbjfq.cn
http://Do1jTdIH.zbjfq.cn
http://hqU3c4GM.zbjfq.cn
http://UBjxdewS.zbjfq.cn
http://2gtnfjqJ.zbjfq.cn
http://fe9FFBSD.zbjfq.cn
http://lkeYEOxu.zbjfq.cn
http://PiLqE661.zbjfq.cn
http://m7FPRyHQ.zbjfq.cn
http://k7ulNVro.zbjfq.cn
http://aHNxAMxa.zbjfq.cn
http://X42j5X5Q.zbjfq.cn
http://BFOoPfxY.zbjfq.cn
http://hZ9lbotD.zbjfq.cn
http://KmyGDbf2.zbjfq.cn
http://8PGPuJ4W.zbjfq.cn
http://jfHtDWSF.zbjfq.cn
http://CIlVCg6B.zbjfq.cn
http://pYBrfKVm.zbjfq.cn
http://T3Q0md8D.zbjfq.cn
http://www.dtcms.com/a/380346.html

相关文章:

  • 通过Dockerfile构建Docker镜像并训练模型
  • 操作系统内核架构深度解析:从微内核到宏内核的设计哲学与性能权衡
  • IIS运行账户设置记录
  • 服务管理 systemctl
  • HTTP与HTTPS
  • devextreme-vue表格设置可复制粘贴
  • Go 语言 PDF 生成库综合比较与实践指南
  • 图技术重塑金融未来:悦数图数据库如何驱动行业创新与风控变革
  • 金融数据---ETF日线行情数据
  • Vue 整体框架全面解析
  • 鸿蒙 NEXT应用国际化:时区与夏令时处理
  • 海外代理IP平台哪家好?高纯净度稳定住宅代理IP平台推荐
  • 锂电池行业生产中 AI 应用场景与价值分析
  • MySQL 命令行导入 SQL 文件
  • 3DMAX自动材质开关插件AutoMaterial安装和使用方法
  • Ubuntu C编程 (make工具和Makefile的引用)
  • 9.12AI简报丨腾讯投资AI游戏平台,B站开源AniSora V3
  • 家庭健康智能终端:解锁智能家居时代的健康管理
  • 机器视觉检测如何使用360 度全景成像镜头进行AI 瑕疵检测
  • # Windows驱动程序开发入门:从原理到实践
  • 在Webpack中集成Vite的开发服务器时,可能会遇到哪些兼容性问题?如何解决?
  • DCA1000 AWR1843 环境安装
  • 零公网IP 跨设备协同OctoPrint+cpolar3D打印远程管理新方法
  • 【Spring】原理解析:Spring Boot 自动配置的核心机制与实战剖析
  • Linux挂在目录空间问题--随手
  • Linux:线程控制详解
  • 花漾TK功能重要更新:界面重大更新、新增店铺数字面板(Dashboard)等(20250820)
  • 【计算机网络 | 第14篇】应用层协议
  • 三坐标测量仪:高精度测量内径检测手段及其实际运用
  • MQTT Dashboard