uvvm-verification
UVM 验证方法论技能 - 从验证计划到功能覆盖率,完整 UVM 验证平台开发
DeepseekModel
キュレーション済みスキル
品質 良好 · 48
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=tangyangchao578-art-icer-skill-package-skills-uvvm-verification-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name uvvm-verification description UVM 验证方法论技能 - 从验证计划到功能覆盖率,完整 UVM 验证平台开发 description.zh UVM 验证方法论技能 - 从验证计划到功能覆盖率,完整 UVM 验证平台开发 origin ICER categories verification UVM 验证方法论技能 当用户需要开发 UVM 验证平台时,启用此技能。遵循 IEEE 标准 UVM,一步一步完成验证开发,从验证计划到功能覆盖率。 When to Activate 开发新的 UVM 验证平台 优化现有 UVM 验证平台结构 调试 UVM 验证平台问题 从 legacy 验证方法迁移到 UVM 代码审查 UVM 验证平台 行业经验数值 覆盖率目标 覆盖率类型 目标值 说明 行覆盖率 ≥ 95% 所有语句至少执行一次 条件覆盖率 ≥ 90% 所有条件分支至少执行一次 翻转覆盖率 ≥ 85% 所有寄存器位翻转 FSM 覆盖率 100% 所有状态和转换 功能覆盖率 100% 所有功能点覆盖 验证时间估算 设计复杂度 代码行数 验证时间 验证人员 小型模块 < 1K 行 2-4 周 1 人 中型模块 1K-10K 行 1-3 月 1-2 人 大型模块 10K-50K 行 3-6 月 2-4 人 子系统 50K-200K 行 6-12 月 4-8 人 SoC > 200K 行 12-24 月 8-20 人 回归测试周期 设计阶段 测试用例数 回归时间 频率 功能开发 100-500 < 1 小时 每次提交 功能完成 500-2000 1-4 小时 每日 回归阶段 2000-10000 4-24 小时 每周 流片前 > 10000 > 24 小时 每周 Bug 密度参考 阶段 Bug/KLOC 说明 功能开发 5-10 正常 功能完成 1-3 逐步减少 回归阶段 0.1-0.5 大部分已修复 流片前 < 0.01 几乎无新 Bug 故障诊断框架 症状1:覆盖率不收敛 诊断步骤: 1. 分析覆盖率报告 2. 识别未覆盖的代码/功能 3. 检查测试用例 4. 检查约束 判断标准: 覆盖率 判断 行动 > 95% 良好 继续 90-95% 接近 补充测试用例 80-90% 不足 检查约束 < 80% 严重 重新评估验证策略 根本原因定位: 根本原因 诊断特征 解决方案 约束过紧 随机值不发散 放宽约束 测试用例不足 功能点未覆盖 补充测试用例 死代码 无法覆盖 检查 RTL 边界条件遗漏 边界未覆盖 添加边界测试 症状2:仿真挂起 诊断步骤: 1. 检查仿真时间 2. 查看波形 3. 检查 UVM phase 4. 检查 objection 根本原因定位: 根本原因 诊断特征 解决方案 死锁 等待信号不变化 检查握手协议 无限循环 时间不推进 检查循环条件 Objection 泄漏 phase 不结束 检查 objection 事件未触发 等待条件不满足 检查事件触发 症状3:功能错误多 诊断步骤: 1. 分析错误日志 2. 分类错误类型 3. 定位错误模块 4. 分析错误原因 根本原因定位: 根本原因 诊断特征 解决方案 规格理解错误 测试用例错误 重新理解规格 RTL Bug 波形不正确 修复 RTL 测试平台错误 预期值错误 修复测试平台 时序问题 竞争条件 修复时序 症状4:仿真速度慢 诊断步骤: 1. 分析仿真时间分布 2. 检查日志输出 3. 检查覆盖率收集 4. 检查波形转储 根本原因定位: 根本原因 诊断特征 解决方案 日志过多 打印时间占比高 减少日志 波形转储 磁盘 I/O 高 仅转储关键信号 覆盖率开销 内存占用高 优化覆盖率 设计效率低 仿真时间长 优化模型 第一步:制定验证计划 验证开始前必须制定验证计划,明确验证范围和目标。 验证计划内容 内容 说明 DUT 功能描述 简要说明 DUT 要实现的功能 功能点列表 所有需要验证的功能点,枚举 测试类型 定向测试/随机测试/约束随机 覆盖率目标 代码覆盖率目标,功能覆盖率目标 收敛标准 达到什么标准验证完成 功能点枚举示例 对于一个异步 FIFO,功能点包括: 空状态读写正确 满状态读写正确 半满状态读写正确 异步复位正确 不同时钟频率工作正确 X 传播正确 覆盖率目标 代码覆盖率: - 行覆盖率 >= 90% - 条件覆盖率 >= 80% - 翻转覆盖率 >= 85% - FSM 覆盖率 = 100% 功能覆盖率: - 所有功能点 100% 覆盖 第二步:制定验证方案 根据验证计划制定验证方案。 验证平台架构 标准 UVM 验证平台结构: testbench/ ├── tb_top.sv # 测试平台顶层(例化DUT和接口) ├── interfaces/ # DUT接口定义 │ └── bus_if.sv ├── agents/ # agent (driver + monitor + sequencer) │ ├── driver.sv │ ├── monitor.sv │ ├── sequencer.sv │ └── agent.sv ├── sequences/ # 激励序列 │ ├── base_seq.sv │ ├── read_seq.sv │ ├── write_seq.sv │ └── stress_seq.sv ├── models/ # 参考模型 │ └── ref_model.sv ├── scoreboards/ # 结果比较 │ └── scoreboard.sv ├── coverage/ # 功能覆盖率收集 │ └── coverage.sv ├── tests/ # 测试用例 │ ├── base_test.sv │ ├── sanity_test.sv │ └── stress_test.sv └── env.sv # 环境顶层 这个结构分工清晰,方便复用。 验证策略 定向测试 :验证特定功能点,适合边界情况 约束随机测试 :随机生成激励,覆盖更多 corner case 覆盖率驱动 :根据覆盖率添加缺失测试 断言补充 :接口属性断言,自动检查 第三步:测试点撰写 每个功能点对应一个测试点,明确测试什么,怎么测试。 测试点模板 测试点 ID: TP-001 测试点名称: 异步FIFO满状态测试 测试点描述: 当FIFO满了,写请求应该被忽略,满信号应该正确输出 测试方法: 连续写直到满,检查满信号,检查数据正确 优先级: P1 覆盖分组: 边界条件 测试点优先级 P1 :必须测试,核心功能 P2 :应该测试,非核心功能 P3 :可选测试,覆盖盲区 功能覆盖率覆盖点 每个测试点对应功能覆盖率覆盖点: covergroup fifo_cg { option.per_instance = 1; empty: coverpoint fifo_empty { bins empty = {1}; bins not_empty = {0}; } full: coverpoint fifo_full { bins full = {1}; bins not_full = {0}; } half_full: coverpoint fifo_counter { bins low[] = {[0:DEPTH/2-1], [DEPTH/2+1:DEPTH-1]}; bins mid = {DEPTH/2}; } } 步骤 4:验证环境搭建 验证环境搭建需要按顺序完成:接口 → 事务 → Driver → Monitor → Agent → Env → Test。 4.1 接口编写 做什么: 定义 DUT 与验证环境的连接接口。 接口编写模板: interface dut_if #( parameter DATA_WIDTH = 32, parameter ADDR_WIDTH = 32 )( input wire clk, input wire rst_n ); // 时钟和复位 logic clk; logic rst_n; // 输入信号 logic [ADDR_WIDTH-1:0] addr; logic [DATA_WIDTH-1:0] wdata; logic wr_en; logic rd_en; // 输出信号 logic [DATA_WIDTH-1:0] rdata; logic ready; logic error; // 时钟块(用于同步) clocking cb @(posedge clk); default input #1ns output #1ns; output addr, wdata, wr_en, rd_en; input rdata, ready, error; endclocking // modport for DUT modport dut ( input clk, rst_n, addr, wdata, wr_en, rd_en, output rdata, ready, error ); // modport for Driver modport driver ( clocking cb, output rst_n ); // modport for Monitor modport monitor ( clocking cb ); endinterface 接口编写检查清单: 所有 DUT 信号都已定义 信号位宽正确 添加了 clocking block(同步) 定义了 modport(DUT/Driver/Monitor) 参数化设计(位宽可配置) 4.2 事务编写 做什么: 定义验证环境中传递的数据结构。 事务编写模板: class dut_trans extends uvm_sequence_item; `uvm_object_utils(dut_trans) // 随机化字段 rand bit [31:0] addr; rand bit [31:0] data; rand bit wr_en; rand bit rd_en; // 约束 constraint c_addr_align { addr[1:0] == 2'b00; // 4字节对齐 } constraint c_valid_trans { wr_en != rd_en; // 读写互斥 } // 覆盖点 covergroup trans_cg; cp_addr: coverpoint addr { bins low = {[0:32'h0000FFFF]}; bins mid = {[32'h00010000:32'hFFFF0000]}; bins high = {[32'hFFFF0001:32'hFFFFFFFF]}; } cp_wr: coverpoint wr_en; cp_rd: coverpoint rd_en; endgroup function new(string name = "dut_trans"); super.new(name); trans_cg = new(); endfunction function void post_randomize(); trans_cg.sample(); endfunction // 复制、比较、打印方法 virtual function void do_copy(uvm_object rhs); dut_trans rhs_; super.do_copy(rhs); $cast(rhs_, rhs); addr = rhs_.addr; data = rhs_.data; wr_en = rhs_.wr_en; rd_en = rhs_.rd_en; endfunction virtual function bit do_compare(uvm_object rhs, uvm_comparer comparer); dut_trans rhs_; bit same = super.do_compare(rhs, comparer); $cast(rhs_, rhs); same = (addr == rhs_.addr) && (data == rhs_.data) && (wr_en == rhs_.wr_en) && (rd_en == rhs_.rd_en); return same; endfunction virtual function string convert2string(); return $sformatf("addr=0x%8h, data=0x%8h, wr=%b, rd=%b", addr, data, wr_en, rd_en); endfunction endclass 事务编写检查清单: 所有传输数据字段都已定义 关键字段添加了随机约束 添加了功能覆盖点 实现了 do_copy、do_compare、convert2string 使用 `uvm_object_utils 注册 4.3 Driver 编写 做什么: 将事务转换为 DUT 接口信号。 Driver 编写模板: class dut_driver extends uvm_driver #(dut_trans); `uvm_component_utils(dut_driver) virtual dut_if vif; function new(string name, uvm_component parent); super.new(name, parent); endfunction virtual function void build_phase(uvm_phase phase); super.build_phase(phase); if (!uvm_config_db#(virtual dut_if)::get(this, "", "vif", vif)) begin `uvm_fatal("build_phase", "Failed to get vif") end endfunction virtual task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); drive_trans(req); seq_item_port.item_done(); end endtask virtual task drive_trans(dut_trans trans); // 等待时钟沿 @(vif.cb); // 驱动信号 vif.cb.addr <= trans.addr; vif.cb.data <= trans.data;
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |