拓扑结构图解析
一、顶层结构(uvm_test_top)
- 类型:
dadd_rand_test
- 角色:UVM 验证的顶层测试用例,是整个验证环境的 “启动入口”,负责实例化验证环境(
dadd_environment
)、序列(dadd_rand_sequence
,代码中已声明但图中未完整展开),并通过main_phase
控制验证流程(如启动序列、管理仿真 objection )。
二、验证环境层(env)
- 类型:
uvm_env
(实际是dadd_environment
,继承自uvm_env
) - 角色:验证子系统的容器,聚合并连接与 DUT 验证相关的核心组件(
iagt
、oagt
、refmdl
、scb
及 TLM FIFO ),使这些组件形成一个可复用的 “验证子系统”。
三、TLM FIFO 层(env 内的 3 个 FIFO)
UVM 中 uvm_tlm_analysis_fifo #(T)
是 “线程安全的异步通信缓冲区”,用于解耦 “数据生产者” 和 “数据消费者”,避免因速度不匹配导致数据丢失。以下是 3 个 FIFO 的作用:
1. dadd_iagt_to_refmdl_fifo
- 关联类型:传递
dadd_item
类型的事务 - 角色:连接
iagt
(输入代理)与refmdl
(参考模型)- 生产者:
iagt.imonitor
(通过iagt.ap
端口写入数据 ) - 消费者:
refmdl
(通过refmdl.port
端口读取数据 ) - 作用:将
iagt
采样的 DUT 输入数据,安全传递给refmdl
,让参考模型基于这些输入计算 “预期输出”。
- 生产者:
2. dadd_oagt_to_scb_fifo
- 关联类型:传递
dadd_item
类型的事务 - 角色:连接
oagt
(输出代理)与scb
(计分板)- 生产者:
oagt.omonitor
(通过oagt.ap
端口写入数据 ) - 消费者:
scb
(通过scb.act_port
端口读取数据 ) - 作用:将
oagt
采样的 DUT 实际输出数据,传递给scb
,用于和 “预期输出” 比对。
- 生产者:
3. dadd_refmdl_to_scb_fifo
- 关联类型:传递
dadd_item
类型的事务 - 角色:连接
refmdl
(参考模型)与scb
(计分板)- 生产者:
refmdl
(通过refmdl.ap
端口写入数据 ) - 消费者:
scb
(通过scb.exp_port
端口读取数据 ) - 作用:将
refmdl
计算出的 预期输出数据,传递给scb
,用于和 “实际输出” 比对,判断验证是否通过。
- 生产者:
四、输入代理层(iagt)
- 类型:
uvm_agent
(实际是dadd_iagent
,继承自uvm_agent
) - 角色:管理 DUT 输入接口的 “激励注入” 和 “输入采样”,包含以下子组件:
1. drv
(dadd_driver
,类型 uvm_driver #(REQ, RSP)
)
- 角色:“激励执行者”,从
iagt.sqr
(序列器)获取dadd_item
事务,将其转换为 物理信号时序(如clk
、addr
、data
等引脚信号 ),驱动 DUT 执行操作。 - 关键端口:
rsp_port
(uvm_analysis_port
):可用于回传响应(若需双向通信,如读操作应答 ,代码中未完整体现时可能仅单向驱动 )。seq_item_port
(uvm_seq_item_pull_port
):与iagt.sqr.seq_item_export
连接,从序列器拉取dadd_item
事务。
2. imon
(dadd_imonitor
,类型 uvm_monitor
)
- 角色:“输入数据观察者”,直接从 DUT 输入接口采样真实信号(如
addr
、data
、data_en
),封装成dadd_item
事务,通过ap
端口发给 TLM FIFO(dadd_iagt_to_refmdl_fifo
),供refmdl
做 “预期输出计算”。 - 关键端口:
ap
(uvm_analysis_port
):向dadd_iagt_to_refmdl_fifo.analysis_export
写入采样的dadd_item
。
3. sqr
(dadd_rand_sequencer
,类型 uvm_sequencer #(dadd_item)
)
- 角色:“激励调度器”,仲裁来自
sequence
(如dadd_rand_sequence
)的dadd_item
事务,按规则(如优先级、顺序 )转发给driver
执行。 - 关键端口:
rsp_export
(uvm_analysis_export
):若需接收driver
的响应,可通过此端口连接(代码未完整体现时可能闲置 )。seq_item_export
(uvm_seq_item_pull_imp
):与driver.seq_item_port
连接,向driver
转发sequence
生成的事务。arbitration_queue
(array
):存储待调度的sequence_item
队列,由 sequencer 仲裁后转发。
五、输出代理层(oagt)
- 类型:
uvm_agent
(实际是dadd_oagent
,继承自uvm_agent
) - 角色:管理 DUT 输出接口的 “输出采样”,核心组件是
omon
(dadd_omonitor
)。
1. omon
(dadd_omonitor
,类型 uvm_monitor
)
- 角色:“输出数据观察者”,直接从 DUT 输出接口采样真实信号(如
dadd_out
、dadd_out_en
、dadd_out_addr
),封装成dadd_item
事务,通过ap
端口发给 TLM FIFO(dadd_oagt_to_scb_fifo
),供scb
(计分板)做 “实际输出比对”。 - 关键端口:
ap
(uvm_analysis_port
):向dadd_oagt_to_scb_fifo.analysis_export
写入采样的dadd_item
。
六、参考模型层(refmdl)
- 类型:
uvm_component
(实际是dadd_refmodel
,继承自uvm_component
) - 角色:“理想行为模拟器”,根据
iagt
采样的 “DUT 输入数据”(从dadd_iagt_to_refmdl_fifo
读取 ),按照 设计文档预期的 DUT 逻辑(如数据加 1、协议转换等 ),计算出 “预期输出数据”,再通过ap
端口发给 TLM FIFO(dadd_refmdl_to_scb_fifo
),供scb
比对。 - 关键端口:
ap
(uvm_analysis_port
):向dadd_refmdl_to_scb_fifo.analysis_export
写入 “预期输出” 的dadd_item
。port
(uvm_blocking_get_port
):从dadd_iagt_to_refmdl_fifo.blocking_get_export
读取 “DUT 输入数据”,是 阻塞式读取(若无数据则等待,确保拿到数据后再计算 )。
七、计分板层(scb)
- 类型:
uvm_component
(实际是dadd_scoreboard
,继承自uvm_component
) - 角色:“验证裁决者”,从两个 TLM FIFO 分别获取:
dadd_oagt_to_scb_fifo
传递的 DUT 实际输出(来自oagt.omonitor
)。dadd_refmdl_to_scb_fifo
传递的 参考模型预期输出(来自refmdl
)。
比对两者的addr
、data
等字段,判断 DUT 行为是否符合预期,输出PASS
/FAIL
结果(代码中逻辑需结合main_phase
实现,此处从结构看是核心比对点 )。
- 关键端口:
act_port
(uvm_blocking_get_port
):从dadd_oagt_to_scb_fifo.blocking_get_export
读取 DUT 实际输出 的dadd_item
,阻塞式读取。exp_port
(uvm_blocking_get_port
):从dadd_refmdl_to_scb_fifo.blocking_get_export
读取 参考模型预期输出 的dadd_item
,阻塞式读取。
八、总结 - 数据流动与验证闭环
通过上述组件,完整的 “激励→采样→模拟→比对” 验证闭环如下:
- 激励注入:
dadd_rand_sequence
(序列)→iagt.sqr
(序列器)→iagt.drv
(驱动)→ DUT 输入接口。 - 输入采样:
iagt.imon
(输入监视器)→ 采样 DUT 输入 → 写入dadd_iagt_to_refmdl_fifo
→refmdl
(参考模型)读取并计算 “预期输出”。 - 输出采样:
oagt.omon
(输出监视器)→ 采样 DUT 输出 → 写入dadd_oagt_to_scb_fifo
→scb
(计分板)读取 “实际输出”。 - 预期输出传递:
refmdl
(参考模型)→ 计算 “预期输出” → 写入dadd_refmdl_to_scb_fifo
→scb
(计分板)读取 “预期输出”。 - 比对裁决:
scb
(计分板)→ 比对 “实际输出” 与 “预期输出” → 输出验证结果(PASS
/FAIL
)。
每一层组件各司其职,通过 TLM 端口和 FIFO 解耦,既保证了数据流动的顺畅,又让各组件可独立复用、维护,是 UVM 模块化验证的典型体现。