【MATLAB源码】CSI-RS:测量链路

0 阅读7分钟

CSI-RS 测量链路

面向无线测量验证的 MATLAB 自研信号链平台

从资源生成到测量可视化,提供端到端可复现实验流程

【CSI-RS 测量】【OFDM 链路】【自研实现】【可复现实验】

📌 为什么选择

当前测量示例常依赖外部封装,定位问题与复现实验成本高。该工程将资源生成、收发链路与测量估计全部拆解为自研模块,便于逐步验证。文档与脚本保持同一参数口径,便于教学与工程协作。

痛点方案
外部黑盒依赖重自研核心模块打通完整测量链路
多资源顺序易错位统一 ResourceOrder 输出语义
相位扰动影响难量化提供可开关相位校正并输出对比结果
测量定义与实现脱节算法文档与代码文档对齐同一工程
演示风格不统一双入口脚本统一参数区与打印流程

🎯 核心价值

​​

🔬 学术研究价值

文档与实现保持同构,便于从理论到实验闭环复现。

  • 标准术语映射
  • Gold 序列建模
  • 多资源边界语义
  • 测量统计推导

💼 工程应用价值

模块职责明确,适合直接接入仿真流程与结果展示链路。

  • 统一函数接口
  • 无外部黑盒依赖
  • 一键演示脚本
  • 可追溯过程打印

⚡ 技术亮点

🌊 自研链路与传统黑盒流程对比

特性传统方案本方案
链路可见性关键步骤隐藏参数与中间量全程可追踪
资源顺序管理多资源顺序依赖隐式约定显式 ResourceOrder 输出
相位校正评估常为固定流程不可切换EnablePhaseCorrection 可开关
OFDM 参数透明度Nfft/CP/重采样细节难复核cm_ofdm_info 统一输出
文档一致性算法与代码分离算法文档与代码文档同目录对齐

📊 性能指标(实测数据)

数据来自同一配置下 EnablePhaseCorrection=false/true 对比实测输出。

场景基线本方案结论
资源 #0 RSRP-93.4906 dBm-91.6538 dBm提升 1.8368 dB
资源 #1 RSRP-91.5625 dBm-90.3371 dBm提升 1.2254 dB
资源 #0 RSRQ-11.0844 dB-9.2476 dB提升 1.8368 dB
资源 #1 RSRQ-9.4125 dB-8.1871 dB提升 1.2254 dB

🎯 测量稳定性专项能力

项目内置扫描与统计视图,支持单次链路与批量统计联合分析。关键配置与输出维度固定,便于横向对比不同参数组。

参数配置性能
SINR 扫描范围-6:2:12 dB10 个扫描点稳定输出三指标曲线
Monte Carlo 次数80 次可输出 RSRP/RSSI/RSRQ 分布箱线图
OFDM 频域规模Nfft=1024扫描与统计流程可重复复现

🖥️ 运行环境

工程使用 MATLAB 脚本与函数组织,默认参数可直接运行。主链路不依赖测试目录,适合在单工程目录独立执行。

  • 语言:MATLAB(R2025b 实测)
  • 依赖:MATLAB 基础数值库与信号处理常用函数
  • 硬件:通用 CPU 工作站(Windows 10/11)

📁 项目结构

csirs_measure/
 ├── src/                           # 核心源码目录
 │   ├── core/                      # 载波、OFDM、序列与资源网格基础模块
 │   ├── csirs/                     # CSI-RS 索引、符号与测量模块
 │   └── viz/                       # 统一风格可视化模块
 ├── docs/                          # 文档目录
 │   ├── 算法文档.md               # 算法原理、公式推导与标准化说明
 │   └── 代码文档.md               # 代码结构、接口、调用关系与形状说明
 └── 根目录脚本                     # 演示入口与路径初始化
     ├── cm_run_demo.m             # 单次完整链路演示
     └── cm_run_advanced_viz.m     # 三类高级图生成入口

📄 文档体系

文档体系围绕“原理可解释 + 代码可执行”组织,算法与实现在同目录维护,便于交叉查阅。

📘 算法文档

位置:docs/算法文档.md,覆盖标准映射、公式推导、测量定义与一致性判据。

算法文档目录(docs/算法文档.md)
 1. 文档定位
 2. 标准映射与术语框架
 3. 系统与配置参数模型
 4. 时频网格与线性索引
 5. CSI-RS 调度与资源启停判决
 6. CSI-RS 资源位置生成
 7. 参考信号符号构造
 8. OFDM 参数统一建模
 9. OFDM 调制与解调的数学流程
 10. 测量量定义、推导与统计解释
 11. 多资源排序与一致性语义
 12. 噪声建模与功率标定
 13. 边界条件与失效模式
 14. 复杂度与实现代价
 15. 一致性核查清单(标准化验收)
 16. 结论

📒 代码文档

位置:docs/代码文档.md,覆盖模块职责、函数输入输出、调用关系与运行方式。

代码文档目录(docs/代码文档.md)
 1. 文档目的
 2. 工程目录结构
 3. 端到端处理链路
 4. 核心数据结构
 5. 入口脚本详解
 6. src/core 模块详解
 7. src/csirs 模块详解
 8. src/viz 模块详解
 9. 模块调用关系
 10. 输入输出形状速查
 11. 参数与默认行为速查
 12. 运行方式
 13. 文档总结

💻 核心代码展示

🔥 CSI-RS 资源索引生成(真实代码)

该片段展示多资源索引生成主干:参数展开、逐资源计算、ResourceOrder 重排与输出格式控制。

function [ind, info] = cm_generate_csirs_indices(carrier, csirs_cfg, varargin)
     outFmt = 'linear';
     if ~isempty(varargin)
         assert(mod(numel(varargin), 2) == 0, 'cm_generate_csirs_indices:invalidArgs', '可选参数必须成对出现');
         i = 1;
         while i <= numel(varargin)
             key = validatestring(varargin{i}, {'OutputResourceFormat'}, mfilename);
             val = varargin{i + 1};
             switch key
                 case 'OutputResourceFormat'
                     outFmt = validatestring(val, {'linear','cell'}, mfilename, 'OutputResourceFormat');
             end
             i = i + 2;
         end
     end
 ​
     carrier = to_carrier_struct(carrier);
     resCfg = normalize_resource_configs(csirs_cfg);
     nRes = numel(resCfg);indPerResource = cell(1, nRes);
     info.KBarLBar = cell(1, nRes);
     info.CDMGroupIndices = cell(1, nRes);
     info.KPrime = cell(1, nRes);
     info.LPrime = cell(1, nRes);
 ​
     % 先按输入资源顺序生成
     for ri = 1:nRes
         [indSingle, infoSingle] = generate_single_indices(carrier, resCfg{ri});
         indPerResource{ri} = indSingle;
         info.KBarLBar{ri} = infoSingle.KBarLBar{1};
         info.CDMGroupIndices{ri} = infoSingle.CDMGroupIndices{1};
         info.KPrime{ri} = infoSingle.KPrime{1};
         info.LPrime{ri} = infoSingle.LPrime{1};
     end
 ​
     % 再按 ZP 优先顺序输出
     resourceOrder = get_resource_order(resCfg);
     indCell = indPerResource(resourceOrder);
     info.ResourceOrder = resourceOrder;
 ​
     if strcmpi(outFmt, 'cell')
         ind = indCell;
     else
         ind = vertcat(indCell{:});
         if isempty(ind)
             ind = uint32(zeros(0,1));
         end
     end
 end

🌟 CSI-RS 符号生成与 CDM 加权(真实代码)

该片段展示符号生成核心路径:调度判定、cinit 构造、PRBS 调制与 CDM 权重展开。

for ui = 1:numel(uniqueGroups)
     gi = find(cdmGroupIdx == uniqueGroups(ui), 1);
     kbar = kbar_lbar{gi}(1);
     lbar = kbar_lbar{gi}(2);
     l = lbar + lprime;
 ​
     cinit = mod(2^10 * (symPerSlot * relSlot + l + 1) * (2 * nid + 1) + nid, 2^31);
 ​
     if rho == 3
         mPrime = floor(crbSet * alpha) + kprime(1) + floor((kbar + [0;4;8]) * rho / 12);
     else
         mPrime = floor(crbSet * alpha) + kprime(:) + floor(kbar * rho / 12);
     end
 ​
     numModSym = max(mPrime(:)) + 1;
     r = complex(zeros(numModSym, numel(l)));
     for si = 1:numel(l)
         c = cm_prbs_gold(cinit(si), 2 * numModSym);
         c = reshape(double(c), 2, []).';
         r(:, si) = (1 / sqrt(2)) * complex(1 - 2 * c(:,1), 1 - 2 * c(:,2));
     end
 ​
     rMPrime = repmat(r(mPrime + 1, :), 1, L);
 ​
     wfWtMat = [];
     for s = 1:L
         wfWtMat = [wfWtMat, wfWt{s}]; %#ok<AGROW>
     end
 ​
     weighted = repmat(wfWtMat, size(rMPrime,1) / size(wfWtMat,1), 1) .* rMPrime;
     sym = [sym; weighted(:)]; %#ok<AGROW>
 end

🚀 测量估计与相位校正(真实代码)

该片段展示测量主干:RSRP/RSSI/RSRQ 计算与可选相位校正路径。

for rxIdx = 1:numRx
     gridRx = grid(:, :, rxIdx);
 ​
     if opts.EnablePhaseCorrection
         gridRx = apply_phase_correction(gridRx, refIndPerResource, refSymPerResource, ...
             csirsSymbolIndices, numSubcarriers, rePerPort);
     end
 ​
     rxSym = reshape(gridRx(refInd), [], 1);
     rsrpLin = abs(mean(rxSym .* conj(refSym)) * portsUsed)^2;
     meas.RSRPPerAntenna(rxIdx, resIdx) = rsrpLin;
 ​
     % RSSI: 取 CSI-RS 所在符号中测量带宽内全部 RE 功率
     numCSIRSSym = numel(csirsSymbolIndices);
     rssiInd = repmat((1:nRB * 12).' + rbOffset * 12, 1, numCSIRSSym) + ...
         repmat((csirsSymbolIndices - 1) * numSubcarriers, nRB * 12, 1);
     rssiSym = gridRx(rssiInd);
     rssiLin = sum(abs(rssiSym(:)).^2) / numCSIRSSym;
     meas.RSSIPerAntenna(rxIdx, resIdx) = rssiLin;
 ​
     meas.RSRQPerAntenna(rxIdx, resIdx) = nRB * rsrpLin / rssiLin;
 end
 ​
 meas.RSRPPerAntenna(isnan(meas.RSRPPerAntenna)) = 0;
 meas.RSSIPerAntenna(isnan(meas.RSSIPerAntenna)) = 0;
 meas.RSRQPerAntenna(isnan(meas.RSRQPerAntenna)) = 0;
 ​
 meas.RSRPPerAntenna = 10 * log10(meas.RSRPPerAntenna) + 30;
 meas.RSSIPerAntenna = 10 * log10(meas.RSSIPerAntenna) + 30;
 meas.RSRQPerAntenna = 10 * log10(meas.RSRQPerAntenna);

🎬 一键运行

startup_cm;
 run('cm_run_demo.m');
 run('cm_run_advanced_viz.m');

结果预览

单次演示可直接输出两资源 RSRP/RSSI/RSRQ,扫描与统计演示可输出 SINR 曲线与 Monte Carlo 分布。当前默认高级演示配置为 Nfft=1024、扫描点数 10、试验次数 80

图示说明:图 1 为时频功率底图叠加资源位置,图 2 为三指标 SINR 扫描曲线,图 3 为三指标 Monte Carlo 分布。

📸 演示图片预览

以下为当前工程建议展示的图示主题。

  • 时频功率底图与 CSI-RS 位置叠加
  • SINR 扫描下 RSRP 变化曲线
  • SINR 扫描下 RSSI 变化曲线
  • SINR 扫描下 RSRQ 变化曲线
  • Monte Carlo 下三指标分布箱线图

CSI-RS 资源网格.pngCSI-RS 测量结果.png图 1  时频功率与 CSI-RS 位置.png图 3  SINR 扫描性能曲线.png图 4  Monte Carlo 分布图.png

🛒 获取方式

本文代码仅为核心片段,完整版工程已整理好。 关注公众号 【3GPP 仿真实验室】进行获取。

📚 参考文献

  1. 3GPP TS 38.211, NR; Physical channels and modulation.
  2. 3GPP TS 38.214, NR; Physical layer procedures for data.
  3. 3GPP TS 38.215, NR; Physical layer measurements.
  4. Andreas F. Molisch, Wireless Communications, 2nd Edition, Wiley, 2011.
  5. John G. Proakis, Digital Communications, 5th Edition, McGraw-Hill, 2007.