news 2026/5/22 1:12:05

【芯片测试】:自定义波形与条件波形

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【芯片测试】:自定义波形与条件波形

第四篇:进阶篇(上)—— 用户自定义波形与条件波形

系列:《VCDSTIL 实战:从仿真波形到 ATE 测试向量》第 4 篇(共 5 篇)


前言

前三篇介绍的都是 VCDSTIL 的"自动提取"模式:工具从 VCD 中识别所有波形,如实地将它们翻译成 STIL。在理想情况下,这已经足够用。

但现实世界中,自动提取往往不是终点,而是起点。主要原因有两个:

问题一:异步信号产生海量波形

当 VCD 文件来自纯事件驱动的异步仿真时,同一根信号线在不同周期内可能在不同的时间点发生跳变,导致自动提取产生数十甚至数百个"相似但不完全相同"的波形。这些波形在 ATE 上是无法直接使用的——ATE 要求每个引脚的波形数量有限,且时间点固定。

问题二:需要精确控制驱动/采样时机

工程师往往对"信号应该在周期内哪个时刻被驱动"或"输出应该在何时被采样"有明确的设计意图。自动提取无法理解这种意图,它只是忠实记录 VCD 中发生的事情。

本篇介绍两种解决方案:

  • 用户自定义波形(User-defined Waveforms):强制指定波形,替代自动提取结果
  • 条件波形(Conditional Waveforms):基于信号状态动态选择波形

第一部分:用户自定义波形

核心概念:true条件 vswaveform条件

理解自定义波形的关键,是区分 timing.csv 中Condition列的两种取值:

Condition 值含义使用场景
waveform将该波形与 VCD 事件比对,匹配则使用自动提取模式(默认)
true无条件使用该波形,不比对 VCD用户强制指定模式

将 Condition 设为true的波形,称为“强制波形(Forced Waveform)”

场景描述

假设我们有如下两个需求:

  1. CLK0:无论 VCD 中的实际波形如何,总是在 0 ns 拉低、在 200 ns 拉高
  2. D0:输入周期时在 150 ns 驱动数据,输出周期时在 250 ns 采样数据

修改 timing.csv

打开timing.csv(或创建新的timing_forced.csv),针对上述需求做如下修改:

CLK0 的修改

将原来的 CLK0 行(自动提取,Condition 为waveform)替换为:

PinWFCWaveformCondition
CLK0D0ns:D; 200ns:Utrue
  • 这里只定义了一个波形(单行)
  • Condition = true意味着无论这个周期内 VCD 的 CLK0 实际波形是什么,都强制使用这个波形
  • 之前自动提取的结果是0ns:D; 150ns:U,现在我们将拉高时间从 150 ns 改为 200 ns
D0 的修改

D0 需要定义两个强制波形,分别处理输入和输出两种情况:

PinWFCWaveformCondition
D0150ns:Ftrue
D0250ns:Rtrue

这里出现了两个特殊的事件符号:FR,需要重点理解。


特殊事件符号详解

VCDSTIL 定义了三个特殊的波形事件符号,专门用于自定义波形中:

F——驱动占位符(Force Placeholder)
150ns:F

F是一个"万能输入驱动符",表示"在 150 ns 时,从 VCD 中取出该信号在此周期的实际逻辑值,并用于驱动"。

关键特性:

  • F只接受输入状态(0、1 等驱动态),不接受输出状态(L、H 等比较态)
  • 因为不同周期的实际值可能不同(D0 可能是高也可能是低),VCDSTIL 会为每种可能的值自动生成一个对应波形
  • 由于波形是动态生成的,不能手动指定 WFC,WFC 列必须留空,工具自动分配

生成结果:
工具会自动展开F为多个实际波形:

"D0" { D { '150ns' D; } U { '150ns' U; } }
R——采样占位符(Read Placeholder)
250ns:R

R是一个"万能输出采样符",表示"在 250 ns 时,采样该信号的值,并与期望值进行比较"。

关键特性:

  • R只接受输出状态(L、H、T 等比较态),不接受输入状态
  • 同样,工具会自动展开为多个采样波形

生成结果:

"D0" { L { '250ns' L; } T { '250ns' T; } H { '250ns' H; } }
S——通用占位符(State Placeholder)

若某个引脚在同一波形中既可能是驱动也可能是采样,可以使用S,它同时接受输入和输出状态。

三种符号对比:

符号接受状态典型使用场景
F仅输入态(驱动)输入引脚,或双向引脚的输入周期
R仅输出态(采样)输出引脚,或双向引脚的输出周期
S输入态 + 输出态需要同时处理两种情况的引脚

执行转换并验证结果

修改完成后,用新的 Setup 文件运行 VCDSTIL:

VCDSTIL-setupsetup_forced.py

setup_forced.py内容与setup_timing.py相同,仅timing_file指向修改后的文件)

查看生成的 STIL,验证结果符合预期:

"CLK0" { D { '0ns' D; '200ns' U; } ← 拉高时间从 150ns 变为了 200ns ✓ } "D0" { D { '150ns' D; } ← 输入周期,150ns 驱动低 U { '150ns' U; } ← 输入周期,150ns 驱动高 L { '250ns' L; } ← 输出周期,250ns 采样低 T { '250ns' T; } ← 输出周期,250ns 采样高阻 H { '250ns' H; } ← 输出周期,250ns 采样高 }

第二部分:条件波形

为什么需要条件波形?

强制波形(true)的粒度是"整个信号的所有周期"——一旦设置,对该信号的每一个周期都生效。但有时我们需要更细的控制:

“当某个信号处于特定状态时,使用 A 波形;否则使用 B 波形。”

这正是条件波形的用途。条件波形通过在Condition列中填写一个布尔表达式,让 VCDSTIL 在每个周期开始时动态评估并选择对应波形。

场景描述

在 CLK0 和 D0 的基础上(沿用timing_forced.csv的配置),对D1新增如下需求:

  • 输入周期:在 150 ns 驱动数据
  • 输出周期:在 250 ns 采样数据
  • 特殊情况:当 CLK2 在周期起点为高电平时,关闭驱动(输出高阻 Z),不驱动也不采样

条件语法

条件表达式的格式为:

信号名 == '值' @ (时间点)

常用示例:

CLK2=='D'@(t0) # CLK2 在周期起点(t0)为低电平(Drive Low) CLK2=='U'@(t0) # CLK2 在周期起点(t0)为高电平(Drive Up) CLK2=='D'@(t0+5ns) # CLK2 在周期起点后 5 ns 为低电平

其中:

  • t0代表当前周期的起始时间点(相对时间 0 ns)
  • 可以加偏移量,如t0+5ns,对于有延迟要求的采样场景很有用
  • 多个条件可以用 AND/OR 组合:CLK2=='D'@(t0) AND RD_=='U'@(t0)

修改 timing.csv

timing_forced.csv的基础上,新增 D1 的三行定义(创建timing_cond.csv):

PinWFCWaveformCondition
D1150ns:FCLK2=='D'@(t0)
D10ns:ZCLK2=='U'@(t0)
D1250ns:R;true

逐行解析:

第 17 行(输入驱动):

Pin=D1, Waveform=150ns:F, Condition=CLK2=='D'@(t0)

当 CLK2 在周期起点为低(D)时,D1 在 150 ns 处驱动实际数据值(通过F占位符)。

第 18 行(驱动关闭):

Pin=D1, Waveform=0ns:Z, Condition=CLK2=='U'@(t0)

当 CLK2 在周期起点为高(U)时,D1 立即(0 ns)进入高阻态Z,驱动关闭。

第 19 行(输出采样):

Pin=D1, Waveform=250ns:R;, Condition=true

在所有输出周期,在 250 ns 采样 D1 的值。true条件确保这一行覆盖所有输出周期。

条件评估顺序

VCDSTIL 按行顺序评估条件,使用第一个条件为真的波形。因此true条件的行应永远放在最后,作为默认项(与switch-case中的default类似)。

执行转换并验证结果

VCDSTIL-setupsetup_cond.py

查看 STIL,D1 的波形定义如下:

"D1" { Z { '0ns' Z; } ← CLK2 为高时,立即高阻 D { '150ns' D; } ← CLK2 为低时,150ns 驱动低 U { '150ns' U; } ← CLK2 为低时,150ns 驱动高 H { '250ns' H; } ← 输出周期,250ns 采样高 T { '250ns' T; } ← 输出周期,250ns 采样 }

在 Pattern 向量中,可以看到 D1 的波形随 CLK2 状态动态切换:

V { "CLK2"=D; ... "D1"=D; ... } ← CLK2 低,D1 在150ns驱动 V { "CLK2"=U; "D1"=Z; ... } ← CLK2 高,D1 高阻 V { "CLK2"=D; ... "D1"=D; ... } ← CLK2 低,继续驱动

两种波形类型总结

类型Condition 值适用场景主要特点
自动波形waveform默认,自动提取严格匹配 VCD,无需手动干预
强制波形true需要统一替换波形对该信号所有周期生效,不比对 VCD
条件波形信号==值@(时间)需要按周期动态选择最灵活,支持 AND/OR 组合

小结

本篇介绍了两种突破自动提取限制的高级特性:

用户自定义波形:

  • 将 Condition 改为true,工具会无条件使用你定义的波形
  • 使用F(仅输入)、R(仅输出)、S(两者)三种特殊符号作为数据占位符
  • 使用FR时,WFC 列必须留空,由工具自动生成

条件波形:

  • 条件语法:信号=='值'@(时间点),可用 AND/OR 组合
  • t0表示周期起点,支持t0+Xns偏移
  • 条件按行顺序评估,第一个为真的波形生效
  • true条件行作为最后的默认项

下一篇(本系列最后一篇)将介绍另一种完全不同的时序方法——基于时钟的时序提取(Clock-Based Timing),它可以为时钟同步信号生成极为整洁的单一波形。


上一篇:第三篇:CLI 实操篇 —— 用命令行实现自动化流程
下一篇:第五篇:进阶篇(下)—— 基于时钟的时序提取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 1:08:05

树莓派4B跑ovos+在线stt模型

这年头说实在有了peering coding之后,写这些都是笑话。今天算记一个互动类程序的常识吧。简言之,程序里面一定要带多线程,这是一个基本思路。以下代码由可可爱爱花了钱的opus 4.7写的flask本地小服务端转送语音请求去googleapis的speech-to-t…

作者头像 李华
网站建设 2026/5/22 1:05:11

1987年6月27日下午13-15点出生性格、运势和命运

1987年6月17日,下午15点到17点之间,正值盛夏时节,阳光炽烈而漫长。这一天出生的孩子,是中国改革开放后“黄金十年”中诞生的又一批弄潮儿。他们的成长轨迹,与全球化浪潮的涌入、市场经济的深化以及互联网的萌芽几乎同步…

作者头像 李华
网站建设 2026/5/22 1:04:00

如何10倍提升英语学习效率:词达人自动化助手终极教程

如何10倍提升英语学习效率:词达人自动化助手终极教程 【免费下载链接】cdr 微信词达人,高正确率,高效简洁。支持班级任务及自选任务 项目地址: https://gitcode.com/gh_mirrors/cd/cdr 核心关键词:词达人自动化助手、Pytho…

作者头像 李华
网站建设 2026/5/22 0:49:22

14. 声明文件(Declaration Files)

14. 声明文件(Declaration Files) 1. 概述 声明文件(.d.ts 文件)用于描述 JavaScript 库的类型信息,让 TypeScript 能够理解和使用纯 JavaScript 编写的代码。声明文件只包含类型定义,不包含实现代码。 ┌─…

作者头像 李华
网站建设 2026/5/22 0:47:33

【软考高级架构】论文预测——论基于ATAM的架构评估方法

论基于ATAM的架构评估方法 摘要 软件架构评估是保障系统质量属性满足业务目标的关键环节。架构权衡分析方法(Architecture Trade-off Analysis Method,ATAM)作为一种系统化的架构评估方法,通过场景捕获、质量属性分析、敏感点与权衡点识别、风险与非风险决策分类等结构化…

作者头像 李华