简介本资源面向通信工程、无线网络方向的学习者与研究者提供LTE下行链路系统级仿真的完整代码实现帮助理解从eNodeB到UE的物理层处理、信道建模、资源分配与多用户调度等核心机制。压缩包共40个文件全部为m脚本文件整体约35KB涵盖物理层编解码、调制解调、信道估计与均衡、CRC校验、OFDM收发、资源块映射以及SISO链路参数配置等模块脚本间调用关系清晰便于按流程逐步调试与二次开发。资源围绕单输入单输出场景展开涉及PDSCH与PDCCH信道处理、CQI反馈、干扰影响及链路级与系统级仿真的差异对比适合作为课程设计、毕业设计或算法验证的参考工程。目前已有330人学习下载可帮助读者快速搭建仿真环境、复现下行链路处理流程并在此基础上评估调度策略与功率控制对网络性能的影响。1. SISO.zip 里的 LTE 下行链路仿真从链路到系统级到底在算什么打开一个名为 SISO.zip 的 LTE 仿真工程很多人第一反应是找 main 函数结果翻遍目录发现入口散落在链路级和系统级两套脚本里。这个标题其实指向一条完整的 LTE 下行仿真链路SISO 单入单出天线配置、链路级误块率曲线、系统级小区吞吐与调度、以及下行共享信道的资源映射。它解决的是「没有商用基站和终端怎么在本地把 LTE 下行从调制到调度跑通并拿到可信曲线」这个问题。适合通信专业学生、基带算法工程师、以及需要做链路预算和调度策略验证的从业者。链路级关心的是单条链路的 BLER 与 SNR 关系系统级关心的是多用户、多小区下的资源分配和干扰。两者共用一套参数配置但时间尺度和抽象层次完全不同。把这两层混在一起跑是新手最常见的翻车点。2. LTE 下行链路级仿真从传输块到 BLER 曲线的最小闭环2.1 为什么先做链路级而不是直接上系统级链路级仿真的价值在于它把物理层的每个环节都显式展开CRC 附着、码块分割、Turbo 编码、速率匹配、加扰、调制、层映射、预编码、RE 映射、OFDM 符号生成再到接收端的解调、解扰、解速率匹配、Turbo 译码。每一步都可以单独打点看星座图、看软比特、看误块率。系统级仿真则把这些环节压缩成一个链路到系统映射表用 SINR 查 BLER 的方式替代完整物理层。如果链路级没跑通系统级查表就是查一个错误的表后面所有调度结论都不可信。SISO 配置下层映射和预编码退化为恒等操作这反而让初学者能把注意力放在编码链路和信道估计上。常见做法是先用 AWGN 信道验证编译码链路再换 EPA、EVA、ETU 等多径信道看频率选择性衰落的影响。2.2 用 MATLAB 搭一条 SISO 下行链路的最小代码下面这段代码覆盖从传输块到 BLER 统计的核心流程参数按 20 MHz 带宽、正常 CP、FDD 帧结构设置。实际工程里我会把每个模块拆成独立函数这里为了看清数据流放在一起。% SISO LTE 下行链路级仿真最小闭环 % 参数20MHz带宽正常CPFDD传输块大小按MCS索引查表 clear; clc; % ---- 1. 基本参数 ---- N_rb 100; % 资源块数20MHz对应100个RB N_sc 12; % 每个RB的子载波数 N_sym 7; % 每个时隙的OFDM符号数正常CP N_cp 4.7e-6; % 正常CP长度秒 fs 30.72e6; % 采样率 MCS 10; % 调制编码等级对应QPSK 1/3左右 TBS 2792; % 传输块大小按MCS和RB数查36.213表 SNR_dB 0:2:20; % 信噪比扫描范围 % ---- 2. 生成传输块 ---- tx_block randi([0 1], TBS, 1); % ---- 3. CRC附着 ---- poly_crc comm.CRCDetector(Polynomial,CRC24A); tx_crc poly_crc(tx_block); % 附加24位CRC % ---- 4. 码块分割与Turbo编码 ---- % 简化处理假设单码块实际需按6144分割 turbo_enc comm.TurboEncoder(TrellisStructure, ... poly2trellis(4,[13 15 17]), InterleaverIndicesSource,Input port); K length(tx_crc); intrlvr randperm(K); tx_enc turbo_enc(tx_crc, intrlvr); % ---- 5. 速率匹配简化截断或重复到目标比特数---- G N_rb * N_sc * N_sym * 2 * 2; % 可用比特数QPSK每符号2比特 if length(tx_enc) G tx_rm tx_enc(1:G); else tx_rm repmat(tx_enc, ceil(G/length(tx_enc)), 1); tx_rm tx_rm(1:G); end % ---- 6. 加扰 ---- c_init 0; % 简化小区ID为0 scramble_seq randi([0 1], G, 1); % 实际用Gold序列生成 tx_scr xor(tx_rm, scramble_seq); % ---- 7. QPSK调制 ---- tx_sym 1/sqrt(2) * ((1-2*tx_scr(1:2:end)) 1j*(1-2*tx_scr(2:2:end))); % ---- 8. 资源映射与OFDM ---- grid zeros(N_rb*N_sc, N_sym); grid(1:length(tx_sym)) tx_sym; tx_ofdm ifft(grid, N_rb*N_sc); % ---- 9. 信道与接收 ---- ber zeros(size(SNR_dB)); for i 1:length(SNR_dB) snr_lin 10^(SNR_dB(i)/10); noise (randn(size(tx_ofdm)) 1j*randn(size(tx_ofdm)))/sqrt(2*snr_lin); rx_ofdm tx_ofdm noise; % 接收端FFT、均衡AWGN下理想、解调 rx_grid fft(rx_ofdm, N_rb*N_sc); rx_sym rx_grid(1:length(tx_sym)); rx_bits zeros(G,1); rx_bits(1:2:end) real(rx_sym) 0; rx_bits(2:2:end) imag(rx_sym) 0; % 解扰、解速率匹配、Turbo译码 rx_desc xor(rx_bits, scramble_seq); % 简化直接比较比特实际需软判决译码 ber(i) sum(rx_desc ~ tx_rm) / G; end semilogy(SNR_dB, ber, b-o); xlabel(SNR (dB)); ylabel(BER); grid on; title(SISO LTE 下行链路 BER 曲线);这段代码的逻辑说明CRC 附着用 CRC24A 是 LTE 下行传输块的标配Turbo 编码的网格结构[13 15 17]对应 LTE 规定的生成多项式速率匹配这里做了简化实际工程要按 36.212 的循环缓冲和冗余版本处理。参数方面TBS必须和MCS、N_rb匹配查 36.213 的 Table 7.1.7.2.1-1随便填会导致码率异常。SNR_dB扫描范围建议从 -5 到 25步长 1 到 2 dB太粗看不出瀑布区。2.3 信道模型怎么选EPA、EVA、ETU 的适用边界LTE 链路级仿真常用的多径信道有三类EPA 对应低时延扩展EVA 对应中等ETU 对应高时延扩展。SISO 配置下频率选择性衰落会让某些子载波深衰落均衡器必须能跟踪。常见做法是在接收端加 MMSE 均衡用估计的信道频响做补偿。如果只做 AWGN曲线会过于乐观系统级查表时 SINR 到 BLER 的映射会偏。信道模型时延扩展典型场景最大多普勒EPA低室内热点5 HzEVA中城市宏小区70 HzETU高恶劣城市300 Hz选信道时要注意多普勒频移决定信道估计的插值密度高速场景下导频符号间隔要更密否则信道估计误差会吃掉编码增益。3. 系统级仿真多小区调度与 SINR 到吞吐的映射3.1 系统级仿真的抽象层次与链路到系统映射系统级仿真不跑完整物理层而是把链路级得到的 BLER-SINR 曲线做成查找表。每个用户在每个资源块上计算 SINR查表得到 BLER再结合 HARQ 和调度算法决定实际传输速率。SISO 配置下小区间干扰是主要限制因素特别是下行共享信道在小区边缘的 SINR 会明显恶化。系统级仿真的时间尺度是 TTI 级每个 TTI 做一次调度。常见调度算法有轮询、比例公平、最大 C/I。比例公平在吞吐和公平性之间折中工程上最常用。实现时要维护每个用户的平均速率调度优先级按瞬时速率除以平均速率排序。3.2 用 MATLAB 搭一个多小区下行调度循环下面这段代码模拟 7 个小区、每小区 10 个用户的下行调度核心是 SINR 计算和比例公平调度。% LTE 系统级下行调度仿真7小区每小区10用户 % 抽象层次TTI级SINR查BLER表比例公平调度 clear; clc; % ---- 1. 仿真参数 ---- N_cell 7; % 小区数中心1个加周围6个 N_ue_per_cell 10; % 每小区用户数 N_rb 100; % 总资源块数 N_tti 1000; % 仿真TTI数 ISD 500; % 站间距米 P_tx 46; % 基站发射功率dBm BW 20e6; % 带宽 noise_dBm -174 10*log10(BW) 7; % 噪声功率含噪声系数 % ---- 2. 用户位置生成 ---- ue_pos zeros(N_cell, N_ue_per_cell, 2); for c 1:N_cell % 小区中心坐标六边形近似 angle (c-1)*pi/3; center ISD * [cos(angle), sin(angle)]; if c 1, center [0, 0]; end for u 1:N_ue_per_cell r ISD/2 * sqrt(rand()); theta 2*pi*rand(); ue_pos(c,u,:) center r*[cos(theta), sin(theta)]; end end % ---- 3. 大尺度路损 ---- alpha 3.5; % 路损指数 PL (d) 128.1 37.6*log10(max(d,35)/1000); % 36.942路损模型 % ---- 4. 比例公平调度主循环 ---- avg_rate ones(N_cell, N_ue_per_cell) * 1e6; % 初始平均速率 cell_throughput zeros(N_tti, N_cell); for tti 1:N_tti for c 1:N_cell % 计算每个用户的瞬时SINR简化取中心RB sinr zeros(N_ue_per_cell, 1); for u 1:N_ue_per_cell d_serv norm(squeeze(ue_pos(c,u,:))); sig_power P_tx - PL(d_serv); % 干扰来自其他小区 interf 0; for cc 2:N_cell if cc c, continue; end d_int norm(squeeze(ue_pos(c,u,:)) - squeeze(ue_pos(cc,1,:))); interf interf 10^((P_tx - PL(d_int))/10); end noise_lin 10^(noise_dBm/10); sinr(u) 10*log10(10^(sig_power/10) / (interf noise_lin)); end % 比例公平优先级 瞬时速率 / 平均速率 inst_rate log2(1 10.^(sinr/10)); % 简化香农公式 priority inst_rate ./ avg_rate(c,:); [~, idx] sort(priority, descend); % 分配RB简化前几个用户各分若干RB rb_per_ue floor(N_rb / N_ue_per_cell); for k 1:N_ue_per_cell u idx(k); rate rb_per_ue * inst_rate(u) * 180e3; % 每RB 180kHz avg_rate(c,u) 0.99*avg_rate(c,u) 0.01*rate; cell_throughput(tti,c) cell_throughput(tti,c) rate; end end end % ---- 5. 结果 ---- avg_cell_tp mean(cell_throughput, 1); fprintf(平均小区吞吐: %.2f Mbps\n, mean(avg_cell_tp)/1e6); fprintf(边缘用户吞吐: %.2f Mbps\n, ... mean(avg_rate(:))/1e6);逻辑说明路损模型用 36.942 的宏站模型alpha和常数项决定信号衰减斜率。SINR 计算里干扰只取了其他小区的第一个用户位置做近似实际工程要遍历所有干扰用户。比例公平的优先级公式里avg_rate的更新用滑动平均时间常数 0.01 对应约 100 TTI 的窗口。参数方面ISD设 500 米是密集城区设 1732 米是标准六边形网格。N_tti至少 1000 才能让平均速率收敛。3.3 链路到系统映射表怎么生成和插值链路级跑出来的 BLER 曲线是离散的 SNR 点系统级需要连续查表。常见做法是把 BLER 对 SNR 做线性插值或者拟合一个 S 曲线。注意 BLER 在 0.1 附近变化最快插值点要密。如果链路级只跑了 AWGN系统级查表时要加一个衰落余量通常 2 到 4 dB具体看信道模型。提示链路级和系统级的 SNR 定义要一致。链路级常用每接收天线 SNR系统级常用 SINR两者差一个干扰项。映射表里要注明。4. 避坑与排查SISO LTE 仿真里最容易翻车的五个点4.1 传输块大小和 MCS 不匹配导致 BLER 恒为 1现象不管 SNR 多高BLER 始终接近 1译码全错。原因TBS 查表时用错了 MCS 索引或 RB 数导致实际码率远超信道容量。解决按 36.213 Table 7.1.7.2.1-1 逐项核对TBS 和 MCS、N_prb 必须严格对应。我一般会在代码里加一个断言检查 TBS 是否在合法集合里。4.2 速率匹配的冗余版本搞反导致 HARQ 合并无效现象HARQ 重传后 BLER 不下降和初传一样。原因每次重传的冗余版本 RV 没变或者循环缓冲的起始位置算错。解决按 36.212 的 RV 定义RV0 从缓冲开头取RV1 从偏移处取RV2、RV3 依次。检查k0的计算公式和N_cb、RV的关系不能错。4.3 系统级 SINR 计算漏掉天线增益和穿透损耗现象小区边缘吞吐偏高和实际路测差很多。原因SINR 计算只用了路损没加天线方向图增益、馈线损耗、建筑物穿透损耗。解决在路损模型里补上这些项。天线增益按 3GPP 的定向天线模型穿透损耗按 20 dB 估算。这些参数在链路预算里都有系统级仿真不能省。4.4 OFDM 符号定时偏移导致星座图旋转现象接收星座图整体旋转解调误码率偏高。原因CP 长度和 FFT 窗口没对齐或者多径时延超过了 CP。解决检查N_cp和采样率的关系确保 CP 长度大于信道最大时延扩展。ETU 信道下 CP 要够长否则加窗或缩短 FFT 窗口。4.5 比例公平的平均速率更新过快导致调度震荡现象调度器在不同用户间频繁切换吞吐不稳定。原因avg_rate的滑动平均系数太大比如用了 0.5导致平均速率跟踪瞬时值。解决系数取 0.01 到 0.05对应 20 到 100 TTI 的窗口。窗口太短公平性差太长响应慢。5. 进阶技巧用链路级曲线反推系统级参数边界链路级和系统级不是孤立的。我习惯在链路级跑完 BLER 曲线后提取两个关键点BLER0.1 对应的 SNR以及 BLER0.01 对应的 SNR。这两个点决定了系统级调度时 MCS 的选择边界。如果系统级某用户 SINR 低于 BLER0.1 的 SNR就不该给它分配高阶 MCS否则 HARQ 重传次数会爆。具体做法是建一张映射表行是 SINR 区间列是可用 MCS 集合。每个 TTI 根据用户 SINR 查表选 MCS再查 TBS。这张表可以用链路级仿真自动生成对每个 MCS 跑一遍 BLER-SNR记录 BLER0.1 的 SNR 作为该 MCS 的最低工作点。% 从链路级BLER曲线生成MCS-SINR映射表 mcs_list 0:28; % LTE MCS索引范围 sinr_threshold zeros(size(mcs_list)); for m 1:length(mcs_list) % 对每个MCS跑链路级得到BLER-SNR曲线 % 这里用简化模型代替实际仿真 snr 0:0.5:25; bler 0.5 * erfc((snr - (m*0.8 - 2))/2); % 示意 idx find(bler 0.1, 1); if ~isempty(idx) sinr_threshold(m) snr(idx); else sinr_threshold(m) Inf; end end % 系统级调度时选满足SINR sinr_threshold的最高MCS参数说明mcs_list覆盖 LTE 的 0 到 28实际调度只用到部分。sinr_threshold是每个 MCS 的最低 SINR系统级查表时用find(sinr sinr_threshold, 1, last)选最高可用 MCS。注意这个表依赖信道模型EPA 和 ETU 的表不能混用。另一个技巧是验证系统级吞吐是否合理。用香农公式算一个理论上界C BW * log2(1 SINR)再乘以一个效率因子通常 0.3 到 0.5。如果系统级仿真结果远高于这个上界说明 SINR 计算或调度有误。我一般会在仿真结束后打印这个对比作为 sanity check。最后说一个习惯每次改参数只改一个跑完记录曲线。LTE 仿真参数太多一次改多个出了问题根本不知道是哪个引起的。这个习惯帮我省了很多后悔药。希望帮到你。本文还有配套的精品资源点击获取