欢迎来到半导体与芯片的世界 - 芯片验证
验证技术的发展历程这是我们作为一名合格验证人员装B必备，如下图所示:2000年：Verisity Design（现在的Cadence公司）引进了Verification Advisor（vAdvisor）采用了e语言，包含了激励的产生，自动比对的策略，覆盖率模型。e语言是面向对象语言，这是业界开始使用面向对象语言 进行测试平台的建立。2002年：Verisity公司公布了第一个验证库——e可重用方法学（eRM）。2003年：Synopsys公司公布了可重用验证方法学库（RVM），这个方法学采用了Synopsys公司的vera语言。2006年：Mentor公司公布了高级验证方法学（AVM）。这个方法学主要是采用了OSCI SystemC的事务抽象层方法学（TLM）标准，它是用SystemVerilog和SystemC两种语言实现的。2006年：Synopsys公司推出了验证方法学手册（VMM），这个是RVM从vera语言过度到SystemVerilog的方法学。2007年：Cadence公司推出了通用可重用验证方法学（URM），主要是从eRM从E语言过度到SystemVerilog的方法学，同时加入了TLM接口，工厂模式替换，配置机制，策励类等。2008年：Cadence公司和Mentor公司共同推出了OVM2010年：Synopsys公司推出了VMM1.2，基本上沿用了OVM的TLM通信机制，并采用了TLM2.0（OSCI最新的标准），采用OVM提出的implicit phase，并且将验证流程继续细化，工厂模式替换机制，建立类层次（建立parent关系）。并且在此基础上，提出了vmm_timeline的概念，方便各个phase之间实现跳转，增加phase或删除phase。增加了rtl_config等概念。Synopsys公司也随即宣布最新版本的VCS 同时支持UVM。2010年：ACCELLERA采用了OVM作为基础，推出了UVM验证方法学。同时引入了VMM的callbacks一些概念。作为业界方法学统一的一个雏形。2011年2月：Accellera通过了通用验证方法学1.0版，并得到三大厂商（Cadence，Synopsys和Mentor Graphics现英飞凌）的共同支持。此后Accellera陆续推出了UVM1.1, UVM1.1a,UVM1.1b,UVM1.1c,UVM1.1d这几个版本。2014年6月，Accellera有推出了通用验证方法学1.2版。目前UVM最新版是UVM-1800.2-2017-1.0（版本号命名都变了哈）UVM(Universal Verification Methodology) UVM几乎完全继承了OVM，同时又采纳了Synopsys在VMM中的寄存器解决方案RAL。UVM继承了OVM和VMM的优点，克服了各自的缺点，代表了验证方法学的发展方向。UVM介绍UVM是一个以SystemVerilog为主体的验证平台开发框架，验证工程师利用其可重用组件可以构建具有标准化层次结构和接口的功能验证环境。UVM是一个库，在这个库中，几乎所有的东西都是使用类(class)来实现的。类是面向对象编程语言中最伟大的发明之一，是面向对象的精髓所在。使用UVM的第一条原则是：验证平台中所有的组件都应该派生自UVM中的类。当要实现一个功能时，首先应该想到的就是从UVM的某个类派生出一个新的类，类中可以有成员变量，也可以有函数和任务，通过成员变量、函数或任务实现所期望的功能。对于验证方法学来说，分层的测试平台是一个关键的概念。虽然分层似乎会使测试平台变得更复杂，但它能够把代码分而治之，有助于减轻工作负担，而且重复利用效率提升。基于UVM的验证平台可以类似分为五个层次：信号层、命令层、功能层、场景层和测试层：如何学习UVMUVM1.2版本包含121个文件，311个类。从经验来说，我们搭建一个普通的UVM验证环境，大约需要编写10个文件，20个类左右。这里分享一下对初学者的个人建议：第一阶段-基础：学习UVM之前, 熟悉SV是必须的，关于SV的系统学习首推“绿皮书”。工作中“asic-world”这个网站可以作为我们的查询手册。第二阶段-学习：有了SV的基础和OOP的思想，我们就可以开始学习UVM了（很多人入门是看《UVM实战》-张强著 ）。这时我们需要了解UVM构架，各种component, phase管理机制等。最好配合实例代码一边看书一边敲代码做练习。第三阶段-应用：当然我们有的朋友会说："我现在的公司还没有用UVM来搭环境呀，怎么应用啊？" 但是，没有条件我们可以创造条件呀！ 网上这么多开源的IP，找一个自己感兴趣的，把自己当成验证主管，自己玩儿呗。或者把已经做过的项目再用UVM搭一遍（别说你没时间哦~第四阶段-研究：这个时候你已经是熟手，并能够独立搭建复用性很强的UVM环境了。这时可以去看看UVM源码，帮助同事解决实际工作中的各种问题。研究一下UVM代码自动生成，UVMF是什么等等
CPU 系统级验证 —— 指令集验证 ——OpenHW core-v 验证环境及文件分析
本文记录的相关源工程和文件为：core-v RISCV 核功能验证工程：https://github.com/openhwgroup/core-v-verifcore-v 验证策略：https://core-v-docs-verif-strat.readthedocs.io/en/latest/#core-v 系列核 cva6 工程：https://github.com/openhwgroup/cva6core-v 系列核 cv32e40p 工程：https://github.com/openhwgroup/cv32e40pLowRISCV Ibex 核工程：https://github.com/lowRISC/ibexcore-v RISCV 核相关说明文档：https://github.com/openhwgroup/core-v-docsRISCV ISA 指令流（instruction stream）生成器：https://github.com/openhwgroup/force-riscvcore-v 系列指令流（instruction stream）生成器：https://github.com/openhwgroup/core-v-isgsail 语言介绍：https://www.cl.cam.ac.uk/~pes20/sail/REMS 的 sail RISCV 开源项目：https://github.com/rems-project/sail-riscvopenHW 全称为 open-source hardware，是一个支持开源软件和硬件的非盈利组织。该组织开源的内容包括开源 CPU 核、相关 IP、工具和软件等。指令集验证指令集验证的需求能够使用操作数产生合法的基本整数运算指令在指令执行完成后能够检查通用寄存器的状态指令执行完成后能检查副效应，例如溢出等。指令集验证内容指令集的验证需要验证工程师思考该指令需要测试的特征是什么，为了确保指令的正确执行需要检查的内容是什么，为了确保该特征被测试需要进行哪些激励和配置等。验证的充不充分取决于验证人员对 CPU 微架构的理解和风险应对能力。（1）RISCV 基本指令定向测试设计出来的 CPU 首先需要兼容 RISCV 基本指令，即需要满足 RISCV 基本整数指令及相关标准指令集。主要测试的内容有：溢出检测及相关标志位下溢检测及相关标志位无指令执行的副效应，比如异常的通用处理寄存器变化，异常的条件代码使用 x0-x31 作为 rs1/rs2使用 x0-x31 作为 rdx0 寄存器的值始终为 0set/clear 所有立即数的比特位set/clear 源寄存器 rs1/rs2 的比特位根据 7/8 两条 set/clear 目的寄存器 rd 的比特位（2）自定义扩展指令定向测试对于自定义扩展指令集的验证，该验证需要修改相关的工具链并通过相关测试验证工具链的修改成功，再进行（1）中的测试。（3）随机约束测试对进行大量的随机指令测试指令集验证激励的种类指令集测试激励分为自检（self-checking）和预存（pre-existing）两种。自检测试激励运行时按照源文件中指令顺序依次，并同时将指令执行结果和参考值作检查，若出错则程序跳转到 fail，打断正常执行顺序，立即执行完成。类似的测试集有 riscv-tests、riscv-compilance-tests 等预存测试激励运行时不会打断执行顺序，执行的结果会和指令集模拟器（ISS）的结果作对比，最终统计对比的结果。类似的测试集有 riscv-dv 等指令集验证 pass/fail 的标志测试的 pass/fail 与上述激励的种类有关self checking：自检性质的测试激励在每条指令执行时就会同时将结果和参考值作对比，若失败则跳转到 failsignature check：特征检查，相对自检来说更加复杂深入。测试的结果将被用来计算该指令的某个特征，这将会和预先确定好的较标准特征作对比。采用该检查的为 riscv-complience-tests。check against ISS：与指令集模拟器对比检查。该情况下，testcase 并不知道测试的参考值，仅仅给 DUT 提供激励，testbench 会对比 DUT 和 ISS 的输出结果确定测试的 pass/fail。该检查较被经常使用，因为它是的 testcase 更加简单。采用该检查的如 riscv-dvcheck against RM：与参考模型对比检查，该检查方式与第三点类似，但相对 ISS 更加通用。通常用作 ISS 检测的补充。assertion check：通过断言判断是否执行出错。相关 CPU 核的验证工程cv32e40pCV32E40P (原先 PULP 开发的 RI5CY) 是一个 32bit 的 4 级流水线核，支持整数运算指令、乘法除法指令、单浮点运算指令、压缩指令以及 DSP 扩展指令（包括硬件循环、SIMD 扩展、位操作和增量指令）该核的验证环境有两套，一套是专门的 core testbench；一套是 UVM 环境搭建的 testbench，该环境下 testcase 的产生是可以基于 UVM 环境的（这种方式类似于 Ibex 核验证环境）。两套环境均由 systemverilog 编写。均包含了指令集验证、中断验证、CSR 寄存器验证、异常验证、debug 验证等。1 core testbench该工程是 PULP 遗留下的产物，OpenHW 做了一定修改并持续维护。验证环境中已集成了指令集模拟器。该工程的测试集激励包含指令兼容性测试（偏定向测试，如 riscv-tests 和 riscv-compilance-tests）和随机约束（google riscv-dv），和其他的一些 fireware 测试用例。测试环境结构如下：该 testbench 简单，运行较快，通过 verilator 运行，但是有额外的开销且不能获取覆盖率。2 UVM 验证环境（uvmt_cv32）cv32 核的 UVM 验证环境已搭建完成，在 DSIM（Metrics）运行也很稳定。验证环境中已集成了指令集模拟器。uvm 验证环境的 testcase 均是由 uvm 相关类生成，同时该环境还集成了 riscv-dv，但具体的激励生成还需要再分析。具体验证环境结构UVM 内部组件关系debug、interrupt、control/status 均通过 UVM_agent 组件产生，且通过 uvm_sequence 组件输入激励。UVM 运行流程采用 UVM 搭环境的优势a) 便于验证环境的结构建模b) UVM 环境类支持完全的 UVM 运行流程和 log 服务c) 使用 UVM sequence-item 类可以产生随即约束激励d) 使用内建于验证环境中的参考模型预测执行的结果。（imperas 有现成的开源 ISS）e) scoreboard 可以比较参考模型和 RTL 的结果。f) 功能覆盖率和代码覆盖率确保验证的完全性。且 UVM 测试环境可复用性较高，也可以用在 CVA6 核上。CVA6CVA６(ariane) 是一个 6 级流水线、单发射、顺序执行的 RV32GC 或 RV64GC 核，支持 M/U/S 三种模式，支持 linux 操作系统。该核现存的验证环境尚未成熟，但同样可以构建 UVM 的验证环境。该工程的指令集测试激励包括 riscv 官方测试套件（即 riscv-tests）。IbexIbex 不是 openHW 的 core-v 系列，而是 lowRISC 持续维护的较为成熟的一款核，验证环境也较为成熟，其结构和运行非常类似于 CV32E 和 CVA6 的激励随机约束。该验证环境激励的产生同样是基于 GOOGLE 的随机指令生成器验证环境特征运行有效性testcase 在验证环境中会持续运行完成，除非激励运行出错方便调试能够增加功能覆盖率能够对比检查 RTL 运行的结果指令集描述语言 ——sailsail 是 REMS 构建的一种描述指令集的语言，可以认为是一种机器可读的形式化 ISA 模型。REMS 是英国的一家学术组织，该组织已构建出 RV32IMAC 和 RV64IMAC 指令集的 sail model，链接见上。riscv 基金会有意用其来描述 RISCV 指令集。初步来看，sail 可以用来形式化 testbench 断言的参考模型，这些 assertion 可以根据 sail spec 来验证基于 RISCV ISA 的某微架构。目前该领域 OneSpin GapFree 已经在 sail model 和 RTL 代码间做了可比性的 check，该公司仍在探索如何充分使用 sail model该语言将持续关注。
无意中发现一个开源的工具，使用systemRDL文件作为输入，可以生成寄存器相关的RTL module，UVM中使用的regmodel，C和verilog的头文件(包含寄存器某个字段的偏移以及mask bits)，以及html的文档。资源如下：https://github.com/zhajio1988/Open_RegModel生成的html文档示例如下：https://systemrdl.github.io/RALBot-html————————————————版权声明：本文为CSDN博主「XtremeDV」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/zhajio/article/details/102620859开源uvm reg model (UVM 寄存器模型)生成工具open-register-design-toolOrdt is a tool for automation of IC register definition and documentation. It currently supports 2 input formats:SystemRDL - a stardard register description format released by Accellera.orgJSpec - a register description format used within Juniper NetworksThe tool can generate several outputs from SystemRDL or JSpec, including:SystemVerilog/Verilog RTL code description of registersUVM model of the registersC++ models of the registersXML and text file register descriptionsSystemRDL and JSpec (conversion)Easiest way to get started with ordt is to download a runnable jar from the release area.Ordt documentation can be found here.注：nvdla中使用SystemRDL格式描述寄存器模型，并使用jar xxx ordt.jar ......生成uvm reg model————————————————版权声明：本文为CSDN博主「XtremeDV」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/zhajio/article/details/82870523
Python在芯片中的应用：RTL自动生成、验证脚本、界面可视化等
今天还是这张图。最近一直在思考集成电路怎么与其它几个前沿领域相结合。今天来讲讲Python。Python其实不是人工智能、神经网络的专属语言，在芯片设计和验证领域也有非常多的应用。下面是一些的开源项目：RTL自动生成：https://github.com/nvdla/hw/blob/master/tools/bin/epython寄存器默型的自动生成：https://github.com/SystemRDL/systemrdl-compiler仿真脚本、回归脚本：https://github.com/zhajio1988/YASA自动生成UVM的方法：https://mp.weixin.qq.com/s/SvWRJBGggg0lqiD8YjEZ3QRISCV Core的仿真脚本：https://github.com/google/riscv-dv因为Python相对于其它语言如Perl，Tcl学习成本更低、资料更多、更容易上手，所以在实际项目中使用python的情况越来越多。当然并不是说Perl、Tcl不需要学了，老项目还需要继续维护。但是，打开大佬的代码后，却一脸懵逼。下面是Google RISCV Core验证项目的脚本run.py截图，大佬们都喜欢用Class来装逼，这个对于Python零基础或者初学者很不友好。函数还没学会，你叫我用class？整天看着UVM就已经够头疼的了，唉。连验证大佬炯哥的脚本也是。。。还有一大堆的import，望而生畏、望而却步。
systemverilog interface普通的模块使用法：注意我们这里只实现了部分功能。。。。不是完全的读写模块。。。。module mem_core( input logic wen, input logic ren, output logic mrdy=1, input logic [7:0] addr, input logic [7:0] mem_din, //写进mem output logic [7:0] mem_dout, //从mem读出 output logic status, input logic clk);logic[7:0] mem [7:0]; //初始化一个meminitial $readmemh("d:/init.txt",mem); //d:/init.txt 文件中是 @01 10 。//或者 assign mem [2'h01]=8'b00000111; 注意这里一定要用 initial 或者assign等语句，不能直接=task reply_read(input logic [7:0] data, integer delay); #delay; @(negedge clk) mrdy=1'b0; mem_dout=data; //从图中可看出这两句话几乎同时执行。 @(negedge clk) mrdy=1'b1;endtaskalways@(negedge ren) reply_read(mem[addr],10);endmodulemodule cpu_core( output logic wen=1, output logic ren=1, input logic mrdy, output logic [7:0] addr=0, input logic [7:0] cpu_din, output logic [7:0] cpu_dout, output logic status=0, input logic clk);task read_memory(input logic [7:0] raddr, output logic [7:0] data); @(posedge clk); ren=1'b0; addr=raddr; @(negedge mrdy); @(posedge clk); data=cpu_din; ren=1'b1; endtaskinitial beginlogic[7:0] read_data; read_memory(2'h01, read_data); $display("Read Result", $time,read_data);endendmodulemodule top; logic mrdy,wen,ren; logic[7:0] addr,d1,d2; wor status; logic clk=0;mem_core mem(., .mem_din(d1), .mem_dout(d2)); //采用对同名的信号做默认连接 cpu_core cpu(.*, .cpu_din(d2), .cpu_dout(d1));initial for(int i=0;i<=255;i++) #1 clk=!clk;endmoduleSystemverilog interface另外，ＳｙｓｔｅｍＶｅｒｉｌｏｇ引入一个重要的数据类型：ｉｎｔｅｒｆａｃｅ。其主要作用有两个：一是简化模块之间的连接；二是实现类和模块之间的通信；随着复杂度的提高，模块间互联变得复杂，SV引入接口，代表一捆连线的结构，具有智能同步和连接功能的代码；接口（ｉｎｔｅｒｆａｃｅ）为硬件模块的端口提供了一个标准化的封装方式。用ｉｎｔｅｒｆａｃｅ来封装接口的信号和功能。ｉｎｔｅｒｆａｃｅ的定义是独立于模块的，通过关键字ｉｎｔｅｒｆａｃｅ和ｅｎｄｉｎｔｅｒｆａｃｅ包起来。此外，ｉｎｔｅｒｆａｃｅ里面还可以带时钟、断言、方法等定义。 一个interface 也可以有input,output或是inout端口。当interface例化时，只有当变量或是线网声明在一个interface的端口列表中才能通过名字或是位置来互连.一种新加的和interface有关系的构造体是Modport 。它提供了module的interface端口和在特定的module中控制task和function使用的方向性信息。这些端口的方向可以在module中可以看到。接口使用无信号的连接方式。Modport将接口中信号分组并指定方向。就像下图中的黑色矩形块里面一样，黑盒，我们从外面看并不关心Modport的定义，只需要考虑clk。Systemverilog interfaceinterface membus(input logic clk, output wor status); logic mrdy; logic wen; logic ren; logic [7:0] addr; logic [7:0] c2m_data; logic [7:0] m2c_data;task reply_read(input logic [7:0] data, integer delay); #delay; @(negedge clk) mrdy=1'b0; m2c_data=data; @(negedge clk) mrdy=1'b1;endtask//Task和function可以定义在interface中，从而允许构造更抽象级的模型task read_memory(input logic [7:0] raddr, output logic [7:0] data); @(posedge clk); ren=1'b0; addr=raddr; @(negedge mrdy); @(posedge clk); data=m2c_data; ren=1'b1; endtaskmodport master(output wen, ren, addr, c2m_data, input mrdy, m2c_data, status, read_memory);modport slave(input wen, ren, addr, c2m_data, output mrdy, m2c_data, status, reply_read);//控制task和function使用的方向性信息，以便在下面的module中使用endinterfacemodule mem_core(membus.slave mb); //modport只需在模块首部指明（或者在()中），在模块例化时不需要指明使用接口时在模块和程序块之外声明接口变量；//接口信号必须采用非阻塞值赋值来驱动。 logic[7:0] mem [7:0]; assign mem [2'h01]=8'b00000111; assign mb.status=0; always@(negedge mb.ren) mb.reply_read(mem[mb.addr],100); //module可使用interface端口endmodulemodule cpu_core(membus.master mb); assign mb.status=0; initial beginlogic[7:0] read_data; mb.read_memory(2'h01, read_data); $display("Read Result", $time,read_data);endendmodulemodule top; wor status; logic clk=0; membus mb(clk,status); mem_core mem(.mb(mb.slave)); cpu_core cpu(.mb(mb.master));initial for(int i=0;i<=255;i++) #1 clk=!clk;endmoduleSystem verilog把测试平台的代码放在一个程序块中，包含代码和变量，我总结了几步使用interface的方法1、 首先定义一个interface interface arb_if(input bit clk); logic [1:0] grant, request; logic reset; clocking cb @(posedge clk); //在其中定义一个时钟块。供下面的测试program使用。测试program中所有使用到的信号都应该定义在其中 output request; //注意这里的方向是测试program中所需要的方向，一般跟DUT 中的相反 input grant; endclockingmodport TEST (clocking cb, // 使用modport,将信号分组 output reset); modport DUT (input request, reset, clk, output grant); modport MONITOR (input request, grant, reset, clk);endinterface2、定义一个基于interface参数的设计模块modulemodule arb (arb_if.DUT arbif); //该interface参数要实例化 reg last_winner; reg winner; reg [1:0] next_grant; reg [1:0] state, nxState; always @(posedge arbif.clk or posedge arbif.reset) begin 。。。 endendmodule 3、定义一个基于interface参数的测试程序program program automatic test (arb_if.TEST arbif); //该interface参数也要实例化task reset_test();begin$display("Task reset_test: asserting and checking reset"); arbif.reset <= 0; #100 arbif.reset <= 1; //测试program中所有使用到的信号都应该调用在interface中的时钟块里定义的信号 arbif.cb.request <= 0; repeat (2) @arbif.cb; arbif.reset <= 0; @arbif.cb; //测试program中是这样等待时钟边沿的。 a0: assert (arbif.cb.grant == 2'b00); 。。。 end endtask task request_grant_test();begin 。。。 end endtask //注意program中不允许使用always块。 initial begin repeat (10) @arbif.cb; reset_test(); request_grant_test(); repeat (10) @arbif.cb; $finish; endendprogram4、‘最后使用一个顶层模块将它们组合起来module top; bit clk; always #5 clk = !clk; arb_if arbif(clk); //实例化一个interface arb a1 (arbif); //实例化一个module，参数调用上面实例化的interface test t1(arbif); //实例化一个测试program，参数调用上面实例化的interfaceendmodule当然也可以隐式端口连接,值使用.*即可。module top; bit clk; always #5 clk = !clk; arb_if arbif(.*); arb a1 (.*); test t1(.*); endmodule虚接口：虚接口是物理接口的句柄interface 和 module是一样的, 都是静态的变量, 也就是在程序开始时, 内存中就有了其实例.但是在class里使用virtual interface时之前有两部必须提前完成：l 定义是将接口作为一个类进行定义。l 实例化：在RTL级的顶层中对接口进行实例化。先定义一个接口。interface Rx_if (input logic clk);logic [7:0] data; logic soc, en, clav, rclk; clocking cb @(posedge clk); output data, soc, clav; input en; endclocking : cb modport DUT (output en, rclk, input data, soc, clav); modport TB (clocking cb);endinterface : Rx_if例如网络交换机中DUT 的每一个通道都有一个接口。，一个Driver类可能会连接到很多接口。我们可以在Driver类中使用一个虚接口作为参数。 class Driver;virtual Rx_if.TB Rx; //想一想，如果不是虚接口，而是一个普通接口，就像一个普通模块一样，是一个静态变量。比如我们在顶层模块例化了这个接口 Rx， 那么下面所有的 实例化的 drv[i]都是对这同一个接口 Rx进行操作，这显然不是我们想要的。如果定义了virtual，则每个实例独立。......endclass然后在测试program中 创建一组虚接口program automatic test(Rx_if.TB Rx[4], Tx_if.TB Tx[4], output logic rst); ........Driver drv[4]; //实例化了4个 Driver 对象，每个 Driver对象带有1个实例化的虚接口 .........initial beginvirtual Rx_if.TB vRx_t=Rx; //创建一组虚接口，由于这里定义了virtual，所以实例化的时候可以有Rx[]. for (int i=0; i<4; i++) begin drv[i] = new(...., vRx[i]); end rst <= 1; repeat (10) @Rx[0].cb; rst <= 0; for (int i=0; i<4; i++) begin drv[i].run(5, driver_done); //发送....... end..........endprogram : test最后在顶层：module top; logic clk, rst;Rx_if Rx[4] (clk); ，，，， atm_router a1 (Rx[0], Rx[1], Rx[2], Rx[3], Tx[0], Tx[1], Tx[2], Tx[3], clk, rst);test t1 (Rx, Tx, rst);initial beginclk = 0; forever #20 clk = !clk; end endmodule : top定义一个interface，且实例化多个后，如果没有定义virtual，则在任何一个实例中修改了某个信号值，在其他实例中都会受到影响。如果定义了virtual，则每个实例独立。如果该interface只有一个实例，可用可不用virtual，有多个实例，需要virtual。再举个例子：8位计数器`timescale 1ns/1nsinterface X_if (input logic clk);logic [7:0] din, dout; logic reset_l, load; clocking cb @(posedge clk); output din, load; input dout; endclocking always @cb //接口里面也可以带子程序，断言，initial，always块等代码。 $strobe("@ : %m: dout= , din= , load= , reset= ", $time, dout, din, load, reset_l); modport DUT (input clk, din, reset_l, load, output dout); modport TB (clocking cb, output reset_l);endinterface// Simple 8-bit counter with load and active-low reset`timescale 1ns/1nsmodule DUT(X_if.DUT xi); logic [7:0] count; assign xi.dout = count; //们想要输出的结果就是计数器always @(posedge xi.clk or negedge xi.reset_l)begin if (!xi.reset_l) count = 0; else if (xi.load) count = xi.din; else count++; end endmodule////////////////////////////////`timescale 1ns/1nsprogram automatic test();parameter NUM_XI = 2; // Number of interface instancestypedef virtual X_if.TB vXi_t; vXi_t vxi[NUM_XI]; //虚接口数组 class Driver; //在测试程序中定义类 vXi_t xi; int id; function new(vXi_t xi, int id); this.xi = xi; this.id = id; endfunction task reset; fork begin $display("@ : %m: Start reset [ ]", $time, id); // Reset the device xi.reset_l <= 1; xi.cb.load <= 0; xi.cb.din <= 0; @(xi.cb) xi.reset_l <= 0; @(xi.cb) xi.reset_l <= 1; $display("@ : %m: End reset [ ]", $time, id); end join_none endtask task load; fork begin $display("@ : %m: Start load [ ]", $time, id); xi.cb.load <= 1; xi.cb.din <= id + 10; xi.cb.load <= 0; repeat (5) @(xi.cb); $display("@ : %m: End load [ ]", $time, id); end join_none endtask endclass Driver driver[]; initial begin // Connect the local virtual interfaces to the top $display("Test.v: There are NUM_XI = interfaces", NUM_XI); if (NUM_XI <= 0) $finish; driver = new[NUM_XI]; //创建driver, 每个DUT 要对应一个driver vxi = top.xi; //XMR跨模块连接。这种是推荐做法，就不用带参数了program automatic test(X_if xi[NUM_XI]); 了。//注意这里其实是把top模块中生成的xi[]数组的句柄传过来的for (int i=0; i《NUM_XI; i++) begin driver[i] = new(vxi[i], i); driver[i].reset; end foreach (driver[i]) driver[i].load; repeat (10) @(vxi[0].cb); $display("@ : Test completed", $time); $finish; end endprogram////////////////////////////////////////////////////////`timescale 1ns/1nsparameter NUM_XI = 2; // Number of interface instancesmodule top; // Clock generator bit clk; initial forever #20 clk = !clk;X_if xi [NUM_XI] (clk); // Instantiate N Xi interfaces// Generate N DUT instances generate for (genvar i=0; i《NUM_XI; i++）begin : dut DUT d (xi[i]); endendgenerate// Instantiate the testbench, overriding the parameter with number of instances test tb();endmodule : top
如何使用vsCode+Icarus verilog+GTKwave编写并仿真verilog
用VS Code + iverilog + GTKwave仿真Verilog【下载地址】用VSCodeiverilogGTKwave仿真Verilog分享用VS Code + iverilog + GTKwave仿真Verilog本资源文件提供了一个详细的教程，指导如何在VS Code中使用iverilog和GTKwave工具进行Verilog代码的仿真 项目地址: https://gitcode.com/Resource-Bundle-Collection/9dfab本资源文件提供了一个详细的教程，指导如何在VS Code中使用iverilog和GTKwave工具进行Verilog代码的仿真。通过本教程，您将学会如何配置VS Code环境，编写和编译Verilog代码，并使用GTKwave查看仿真波形。内容概述VS Code部分安装VS Code并配置Verilog插件。创建Verilog源代码文件并进行编辑。iverilog部分下载并安装iverilog编译器。使用iverilog编译Verilog代码生成VVP文件。GTKwave部分使用GTKwave查看仿真生成的VCD文件。调整波形显示以方便分析。使用步骤安装VS Code首先，下载并安装VS Code。安装完成后，打开VS Code并安装Verilog插件，以便在编辑Verilog代码时获得语法高亮和错误检查功能。编写Verilog代码在VS Code中创建一个新的Verilog文件，编写您的Verilog代码。您可以参考教程中的示例代码，编写一个简单的计数器模块。编写测试文件创建一个测试文件（testbench），用于测试您的Verilog模块。测试文件中应包含初始化代码、时钟生成代码以及仿真结束的控制代码。编译Verilog代码使用iverilog编译器将Verilog代码和测试文件编译成VVP文件。编译命令如下：iverilog -o "test_tb.vvp" test_tb.v test.v运行仿真在命令行中运行生成的VVP文件，生成VCD波形文件：vvp test_tb.vvp查看波形使用GTKwave打开生成的VCD文件，查看仿真波形。您可以通过调整波形显示来分析仿真结果。注意事项确保iverilog和GTKwave已正确安装并配置好环境变量。在编写Verilog代码时，注意模块的输入输出定义和时序逻辑的正确性。在仿真过程中，可以通过调整测试文件中的参数来验证不同条件下的仿真结果。通过本教程，您将能够熟练使用VS Code、iverilog和GTKwave进行Verilog代码的仿真，为硬件设计提供强大的支持。【下载地址】用VSCodeiverilogGTKwave仿真Verilog分享用VS Code + iverilog + GTKwave仿真Verilog本资源文件提供了一个详细的教程，指导如何在VS Code中使用iverilog和GTKwave工具进行Verilog代码的仿真 项目地址: https://gitcode.com/Resource-Bundle-Collection/9dfab————————————————版权声明：本文为CSDN博主「邱蒙励」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/gitblog_06576/article/details/143385319
前言veirlog模块例化的时候，辣么多的信号端子，手动例化又慢又容易出错，葵花妈妈开课啦，孩子手残老犯错怎么办？当然是脚本一劳永逸，妈妈再也不担心手残党。流程（1）在vscode中安装如下插件。（2）在电脑中安装python3以上的环境。下载地址：https://www.python.org/downloads/release/python-373/安装记得一定要勾选添加路径，记得管理员安装。重启你的电脑。在cmd窗口输入python即可验证是否安装成功！（3）安装chardet。为确保插件可用，这个需要安装。参考链接：https://blog.csdn.net/sinat_28631741/article/details/80483064方式一 源码按照：第一步：下载压缩文件，例如： 'chardet-3.0.4.tar.gz'； 第二步：解压文件到python安装位置下的‘site-packages’目录下，例如：‘D:\python2.7\Lib\site-packages’； 第三步：打开终端命令窗口，进入解压的‘chardet’目录下，执行命令：python setup.py install （4）修改插件的原始py文件，觉得开发者的py有瑕疵，让帅气的同事重新整了个，把以下代码替换进原始py文件即可。在打开v文件的vscode下按ctrl+p，输入instance可出现下述界面。替换此py文件的代码即可。 #! /usr/bin/env python ''' vTbgenerator.py -- generate verilog module Testbench generated bench file like this: fifo_sc #( .DATA_WIDTH ( 8 ), .ADDR_WIDTH ( 8 ) ) u_fifo_sc ( .CLK ( CLK ), .RST_N ( RST_N ), .RD_EN ( RD_EN ), .WR_EN ( WR_EN ), .DIN ( DIN [DATA_WIDTH-1 :0] ), .DOUT ( DOUT [DATA_WIDTH-1 :0] ), .EMPTY ( EMPTY ), .FULL ( FULL ) ); Usage: python vTbgenerator.py ModuleFileName.v ''' import random import re import sys from queue import Queue import chardet def delComment(Text): """ removed comment """ single_line_comment = re.compile(r"//(.*)$", re.MULTILINE) multi_line_comment = re.compile(r"/\*(.*?)\*/", re.DOTALL) Text = multi_line_comment.sub('\n', Text) Text = single_line_comment.sub('\n', Text) return Text def delBlock(Text): """ removed task and function block """ Text = re.sub(r'\Wtask\W[\W\w]*?\Wendtask\W', '\n', Text) Text = re.sub(r'\Wfunction\W[\W\w]*?\Wendfunction\W', '\n', Text) return Text def findName(inText): """ find module name and port list""" p = re.search(r'([a-zA-Z_][a-zA-Z_0-9]*)\s*', inText) mo_Name = p.group(0).strip() return mo_Name def paraDeclare(inText, portArr): """ find parameter declare """ pat = r'\s' + portArr + r'\s[\w\W]*?[;,)]' ParaList = re.findall(pat, inText) return ParaList def portDeclare(inText, portArr): """find port declare, Syntax: input [ net_type ] [ signed ] [ range ] list_of_port_identifiers return list as : (port, [range]) """ port_definition = re.compile( r'\b' + portArr + r''' (\s+(wire|reg)\s+)* (\s*signed\s+)* (\s*\[.*?:.*?\]\s*)* (?P<port_list>.*?) (?= \binput\b | \boutput\b | \binout\b | ; | \) ) ''', re.VERBOSE | re.MULTILINE | re.DOTALL ) pList = port_definition.findall(inText) t = [] for ls in pList: if len(ls) >= 2: t = t + portDic(ls[-2:]) return t def portDic(port): """delet as : input a =c &d; return list as : (port, [range]) """ pRe = re.compile(r'(.*?)\s*=.*', re.DOTALL) pRange = port[0] pList = port[1].split(',') pList = [i.strip() for i in pList if i.strip() != ''] pList = [(pRe.sub(r'\1', p), pRange.strip()) for p in pList] return pList def formatPort(AllPortList, isPortRange=1): PortList = AllPortList str = '' if PortList != []: l1 = max([len(i[0]) for i in PortList])+2 l3 = max(18, l1) strList = [] str = ',\n'.join([' ' * 4 + '.' + i[0].ljust(l3) + '(' + (i[0]) + ')' for i in AllPortList]) strList = strList + [str] str = ',\n\n'.join(strList) return str def formatDeclare(PortList, portArr, initial=""): str = '' if PortList != []: str = '\n'.join([portArr.ljust(4) + ' '+(i[1]+min(len(i[1]), 1)*' ' + i[0]) + ';' for i in PortList]) return str def formatPara(ParaList): paraDec = '' paraDef = '' if ParaList != []: s = '\n'.join(ParaList) pat = r'([a-zA-Z_][a-zA-Z_0-9]*)\s*=\s*([\w\W]*?)\s*[;,)]' p = re.findall(pat, s) l1 = max([len(i[0]) for i in p]) l2 = max([len(i[1]) for i in p]) paraDec = '\n'.join(['parameter %s = %s;' % (i[0].ljust(l1 + 1), i[1].ljust(l2)) for i in p]) paraDef = '#(\n' + ',\n'.join([' .' + i[0].ljust(l1 + 1) + '( ' + i[1].ljust(l2)+' )' for i in p]) + ')\n' return paraDec, paraDef def portT(inText, ioPadAttr): x = {} count_list = [] order_list = [] for i in ioPadAttr: p = port_index_list(inText, i) for j in p: count_list.append(j) x[j] = i count_list = quick_sort(count_list, 0, len(count_list)-1) for c in count_list: order_list.append(x.get(c)) return order_list def quick_sort(myList, start, end): if start < end: i, j = start, end base = myList[i] while i < j: while (i < j) and (myList[j] >= base): j = j - 1 myList[i] = myList[j] while (i < j) and (myList[i] <= base): i = i + 1 myList[j] = myList[i] myList[i] = base quick_sort(myList, start, i - 1) quick_sort(myList, j + 1, end) return myList def formatPort_order(padAttr, orderList): for p in padAttr: q = Queue() for i in padAttr.get(p): q.put(i) padAttr[p] = q AllPortList = [] for o in orderList: AllPortList.append(padAttr.get(o).get()) return AllPortList def port_index_list(intext, text): l = [] t = intext index = t.find(text) while index > -1: t = t.replace(text, random_str(len(text)), 1) l.append(index) index = t.find(text) return l def random_str(size): s = '' for i in range(size): s += str(random.randint(0, 9)) return s def getPortMap(AllPortList, ioPadAttr): if len(AllPortList) != len(ioPadAttr): return p_map = {} for i in range(len(AllPortList)): p_map[ioPadAttr[i]] = AllPortList[i] return p_map def writeTestBench(input_file): """ write testbench to file """ with open(input_file, 'rb') as f: f_info = chardet.detect(f.read()) f_encoding = f_info['encoding'] with open(input_file, encoding=f_encoding) as inFile: inText = inFile.read() # removed comment,task,function inText = delComment(inText) inText = delBlock(inText) # moduel ... endmodule # moPos_begin = re.search(r'(\b|^)module\b', inText).end() moPos_end = re.search(r'\bendmodule\b', inText).start() inText = inText[moPos_begin:moPos_end] name = findName(inText) paraList = paraDeclare(inText, 'parameter') paraDec, paraDef = formatPara(paraList) ioPadAttr = ['input', 'output', 'inout'] orlder = portT(inText, ioPadAttr) input = portDeclare(inText, ioPadAttr[0]) output = portDeclare(inText, ioPadAttr[1]) inout = portDeclare(inText, ioPadAttr[2]) portList = formatPort(formatPort_order( getPortMap([input, output, inout], ioPadAttr), orlder)) input = formatDeclare(input, 'reg') output = formatDeclare(output, 'wire') inout = formatDeclare(inout, 'wire') # write Instance # module_parameter_port_list if(paraDec != ''): print("// %s Parameters\n%s\n" % (name, paraDec)) # list_of_port_declarations #print("// %s Inputs\n%s\n" % (name, input)) #print("// %s Outputs\n%s\n" % (name, output)) #if(inout != ''): # print("// %s Bidirs\n%s\n" % (name, inout)) print("\n") # UUT print("%s %s inst_%s (\n%s\n);" % (name, paraDef, name, portList)) if __name__ == '__main__': writeTestBench(sys.argv[1]) （5）享受一下吧。比如我们有如下代码：crtl+p，输入instance，按回车即可。 复制粘贴大发好。以上。转载于:https://www.cnblogs.com/kingstacker/p/9944259.html
前言UVM是IC验证的一种方法学，利用UVM搭建的验证环境基本框架都类似，因此，可以通过脚本来生成UVM的验证环境基本框架。本文主要介绍synopsys公司，在vcs工具中自带的一个脚本uvmgen，通过这个脚本，可以自动产生一整套UVM的验证环境，或者也可以只生成其中的一个UVM组件。一、uvmgen的使用首先利用uvmgen这个脚本，产生一个完整的UVM环境；然后运行这个环境，解决一些系统、工具、UVM环境之间的一些兼容性问题。1.1 uvmgen产生一个完整UVM环境这里展示一下，如何通过uvmgen这个脚本，产生一个完整的UVM环境。 hefei@ubuntu:~$ which uvmgen /opt/synopsys/vcs_vO-2018.09-SP2/bin/uvmgen hefei@ubuntu:~$ uvmgen ------------------------------------------------------------ WELCOME TO UVM TEMPLATE GENERATOR ------------------------------------------------------------ UVM templates compatible to UVM 1.1/1.2 used. Using template from /opt/synopsys/vcs_vO-2018.09-SP2/etc/uvm_template/shared/lib/templates/uvm 1) Enter 1 to Create Complete Environment 2) Enter 2 to Generate Individual Template Select [1-2]: 1 Do you want to create your own methods [Instead of UVM shorthand macros] ? Select [ y/Y/n/N ][Default: n]: n Would you be associating UVM REG models in your environment class? enter (y/n) [Default: n]:y Enter Name of RAL Adapter:ral_ad1 Enter the environment name: top_env Do you want to create Agents? Select(y/Y/n/N) [Default: n]:y Enter Master agent data Enter name of master agent: mst Enter name of sequencer: sqr1 Enter name of driver: drv1 Enter name of monitor: mon1 Enter name of interface: intf1 Enter name of the transaction: tr1 Is this transaction class extended from a BU class? enter (y/n): n Enter Slave agent data Enter name of slave agent: slv Enter name of sequencer: sqr2 Enter name of driver: drv2 Enter name of monitor: mon2 Enter name of interface: intf2 Do you want to use same transaction class for master and slave agents ? enter (y/n):y Choose one of the following ral bfm: 1) RAL sequence adapter, single domain 2) RAL sequence adapter, multiplexed domains select [1-2]:2 Enter Name of second RAL Adapter:ral_ad2 Enter Driver information for the slave agent slv :: Choose one of following driver available 1) Driver, PUSH DRIVER (uvm_push_driver) 2) Driver, PULL DRIVER (uvm_driver) Select [1- 2] [Default: 2]: Enter Driver information for the master agent mst :: Choose one of following driver available 1) Driver, PUSH DRIVER (uvm_push_driver) 2) Driver, PULL DRIVER (uvm_driver) Select [1- 2] [Default: 2]: Would you like to implement scoreboard? Select(y/Y/n/N) [Default: y]:y Enter Name of Scoreboard Class:scb The testcase generated is top_env_test ------------------------------------------------------------ Template generation completed. ------------------------------------------------------------ Usage notes : 1) Find the generated files in "proj/top_env" directory. 2) Makefile has been placed in run "proj/top_env/run" directory. 3) Edit files and look for comments marked "ToDo:" and fill in the application-specific behavior for your function. ------------------------------------------------------------ 执行完成上面的脚本后，在执行的目录下，会产生一个proj的文件夹，该文件夹的层次结构如下所示： hefei@ubuntu:~/proj$ tree . ├── README ├── top_env │ ├── doc │ ├── env │ │ ├── mst.sv │ │ ├── slv.sv │ │ ├── top_env_ral_env.sv │ │ └── top_env.ralf │ ├── examples │ ├── hdl │ │ └── top_env_top.sv │ ├── include │ │ ├── mstr_slv_intfs.incl │ │ ├── mstr_slv_src.incl │ │ └── top_env.sv │ ├── run │ │ └── Makefile │ ├── src │ │ ├── mon_2cov.sv │ │ ├── mst_drv1.sv │ │ ├── mst_intf1.sv │ │ ├── mst_mon1.sv │ │ ├── mst_sequence_library.sv │ │ ├── mst_sqr1.sv │ │ ├── mst_tr1.sv │ │ ├── ral_multiplexed.sv │ │ ├── scb.sv │ │ ├── slv_drv2.sv │ │ ├── slv_intf2.sv │ │ ├── slv_mon2.sv │ │ ├── slv_sqr2.sv │ │ ├── slv_tr1.sv │ │ ├── top_env_cfg.sv │ │ └── top_env_cov.sv │ └── tests │ ├── top_env_tb_mod.sv │ └── top_env_test.sv └── uvmgen_options_log.txt 1.2 解决运行报错的问题直接进入到proj/top_env/run这个文件夹，执行make后，会报如下错误，这是因为我们的系统是64位的，而执行ralgen和vcs的时候都没有加上-full64这个选项。 hefei@ubuntu:~/proj/top_env/run$ make rm -rf simv* csrc rm -rf vc_hdrs.h .vcsmx_rebuild *.log rm -rf work/* *.svshell vcs_version cd ../env; ralgen -uvm -l sv -t top_env -c b -c a -c f top_env.ralf;cd - Error: Bad VMM installation. Executable 'ralgen.binary' not visible. /home/hefei/proj/top_env/run vcs -sverilog -l vcs.log -debug_pp +incdir+/opt/uvm-1.2/src /opt/uvm-1.2/src/uvm_pkg.sv /opt/uvm-1.2/src/dpi/uvm_dpi.cc -CFLAGS -DVCS +incdir+../include+../src+../env+../tests+../hdl \ ../tests/top_env_tb_mod.sv ../hdl/top_env_top.sv Error-[VCS_COM_UNE] Cannot find VCS compiler VCS compiler not found. Environment variable VCS_HOME (/opt/synopsys/vcs_vO-2018.09-SP2/linux) is selecting a directory in which there isn't a compiler '/opt/synopsys/vcs_vO-2018.09-SP2/linux/bin/vcs1' for a machine of this type 'linux'. Please check whether 'VCS_HOME' is incorrect; if not, see below. Perhaps vcs hasn't been installed for machine of type "linux". Or the installation has been damaged. To verify whether vcsO-2018.09 supports machine of type "Linux 5.4.0-77-generic", please look at ReleaseNotes for more details . We determine the machine type from uname; maybe uname is incorrect. You can fix installation problems by reinstalling from CDROM or downloading it from the Synopsys ftp server. For assistance, please contact vcs technical support at vcs_support@synopsys.com or call 1-800-VERILOG Makefile:61: recipe for target 'comp' failed make: *** [comp] Error 1 打开Makefile文件，在41行COMP_OPTS，以及61行ralgen后面，分别加入-full64选项，如下代码所示。 COMP_OPTS = -full64 -sverilog -l vcs.log $(UVM) $(INCL) $(DEFINES) cd ../env; ralgen -full64 -uvm -l sv -t top_env -c b -c a -c f top_env.ralf;cd - 重新make后，遇到的libvcsnew.so: undefined reference to问题，可以参考如下链接进行解决。libvcsnew.so: undefined reference to加入-LDFLAGS -Wl,–no-as-needed选项后，代码如下： COMP_OPTS = -full64 -sverilog -LDFLAGS -Wl,--no-as-needed -l vcs.log $(UVM) $(INCL) $(DEFINES) 一键获取完整项目代码再重新make后，得到的仿真log如下所示 ./simv -l simv.log \ +ntb_random_seed=1 +UVM_TESTNAME=top_env_test Chronologic VCS simulator copyright 1991-2018 Contains Synopsys proprietary information. Compiler version O-2018.09-SP2_Full64; Runtime version O-2018.09-SP2_Full64; Jun 24 19:47 2021 UVM_INFO /opt/uvm-1.2/src/base/uvm_root.svh(392) @ 0: reporter [UVM/RELNOTES] ---------------------------------------------------------------- UVM-1.2 (C) 2007-2014 Mentor Graphics Corporation (C) 2007-2014 Cadence Design Systems, Inc. (C) 2006-2014 Synopsys, Inc. (C) 2011-2013 Cypress Semiconductor Corp. (C) 2013-2014 NVIDIA Corporation ---------------------------------------------------------------- *********** IMPORTANT RELEASE NOTES ************ You are using a version of the UVM library that has been compiled with `UVM_NO_DEPRECATED undefined. See http://www.eda.org/svdb/view.php?id=3313 for more details. You are using a version of the UVM library that has been compiled with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined. See http://www.eda.org/svdb/view.php?id=3770 for more details. (Specify +UVM_NO_RELNOTES to turn off this notice) UVM_INFO @ 0: reporter [RNTST] Running test top_env_test... UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence Note-[FCICIO] Instance coverage is ON /home/hefei/proj/top_env/run/../env/ral_top_env.sv, 161 top_env_tb_mod, "top_env_tb_mod::ral_block_top_env::cg_addr" Instance coverage is set (option.per_instance = 1) for covergroup 'top_env_tb_mod::ral_block_top_env::cg_addr' Covergroup Instance: me.obj.cg_addr Design hierarchy: top_env_top.test UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence Note-[FCICIO] Instance coverage is ON /home/hefei/proj/top_env/run/../env/ral_top_env.sv, 14 top_env_tb_mod, "top_env_tb_mod::ral_reg_top_env_CHIP_ID::cg_bits" Instance coverage is set (option.per_instance = 1) for covergroup 'top_env_tb_mod::ral_reg_top_env_CHIP_ID::cg_bits' Covergroup Instance: me.obj.cg_bits Design hierarchy: top_env_top.test UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence UVM_INFO /opt/uvm-1.2/src/base/uvm_root.svh(579) @ 0: reporter [UVMTOP] UVM testbench topology: -------------------------------------------------------------------------- Name Type Size Value -------------------------------------------------------------------------- uvm_test_top top_env_test - @423 env top_env_ral_env - @436 cov top_env_cov - @467 Coverage Analysis uvm_analysis_imp - @476 master_agent mst - @449 mast_drv drv1 - @688 rsp_port uvm_analysis_port - @707 seq_item_port uvm_seq_item_pull_port - @697 mast_mon mon1 - @532 mon_analysis_port uvm_analysis_port - @541 mast_sqr sqr1 - @551 rsp_export uvm_analysis_export - @560 seq_item_export uvm_seq_item_pull_imp - @678 arbitration_queue array 0 - lock_queue array 0 - num_last_reqs integral 32 'd1 num_last_rsps integral 32 'd1 mon2cov mon1_2cov_connect - @486 sb scb - @495 after_export uvm_analysis_export - @736 before_export uvm_analysis_export - @726 comparator uvm_in_order_class_comparator #(T) - @746 after uvm_tlm_analysis_fifo #(T) - @844 analysis_export uvm_analysis_imp - @893 get_ap uvm_analysis_port - @883 get_peek_export uvm_get_peek_imp - @863 put_ap uvm_analysis_port - @873 put_export uvm_put_imp - @853 after_export uvm_analysis_export - @765 before uvm_tlm_analysis_fifo #(T) - @785 analysis_export uvm_analysis_imp - @834 get_ap uvm_analysis_port - @824 get_peek_export uvm_get_peek_imp - @804 put_ap uvm_analysis_port - @814 put_export uvm_put_imp - @794 before_export uvm_analysis_export - @755 pair_ap uvm_analysis_port - @775 slave_agent slv - @458 drv drv2 - @923 rsp_port uvm_analysis_port - @942 seq_item_port uvm_seq_item_pull_port - @932 mon mon2 - @904 mon_analysis_port uvm_analysis_port - @913 slv_seqr sqr2 - @952 rsp_export uvm_analysis_export - @961 seq_item_export uvm_seq_item_pull_imp - @1079 arbitration_queue array 0 - lock_queue array 0 - num_last_reqs integral 32 'd1 num_last_rsps integral 32 'd1 -------------------------------------------------------------------------- UVM_INFO /opt/uvm-1.2/src/base/uvm_factory.svh(1645) @ 0: reporter [UVM/FACTORY/PRINT] #### Factory Configuration (*) No instance or type overrides are registered with this factory All types registered with the factory: 80 total Type Name --------- REGTR base_sequence drv1 drv2 mon1 mon1_2cov_connect mon2 mst ral_ad2 ral_block_top_env ral_mem_top_env_top_env_RAM ral_reg_top_env_CHIP_ID reg_seq scb sequence_0 sequence_1 slv sqr1 sqr1_sequence_library sqr2 top_env_cfg top_env_cov top_env_ral_env top_env_test tr1 (*) Types with no associated type name will be printed as <unknown> #### UVM_INFO ../src/mst_drv1.sv(121) @ 0: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_mon1.sv(133) @ 0: uvm_test_top.env.master_agent.mast_mon [top_env_MONITOR] Starting transaction... UVM_INFO ../src/mst_mon1.sv(137) @ 0: uvm_test_top.env.master_agent.mast_mon [top_env_MONITOR] User need to add monitoring logic $finish called from file "../src/mst_mon1.sv", line 138. $finish at simulation time 0 V C S S i m u l a t i o n R e p o r t Time: 0 CPU Time: 1.110 seconds; Data structure size: 0.4Mb 到此为止，通过uvmgen脚本生成的整个UVM环境已经能够正常运行。uvmgen还可以生成单个的UVM组件，以及快速产生一个完整的UVM环境的方法，更多关于uvmgen脚本的使用方法，可以参考如下文档。uvmgen_userguide.pdf二、uvmgen产生的UVM环境拿到这个环境，首先，了解一下这个环境的框架，其次想着打印一下接口的波形，看看时钟复位是否正确；最后，要解决仿真异常结束的问题，上面仿真执行的log显示，$finish called from file “…/src/mst_mon1.sv”, line 138.，这不是UVM仿真的正常结束的log。2.1 环境框架uvmgen产生的uvm环境的框架如下图所示：2.2 添加打印波形打开顶层文件proj/top_env/hdl/top_env_top.sv，加入如下代码实现打印波形。 initial $fsdbDumpvars(); 重新make后，遇到的Undefined System Task call to '$fsdbDumpfile '问题，解决方法参考如下：Undefined System Task call to ‘$fsdbDumpfile’之后打开fsdb波形，调出时钟和复位信号后，显示正常，并没有像下文所述存在bug的情况，虽然VCS版本不同，但对比了时钟复位产生的源代码都是一致的。2011版VCS自带的工具UVMGEN的一个BUG，很难想像有这种级别的BUG～～2.3 解决仿真异常结束的问题仿真执行的log显示，$finish called from file “…/src/mst_mon1.sv”, line 138.，这不是UVM仿真的正常结束的log，对应的sequence激励也没有下发。打开proj/top_env/src/mst_mon1.sv，定位到138行，将138行的finish屏蔽，在130行加入一个wait(0)，避免mon1中的forever循环一直刷log(这里只是临时处理一下，后期填入代码的时候需要将其去掉)，如下图所示。同样的方式处理proj/top_env/src/slv_mon2.sv文件。再重新make，通过下面的log，可以看到仿真已经正常结束，sequence中的激励，也已经下发到了drver中。 ./simv -l simv.log \ +ntb_random_seed=1 +UVM_TESTNAME=top_env_test Chronologic VCS simulator copyright 1991-2018 Contains Synopsys proprietary information. Compiler version O-2018.09-SP2_Full64; Runtime version O-2018.09-SP2_Full64; Jun 25 00:02 2021 UVM_INFO /opt/uvm-1.2/src/base/uvm_root.svh(392) @ 0: reporter [UVM/RELNOTES] ---------------------------------------------------------------- UVM-1.2 (C) 2007-2014 Mentor Graphics Corporation (C) 2007-2014 Cadence Design Systems, Inc. (C) 2006-2014 Synopsys, Inc. (C) 2011-2013 Cypress Semiconductor Corp. (C) 2013-2014 NVIDIA Corporation ---------------------------------------------------------------- *********** IMPORTANT RELEASE NOTES ************ You are using a version of the UVM library that has been compiled with `UVM_NO_DEPRECATED undefined. See http://www.eda.org/svdb/view.php?id=3313 for more details. You are using a version of the UVM library that has been compiled with `UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR undefined. See http://www.eda.org/svdb/view.php?id=3770 for more details. (Specify +UVM_NO_RELNOTES to turn off this notice) UVM_INFO @ 0: reporter [RNTST] Running test top_env_test... *Verdi* Loading libsscore_vcs201809.so FSDB Dumper for VCS, Release Verdi_O-2018.09-SP2, Linux x86_64/64bit, 02/21/2019 (C) 1996 - 2019 by Synopsys, Inc. *Verdi* FSDB WARNING: The FSDB file already exists. Overwriting the FSDB file may crash the programs that are using this file. *Verdi* : Create FSDB file 'novas.fsdb' *Verdi* : Begin traversing the scopes, layer (0). *Verdi* : End of traversing. UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence Note-[FCICIO] Instance coverage is ON /home/hefei/proj/top_env/run/../env/ral_top_env.sv, 161 top_env_tb_mod, "top_env_tb_mod::ral_block_top_env::cg_addr" Instance coverage is set (option.per_instance = 1) for covergroup 'top_env_tb_mod::ral_block_top_env::cg_addr' Covergroup Instance: me.obj.cg_addr Design hierarchy: top_env_top.test UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence Note-[FCICIO] Instance coverage is ON /home/hefei/proj/top_env/run/../env/ral_top_env.sv, 14 top_env_tb_mod, "top_env_tb_mod::ral_reg_top_env_CHIP_ID::cg_bits" Instance coverage is set (option.per_instance = 1) for covergroup 'top_env_tb_mod::ral_reg_top_env_CHIP_ID::cg_bits' Covergroup Instance: me.obj.cg_bits Design hierarchy: top_env_top.test UVM_INFO /opt/uvm-1.2/src/base/uvm_spell_chkr.svh(123) @ 0: reporter [UVM/CONFIGDB/SPELLCHK] include_coverage not located, did you mean default_sequence UVM_INFO /opt/uvm-1.2/src/base/uvm_root.svh(579) @ 0: reporter [UVMTOP] UVM testbench topology: -------------------------------------------------------------------------- Name Type Size Value -------------------------------------------------------------------------- uvm_test_top top_env_test - @423 env top_env_ral_env - @436 cov top_env_cov - @467 Coverage Analysis uvm_analysis_imp - @476 master_agent mst - @449 mast_drv drv1 - @688 rsp_port uvm_analysis_port - @707 seq_item_port uvm_seq_item_pull_port - @697 mast_mon mon1 - @532 mon_analysis_port uvm_analysis_port - @541 mast_sqr sqr1 - @551 rsp_export uvm_analysis_export - @560 seq_item_export uvm_seq_item_pull_imp - @678 arbitration_queue array 0 - lock_queue array 0 - num_last_reqs integral 32 'd1 num_last_rsps integral 32 'd1 mon2cov mon1_2cov_connect - @486 sb scb - @495 after_export uvm_analysis_export - @736 before_export uvm_analysis_export - @726 comparator uvm_in_order_class_comparator #(T) - @746 after uvm_tlm_analysis_fifo #(T) - @844 analysis_export uvm_analysis_imp - @893 get_ap uvm_analysis_port - @883 get_peek_export uvm_get_peek_imp - @863 put_ap uvm_analysis_port - @873 put_export uvm_put_imp - @853 after_export uvm_analysis_export - @765 before uvm_tlm_analysis_fifo #(T) - @785 analysis_export uvm_analysis_imp - @834 get_ap uvm_analysis_port - @824 get_peek_export uvm_get_peek_imp - @804 put_ap uvm_analysis_port - @814 put_export uvm_put_imp - @794 before_export uvm_analysis_export - @755 pair_ap uvm_analysis_port - @775 slave_agent slv - @458 drv drv2 - @923 rsp_port uvm_analysis_port - @942 seq_item_port uvm_seq_item_pull_port - @932 mon mon2 - @904 mon_analysis_port uvm_analysis_port - @913 slv_seqr sqr2 - @952 rsp_export uvm_analysis_export - @961 seq_item_export uvm_seq_item_pull_imp - @1079 arbitration_queue array 0 - lock_queue array 0 - num_last_reqs integral 32 'd1 num_last_rsps integral 32 'd1 -------------------------------------------------------------------------- UVM_INFO /opt/uvm-1.2/src/base/uvm_factory.svh(1645) @ 0: reporter [UVM/FACTORY/PRINT] #### Factory Configuration (*) No instance or type overrides are registered with this factory All types registered with the factory: 80 total Type Name --------- REGTR base_sequence drv1 drv2 mon1 mon1_2cov_connect mon2 mst ral_ad2 ral_block_top_env ral_mem_top_env_top_env_RAM ral_reg_top_env_CHIP_ID reg_seq scb sequence_0 sequence_1 slv sqr1 sqr1_sequence_library sqr2 top_env_cfg top_env_cov top_env_ral_env top_env_test tr1 (*) Types with no associated type name will be printed as <unknown> #### UVM_INFO ../src/mst_drv1.sv(121) @ 0: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/slv_drv2.sv(121) @ 0: uvm_test_top.env.slave_agent.drv [top_env_DRIVER] Starting transaction... UVM_INFO /opt/uvm-1.2/src/seq/uvm_sequence_library.svh(659) @ 0: uvm_test_top.env.master_agent.mast_sqr@@sqr1_sequence_library [SEQLIB/START] Starting sequence library sqr1_sequence_library in main phase: 10 iterations in mode UVM_SEQ_LIB_RAND UVM_INFO ../src/mst_drv1.sv(137) @ 0: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 0: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 1900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 1900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2100: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2200: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2300: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2400: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2500: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2600: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2700: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2800: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 2900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 2900: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO ../src/mst_drv1.sv(137) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Completed transaction... UVM_INFO ../src/mst_drv1.sv(121) @ 3000: uvm_test_top.env.master_agent.mast_drv [top_env_DRIVER] Starting transaction... UVM_INFO /opt/uvm-1.2/src/seq/uvm_sequence_library.svh(736) @ 3000: uvm_test_top.env.master_agent.mast_sqr@@sqr1_sequence_library [SEQLIB/END] Ending sequence library in phase main UVM_INFO ../src/scb.sv(50) @ 3000: uvm_test_top.env.sb [SBRPT] Matches = 0, Mismatches = 0 UVM_INFO /opt/uvm-1.2/src/base/uvm_report_server.svh(847) @ 3000: reporter [UVM/REPORT/SERVER] --- UVM Report Summary --- ** Report counts by severity UVM_INFO : 212 UVM_WARNING : 0 UVM_ERROR : 0 UVM_FATAL : 0 ** Report counts by id [RNTST] 1 [SBRPT] 1 [SEQLIB/END] 1 [SEQLIB/START] 1 [UVM/CONFIGDB/SPELLCHK] 3 [UVM/FACTORY/PRINT] 1 [UVM/RELNOTES] 1 [UVMTOP] 1 [top_env_DRIVER] 202 $finish called from file "/opt/uvm-1.2/src/base/uvm_root.svh", line 517. $finish at simulation time 3000 V C S S i m u l a t i o n R e p o r t Time: 3000 CPU Time: 1.350 seconds; Data structure size: 0.5Mb到此为止，通过uvmgen脚本产生的UVM环境框架，已经正常编译仿真，下面需要做的就是，根据我们自己的项目，往对应的组件里边填入具体的实现，需要修改的组件包括driver、monitor、sequence、regmodel、coverage等。2.3 发现环境中存在的一些问题问题一：monitor组件获取不到interface。不管是mst还是slv中的monitor组件，一方面是get的时候用的标签，和前面set的不一致，导致get不到interface；另一方面，没有去判断get到的句柄是否为空。修改mst_mon1的代码如下所示：主要修改的地方有两点：1、85行get函数的第三个参数标签由mon_if改为mst_if；2、添加91和92行，用于检测mst_mon1中是否get到interface，如果get不到，立马结束仿真。slv_mon2的代码修改方式和mst_mon1类似，标签改成slv_if。至于与这些get任务相对应的set任务在哪里，可以参考如下帖子：如何定位uvm_config_db get任务的来源总的来说，agt、drv、mon中的get任务都来自proj/top_env/tests/top_env_tb_mod.sv中，19和20行的两个set任务，当set任务前面两个参数为空的情况下，应该是全域去set，因此可以在uvm所有地方都能get到这个interface。最后，需要将proj/top_env/env/mst.sv和proj/top_env/env/slv.sv的38和39行注释掉，如下图所示，这是因为，这个set函数将自己的interface传递给自己没有任何意义，而且在仿真的时候，通过 +UVM_CONFIG_DB_TRACE加入这个宏之后，还会debug报错。总结本文首先记录了利用uvmgen这个脚本，去产生一个完整的UVM验证环境框架的方法；然后解决了一些系统、工具、UVM环境之间的兼容性问题；最后发现并解决了，脚本生成的UVM验证环境框架中，在通过config_db传递interface时候的问题。————————————————版权声明：本文为CSDN博主「hh199203」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/hh199203/article/details/118210541
在sdf2.1版本中，只能用$setup，$hold和$recovery，$hold。在sdf3.0版本中，增加了$setuphold，$recrem，$removal。分开描述的$setup、$hold、$recovery、$removal不支持negative value。如果要标注负值只能用合起来的$setuphold和$recrem。某工艺的verilog仿真库 $hold(posedge T &&& (shcheckTDlh=== 1'b1), posedge D &&& (shcheckTDlh=== 1'b1),1.0); $hold(posedge T &&& (shcheckTDlh=== 1'b1), negedge D &&& (shcheckTDlh=== 1'b1),1.0); $setup(posedge D &&&(shcheckTDlh === 1'b1), posedge T &&& (shcheckTDlh=== 1'b1),1.0); $setup(negedge D &&&(shcheckTDlh === 1'b1), posedge T &&& (shcheckTDlh=== 1'b1),1.0); $recovery(posedge S,posedge T,1.0); $removal(posedge S,posedge T,1.0);对应3.0版本的SDFTIMINGCHECK (WIDTH (negedge S) (0.103::0.103)) (REMOVAL (posedge S) (posedge T)(0.140::0.140)) (RECOVERY (posedge S) (posedge T)(0.000::0.000)) (WIDTH (negedge T) (0.078::0.078)) (WIDTH (posedge T) (0.094::0.094)) (SETUP (posedge D) (COND shcheckTDlh===1'b1(posedge T)) (0.000::0.000)) (SETUP (negedge D) (COND shcheckTDlh===1'b1(posedge T)) (0.016::0.028)) (HOLD (posedge D) (COND shcheckTDlh===1'b1 (posedgeT)) (0.043::0.049)) (HOLD (negedge D) (COND shcheckTDlh===1'b1 (posedgeT)) (0.009::0.010)) )另一个工艺的verilog仿真库 $setuphold (posedge CP, posedge D, 0, 0,notifier,,, delayed_CP, delayed_D); $setuphold (posedge CP, negedge D, 0, 0,notifier,,, delayed_CP, delayed_D); $recovery (posedge SDN, posedge CP, 0,notifier); $hold (posedge CP, posedge SDN, 0,notifier);对应的2.1版本的SDF： (TIMINGCHECK (WIDTH (negedge SDN) (1.404::1.404)) (HOLD (posedge SDN) (posedge CP)(-0.198::-0.198)) (RECOVERY (posedge SDN) (posedge CP)(0.267::0.267)) (WIDTH (negedge CP) (0.425::0.425)) (WIDTH (posedge CP) (0.440::0.440)) (SETUP (posedge D) (posedge CP)(0.057::0.057)) (SETUP (negedge D) (posedge CP)(0.082::0.082)) (HOLD (posedge D) (posedge CP)(-0.048::-0.048)) (HOLD (negedge D) (posedge CP)(-0.013::-0.013)) )对比两个版本的SDF可以看出3.0的SDF用$removal代替了$hold。第一个verilog仿真库，采用了分开的$setup和$hold，$recovery和$removal。第二个库采用了合起来的$setuphold，但$recovery和$hold还是分开的。所以，第一个库不支持负值的标注；第二个库$setup和$hold支持负值，而$recovery和$hold不支持负值。在SDF版本选择上，第一个库只能用3.0，因为库里用到了$removal。第二个库只能用2.1，因为使用了$hold，如果用3.0的话，Incisive后仿时，会报错，说找不到$removal。结论工厂提供的verilog仿真库总是不那么规范。要么修改库（让工厂修改或自己修改），要么根据库产生符合条件的SDF，但也就不能反标注负值了。提示：pt产生SDF时加参数-version 2.1|3.0，用include来灵活控制，可产生不同需求的SDF。具体可查pt的write_sdf命令的参数。下面是一个例子：write_sdf -version 3.0 \-context verilog \ -include {SETUPHOLD RECREM} \ max.sdf 后仿时看反标注的成功率，如果反标成功率太低，要仔细检查。Incisive的反标率如下：SDF statistics: No. of Pathdelays =37802 Annotated = 100.00% -- No. ofTchecks = 25964 Annotated = 99.60% Total Annotated Percentage Path Delays 37802 37802 100.00 $hold 2306 2306 100.00 $width 12632 12632 100.00 $recovery 2306 2306 100.00 $setuphold 8720 8616 98.81然而VCS并没有这样的百分比报告。
在芯片验证的仿真中，有时候需要从文件中加载一些数据，比如激励、初始化数据、code等等，这些文件路径可以用绝对路径，当然为了其他人也可以用，最好用相对路径，这就需要用到环境变量来做路径的前半段。在module中得到或设置系统环境变量需要用到systemverilog的DPI-C，import C函数，然后在module中的块语句中调用C函数。步骤如下：在要获得环境变量的文件中 import setenv和getenv如下所示，把这两个函数import进去，不需要定义对应的C函数import "DPI-C" function int setenv(input string env_name, input string env_value, input int overwrite);import "DPI-C" function string getenv (input string env_name);直接使用getenv, setenv来获得和设置环境变量module mem read( input [8*200-1: O] mem_file )； initial begin $display("mem_file is %Os", mem_file); end endmodule module dut ( input clk, input wire [31:0]addr, output [31:0] rdata, input [31:0] wdata, input wire wr ); string path; initial begin setenv("PRJDIR", "/project/uart", 1); path = getenv( "PRJDIR"); $display("PRJDIR is %Os", path); setenv( "PRJDIR", "/project/sp", 1); path = getenv( "PRJDIR"); $display("PRJDIR is %0s", path); end mem_read u_mem_rd(.mem_file(path)); endmodule————————————————版权声明：本文为CSDN博主「甲六乙」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。原文链接：https://blog.csdn.net/m0_38037810/article/details/126136552