《从零开始,搭建一个简单的UVM验证平台》实操

2024-05-09 01:44

本文主要是介绍《从零开始,搭建一个简单的UVM验证平台》实操,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近的工作中需要用UVM平台去仿真软件同事写的C程序,虽然只要用EDA同事已经搭好的UVM平台稍微改改就行,但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的,因为我对这方面一点概念都没有。

基于此,想着边用边学,就在网上找了一些资料学习。看到了下面这篇文章:

从零开始,搭建一个简单的UVM验证平台(一)

看着还是挺简单的,但亲自动手去做一遍,还是费了很大功夫的。虽然这个博客里提供了大部分代码,但并没有写一步步地怎么做。另外,特别注意,这个博客系列文章里的代码有一些小问题,会导致结果出不来,我就遇到了好几个坑。

下面就记录下,我一步步的过程,并附上所以源码和相应的截图。

第1步:把这几个模块代码拷贝下来

dut.v

module dut(input             clk           , input             rstn          ,input      [7:0]  data_i        ,input             data_i_valid  ,output reg [7:0]  data_o        ,output reg        data_o_valid
);always @(posedge clk)beginif(!rstn)begindata_o       <= 8'd0;data_o_valid <= 1'b0;endelse begindata_o       <= data_i;data_o_valid <= data_i_valid;end
endendmodule 

my_driver.sv

//`ifndef _MY_DRIVER
//`define _MY_DRIVER`include "uvm_macros.svh"
import uvm_pkg::*;class my_driver extends uvm_driver;`uvm_component_utils(my_driver); // 注册function new(string name = "my_driver", uvm_component parent = null);super.new(name, parent);`uvm_info("my_driver", "new is called.", UVM_LOW)endfunctionextern virtual task main_phase(uvm_phase phase); 
endclasstask my_driver::main_phase(uvm_phase phase);phase.raise_objection(this);`uvm_info("my_driver", "main phase is called.", UVM_LOW);top_tb.data_i       <= 8'd0;top_tb.data_i_valid <= 1'b0;while(!top_tb.rstn)@(posedge top_tb.clk);for(int i = 0; i < 256; i = i+1)begin@(posedge top_tb.clk)top_tb.data_i <= $urandom_range(0,255);top_tb.data_i_valid <= 1'b1;`uvm_info("my_driver", "data is drived.", UVM_LOW) end@(posedge top_tb.clk);top_tb.data_i_valid <= 1'b0;phase.drop_objection(this);
endtask//`endif

top_tb.sv

`timescale 1ns/1ps
`include "uvm_macros.svh" //这是UVM中的一个文件,包含了众多宏定义import uvm_pkg::*;        //只有导入了这个库,编译器在编译my_driver.sv文件时才会认识其中继承的uvm_driver等类名//`include "my_driver.sv"module top_tb;reg clk,rstn;
reg  [7:0] data_i;
reg  data_i_valid;
wire [7:0] data_o;
wire data_o_valid;dut my_dut(.clk            (clk   )        ,.rstn           (rstn  )        ,.data_i         (data_i)        ,.data_o         (data_o)        ,.data_i_valid   (data_i_valid)  ,.data_o_valid   (data_o_valid)
);//initial begin
//  my_driver drv; // instance
//  drv = new("drv", null);
//  drv.main_phase(null);
//  $finish();
//endinitial beginrun_test("my_driver");
end initial beginclk = 0;forever begin#100 clk = ~clk;end
endinitial beginrstn = 1'b0;#1000rstn = 1'b1;
endinitial begin$fsdbDumpfile("tb.fsdb");$fsdbDumpvars;
endendmodule

第2步:产生filelist

find ./ -name "*.*v" > filelist.f

第3步:产生makefile

这个makefile,我是在网上找了一些资料作为参考,写了个简单能用的。

#--------------------------------------------------------------------------------------
all  : clean vcs
#--------------------------------------------------------------------------------------
vcs   :vcs   	  -f filelist.f \-ntb_opts uvm \-timescale=1ns/1ps \-full64 -R  +vc  +v2k  -sverilog \-debug_access \-kdb \-l simv.log &
#--------------------------------------------------------------------------------------
verdi  :verdi -f filelist.f -ssf tb.fsdb &
#--------------------------------------------------------------------------------------
clean  :rm  -rf  *~  core  csrc  simv*  vc_hdrs.h  ucli.key  urg* *.log  novas.* *.fsdb*  rm  -rf  64* DVEfiles *.vpd  verdiLog verdi_config_file
#---------------------------------------------------------------------------------------

第4步:编译

所有文件如上图所示,在当前路径下执行如下命令进行编译:

make all或者make vcs

第5步:查看结果

编译结果如下图所示:

也可以打开simv.log查看编译结果,还可以用make verdi查看波形。


附:问题记录

我现在学到了第三篇,也就是下面这篇博客,遇到了几个问题,卡了我好几天才找到原因,也一并记录在此,方便后来人!

从零开始,搭建一个简单的UVM验证平台(三)

第一个问题

第二个问题,这个是巨坑啊,编译的时候发现会卡住,一直找不到原因,差点让我UVM从入门到放弃,花了几天的时间各种找资料各种加log才定位到这里。啊。。。超级想骂人!!!

这篇关于《从零开始,搭建一个简单的UVM验证平台》实操的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972041

相关文章

使用DeepSeek搭建个人知识库(在笔记本电脑上)

《使用DeepSeek搭建个人知识库(在笔记本电脑上)》本文介绍了如何在笔记本电脑上使用DeepSeek和开源工具搭建个人知识库,通过安装DeepSeek和RAGFlow,并使用CherryStudi... 目录部署环境软件清单安装DeepSeek安装Cherry Studio安装RAGFlow设置知识库总

Linux搭建Mysql主从同步的教程

《Linux搭建Mysql主从同步的教程》:本文主要介绍Linux搭建Mysql主从同步的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux搭建mysql主从同步1.启动mysql服务2.修改Mysql主库配置文件/etc/my.cnf3.重启主库my

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

redis群集简单部署过程

《redis群集简单部署过程》文章介绍了Redis,一个高性能的键值存储系统,其支持多种数据结构和命令,它还讨论了Redis的服务器端架构、数据存储和获取、协议和命令、高可用性方案、缓存机制以及监控和... 目录Redis介绍1. 基本概念2. 服务器端3. 存储和获取数据4. 协议和命令5. 高可用性6.

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

本地搭建DeepSeek-R1、WebUI的完整过程及访问

《本地搭建DeepSeek-R1、WebUI的完整过程及访问》:本文主要介绍本地搭建DeepSeek-R1、WebUI的完整过程及访问的相关资料,DeepSeek-R1是一个开源的人工智能平台,主... 目录背景       搭建准备基础概念搭建过程访问对话测试总结背景       最近几年,人工智能技术