UVM checklist
UVM checkist
1. 基于 UVM 的 TB 架构
- 顶层模块 -> Test -> env -> sub_env -> agent -> driver, sequencer, monitor
- 为每个测试用例创建 Testbench
- 测试用例代码保存在case库(xx_test_lib.sv)文件中(类似于将所有测试定义保存在一个文件中的 package)
- 测试库文件被包含在顶层模块中
- UVM TB 中不使用 Program block
2. 在 UVM 中运行测试
vsim +novopt work.top +UVM_TESTNAME=测试名称- 必须从顶层模块中的
initial block调用run_test() - 可以通过
run_test("testname")运行测试,但不建议这样做,因为它将 Testbench 绑定到单个测试。 - 如果
run_test()或者UVM_TESTNAME的testname没有在 UVM factory 中注册,模拟将导致致命错误。 - 如果没有在顶层模块中调用
run_test(),则 UVM phase 不会被调用。我们仍然可以调用全局 UVM 方法。
3. 测试运行中的 Phases
- build_phase
- config_phase
- end_of_elaboration_phase
- start_of_simulation_phase
- run_phase
- extract
- check
- report
4. 报告信息
- 使用
+UVM_VERBOSITY和+UVM_SEVERITY来管理报告 UVM_VERBOSITY: 通过模拟命令选项更改所有 UVM 组件的详细级别。+uvm_set_verbosity选项有一个特定格式,允许控制详细级别更改适用于哪些阶段,以及在耗时阶段时准确应用的时间。- 示例命令:
sim_cmd +uvm_set_verbosity=组件名称,id,详细级别,阶段名称,可选时间
sim_cmd +uvm_set_action=组件名称,id,严重性,操作
sim_cmd +uvm_set_severity=组件名称,id,当前严重性,新的严重性
-
uvm_report_info/uvm_report_warning/uvm_report_error/uvm_report_fatal -
uvm_report_info函数示例:virtual function void uvm_report_info(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line=0) -
序列项和序列使用与其关联的 sequencer 进行报告。如果未设置 sequencer,则将使用全局 reporter。
-
uvm_info/uvm_warning/uvm_error/uvm_fatal宏: -
uvm_info(ID, MSG, VERBOSITY):当 VERBOSITY 低于配置的 reporter 详细级别时,调用uvm_report_info。 -
uvm_warning(ID, MSG)/uvm_error(ID, MSG)/uvm_fatal(ID, MSG):- 这些宏将使用
UVM_NONE详细级别,因此无法通过设置 reporter 详细级别禁用它们,但可以通过设置消息的操作来关闭它们。
- 这些宏将使用
-
UVM_VERBOSITY等级:UVM_NONE/UVM_LOW/UVM_MEDIUM/UVM_HIGH/UVM_FULLUVM_NONE: 报告始终打印,无法通过详细级别禁用。UVM_LOW: 报告仅在详细级别设置为UVM_LOW或以上(如UVM_MEDIUM/HIGH/FULL)时发出。
-
UVM_SEVERITY等级:UVM_INFO/UVM_WARNING/UVM_ERROR/UVM_FATALUVM_FATAL: 模拟在此级别使用$finish退出。
5. TB 组件编码
i. Driver
- 从
uvm_driver#(REQ, RSP)继承 - 实例化虚拟接口
- 声明配置变量,以提供从测试中更新组件行为的接口
- 使用
uvm_component_utils注册到工厂 - 使用
uvm_config_db#(virtual ubus_if)::get(this, "", "vif", vif)获取虚拟接口句柄 - 在
run_phase中实现驱动功能 - 填写 id 信息后,将
rsp返回给序列:rsp.set_id_info(req)
ii. Sequencer
- 从
uvm_sequencer#(REQ, RSP)继承 - 使用
uvm_component_utils注册到工厂 - 也可以使用
uvm_sequencer#(REQ, RSP)的 typedef 来定义 sequencer uvm_sequencer_utils宏用于为 sequencer 提供自动化宏。
iii. Monitor
- 从
uvm_monitor继承(注意:没有参数) - 使用
uvm_analysis_port#(Tx_name)实例化分析端口 - 声明任何影响监控器行为的配置变量,并将这些变量注册到工厂
- 使用
ap.write(tx)将收集到的事务传递给连接的分析端口。
6. 配置对象
- 通用容器类,用于保存所有与环境相关的配置变量和接口句柄。
7. 结束测试用例运行
- 使用
global_stop_request()结束测试。在测试的run_phase中调用,测试运行时间结束后调用。+UVM_USE_OVM_RUN_SEMANTIC应用于使global_stop_request()在 UVM 中生效。 raise_objection和drop_objection是终止测试的首选方式。所有 objections 被移除时会隐式调用global_stop_request。- 任何
raise_objection都会使global_stop_request无效。
8. 在整个 TB 层次结构中传递接口、配置对象
- 设置虚拟接口句柄:
uvm_config_db#(virtual ubus_if)::set(null,"ubus_example_tb0.*", "vif",vif);
9. 注册组件到工厂
- 创建 type_id,包括
get,get_type,create方法 - Type_id 示例:
uvm_config_db#(virtual ubus_if)::set(null,"ubus_example_tb0.*", "vif",vif);
10. 注册对象到工厂
11. 根据测试用例需求修改 Testbench 拓扑
set_inst_overrideset_type_overrideuvm_config_dbuvm_resource_db
12. TLM1.0 中的不同类型端口
注:TLM 也就是:使用函数的调用在compont通信 |=====》 创建一个 block或者component 之前的通信。 亦或者是 一个component中声明的函数 可以被另一个组件调用。理论上讲,没有什么 可以阻止driver 从sequencer 调用 get 这个task。 但是 这让 driver和 sequencer 产生依赖关系,并且还使得 代码难以维护。因此,在UVM中,通过所谓ports 和exports间接连接。(exports 是已从export 中借出(borrow),看看是否在UVM中借出??(systemc是如此))。此外 driver通过ports(ports是连接到sequencer的 exports) 调用task,VS.driver直接调用 get task。 exports作用是什么?是申明某一个componet,准备提供一个特定task (Provides the get() ))或者function; ports ( Requires a get)) 。准确的说,就是sequencer 提供port 所声明的get 任务的实现。ports是 某个组件 需要的 一项特定task是可用的,因为他要这样调用它。在sequence item 的pool port讲:我们的我们的 driver 准备调用 get function。, 在driver 实例化sequencer,当我们在顶层 讲 port 连接到export出口。
注:从sequencer 发出的不是 对get 任务的调用,而是 反应正在 输出的事实 或者 是 提供 一个获取任务。所以 driver 就能够 调用 它。
注:交易 和 任务 是从 左到右。 但是 get 任务本身是从 右到左。




典型code:注意:analysis_port 是不支持工厂机制。


- port / export / fifo
- TLM1.0 通信的不同模型:
-
Push 模型
-
Pull 模型
-
FIFO 模型
-
Analysis 模型 1:N。 export port是 1:1
注:put 通常 用于发送transcations,是一个阻塞的方法 (放下 才能put第二个。也就是 知道 transaction的 接收方reciver 已经准备好下一次 调用put) (trans 端到端到连接 是不会覆盖的)
注:get 通常 用于接受transcations,是一个阻塞的方法 (也就是 知道 transaction 发送侧 已经准备就绪 , 已经准备好下一笔 数据) (trans 端到端到连接 是不会覆盖的)
port 向上连接。export 传递 组件内部。

uvm_analysis_port是 广播。可以连接到 不同 subscriber

功能覆盖率 必须是t

TOP ENV 实际有 agent 和 coverage

subscriber class 是=component类+ analysis_imp(必须有weite方法)

这里 不需要 m_item 去new;可以访问 t;虽然不能修改。
问题1:处理 multiple incoming ()多个传入的数据流。
问题2:存储 trans 之后 分析。
参考模型: 往往需要处理多个数据事物。 每一个进入的 transaction 的数据流 需要与之 对应的 write 。它会处理接受分析的transaction 。(SV 不支持函数重载---- 咋处理 。 那就意味着 在一个class 中不能有多个 同名的方法 咋办----使用 uvm_analysis_imp_decl)

注意:ref 一般不能 使用 uvm scber 类;主要是 suber类;只有一个单一的imp分析 交易的流。
用户不想直接处理接受到的交易 咋办???? (FIFO存起来)
那就用compont类; 将数据转发。到 fifo。。 这些都没有注册到工厂机制;

- 可能的port连接:
- port - export
- export-export
- Push 模型
- Pull 模型
- FIFO 模型
- Analysis 模型
13. TLM2.0 中的不同 sockets 类型
- sockets
- block transport
- non block transport
- 跟踪事务执行的时间和阶段
14. 打印 Testbench 拓扑
- 支持不同格式的打印(table, tree, line)
15. Scoreboard 实现
- 具有多个监控器连接的 Scoreboard
- uvm_analysis_port_decl宏,用于创建多个write_*方法
- 基于 uvm _ analysis _ export & uvm _ tlm _ analysis _ fifo 的实现
16. 创建通用资源池
uvm_pooluvm_resources
17. 串行通信协议的 PKT 数据项编码
- 使用旋钮的概念生成特定于每个测试的多个有趣的场景
18. 片上通信协议的事务数据项编码
- 使用旋钮的概念生成特定于每个测试的多个有趣的场景
19. UVM 中的标准连接类型
20. Sequence coding
21. 虚拟序列编码
22. 虚拟 sequencer
23. 执行序列
24. 执行事务项
25. 使用默认序列将测试用例链接到序列
26. 使用 uvm_objection 跟踪 Testbench 执行进度
27. 创建序列库
28. 更新组件定义
29. 使用 UVM 编写可重用的验证环境
30. Testbench 中的寄存器层
31. 工厂类
32. AHB UVC 开发概念
33. AHB 互连验证
34. USB 2.0 核心验证
35. uvm_root
- 作为所有 UVM 组件的隐式顶层和 phase 控制器。用户无需直接实例化
uvm_root,UVM 会自动创建一个 用户可以通过全局变量uvm_top访问的uvm_root单实例。

浙公网安备 33010602011771号