《从零开始,搭建一个简单的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)begin
  if(!rstn)begin
    data_o       <= 8'd0;
    data_o_valid <= 1'b0;
  end
  else begin
    data_o       <= data_i;
    data_o_valid <= data_i_valid;
  end
end
 
endmodule 

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)
    endfunction
 
    extern virtual task main_phase(uvm_phase phase); 
endclass


task 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();
//end

initial begin
    run_test("my_driver");
end 


initial begin
  clk = 0;
  forever begin
    #100 clk = ~clk;
  end
end
 
initial begin
  rstn = 1'b0;
  #1000
  rstn = 1'b1;
end

initial begin
    $fsdbDumpfile("tb.fsdb");
    $fsdbDumpvars;
end
 
endmodule

第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才定位到这里。啊。。。超级想骂人!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文盘点 Partisia Blockchain 生态 4 月市场进展

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

17.接口自动化学习-日志

1.日志输出渠道 &#xff08;1&#xff09;文件格式 xx.log &#xff08;2&#xff09;控制台输出 2.日志级别 debug<info<warnning<error<critical 3.代码实现 from utils.handle_path import log_path import logging import datetime def logger(fileLogTr…

rocketMQ-常用知识点

1、RocketMQ有什么作用&#xff1f; 1、应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任何一个子系统出了故障或者因为升级等原因暂时不可用&#xff0c;都…

多线程【阻塞队列】(生产者消费者模型代码实现)

阻塞队列 解耦合削峰填谷生产者消费者模型&#xff1a; 解耦合 削峰填谷 生产者消费者模型&#xff1a; 正常来说&#xff0c;wait通过notify唤醒&#xff0c;其他线程调用了take,在take的最后一步进行notify. package thread; class MyBlockingQueue{private String [] data…

OpenCV 入门(二)—— 车牌定位

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

存储虚拟化概述

目录 1. 存储体系架构 2. 存储设备层虚拟化 3. 块聚合层虚拟化 3.1. 块聚合层虚拟化实现方式 3.2. 块聚合层虚拟化分类 3.3. 块聚合层虚拟化技术 4. 文件/记录层的存储虚拟化 存储虚拟化是一种将存储系统的内部功能从应用、主机或者网络资源中抽象、隐藏或者隔离的技术&…

事业单位向媒体投稿发文章上级领导交给了我投稿方法

作为一名事业单位的普通职员,负责信息宣传工作,我见证了从传统投稿方式到智能化转型的全过程,这段旅程既是一次挑战,也是一次宝贵的成长。回想起初涉此领域的日子,那些通过邮箱投稿的时光,至今仍然历历在目,其中的酸甜苦辣,构成了我职业生涯中一段难忘的经历。 邮箱投稿:费时费…

06-beanFactoryPostProcessor的执行

文章目录 invokeBeanFactoryPostProcessors(beanFactory)invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);invokeBeanFactoryPostProcessors(regularPostProc…

JAVA基础之jsp标准标签

jsp动作标签实现实例化一个实体类 <jsp:useBean id"标识符" class"java类名" scope"作用范围"> 传统的java方式实例化一个实体类 Users user new Users(); <%%> id: 对象名 * class:类 创建对象时,完全限定名(包名…

设置默认表空间和重命名

目录 设置默认表空间 创建的临时表空间 tspace4 修改为默认临时表空间 创建的永久性表空间 tspace3 修改为默认永久表空间 重命名表空间 将表空间 tspace3 修改为 tspace3_1 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/13520…

Spring Boot | Spring Boot 整合 “RabbitMQ“ ( 消息中间件 ) 实现

目录: Spring Boot 整合 "RabbitMQ" ( 消息中间件 )实现 &#xff1a;一、Spring Boot 整合 整合实现 : Publish/Subscribe ( 发布订阅 ) 工作模式 ( "3种"整合实现方式 )1.1 基于"API"的方式 ( 实现 Publish/Subscribe "发布订阅"工作…

OSPF Stub区域

原理概述 OSPF 协议定义了多种区域&#xff08; Area &#xff09;类型&#xff0c;其中比较常见的有 Stub 区域和 Totally Stub 区域。区域的类型决定了在这个区域当中所存在的 LSA 的类型。 Stub 区域不允许 Type-4和 Type-5 LSA 进入&#xff0c;该区域会通过 Type-3 LSA…

电子商务对应的职业有哪些?10年互联网人透底行业秘密!

电子商务对应的职业有哪些&#xff1f;10年互联网人透底行业秘密&#xff01; 事实说话&#xff0c;实事求是&#xff0c;不要再把美颜滤镜下的市场&#xff0c;传给新人小伙伴了&#xff01; 大家好&#xff0c;我是微三云胡佳东&#xff0c;一家软件公司负责人&#xff01; …

keystone学习小结

1 keystone middleware 1.1 工作流程 middleware在客户端和服务端之间&#xff0c;会拦截客户端请求并判断请求身份是否是正确合法的&#xff0c;若是&#xff0c;则继续将请求发给其他middleware或app 具体看&#xff0c;干了这些事 1将请求里的auth header去除&#xff0c…

景源畅信:想要做抖音电商有哪些适合的发展渠道?

在数字浪潮的推动下&#xff0c;抖音电商如同一股不可阻挡的潮流&#xff0c;正吸引着无数创业者和品牌的目光。如何在这一领域获得成功&#xff0c;选择合适的发展渠道成为关键。接下来&#xff0c;让我们深入探讨这一话题&#xff0c;揭开抖音电商成功之路的秘密。 一、内容创…

C# Web控件与数据感应之 TreeView 类

目录 关于 TreeView 一些区别 准备数据源 范例运行环境 一些实用方法 获取数据进行呈现 ​根据ID设置节点 获取所有结点的索引 小结 关于 TreeView 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;Web控件与数据源之间的交互&#xff0c;本文将继续介绍与…

Idea + maven 搭建 SSH (struts2 +hibernate5 + spring5) 环境

org.apache.struts struts2-core 2.3.35 org.apache.struts struts2-spring-plugin 2.3.35 org.apache.struts struts2-json-plugin 2.3.8 1.4 配置Java EE 坐标依赖 这里可以引入 servlet api&#xff0c;jstl 标签库等一系列工具 javax.servlet javax.servlet-api …

c语言实现贪吃蛇小游戏————附全代码!!!

目录 1.Win32 API 1.1控制台应用程序 1.2控制台的名称&#xff0c;控制台窗口大小 1.3设置控制台光标位置 COORD - 光标坐标 GetStdHandle - 获取句柄 SetConsoleCursorPosition - 设置光标位置 封装一个设置光标的函数 1.4设置控制台光标的属性 CONSOLE_CURSOR_INFO …

【第13章】spring-mvc之validator

文章目录 前言一、准备1. 引入库2. add.jsp3. show.jsp 二、代码部分1.实体类2. 控制器类3. 效果4. 展示 总结 前言 【第20章】spring-validator 虽然前面已经在spring介绍过&#xff0c;但是为了保证代码可用&#xff0c;还是会从头讲到尾&#xff0c;尽量把关键点列出来讲给…
最新文章