UVM搭建的注意事项

1. 数据项(Data Item / Sequence Item)

在 driver 与 sequencer 之间流动的对象,就是"数据项",它继承自 uvm_sequence_item。数据项的字段可以分为两类:

  • 数据字段:事务本体,比如地址(addr)、数据(data)、读写方向(read_write)等
  • 控制字段(knobs):影响 driver 行为的"旋钮",比如是否注入延迟、是否使能错误注入、发送多少个字节等。这些字段让同一个 driver 能应对不同场景。

数据项的字段通常是 rand 类型,配合 constraint 来描述合法取值范围。这样 sequence 在做随机化时,就能在合法空间里自动生成激励。

2.约束分层(Constraint Layering)

一个可复用的数据项,应该把"最通用的约束"写在基类里,把"特定场景的约束"留给派生类或测试去增删。通过继承与 constraint 的增删,你可以不破坏基础约束的情况下,逐步收紧或放宽激励空间。这就是"约束分层"的思想,它让同一个数据项能在不同测试里表现出不同的随机特征。

3. Driver 与 Sequencer 的交互

driver 通过 seq_item_port 与 sequencer 通信。最基本的握手方式是 get_next_item() + item_done()。
image
seq_item_port正是driver与sequencer之间的专用通信端口,是一种双向端口,也是一个类,其内定义了众多方法,允许driver主动“拉取”(pull)数据,并返回“响应”(response)。除 get_next_item() 之外,seq_item_port 还提供了其它方法,用于更灵活的交互:
image

  • try_next_item(req):非阻塞地取 item,没有就立即返回,可用于 driver 执行空闲事务(idle)。
  • put_response(rsp):把响应事务返回给 sequence,用于需要回读/应答的场景

4.工厂与 override

UVM 的工厂(factory)是覆盖机制的基础。所有组件都要用宏注册,并用 type_id::create() 创建:

点击查看代码
`uvm_component_utils(my_driver)
...
drv = my_driver::type_id::create("drv", this);  // 而不是 new()
为什么要绕个弯子用工厂创建?因为工厂支持"覆盖(override)"——在测试里把某个类替换成它的派生类,而不改动原环境代码。覆盖分两种:
  • 类型覆盖:set_type_override("原类型", "新类型"),把整类实例全部替换。
  • 实例覆盖:set_inst_override("原类型", "新类型", "实例路径"),只替换指定层次路径下的实例。

注意:覆盖必须在目标对象被创建之前设置才会生效,所以通常写在 build_phase 的最前面。

5.Sequence 与激励宏

sequence 继承自 uvm_sequence,激励流程写在 body() 里。UVM 提供了一组宏/方法,让"创建 + 随机化 + 发送 + 等待完成"这一串操作变得简洁:

  • uvm_do(item):创建 + 随机化 + 发送 + 等待完成,一步到位。
  • uvm_do_with(item, {约束}):在 uvm_do 基础上附加内联约束。• uvm_do_on(item, sequencer):指定在哪个 sequencer 上执行。
  • uvm_create(item) + uvm_send(item):把创建与发送拆成两步,便于中途修改。• uvm_rand_send(item):只随机发送,不等待完成。sequence item 在拉模式(pull mode)下的流动过程。
    image

6. Monitor 与 analysis

portmonitor 是被动的观察者:它采样 interface 上的信号,把它们组装成事务,再通过 analysis_port.write() 广播出去,供 scoreboard、coverage collector 订阅。monitor 通常不驱动信号,是纯"读"的一方。

7. Agent 的组装

agent 把 driver、sequencer、monitor 组合在一起,并在 connect_phase 里把 driver 与 sequencer 连起来:

点击查看代码
function void my_agent::connect_phase(uvm_phase phase);
if (is_active == UVM_ACTIVE)
	driver.seq_item_port.connect(sequencer.seq_item_export);
endfunction
is_active 字段决定是否创建 sequencer 与 driver(active 模式),还是只保留 monitor(passive 模式)。

8.环境(Environment)的组装

environment 是"可复用组件的顶层容器"。它例化并配置各种 agent,并把 monitor 的 analysis port 连到 scoreboard 等组件。一个典型 UVM 环境里各组件如何组织在一起。
image

posted on 2026-08-30 11:59  tuck0603  阅读(21)  评论(0)    收藏  举报

导航