简介这份资源面向电子通信、信号完整性分析与高速数字传输方向的学习者与工程师聚焦用Matlab绘制PAM4彩色眼图这一具体任务。PAM4在一个符号周期内传输四种幅度电平可提升速率但也更易受噪声与干扰影响眼图因此成为评估信号质量的关键手段。资源包共3个文件包含1个m脚本、1个mat数据文件和1个png结果图压缩包约7.84MB脚本负责读取信号、计算眼图并完成配色mat文件提供PAM4采样数据png则给出最终彩色眼图效果。核心思路是借助eyediagram函数生成眼图再结合jet色彩映射让不同幅度区间对应不同颜色从而更直观地观察眼高、眼宽、眼开口清晰度等指标判断信号强度与噪声水平。目前已有608人学习下载适合希望快速上手PAM4眼图可视化、理解信号质量评估流程的读者参考与复用。1. 从一条“糊成一团”的 PAM4 眼图说起如果你用 Matlab 画过 PAM4 眼图大概率经历过这个场景辛辛苦苦跑完仿真eyediagram一调用出来的图三条眼线糊成一团颜色单一、噪声边界看不清根本没法放进报告里。更麻烦的是PAM4 有三个眼开口传统 NRZ 那套单眼图的画法直接套过来电平判决门限和噪声容限完全对不上。这份资源就是冲着这个问题来的——它提供了一套用 Matlab 绘制彩色眼图的完整实现核心思路是把 PAM4 的三电平眼图按幅度区间分色渲染让每个眼开口的噪声分布和抖动情况一眼可辨。适合正在做高速 SerDes 仿真、信号完整性分析或者需要把眼图结果整理成技术文档的从业者。不管你是刚接触 PAM4 的新手还是已经能跑通链路仿真但卡在可视化环节的老手这套东西都能直接拿去改参数用。2. PAM4 眼图为什么不能照搬 NRZ 的画法2.1 三电平判决与眼开口的对应关系NRZ 只有高低两个电平一个眼开口判决门限就一个。PAM4 不一样它有四个电平-3、-1、1、3归一化后相邻电平之间形成三个眼开口。每个眼开口对应一个判决门限分别是 -2、0、2。这意味着你在看眼图的时候不能只盯着一个位置看得同时关注三个开口的张开程度。常见做法是先把仿真得到的 PAM4 波形按符号周期分段然后叠加到同一个时间窗口里。Matlab 的eyediagram函数本身支持多电平输入但它默认只画一条轨迹不会按电平区间分色。所以直接调用eyediagram得到的图三个眼开口的边界是混在一起的噪声大的区间和噪声小的区间颜色一样根本区分不出来。我一般会先把波形做归一化处理确保四个电平落在 -3 到 3 之间然后再做分段叠加。这一步很关键因为如果电平幅度没对齐后面分色的时候区间边界就会偏导致颜色错位。2.2 彩色渲染的核心逻辑按幅度区间映射颜色彩色眼图的本质是把叠加后的波形按瞬时幅度值映射到不同的颜色。具体来说对于 PAM4 信号我们可以定义三个幅度区间区间编号幅度范围对应眼开口建议颜色1-3 ~ -1下眼蓝色系2-1 ~ 1中眼绿色系31 ~ 3上眼红色系每个区间内的波形点用同一色系渲染色深可以反映该点的密度或者幅度偏离程度。这样画出来的眼图三个眼开口的颜色分明噪声大的地方颜色扩散明显抖动大的地方颜色边界模糊一眼就能看出哪个眼的质量最差。实现上不能用eyediagram直接出图得自己写叠加和渲染逻辑。基本步骤是先做符号同步把波形按符号周期切成段然后每段做时间对齐叠加到一个矩阵里最后用scatter或者imagesc按幅度区间上色。scatter更灵活可以控制每个点的颜色和透明度适合点密度不高的场景imagesc适合点很密的情况但颜色映射需要自己调。注意叠加的段数不是越多越好。段数太多图会糊段数太少噪声分布看不出来。一般建议叠加 200 到 500 段具体看你的信噪比和符号率。3. 用 Matlab 实现彩色眼图从波形到成图3.1 生成 PAM4 仿真波形在画眼图之前得先有波形。如果你已经有仿真数据可以跳过这一步。如果没有下面这段代码可以生成一个带噪声的 PAM4 基带信号方便后面做眼图验证。% 参数设置 Fs 100e9; % 采样率 100 GHz Rs 25e9; % 符号率 25 GBaud N 2000; % 符号数 SNR_dB 20; % 信噪比 % 生成 PAM4 符号 levels [-3, -1, 1, 3]; symbols levels(randi([1,4], N, 1)); % 上采样 sps Fs / Rs; % 每符号采样点数 waveform repelem(symbols, sps); % 加高斯白噪声 waveform awgn(waveform, SNR_dB, measured); % 简单低通滤波模拟信道带宽限制 h fir1(20, 0.5); waveform filter(h, 1, waveform);这段代码的逻辑很直接先随机生成 PAM4 符号然后上采样到采样率再加噪声和滤波。sps是每符号采样点数决定了眼图的时间分辨率。SNR_dB控制噪声大小20 dB 是一个比较典型的场景眼图不会太干净也不会完全糊掉。滤波器的截止频率设成 0.5 倍符号率模拟一个带宽受限的信道。参数怎么改如果你的符号率更高比如 50 GBaud把Rs改掉sps会自动算。N建议至少 1000不然叠加段数不够眼图看起来会稀疏。SNR_dB可以调到 15 以下看看噪声大的时候彩色渲染的效果这时候颜色扩散会很明显。3.2 符号同步与波形分段叠加有了波形之后下一步是做符号同步找到每个符号周期的起始点然后按周期切段叠加。实际仿真里符号同步可能是个麻烦事但如果你是自己生成的波形同步点其实是已知的。下面这段代码假设同步已经做好直接做分段叠加。% 符号同步假设已知起始偏移 offset 10; % 起始偏移根据实际情况调整 sps Fs / Rs; num_symbols floor((length(waveform) - offset) / sps); % 分段叠加矩阵 segments zeros(num_symbols, sps); for k 1:num_symbols idx_start offset (k-1)*sps 1; idx_end idx_start sps - 1; segments(k, :) waveform(idx_start:idx_end); end % 时间轴 t (0:sps-1) / Fs * 1e12; % 单位 ps这里的关键是offset它决定了从哪个采样点开始切第一个符号。如果偏移不对叠加出来的眼图会歪眼开口张不开。实际项目中我一般会用互相关或者早迟门做符号同步但那是另一个话题了。segments矩阵的每一行是一个符号周期的波形行数就是叠加段数。t是时间轴单位换算成皮秒方便后面画图。PAM4 的符号周期一般在几十皮秒量级所以用皮秒做单位比较直观。3.3 按幅度区间分色渲染到了最关键的一步把叠加后的波形按幅度区间上色。下面这段代码用scatter实现每个点根据幅度值分配颜色。figure; hold on; grid on; % 定义三个幅度区间和对应颜色 ranges [-3, -1; -1, 1; 1, 3]; colors [0.2, 0.4, 0.9; % 蓝色系 0.2, 0.8, 0.3; % 绿色系 0.9, 0.3, 0.2]; % 红色系 % 逐区间渲染 for r 1:3 mask segments ranges(r,1) segments ranges(r,2); [row, col] find(mask); x t(col); y segments(sub2ind(size(segments), row, col)); scatter(x, y, 1, colors(r,:), filled, MarkerFaceAlpha, 0.1); end xlabel(时间 (ps)); ylabel(幅度); title(PAM4 彩色眼图); xlim([0, t(end)]); ylim([-3.5, 3.5]);这段代码的逻辑是对每个幅度区间找出落在该区间内的所有波形点然后用对应颜色画散点。MarkerFaceAlpha设成 0.1 是为了让重叠的点累积出密度感点越密的地方颜色越深。三个区间分别用蓝、绿、红眼图上的三个开口就分得很清楚。参数怎么调MarkerFaceAlpha控制透明度值越小越透明适合叠加段数多的情况值越大越不透明适合段数少的情况。scatter的第三个参数是点的大小设成 1 是为了让点尽量小避免糊成一片。如果你的采样率很高sps很大点会很多可以考虑用imagesc替代scatter但颜色映射要自己写。提示如果发现某个区间的颜色特别淡说明该区间的波形点比较少可能是噪声把电平推到了区间边界之外。这时候可以检查一下信号幅度是否归一化到位。4. 避坑与排查彩色眼图常见的五个翻车点4.1 眼图糊成一团三个开口分不开现象画出来的图三个眼开口的颜色混在一起看不出边界。原因最常见的原因是符号同步没做好叠加的时候每个段的时间起点没对齐导致波形在时间轴上散开。另一个可能是噪声太大电平已经越过了区间边界分色逻辑失效。解决先检查offset是否准确可以用互相关找同步点。如果是噪声问题把SNR_dB调高到 25 以上看看眼图是否清晰确认是噪声导致的再考虑加均衡或者滤波。4.2 颜色区间边界处出现明显断层现象在 -1、1 这些区间边界附近颜色突然从蓝变绿或者从绿变红看起来像一条硬线。原因分色的时候用的是硬边界segments ranges(r,1) segments ranges(r,2)这种条件在边界处是突变的。如果波形点刚好落在边界上颜色就会跳变。解决可以在边界处做颜色插值或者把区间稍微重叠一点。我一般会把区间边界往外扩 0.1让相邻区间有少量重叠颜色过渡会自然一些。4.3 叠加段数太多导致图太糊现象眼图看起来像一团颜料密度感太强反而看不清眼开口的形状。原因叠加段数过多每个时间点上的点太密scatter的透明度累积后颜色饱和细节丢失。解决减少叠加段数或者降低MarkerFaceAlpha。一般 200 到 300 段就够了再多的话用imagesc做密度图更合适。4.4 时间轴单位不对眼图宽度看起来怪现象眼图的横轴范围跟符号周期对不上眼开口要么太窄要么太宽。原因t的计算用了Fs但如果Fs和Rs的关系没搞对sps就不是整数分段的时候会出问题。解决确保Fs是Rs的整数倍sps取整。如果sps不是整数要么调整Fs要么做重采样。4.5 颜色映射不直观分不清哪个眼是哪个现象三个眼开口的颜色虽然不同但看的时候还是得对照图例才能分清上下眼。原因颜色选择没有跟幅度顺序对应比如上眼用了蓝色下眼用了红色视觉上容易混淆。解决按幅度从低到高分配冷色到暖色比如下眼蓝、中眼绿、上眼红。这样一看颜色就知道是哪个电平区间不用查图例。5. 进阶技巧用密度热力图替代散点渲染散点渲染在叠加段数不多的时候效果不错但段数一多点重叠严重颜色饱和后反而看不清密度分布。这时候可以用密度热力图替代核心思路是把时间-幅度平面划分成网格统计每个网格内的点数然后用imagesc或者pcolor渲染。% 密度热力图 num_bins_t 200; % 时间轴分箱数 num_bins_a 100; % 幅度轴分箱数 % 统计每个网格的点数 [N, ~, ~] histcounts2(segments(:), repmat(t, size(segments,1), 1), ... num_bins_a, num_bins_t); % 渲染 figure; imagesc(t, linspace(-3.5, 3.5, num_bins_a), N); colormap(jet); colorbar; xlabel(时间 (ps)); ylabel(幅度); title(PAM4 密度热力图);这段代码用histcounts2做二维直方图统计N是每个网格的点数。imagesc把N渲染成热力图颜色越暖表示密度越高。num_bins_t和num_bins_a控制分辨率值越大越精细但计算量也越大。一般num_bins_t取 200 到 500num_bins_a取 100 到 200 就够了。跟散点渲染比密度热力图的优势是密度信息更准确不会因为透明度累积而饱和。缺点是颜色映射是连续的三个眼开口的边界不如分色散点那么分明。我一般会两种图都画散点图看边界热力图看密度分布。还有一个技巧是在热力图基础上叠加等高线把眼开口的轮廓勾出来。用contour函数选几个密度阈值画出来的线就是眼图的轮廓线。这样既有密度信息又有清晰的边界。从那以后我每次画 PAM4 眼图都会先跑一遍散点分色确认三个眼开口的位置和噪声分布再跑一遍密度热力图看细节。两套图对照着看基本不会漏掉问题。希望帮到你。本文还有配套的精品资源点击获取