告别理论!用Python+Matplotlib一步步画出NR PDSCH交织映射图(附代码)

张开发
2026/4/15 14:07:26 15 分钟阅读

分享文章

告别理论!用Python+Matplotlib一步步画出NR PDSCH交织映射图(附代码)
用PythonMatplotlib实战解析5G NR PDSCH交织映射的可视化实现当5G NR物理层协议文档中那些晦涩的公式和抽象描述让你望而却步时不妨换个思路——用代码将理论转化为直观的图形。本文将带你用Python和Matplotlib一步步实现VRB到PRB交织映射的可视化让枯燥的协议条文变成跃然屏上的彩色图表。1. 理解VRB与PRB映射的核心概念在开始编码之前我们需要明确几个关键术语VRB(Virtual Resource Block): 虚拟资源块是逻辑上的资源分配单元PRB(Physical Resource Block): 物理资源块实际用于数据传输的物理资源交织映射(Interleaved Mapping): 一种将VRB分散映射到PRB的技术目的是获得频率分集增益传统学习方式往往停留在理论公式的推导上而我们将采用代码即文档的方法通过可运行的Python脚本来验证每一个协议细节。这种实践方式不仅能加深理解还能随时调整参数观察不同配置下的映射效果。提示本文所有代码示例均基于3GPP 38.211协议中第7.3.1.6节定义的VRB到PRB交织映射规则2. 环境准备与基础配置2.1 安装必要的Python库确保你的Python环境(建议3.8)已安装以下库pip install numpy matplotlib2.2 初始化映射参数我们先定义一组基础参数模拟一个典型的NR部署场景import numpy as np # BWP配置参数 bwp_size 100 # BWP总RB数 bwp_offset 10 # BWP起始RB偏移 bundle_size 2 # Bundle大小(L) # PDSCH配置参数 pdsch_size 60 # PDSCH分配的RB数 pdsch_offset 5 # PDSCH起始RB偏移这些参数对应协议中常见的配置场景后续我们将通过调整这些值来观察不同配置下的映射行为。3. 实现VRB到PRB的交织映射算法3.1 Bundle划分计算根据协议首先需要将VRB划分为多个Bundle。每个Bundle包含的VRB数量可能不同def calculate_bundles(bwp_size, bwp_offset, bundle_size): # 计算总Bundle数 C (bwp_size bundle_size - 1) // bundle_size # 初始化Bundle列表 bundles [] remaining_rbs bwp_size # 分配每个Bundle的VRB范围 for i in range(C): if i 0 or i C-1: current_size 1 if remaining_rbs % bundle_size ! 0 else bundle_size else: current_size bundle_size start i * bundle_size end start current_size bundles.append((start, end)) remaining_rbs - current_size return bundles3.2 交织映射核心算法实现协议规定的交织公式是本文的核心以下是Python实现def interleaved_mapping(bundles, bwp_size, bwp_offset, bundle_size): C len(bundles) prb_map {} # 计算中间变量R R 2 # 对于PDSCH交织R固定为2 for bundle_idx, (start_vrb, end_vrb) in enumerate(bundles): for vrb in range(start_vrb, end_vrb): # 计算j、c、r参数 j bundle_idx 1 c (j % R) * C // R r j // R # 计算映射后的PRB bundle索引 prb_bundle r * (C // R) c # 转换为实际PRB索引 if prb_bundle len(bundles): prb_start, prb_end bundles[prb_bundle] prb prb_start (vrb - start_vrb) prb_map[vrb] prb return prb_map4. 可视化映射结果4.1 绘制VRB-PRB映射关系图使用Matplotlib创建直观的映射关系图import matplotlib.pyplot as plt from matplotlib.patches import Rectangle def plot_mapping(bundles, prb_map, bwp_size, pdsch_offset, pdsch_size): fig, (ax1, ax2) plt.subplots(2, 1, figsize(12, 8)) # 绘制VRB分布 for i, (start, end) in enumerate(bundles): for vrb in range(start, end): color lightblue if vrb % 2 0 else lightgreen ax1.add_patch(Rectangle((vrb, 0), 1, 1, facecolorcolor)) ax1.text(vrb 0.5, 0.5, f{vrb}, hacenter, vacenter) ax1.set_xlim(0, bwp_size) ax1.set_ylim(0, 1) ax1.set_title(VRB Distribution (Before Mapping)) ax1.set_xlabel(VRB Index) ax1.set_yticks([]) # 绘制PRB映射结果 for vrb, prb in prb_map.items(): color blue if vrb % 2 0 else green ax2.add_patch(Rectangle((prb, 0), 1, 1, facecolorcolor)) ax2.text(prb 0.5, 0.5, f{vrb}, hacenter, vacenter) # 高亮PDSCH分配区域 pdsch_start pdsch_offset pdsch_end pdsch_start pdsch_size ax2.axvspan(pdsch_start, pdsch_end, colorred, alpha0.1) ax2.set_xlim(0, bwp_size) ax2.set_ylim(0, 1) ax2.set_title(PRB Distribution (After Interleaved Mapping)) ax2.set_xlabel(PRB Index) ax2.set_yticks([]) plt.tight_layout() plt.show()4.2 完整流程执行将上述模块组合起来执行完整的映射和可视化流程# 计算Bundle划分 bundles calculate_bundles(bwp_size, bwp_offset, bundle_size) # 计算交织映射 prb_map interleaved_mapping(bundles, bwp_size, bwp_offset, bundle_size) # 可视化结果 plot_mapping(bundles, prb_map, bwp_size, pdsch_offset, pdsch_size)执行这段代码后你将看到一个清晰的映射关系图左侧显示原始的VRB分布右侧展示经过交织映射后的PRB分布其中红色区域表示PDSCH实际分配的资源块。5. 参数影响分析与实际应用5.1 Bundle大小对映射的影响Bundle大小(L)是影响映射模式的关键参数。我们可以通过修改bundle_size值来观察不同配置下的映射行为Bundle大小(L)映射特征分集效果适用场景2典型的奇偶分离映射良好大多数常规场景4更粗粒度的分集中等高移动性场景1相当于无交织无兼容性测试5.2 PDSCH资源分配的特殊处理在实际系统中PDSCH通常只占用BWP的一部分资源。我们的代码已经考虑了这种情况通过pdsch_offset和pdsch_size参数限定PDSCH的VRB范围在可视化中用红色半透明区域标记PDSCH实际占用的PRB可以观察到交织映射如何将连续的VRB分散到不连续的PRB上这种可视化方法特别有助于理解协议中关于PDSCH资源分配类型的描述能够直观展示交织映射带来的频率分集效果。6. 扩展应用与调试技巧6.1 验证协议案例我们可以用代码验证协议文档中的示例案例# 协议中的示例参数 bwp_size_example 200 bwp_offset_example 15 bundle_size_example 2 # 重新计算并绘图 bundles_example calculate_bundles(bwp_size_example, bwp_offset_example, bundle_size_example) prb_map_example interleaved_mapping(bundles_example, bwp_size_example, bwp_offset_example, bundle_size_example) plot_mapping(bundles_example, prb_map_example, bwp_size_example, 5, 140)运行这段代码你会得到与协议文档描述完全一致的映射图形这验证了我们实现的正确性。6.2 调试与问题排查在实际开发中可能会遇到映射结果与预期不符的情况。以下是一些调试技巧检查Bundle划分确保第一个和最后一个Bundle的大小计算正确验证中间变量检查j、c、r等中间变量的计算是否符合预期边界条件测试尝试极端参数值(如bwp_size1)确保算法鲁棒性逐步可视化在关键计算步骤后添加临时绘图代码观察中间状态注意当BWP大小不是Bundle大小的整数倍时最后一个Bundle的大小会有所不同这是常见的错误来源7. 工程实践建议在实际项目中应用这种可视化方法时我有几点经验分享参数化设计将关键参数设计为脚本的输入参数便于快速测试不同配置性能优化对于大规模RB配置(如400MHz带宽)考虑使用numpy向量化操作日志输出在关键步骤添加详细的日志输出便于离线分析单元测试为算法核心建立测试用例覆盖各种边界条件以下是一个改进后的命令行接口示例import argparse def main(): parser argparse.ArgumentParser(descriptionNR PDSCH VRB-PRB Mapping Visualizer) parser.add_argument(--bwp_size, typeint, default100, helpBWP size in RBs) parser.add_argument(--bwp_offset, typeint, default0, helpBWP offset) parser.add_argument(--bundle_size, typeint, default2, helpBundle size (L)) parser.add_argument(--pdsch_size, typeint, default50, helpPDSCH size in RBs) parser.add_argument(--pdsch_offset, typeint, default0, helpPDSCH offset) args parser.parse_args() bundles calculate_bundles(args.bwp_size, args.bwp_offset, args.bundle_size) prb_map interleaved_mapping(bundles, args.bwp_size, args.bwp_offset, args.bundle_size) plot_mapping(bundles, prb_map, args.bwp_size, args.pdsch_offset, args.pdsch_size) if __name__ __main__: main()这样你可以通过命令行参数快速测试不同配置例如python vrb_prb_mapping.py --bwp_size 200 --bwp_offset 15 --pdsch_size 140 --pdsch_offset 5

更多文章