SVIP APB 使用指导
Author: syan
版本范围:当前仓库 APB3/APB4 requester / passive,VCS / UVM 1.2
本指南提供首次接入、配置与API参考、日常操作、检查和调试路径。特殊pattern和控制的完整recipe见 客户用例指南,实现关系见 架构。所有shell命令从产品仓库根执行。
1. 产品角色与支持范围
| 验证任务 | 使用方式 |
|---|---|
| 验证APB外设 | svip_apb_agent,cfg.is_active=UVM_ACTIVE,驱动请求 |
| 观察已有APB连接 | 相同agent,cfg.is_active=UVM_PASSIVE,无主动driver |
| 自测时制造响应等待/错误 | 使用testbench中的独立responder和ctrl,不是产品subordinate |
支持对齐APB3/APB4请求、有效ADDR1..32、DATA8/16/32、APB4 PPROT/PSTRB、同步sequence结果、reset中止、SVA、独立monitor、单word RAL、tracker和native功能覆盖率。接口是32-bit最大容器,DUT窄端口显式slice/zero extend。
产品当前不提供subordinate、memory backdoor、用户接管resp、APB5 USER或unaligned API。APB无wire ID/burst/outstanding,读写串行;使用sequence组织业务流量即可。
sequence / RAL -> sequencer -> requester -> DUT / independent responder
| PREADY/PSLVERR/PRDATA
+------ APB pins ------+
|
SVA + monitor -> AP / tracker / coverage
2. 首次运行与编译顺序
先准备VCS/UVM1.2站点环境,再运行小场景:
python3 apb/scripts/run.py all --case smoke --version 3
python3 apb/scripts/run.py all --case example_sequence --version 4 --coverage
python3 apb/scripts/regress.py --suite examples --list
每场有独立run目录;检查精确case/class/profile PASS标记、UVM总结和产物。编译进自己的工程时:
vcs -full64 -sverilog -ntb_opts uvm-1.2 -timescale=1ns/1ps \
-f apb/files.f -f apb/sequence_lib/files.f your_tb.sv
core顺序是interface → package,可选sequence package放其后。独立vlogan时先bootstrap UVM,再分别分析两个filelist;filelist按产品根的相对路径使用。产品interface包含pin SVA,不需要随库安装外部商业checker。
3. 顶层连接与环境创建
以下片段分别放在top和env;pclk/presetn及DUT端口由项目提供:
// 顶层
import uvm_pkg::*;
import svip_apb_pkg::*;
svip_apb_if bus(pclk,presetn);
initial begin
svip_apb_cfg cfg=svip_apb_cfg::type_id::create("cfg");
cfg.vif=bus;
cfg.addr_width=20; cfg.data_width=32; cfg.apb4=1;
cfg.tracker_en=1; cfg.tracker_filename="apb.tracker.log";
uvm_config_db#(svip_apb_cfg)::set(null,"uvm_test_top.env.apb","cfg",cfg);
run_test();
end
// env成员与build_phase内的创建语句
svip_apb_agent apb;
// 在build_phase中:
apb=svip_apb_agent::type_id::create("apb",this);
DUT的PADDR/PWDATA/PSTRB连接容器低有效位;PRDATA高位补零。PREADY/PSLVERR直接接入;APB3没有PPROT/PSTRB引脚,按该profile使用默认零/完整word语义。每个主动输出只有一个驱动者,不要同时运行VIP requester和独立pin requester。
纯passive配置 cfg.is_active=UVM_PASSIVE,由DUT或其他requester驱动总线,照常保留monitor/checker。多实例使用独立cfg、准确config_db路径和不同tracker文件名。
4. 配置参考与消费点
| 字段/方法 | 用途 | 生效时机 |
|---|---|---|
vif/is_active |
连接及主动/被动角色 | build前 |
addr_width/data_width/apb4 |
有效位宽与APB版本 | build前固定 |
tracker_en/tracker_filename/coverage_en |
观察组件创建及日志 | build前 |
back_to_back |
是否省去额外idle,仍保留SETUP | 当前请求终结后的间隔消费点 |
min_idle_cycles/max_idle_cycles |
固定或范围随机idle,单位cycle | 选择间隔时 |
hold |
暂停尚未呈现的新工作 | pull与正式呈现前;已呈现工作继续完成 |
agent.set_checks(0/1) |
同步切换SVA和monitor watchdog | 运行期 |
max_wait_cycles |
0关闭;正数为等待诊断阈值 | 每个等待采样点 |
运行期切换checks应使用公开方法,不仅改cfg字段。Watchdog超限只报告一次,保持ACCESS等待PREADY或reset,不能擅自撤回请求。已选择的idle不重新抽样;希望改变后续业务段时按消费点安排,而不是假设改字段能追溯生效。
5. 便利 read/write sequence
使用可选sequence包,在test/sequence的objection保护下执行:
import svip_apb_seq_pkg::*;
svip_apb_rw_seq seq=svip_apb_rw_seq::type_id::create("rw");
seq.cfg=apb.cfg;
seq.addr='h40; seq.write=1; seq.data='h01234567;
seq.strb='1; seq.prot=3'b101; // 此例是APB4/DATA32
seq.start(apb.sqr);
if (seq.result.status!=SVIP_APB_OK)
`uvm_error("WRITE",seq.result.convert2string())
seq.write=0; seq.start(apb.sqr);
if (seq.result.status!=SVIP_APB_OK || seq.data!==32'h01234567)
`uvm_error("READ","readback differed")
本例读回假设地址属于可读写存储寄存器,真实外设按自身模型检查。APB3把prot设0;DATA8/16只比较有效数据位。seq.strb用于写,读请求自动置零;seq.prot同时用于读写。不会自动把最低byte搬到被选lane。
APB是同步完成接口。 finish_item()或 seq.start() 返回时request已写回终结结果,不需要 get_response()。这与SVIP AXI的异步send/response契约不同,迁移sequence时需显式处理。
6. 自定义transaction与随机pattern
在自定义 uvm_sequence #(svip_apb_txn) 内,由工程提供cfg:
svip_apb_txn t=cfg.create_txn("random_write");
start_item(t);
if (!t.randomize() with {
write==1; addr inside {['h40:'h7f]}; data[7:4]==4'ha;
}) `uvm_fatal("PATTERN","randomize failed")
finish_item(t);
if (t.status!=SVIP_APB_OK) `uvm_error("RESULT",t.convert2string())
cfg.create_txn()传入有效profile;约束保证自然word对齐、有效位宽和协议侧带。APB4随机写可能有partial/zero strobe;需要full write时约束strobe或设置 t.strb=cfg.strb_mask()。固定内容直接赋值即可,不必创建新pattern类。
| Transaction字段 | 语义 |
|---|---|
write/addr/data/strb/prot |
方向、地址、数据、写byte enable、APB4保护属性 |
status/slverr |
本地终结状态与实际四态总线响应 |
wait_cycles |
选中ACCESS且未完成的采样次数,不含SETUP |
t_start/t_end |
ns时间、1ps精度;active呈现与passive首次SETUP采样起点不同 |
status为OK、SLVERR、RESET_ABORTED、BAD_REQUEST或X_RESPONSE;错误读响应允许数据无效,不能无条件比较数据。完整literal列表、固定nibble随机、逐byte和零strobe代码见 cookbook。
7. Hold、latency与响应反压
cfg.back_to_back=0;
cfg.min_idle_cycles=2; cfg.max_idle_cycles=5;
cfg.hold=1; // 阻止新工作到达引脚;已呈现请求继续完成
// ... wait for the desired event ...
cfg.hold=0;
PREADY由DUT/响应模型驱动。产品requester不能主动强迫DUT产生合法反压。自测fixture提供 ctrl.wait_cycles(SETUP准备时读取)与 manual_response/manual_ready(响应mux)来演示反压;这些不是产品agent API。
example_backpressure连续16个ACCESS等待样本后释放READY,验证稳定和恰一次完成;backpressure_reset_write在等待中reset并读回旧值。Fixture采用实际bus READY/ERROR决定memory提交;该旧值策略不代表所有DUT在reset时回滚副作用。
8. Reset、X与协议检查
clocking input为#1step,output为#0。Raw reset guard识别采样沿间短pulse,停止旧epoch后在NBA settling后重新压低控制;同时间步reset优先于完成候选。RESET_ABORTED不同于PSLVERR,所有已接纳请求有一次终结。恢复后从SETUP重新开始。
SVA检查阶段转换、选中窗口known、等待稳定性和有效sideband;monitor重建完成/abort、统计wait。PREADY仅在选中ACCESS检查,PSLVERR仅在完成窗口检查,error read不要求PRDATA known。APB4 inactive byte可保持X,但有效PWDATA总线仍须在传输期间稳定。具体窗口与反例见 checker规则。
Driver对非法请求和未知完成响应的检查是API边界,不能通过关闭protocol checks绕过。故意非法pin测试使用独立fixture与精确rule/count预算,额外诊断仍使场景失败。
9. Analysis、RAL、tracker与coverage
| 入口 | 内容 |
|---|---|
agent.ap |
monitor完整完成事务,含错误 |
agent.abort_ap |
monitor看到SETUP后发生的reset abort |
agent.drv.done_ap |
active全部已接纳请求终结,含BAD_REQUEST/早期abort |
agent.mon.reg_ap |
只发布成功完成,用于RAL predictor |
Analysis对象只读;subscriber需要修改时自行clone。Active tracker/coverage消费driver terminal,passive消费monitor完成/abort,避免双写。
RAL使用 agent.connect_reg_map(map) 和 connect_predictor(predictor,map),关闭map auto_predict;APB4支持byte enable。当前支持不大于一个APB data word的register,helper提前拒绝更宽register。错误/reset不更新无效mirror数据;可复制frontdoor/field-write见 example_ral/ral_byte_enable/ral_error/ral_reset,不要自行绕开成功端口过滤。
Tracker含TXN/ABORT/REJECT、方向、地址、数据、prot/strobe、status、wait与起止时间。Native covergroup在真实terminal采样方向、结果、wait、有效DATA、prot/strobe及cross。自测 --coverage同时启用VCS编译/运行选项和独立VDB;工程接入时 coverage_en只控制采样,还需设置模拟器coverage输出。APB当前没有FC JSON/跨run合并API。
10. 示例索引、波形与回归
| 学习目标 | Case |
|---|---|
| 最小接入/便利sequence | smoke、example_sequence |
| 随机与指定内容 | example_random、example_directed_pattern、example_constrained_pattern |
| Byte lane | example_byte_lanes(APB4) |
| 时序控制 | example_timing、example_back_to_back、example_hold |
| 人工反压/中止 | example_backpressure、backpressure_reset_write |
| 错误/RAL/passive | example_error、example_ral、example_passive |
| 完整判错 | compliance及check_*;详见catalog/rules |
python3 apb/scripts/run.py all --case example_backpressure --version 4 --coverage --waves fsdb
python3 apb/scripts/run.py all --case example_constrained_pattern --version 4 \
--addr-width 20 --data-width 16 --clock-half-ps 250 --coverage
python3 apb/scripts/regress.py --suite full --reset-matrix --coverage
裸 --waves或 --waves vcd 输出VCD;FSDB要求站点VCS/Verdi支持。用raw pre-edge和mon_cb捕获输入沿后1ps交叉看握手;时钟沿后的raw idle不能抹去本沿完成。Settled FSDB无法恢复未记录delta/NBA顺序,边界还需原生SV检查。
运行器保留source/case/class/profile/binary/command/log与所需产物,拒绝过期输入和错误波形格式。当前524场冻结回归及wavedbg确认见 第二轮验收,历史演进见 首轮记录。
11. 常见接入问题
| 现象 | 优先检查 |
|---|---|
| 找不到vif/cfg | config_db完整层级、类型及build前配置 |
| 请求未到引脚 | hold、reset、agent角色及sequence是否启动在对应sqr |
| ACCESS不结束 | DUT PREADY、fixture manual_ready、响应端reset;watchdog不会撤回请求 |
| BAD_REQUEST | 地址对齐/高位、prot/strobe有效范围及X值 |
| 部分byte不变 | PSTRB与data lane放置、外设byte-enable语义 |
| RAL mirror异常 | 成功reg_ap、auto_predict关闭、register不超过一个word |
| tracker数量不符 | 区分driver terminal与monitor completion,避免同时订阅两者重复计数 |
| 运行结果与旧波形不一致 | 使用同一UUID目录的manifest、tracker和波形,核对seed/profile |