ADCToolbox 算法概览
最后更新: 2025-12-03
简介
本文档介绍 ADCToolbox 中 MATLAB 算法的工作原理与架构设计。工具箱经过优化,注重执行效率、可维护性和统一的输出格式。
工具集架构
设计原则
关注点分离:工具执行与面板生成为独立函数
数据驱动执行:以数据结构定义工具列表,消除重复代码
自动检测:面板函数根据命名规范自动定位图表文件
统一格式:所有工具使用标准化的图形属性和输出
文件组织
matlab/src/
├── toolset_aout.m # 9 analog analysis tools
├── toolset_aout_panel.m # Combine AOUT plots into 3×3 panel
├── toolset_dout.m # 6 digital analysis tools
├── toolset_dout_panel.m # Combine DOUT plots into 3×2 panel
└── [individual tool functions]
toolset_aout:模拟输出分析
文件:
MATLAB:
matlab/src/toolset_aout.mPython:
python/src/adctoolbox/toolset_aout.py
功能说明
对校准后的 ADC 模拟输出数据(正弦波)执行 9 个诊断工具,涵盖时域、频域和统计误差分析。
算法流程
1. Parse inputs (aout_data, outputDir, optional parameters)
2. Create output directory if needed
3. Pre-compute common parameters:
- freqCal = findfreq(aout_data) % Auto-detect input frequency
- FullScale = max(aout_data) - min(aout_data)
- err_data = aout_data - sinfit(aout_data) % Error signal
4. For each tool i = 1:9:
- Create figure (800×600, visible/hidden)
- Execute tool function with pre-computed params
- Format (title, font size 14)
- Save PNG: <prefix>_<i>_<toolname>.png
- Close figure
- Print progress message
5. Return cell array of 9 file paths
工具执行模式
每个工具遵循标准化执行模式:
fprintf('[%d/9] toolname');
figure('Position', [100, 100, 800, 600], 'Visible', opts.Visible);
tool_function(params...);
title('Tool Name');
set(gca, 'FontSize', 14);
plot_files{i} = fullfile(outputDir, sprintf('%s_%d_toolname.png', opts.Prefix, i));
saveas(gcf, plot_files{i});
close(gcf);
fprintf(' -> %s\n', plot_files{i});
执行的工具
# |
工具 |
关键参数 |
|---|---|---|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
主要特点
预计算:耗时运算(频率检测、正弦拟合)只计算一次并复用
内存管理:图形保存后立即关闭,防止内存积累
快速失败:首次出错即停止执行(使用
try-catch实现容错执行)标准化输出:所有图表具有统一的尺寸和格式
toolset_dout:数字输出分析
文件:
MATLAB:
matlab/src/toolset_dout.mPython:
python/src/adctoolbox/toolset_dout.py
功能说明
对 ADC 数字位输出(适用于 SAR ADC 和位权重架构)执行 6 个诊断工具,包括校准、权重分析和性能评估。
算法流程
1. Parse inputs (bits, outputDir, optional parameters)
2. Create output directory if needed
3. Extract resolution: nBits = size(bits, 2)
4. Calibrate bit weights:
[w_cal, ~, ~, ~, ~, f_cal] = wcalsine(bits, 'freq', 0, 'order', Order, 'verbose', 0)
5. Pre-compute digital codes:
- digitalCodes = bits * (2.^(nBits-1:-1:0))' % Nominal binary weights
- digitalCodes_cal = bits * w_cal' % Calibrated weights
6. Define tool execution table (struct array with 6 entries)
7. For each tool i = 1:6:
- Create figure (variable size, visible/hidden)
- Execute tool function handle from struct
- Format (title, font size 14)
- Save PNG with exportgraphics (150 DPI)
- Close figure
- Print progress message
8. Return cell array of 6 file paths
数据驱动的工具执行
与旧式重复代码不同,工具定义为结构体数组:
tools = {
struct('idx', 1, 'name', 'Spectrum (Nominal)', 'suffix', '1_spectrum_nominal', ...
'pos', [100, 100, 800, 600], ...
'fn', @() plotspec(digitalCodes, 'label', 1, 'harmonic', 5, 'OSR', 1, 'window', @hann));
struct('idx', 2, 'name', 'Spectrum (Calibrated)', 'suffix', '2_spectrum_calibrated', ...
'pos', [100, 100, 800, 600], ...
'fn', @() plotspec(digitalCodes_cal, 'label', 1, 'harmonic', 5, 'OSR', 1, 'window', @hann));
% ... 4 more tools
};
for i = 1:6
fprintf('[%d/6] %s', i, tools{i}.name);
figure('Position', tools{i}.pos, 'Visible', p.Results.Visible);
tools{i}.fn(); % Execute function handle
title(tools{i}.name);
set(gca, 'FontSize', 14);
plot_files{i} = fullfile(outputDir, sprintf('%s_%s.png', p.Results.Prefix, tools{i}.suffix));
exportgraphics(gcf, plot_files{i}, 'Resolution', 150);
close(gcf);
fprintf(' -> %s\n', plot_files{i});
end
数据驱动方式的优势:
代码精简:109 行 → 66 行(减少 40%)
一致性:格式控制集中于单一位置
可维护性:便于添加、删除或修改工具
可读性:工具属性在结构体定义中一目了然
执行的工具
# |
工具 |
功能说明 |
图形尺寸 |
|---|---|---|---|
1 |
|
校准前频谱 |
800×600 |
2 |
|
|
800×600 |
3 |
|
位翻转率分析 |
1000×750 |
4 |
|
溢出/冗余检查 |
1000×600 |
5 |
|
基数可视化 |
800×600 |
6 |
|
ENoB 与位数关系 |
800×600 |
面板函数
toolset_aout_panel
文件: matlab/src/toolset_aout_panel.m
将 9 个独立 AOUT 图表组合为 3×3 面板图。
算法
1. Parse inputs (outputDir, optional Prefix, PlotFiles, Visible)
2. If PlotFiles not provided:
- Auto-construct file paths: <outputDir>/<prefix>_<i>_<name>.png
3. Validate 9 files expected
4. Create 3×3 tiled layout figure (1800×1000)
5. For each plot i = 1:9:
- nexttile
- If file exists: imread, imshow, title
- Else: display "Missing" text in red
6. Add super title "AOUT Toolset Overview"
7. Export panel: PANEL_<PREFIX>.png (300 DPI)
8. Close figure
9. Return status struct (.success, .panel_path, .errors)
文件命名规范
自动检测的文件:
<prefix>_1_tomdec.png
<prefix>_2_plotspec.png
<prefix>_3_plotphase.png
<prefix>_4_errsin_code.png
<prefix>_5_errsin_phase.png
<prefix>_6_errPDF.png
<prefix>_7_errAutoCorrelation.png
<prefix>_8_errSpectrum.png
<prefix>_9_errEnvelopeSpectrum.png
toolset_dout_panel
文件: matlab/src/toolset_dout_panel.m
将 6 个独立 DOUT 图表组合为 3×2 面板图。
算法
与 toolset_aout_panel 相同,但以 3×2 布局排列 6 个图表(1200×1000)。
文件命名规范
自动检测的文件:
<prefix>_1_spectrum_nominal.png
<prefix>_2_spectrum_calibrated.png
<prefix>_3_bitActivity.png
<prefix>_4_overflowChk.png
<prefix>_5_weightScaling.png
<prefix>_6_ENoB_sweep.png
主要特点
自动检测:使用前缀查找文件,无需手动指定路径
灵活性:可通过显式
PlotFiles参数覆盖鲁棒性:优雅处理缺失文件(显示占位符)
可复用:无需重新运行工具即可重新生成面板
通用工具函数
findfreq
文件: matlab/src/findfreq.m
使用 FFT 从时域信号中自动检测正弦波频率。
算法:
计算输入信号的 FFT
在幅度频谱中查找峰值
将频率箱索引转换为归一化频率
返回频率(0 至 0.5,归一化至采样率)
sinfit
文件: matlab/src/sinfit.m
对数据进行四参数正弦拟合:A*sin(2πft + φ) + DC
算法:
使用
findfreq检测频率建立非线性最小二乘问题
优化幅度、频率、相位和直流偏置
返回拟合正弦波
命名规范
文件命名
单个工具输出:
<prefix>_<index>_<toolname>.png
示例:
aout_1_tomdec.pngdout_3_bitActivity.png
面板输出:
PANEL_<PREFIX>.png
示例:
PANEL_AOUT.pngPANEL_DOUT.png
变量命名
plot_files— PNG 文件路径的元胞数组outputDir— 输出文件目录freqCal— 校准/检测频率w_cal— 校准后的位权重digitalCodes— 数字输出码(标称权重)digitalCodes_cal— 数字输出码(校准权重)
性能优化
内存管理
图形保存后立即关闭
批处理时使用
'Visible', false(速度更快)预分配文件路径的元胞数组
计算效率
预计算:耗时操作(频率检测、正弦拟合、校准)只执行一次
数据驱动循环:消除重复代码
最小化磁盘 I/O:每个图表只保存一次
代码效率
重构前(重复代码):
% Tool 1
fprintf('[1/6] Tool1...');
f = figure('Visible', figVis, 'Position', [100, 100, 800, 600]);
tool1_function(params);
save_and_close(f, outputDir, opts.Prefix, '1_tool1', 'Tool 1');
% Tool 2
fprintf('[2/6] Tool2...');
f = figure('Visible', figVis, 'Position', [100, 100, 800, 600]);
tool2_function(params);
save_and_close(f, outputDir, opts.Prefix, '2_tool2', 'Tool 2');
% ... repeated 4 more times
重构后(数据驱动):
tools = {struct('name', 'Tool1', 'suffix', '1_tool1', 'pos', [100,100,800,600], 'fn', @() tool1_function(params)); ...};
for i = 1:6
fprintf('[%d/6] %s', i, tools{i}.name);
figure('Position', tools{i}.pos, 'Visible', figVis);
tools{i}.fn();
% ... standardized save
end
结果: 109 行 → 66 行(减少 40%)
使用模式
模式一:同时生成图表和面板
% AOUT
plot_files = toolset_aout(aout_data, 'output/test1');
panel_status = toolset_aout_panel('output/test1', 'Prefix', 'aout');
% DOUT
plot_files = toolset_dout(bits, 'output/test1');
panel_status = toolset_dout_panel('output/test1', 'Prefix', 'dout');
模式二:批量生成图表,然后汇总面板
% Generate all plots first
for i = 1:N
toolset_aout(data{i}, sprintf('output/run%d', i), 'Prefix', sprintf('run%d', i));
end
% Then generate all panels
for i = 1:N
toolset_aout_panel(sprintf('output/run%d', i), 'Prefix', sprintf('run%d', i));
end
模式三:仅重新生成面板(图表已存在)
% No need to re-run toolset - just regenerate panels
toolset_aout_panel('output/test1', 'Prefix', 'aout');
toolset_dout_panel('output/test2', 'Prefix', 'dout');
错误处理
当前行为
两个工具集均采用快速失败错误处理策略:
首次出错即停止执行
MATLAB 显示错误信息
可能保存部分结果
实现容错执行
若需在出错后继续执行,请将工具包装在 try-catch 中:
for i = 1:length(tools)
try
% ... tool execution
success(i) = true;
catch ME
fprintf(' ✗ %s\n', ME.message);
errors{end+1} = sprintf('Tool %d: %s', i, ME.message);
success(i) = false;
end
end
未来增强计划
计划功能
Python 面板函数:用 Python 实现
toolset_aout_panel和toolset_dout_panel并行执行:使用
parfor并行运行独立工具进度回调:可选的进度更新回调函数
自定义工具选择:允许用户指定要运行的工具
容错模式:出错后继续执行的选项
架构改进
工具注册表:所有可用工具的集中注册表
插件系统:便于添加自定义工具
配置文件:使用 YAML/JSON 配置工具参数
结果缓存:缓存耗时计算结果以供复用
参考文献
IEEE Std 1241-2010:ADC 测试方法标准
IEEE Std 1057-2017:数字化波形记录仪标准
MATLAB 文档:函数句柄、结构体数组、exportgraphics
版本历史
版本 |
日期 |
变更内容 |
|---|---|---|
2.0 |
2025-12-03 |
精简工具集,采用数据驱动执行,独立面板函数 |
1.0 |
2025-01-28 |
初始实现 |