【UVM学习笔记】UVM基础—一文告诉你UVM的组成部分


前言

该专题用于记录学习UVM芯片验证的过程,主要学习书籍为经典的《UVM实战》,同时也会去进行一些UVM的项目联系。

一、Driver驱动器

这段代码是用 SystemVerilog 编写的一个基于 UVM(Universal Verification Methodology)的驱动器(driver)组件,名为 my_driver。它继承自 uvm_driver 类,用于在验证环境中驱动 DUT(Design Under Test,被测设计)的输入信号。下面我将逐步解释这段代码的结构和功能。

1.1 整体结构

代码分为两个主要部分:

  • 类定义部分:定义了 my_driver 类,包括构造函数和一个外部声明的任务(main_phase)。
  • 任务实现部分:实现了 main_phase 任务,负责具体的信号驱动逻辑。

此外,代码使用 ifndef 和 define 宏来防止重复包含。

1.2 详细解释

1.2.1 宏定义保护

ifndef MY_DRIVER__SV
define MY_DRIVER__SV

检查是否已经定义了宏MY_DRIVER__SV。如果没有定义,则编译器会继续处理后面的代码。
最后,文件末尾的 endif 与开头的 ifndef 配对,结束条件编译块。

1.2.2 类定义

class my_driver extends uvm_driver;
   function new(string name = "my_driver", uvm_component parent = null);
      super.new(name, parent);
   endfunction
   extern virtual task main_phase(uvm_phase phase);
endclass

class my_driver extends uvm_driver:定义一个名为 my_driver 的类,并且表示 my_driver 继承自 UVM 提供的基类 uvm_driver。
uvm_driver 是 UVM 框架中的一个标准组件类,用于将事务级数据转换为 DUT 的引脚级信号。

事务级数据是指更高层次的抽象数据,通常以结构体或类的形式表示,而不是直接的硬件信号(0 和 1)。它描述的是“做什么”,而不是“怎么做”。
假设事务是一个 8 位数据 8’b10100101。
驱动器将其转换为:
top_tb.rxd <= 8’b10100101;(数据信号)
top_tb.rx_dv <= 1’b1;(有效信号)
并在 @(posedge top_tb.clk) 时更新这些信号。

function new:定义类的构造函数,用于创建 my_driver 对象。
super.new(name, parent):调用父类 uvm_driver 的构造函数,将 name 和 parent 参数传递给它。这是 UVM 中面向对象编程的标准做法,确保父类的初始化逻辑被执行。
extern:表示 main_phase 任务的实现不在类定义内部,而是在外部单独定义。
virtual:声明这是一个虚任务,允许子类重写(override)它。这是 UVM 中 phase 方法的常见做法。
task main_phase(uvm_phase phase):定义一个名为 main_phase 的任务,接收一个 uvm_phase 类型的参数 phase,表示 UVM 的仿真阶段(这里是 main_phase,通常用于主要的测试执行阶段)。

1.2.3 任务实现

task my_driver::main_phase(uvm_phase phase);
   top_tb.rxd <= 8'b0;
   top_tb.rx_dv <= 1'b0;
   while(!top_tb.rst_n)
      @(posedge top_tb.clk);
   for(int i = 0; i < 256; i++)begin
      @(posedge top_tb.clk);
      top_tb.rxd <= $urandom_range(0, 255);
      top_tb.rx_dv <= 1'b1;
      `uvm_info("my_driver", "data is drived", UVM_LOW)
   end
   @(posedge top_tb.clk);
   top_tb.rx_dv <= 1'b0;
endtask

my_driver::main_phase:明确指定这个任务是 my_driver 类的一部分。
这是 main_phase 的具体实现,负责驱动 DUT 的信号。
uvm_info(“my_driver”, “data is drived”, UVM_LOW):
UVM 提供的日志记录宏,打印信息。
my_driver:消息来源(组件名)。
data is drived:消息内容。
UVM_LOW:日志级别,表示低详细程度。
作用:在 256 个时钟周期内,连续向 DUT 的 rxd 输入随机数据,并将 rx_dv 置为 1,同时记录日志。

所谓类的定义,就是用编辑器写下:

class A
...
endclass

而所谓类的实例化指的是通过new创造出A的一个实例:

A a_list;
a_list = new();

1.2.4 factory机制

factory机制的实现被集成在了一个宏中:uvm_component_utils。这个宏所做的事情非常多,其中之一就是将my_driver登记在UVM内部的一张表中,这张表是 factory 功能实现的基础。只要在定义一个新的类时使用这个宏,就相当于把这个类注册到了这张表中。

`uvm_component_utils(my_driver)

在给driver中加入factory机制后,还需要对top_tb做一些改动:

initial begin
	run_test("my_driver");
end

但是输出的结果只有两个,没有执行后面的代码,关于这个问题,牵涉UVM的objection机制。

UVM_INFO my_driver.sv(8) @ 0: uvm_test_top [my_driver] new is called
UVM_INFO @ 0: reporter [RNTST] Running test my_driver...
UVM_INFO my_driver.sv(14) @ 0: uvm_test_top [my_driver] main_phase is called

1.2.4 objection机制

UVM中通过objection机制来控制验证平台的关闭。细心的读者可能发现,在上节的例子中,并没有如2.2.1节所示显式地调用 finish 语句来结束仿真。但是在运行上节例子时,仿真平台确实关闭了。在每个phase中,UVM会检查是否有objection被提起

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值