测量差分对偏斜与共模偏差
目标
求出两个互补信号的到达差,并分别判定共模偏差与差分阈值的到达时刻。
先修知识是前面的信号完整性实验,以及 Python 函数、元组、JSON、文件处理。预计需要 85 分钟。请在默认的 60 分钟结束之前,用“+时间”延长(最多 180 分钟)。会话结束时文件会消失。请另行保存源代码和报告。
为什么重要
即使最终差分电压相同,共模和接收时间也可能不同。必须把相对偏斜与绝对传播延迟、较慢边沿的好处与代价区分开,才能解释设计措施的效果。这是两条互不耦合的理想匹配线路的模型。它不是实物测量、辐射认证或耦合线路分析。
步骤
- 用 mkdir -p /root/differential-skew 创建目录后,把所有实现保存到 /root/differential-skew/analyze.py 中。predict(config,t_ns) 返回 (Vp,Vn) 元组。config 是恰好包含 delay_p_ns=1/1.5、skew_ns=-0.4/-0.2/0/0.2/0.4、rise_ns=0.4/0.8 三个键的 dict,每个值都是非 bool 的 int/float。t_ns 是非 bool 的有限非负 int/float。其余情况为 ValueError。P=clip((t_ns−2−delay_p_ns)/rise_ns,0,1),N=1−clip((t_ns−2−delay_p_ns−skew_ns)/rise_ns,0,1),并保留输入。
- modes(rows) 把有效的 (秒,Vp,Vn) 元组列表转换为 (ns,Vdiff,Vcm) 元组列表。Vdiff=Vp−Vn,Vcm=(Vp+Vn)/2。不要修改输入,并保留全部采样点及其顺序。
- crossing(points,level,direction) 在时间严格递增的有效 (ns,电压) 表中,对第一次穿越时间做线性插值后返回。direction 只能是 rising/falling,其他值为 ValueError。rising 寻找满足 alevel>=b 的相邻电压 a,b。没有穿越则为 None,一开始就停留在阈值上的平坦采样点不算穿越。
- metrics(rows) 从时间递增的有效 (秒,Vp,Vn) 表中,返回如下对象:skew_ns=N 的 0.5V 下降穿越−P 的 0.5V 上升穿越,common_peak_v=所有采样点 |Vcm−0.5| 的最大值,received_ns=Vdiff 的第一个 +0.8V 上升穿越或 None,final_diff_v=最后一个 Vdiff。只要有一个没有 50% 穿越,就是 ValueError。要从采样点计算,不要用输入配置代为填入。
- assess(observed) 根据 metrics 的结果,返回如下对象:common_ok=(common_peak_v<=0.15),timing_ok=(received_ns 不是 None 且 <=4),meets_spec=(两个条件都为真)。包含边界值。不要把两个失败原因合并为一个而抹掉。
- analyze(folder) 分析由 config.json 和 simulator.read_wave 读取的 wave.tsv。保留观测的 metrics 和 assess 结果,并把所有原始采样点的两个电压与 predict 比较,求出最大绝对误差 max_voltage_error。误差<=0.003 则 consistent,只有 consistent 和 meets_spec 都为真时才 passed。要包含参考中的所有返回键,并且 measured=False。即使不一致,也要保留观测值,且不修改原始文件。
- campaign(values,folder) 预先验证由 1–8 个无重复配置组成的整个 list,并创建新文件夹。用 simulator.capture(config,folder/case-NN) 生成原始数据后进行 analyze。NN 从 00 开始,如果结果 config 与请求不同,则为 ValueError。返回包含 results、所有 passed 的逻辑与 all_pass、model=independent_matched_lossless_lines、measured=False 的对象,并保存相同的 report.json。保留失败的条件和原始的四个文件,已有的文件夹即使为空也要拒绝。配置错误要在创建文件夹之前拒绝。
参考
提供的辅助程序是 /opt/lab/fixtures/differential_skew/simulator.py。不需要联网,也不需要额外安装。capture(config,新文件夹) 会保存 config.json、circuit.cir、wave.tsv、ngspice.log,并返回 Path。read_wave(path) 会检查表头、有限数值、递增的时间、最大 2.1ps 的采样间隔以及 0–6ns 的完整范围,并给出 (秒,Vp,Vn) 元组列表。被截断的波形为 ValueError。ngspice 使用最大间隔为 2ps 的自适应时间网格。采样最大值与连续时间的最高点可能不同。source 的 PWL 转换从 2ns 开始,两条线路、源和端接各为 50Ω。
第 6 步的返回键:config、observed(metrics 的结果)、common_ok、timing_ok、meets_spec、max_voltage_error、consistent、passed、measured。最后一个值为 False。所有原始采样点的电压误差允许值 0.003V,与学习规范 0.15V·4ns,是两种不同的标准。一般函数的数值比较容差为相对和绝对 1e-8。要用从采样点中实际求出的值进行比较。对于明确说明接收有效数值表的函数,不需要另外添加解析器。
最后一步之后,实际运行下面六个条件。每个条件是 (P 延迟 ns, 偏斜 ns, 斜坡 ns)。正常的报告中也包含失败的条件,所以 all_pass=False。再次运行时要使用新文件夹。
cd /root/differential-skew
PYTHONPATH=/opt/lab/fixtures/differential_skew python3 - <<'PY'
from analyze import campaign
values = [(1,0,.4),(1,.2,.4),(1,.2,.8),(1,.4,.8),(1.5,0,.8),(1,-.2,.4)]
configs = [dict(delay_p_ns=p,skew_ns=s,rise_ns=r) for p,s,r in values]
print(campaign(configs, '/root/differential-skew/run-01'))
PY
文件必须是 64KiB 以下的普通文件,并且在 import 时不要输出内容。评分使用独立的采样点和真实引擎条件,并且不会修改学员的源代码。检查进程的 CPU 12 秒、文件 8MiB、总计 35 秒的限制,是与学习时间不同的运行保护措施。
预测互补信号的到达
用 mkdir -p /root/differential-skew 创建目录后,把所有实现保存到 /root/differential-skew/analyze.py 中。predict(config,t_ns) 返回 (Vp,Vn) 元组。config 是恰好包含 delay_p_ns=1/1.5、skew_ns=-0.4/-0.2/0/0.2/0.4、rise_ns=0.4/0.8 三个键的 dict,每个值都是非 bool 的 int/float。t_ns 是非 bool 的有限非负 int/float。其余情况为 ValueError。P=clip((t_ns−2−delay_p_ns)/rise_ns,0,1),N=1−clip((t_ns−2−delay_p_ns−skew_ns)/rise_ns,0,1),并保留输入。
匹配后的接收幅度是源幅度的一半。不要把两个延迟取平均,而是只把偏斜加到 N 的延迟上。
分离差分与共模
modes(rows) 把有效的 (秒,Vp,Vn) 元组列表转换为 (ns,Vdiff,Vcm) 元组列表。Vdiff=Vp−Vn,Vcm=(Vp+Vn)/2。不要修改输入,并保留全部采样点及其顺序。
差分是差值,共模是平均值。波形文件中的秒,在返回对象中要换算为 ns。
对有方向的阈值穿越做插值
crossing(points,level,direction) 在时间严格递增的有效 (ns,电压) 表中,对第一次穿越时间做线性插值后返回。direction 只能是 rising/falling,其他值为 ValueError。rising 寻找满足 alevel>=b 的相邻电压 a,b。没有穿越则为 None,一开始就停留在阈值上的平坦采样点不算穿越。
第一个大于或小于阈值的采样点本身,并不是准确的穿越时间。请按电压比例在两个时间之间插值。
求出观测到的偏斜和共模偏差
metrics(rows) 从时间递增的有效 (秒,Vp,Vn) 表中,返回如下对象:skew_ns=N 的 0.5V 下降穿越−P 的 0.5V 上升穿越,common_peak_v=所有采样点 |Vcm−0.5| 的最大值,received_ns=Vdiff 的第一个 +0.8V 上升穿越或 None,final_diff_v=最后一个 Vdiff。只要有一个没有 50% 穿越,就是 ValueError。要从采样点计算,不要用输入配置代为填入。
负的偏斜不是错误。共模要最大化的是减去基准 0.5V 之后的偏差的绝对值。
分别判定共模与接收时间
assess(observed) 根据 metrics 的结果,返回如下对象:common_ok=(common_peak_v<=0.15),timing_ok=(received_ns 不是 None 且 <=4),meets_spec=(两个条件都为真)。包含边界值。不要把两个失败原因合并为一个而抹掉。
即使偏斜为 0,如果两者一起变晚,时间规范也会失败。未到达阈值是 None,而不是 0ns。
把两个电压的原始证据与模型比较
analyze(folder) 分析由 config.json 和 simulator.read_wave 读取的 wave.tsv。保留观测的 metrics 和 assess 结果,并把所有原始采样点的两个电压与 predict 比较,求出最大绝对误差 max_voltage_error。误差<=0.003 则 consistent,只有 consistent 和 meets_spec 都为真时才 passed。要包含参考中的所有返回键,并且 measured=False。即使不一致,也要保留观测值,且不修改原始文件。
如果给两个信号加上相同的偏移,差分不变,共模却会改变。不要只核验差分。
比较边沿与路径延迟之间的权衡
campaign(values,folder) 预先验证由 1–8 个无重复配置组成的整个 list,并创建新文件夹。用 simulator.capture(config,folder/case-NN) 生成原始数据后进行 analyze。NN 从 00 开始,如果结果 config 与请求不同,则为 ValueError。返回包含 results、所有 passed 的逻辑与 all_pass、model=independent_matched_lossless_lines、measured=False 的对象,并保存相同的 report.json。保留失败的条件和原始的四个文件,已有的文件夹即使为空也要拒绝。配置错误要在创建文件夹之前拒绝。
放慢边沿,共模偏差会减小,但时间余量也会减少。不要只留下好的结果。