引脚电容造成的带宽损失
目标
从集总参数 RC 电路的真实 AC 响应中,提取相对带宽和相位,并比较六个条件。
需要具备 Python 函数、复数、列表、JSON、分压的基础。预计需要 80 分钟,所以请在默认的 60 分钟结束之前,用“+时间”延长(最多 180 分钟)。会话结束后文件会消失,所以请另行保存。
为什么重要
学习只用电阻来看待输入引脚负载时,会漏掉的频率依赖性。要分别区分绝对电压分压与相对于通带的衰减、幅度与相位、运行成功与规范通过。这是理想的集总参数 RC 模型,不能代替长传输线、非线性引脚、实物测量和总线规范认证。
步骤
- 所有实现都保存到 /root/pin-bandwidth/analyze.py 中。predict(config) 返回 dc_gain、rth_ohm、pole_hz。配置是恰好包含 source_ohm=10/25/50、load_ohm=50/100、cap_pf=10/20/40 各取其一的三个键的 dict。只接受数字 int/float,bool、字符串、缺失、多余的键、超出范围的值都是 ValueError。不要修改原始数据。请计算 DC 分压、并联等效电阻和 1/(2πRthC)。
- read_response(path) 读取表头为 frequency hre him、以空白分隔的文件,返回 (Hz,实部,虚部) 元组列表。检查是否为 1MiB 以下的普通文件、数据至少 2 行、每行有 3 个有限数字、频率为正且严格递增,违反则以 ValueError 拒绝。不要转换为秒或 MHz。允许表头前后有空白。
- metrics(rows) 接收有效的 (Hz,实部,虚部) 列表,返回每行的 hz、magnitude、db、phase_deg 对象列表。幅度是复数的绝对值,db 是 20log10(幅度),相位是 atan2 的度数,范围为 −180 到 180 度。幅度为 0 是 ValueError。请保留所有输入行及其顺序。
- bandwidth(points,dc_gain) 接收有效的 metrics 结果和正的 DC 增益。阈值是 20log10(dc_gain)−10log10(2)。在满足 a.db > 阈值 >= b.db 的第一个相邻区间中,对 dB 与 log10(Hz) 做线性插值并返回 Hz。没有穿越则为 None,一开始就在阈值以下的情形不视为穿越。
- at_frequency(rows,hz) 从有效的复数响应表中返回 hz 处的 complex 值。如果恰好是采样点就用该值,如果位于两点之间,则按 log(频率) 轴上的比例,对实部和虚部分别做线性插值。超出表的范围则为 ValueError。这不是分别对幅度或相位插值的函数。
- analyze(folder) 读取 config.json 和 response.tsv,返回下面参考中的结果对象。检查完整的 161 行、1MHz 到 10GHz、每十倍频程 40 点的网格,不足或不同则为 ValueError(频率相对误差 1e-9)。带宽、100MHz 处的相对增益和相位从表中求得,并把所有复数采样点与 H0/(1+jf/fc) 比较。即使模型不一致,也要保留观测值。
- campaign(values,folder) 用 predict 验证由 1–18 个无重复配置组成的整个 list 之后,创建新文件夹。用提供的 simulator.capture(config,folder/case-NN) 运行各个条件并 analyze。NN 按输入顺序从 00 开始,如果观测到的 config 与请求不同,则为 ValueError。返回 results 列表、表示所有 passed 是否都为 True 的 all_pass、model=lumped_rc、measured=False,并把相同的对象保存到 report.json。已有的文件夹即使为空也要拒绝。配置错误时也不创建文件夹。
参考
实现路径是 /root/pin-bandwidth/analyze.py。不需要联网、额外的软件包或设备。提供的辅助程序 /opt/lab/fixtures/pin_bandwidth/simulator.py 只负责生成电路和运行真实的 ngspice。向 Rs 串联、RL 与 C 并联的电路输入 AC 1V,在 1MHz 到 10GHz 范围内每十倍频程取 40 点来计算。capture(config,新文件夹) 返回 Path,不会覆盖已有结果。输入 C 的单位是 pF。
第 6 步的返回键是 config、bandwidth_hz、relative_db、phase_deg、max_complex_error、consistent、meets_spec、passed、measured。relative_db 是 100MHz 处的 20log10(|H|/H0),phase_deg 是相同插值 H 的相位。max_complex_error 是所有行的观测 H 与模型 H 之差绝对值的最大值。只有当这个误差在 1e-8 以下、观测带宽存在,并且相对于预测的 fc 的误差在 0.2% 以下时,consistent 才为 True。meets_spec 在观测带宽不低于 200MHz、relative_db 不低于 −0.5dB、phase_deg 不低于 −20 度同时成立时为 True。passed 表示 consistent 和 meets_spec 是否都为 True,measured 为 False。如果没有穿越,带宽为 None,那么 consistent、meets_spec、passed 为 False。但不要丢弃观测本身。
完成第 7 步的实现之后,请用下面的命令运行源电阻 25/50Ω × C 10/20/40pF、负载 50Ω 的六个条件。因为包含失败的条件,所以正常报告的 all_pass 为 False。重新运行时,请使用新的输出文件夹名称。
cd /root/pin-bandwidth
PYTHONPATH=/opt/lab/fixtures/pin_bandwidth python3 - <<'PY'
from analyze import campaign
conditions = [dict(source_ohm=r, load_ohm=50, cap_pf=c) for r in (25,50) for c in (10,20,40)]
report = campaign(conditions, '/root/pin-bandwidth/run-01')
print(report)
PY
源代码必须是 64KiB 以下的普通文件,并且在 import 时不输出任何内容。波形和配置只能读取。评分使用另外的小采样点和真实引擎,一般数值容差为相对和绝对 1e-8。评分进程的上限是 CPU 12 秒、输出文件 8MiB、总计 35 秒,这与学习时间不同。
预测分压与极点
所有实现都保存到 /root/pin-bandwidth/analyze.py 中。predict(config) 返回 dc_gain、rth_ohm、pole_hz。配置是恰好包含 source_ohm=10/25/50、load_ohm=50/100、cap_pf=10/20/40 各取其一的三个键的 dict。只接受数字 int/float,bool、字符串、缺失、多余的键、超出范围的值都是 ValueError。不要修改原始数据。请计算 DC 分压、并联等效电阻和 1/(2πRthC)。
请把 pF 换算成 F,并思考把电压源置零之后,电容看到的两个电阻。
读取复数响应表
read_response(path) 读取表头为 frequency hre him、以空白分隔的文件,返回 (Hz,实部,虚部) 元组列表。检查是否为 1MiB 以下的普通文件、数据至少 2 行、每行有 3 个有限数字、频率为正且严格递增,违反则以 ValueError 拒绝。不要转换为秒或 MHz。允许表头前后有空白。
相邻两行频率相同的情形也要拒绝。分析不会修改原始文件。
分离幅度与相位
metrics(rows) 接收有效的 (Hz,实部,虚部) 列表,返回每行的 hz、magnitude、db、phase_deg 对象列表。幅度是复数的绝对值,db 是 20log10(幅度),相位是 atan2 的度数,范围为 −180 到 180 度。幅度为 0 是 ValueError。请保留所有输入行及其顺序。
实部不等于幅度。请用手算确认 3+4j 的幅度,以及负实部、负虚部所在的象限。
找出相对半功率频率
bandwidth(points,dc_gain) 接收有效的 metrics 结果和正的 DC 增益。阈值是 20log10(dc_gain)−10log10(2)。在满足 a.db > 阈值 >= b.db 的第一个相邻区间中,对 dB 与 log10(Hz) 做线性插值并返回 Hz。没有穿越则为 None,一开始就在阈值以下的情形不视为穿越。
不是绝对的 −3dB。在 1MHz 与 100MHz 之间,如果 dB 之差是一半,则频率为 10MHz。
在同一频率比较复数
at_frequency(rows,hz) 从有效的复数响应表中返回 hz 处的 complex 值。如果恰好是采样点就用该值,如果位于两点之间,则按 log(频率) 轴上的比例,对实部和虚部分别做线性插值。超出表的范围则为 ValueError。这不是分别对幅度或相位插值的函数。
先求出对数轴上的位置比例,再在两个复数之间移动。两个端点不属于外推。
分别验证观测与规范
analyze(folder) 读取 config.json 和 response.tsv,返回下面参考中的结果对象。检查完整的 161 行、1MHz 到 10GHz、每十倍频程 40 点的网格,不足或不同则为 ValueError(频率相对误差 1e-9)。带宽、100MHz 处的相对增益和相位从表中求得,并把所有复数采样点与 H0/(1+jf/fc) 比较。即使模型不一致,也要保留观测值。
要抓住幅度相同但相位错误的情形,必须比较复数之差的绝对值。请把规范判定与模型一致分开。
保存六个条件的依据
campaign(values,folder) 用 predict 验证由 1–18 个无重复配置组成的整个 list 之后,创建新文件夹。用提供的 simulator.capture(config,folder/case-NN) 运行各个条件并 analyze。NN 按输入顺序从 00 开始,如果观测到的 config 与请求不同,则为 ValueError。返回 results 列表、表示所有 passed 是否都为 True 的 all_pass、model=lumped_rc、measured=False,并把相同的对象保存到 report.json。已有的文件夹即使为空也要拒绝。配置错误时也不创建文件夹。
失败的条件也要留在 results 中。不要删除 capture 生成的 config.json、circuit.cir、response.tsv、ngspice.log。