%% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding %% Cell-Wide Settings % A structure |enbConfig| is used to configure the eNodeB. clear Npackets = 1000; SNR_values = linspace(-0.5,3,6); txCFI = 3; enbConfig.NDLRB = 15; % No of Downlink RBs in total BW enbConfig.CyclicPrefix = 'Normal'; % CP length enbConfig.CFI = txCFI; ; % 4 PDCCH symbols as NDLRB <= 10 enbConfig.Ng = 'Sixth'; % HICH groups enbConfig.CellRefP = 1; % 1-antenna ports enbConfig.NCellID = 0; % Physical layer cell identity enbConfig.NSubframe = 5; % Subframe number 0 enbConfig.DuplexMode = 'FDD'; % Frame structure enbConfig.PHICHDuration = 'Normal'; C_RNTI = 65535; % 16-bit UE-specific mask %% Setup Fading channel model cfg.Seed = 8; % Random channel seed cfg.NRxAnts = 1; % 1 receive antenna cfg.DelayProfile = 'EPA'; % EVA delay spread cfg.DopplerFreq = 5; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation cfg.InitTime = 0; % Initialize at time zero cfg.NTerms = 16; % Oscillators used in fading model cfg.ModelType = 'GMEDS'; % Rayleigh fading model type cfg.InitPhase = 'Random'; % Random initial phases cfg.NormalizePathGains = 'On'; % Normalize delay profile power cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas % Setup channel equalizer cec.PilotAverage = 'UserDefined'; % Type of pilot averaging cec.FreqWindow = 9; % Frequency window size cec.TimeWindow = 9; % Time window size cec.InterpType = 'linear'; % 2D interpolation type cec.InterpWindow = 'Centered'; % Interpolation window type cec.InterpWinSize = 1; % Interpolation window size %% DCI Message Generation % Generate a DCI message to be mapped to the PDCCH. dciConfig.DCIFormat = 'Format1A'; % DCI message format dciConfig.Allocation.RIV = 26; % Resource indication value % Create DCI message for given configuration [dciMessage, dciMessageBits] = lteDCI(enbConfig, dciConfig); %% DCI Channel Coding pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier pdcchConfig.PDCCHFormat = 3; % PDCCH format ueConfig.RNTI = C_RNTI; % DCI message bits coding to form coded DCI bits codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits); %% PDCCH Bits Generation pdcchDims = ltePDCCHInfo(enbConfig); % Initialize elements with -1 to indicate that all the bits are unused pdcchBits = -1*ones(pdcchDims.MTot, 1); % Perform search space for UE-specific control channel candidates. candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'}); Ncad=randi(length(candidates),1,1); % Map PDCCH payload on available UE-specific candidate. In this example the % first available candidate is used to map the coded DCI bits. pdcchBits ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits; %% PDCCH Complex-Valued Modulated Symbol Generation pdcchSymbols = ltePDCCH(enbConfig, pdcchBits); pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'}); subframe_tx = lteDLResourceGrid(enbConfig); subframe_tx(pdcchIndices) = pdcchSymbols; %% PCFICH cfiCodeword = lteCFI(enbConfig); pcfichSymbols = ltePCFICH(enbConfig,cfiCodeword); pcfichIndices = ltePCFICHIndices(enbConfig,'1based'); subframe_tx(pcfichIndices) = pcfichSymbols; %% Add references cellRsSym = lteCellRS(enbConfig); cellRsInd = lteCellRSIndices(enbConfig); subframe_tx(cellRsInd) = cellRsSym; [txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx); cfg.SamplingRate = info.SamplingRate; addpath('../../debug/lte/phy/lib/phch/test') decoded = zeros(size(SNR_values)); decoded_cfi = zeros(size(SNR_values)); decoded_liblte = zeros(size(SNR_values)); decoded_cfi_liblte = zeros(size(SNR_values)); parfor snr_idx=1:length(SNR_values) SNRdB = SNR_values(snr_idx); SNR = 10^(SNRdB/10); % Linear SNR N0 = 1/(sqrt(2.0*enbConfig.CellRefP*double(info.Nfft))*SNR); for i=1:Npackets enbConfigRx=enbConfig; rxWaveform = sum(txWaveform,2); %% Fading rxWaveform = lteFadingChannel(cfg,rxWaveform); %% Noise Addition noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise rxWaveform = rxWaveform + noise; %% Demodulate subframe_rx = lteOFDMDemodulate(enbConfigRx, rxWaveform); % Perform channel estimation [hest, nest] = lteDLChannelEstimate(enbConfigRx, cec, subframe_rx); [pcfichSymbolsRx, pdcfichSymbolsHest] = lteExtractResources(pcfichIndices(:,1), subframe_rx, hest); %% PCFICH decoding [pcfichBits, pcfichSymbols] = ltePCFICHDecode(enbConfigRx,pcfichSymbolsRx, pdcfichSymbolsHest, nest); rxCFI = lteCFIDecode(pcfichBits); decoded_cfi(snr_idx) = decoded_cfi(snr_idx) + (rxCFI == txCFI); %% PDCCH Decoding enbConfigRx.CFI = rxCFI; pdcchIndicesRx = ltePDCCHIndices(enbConfigRx,{'1based'}); [pdcchSymbolsRx, pdcchSymbolsHest] = lteExtractResources(pdcchIndicesRx(:,1), subframe_rx, hest); [recPdcchBits] = ltePDCCHDecode(enbConfigRx, pdcchSymbolsRx, pdcchSymbolsHest, nest); %% Blind Decoding using DCI Search [rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfigRx, ueConfig, recPdcchBits); decoded(snr_idx) = decoded(snr_idx) + (length(rxDCI)>0); %% Same with libLTE [rxCFI, pcfichSymbols2, pcfichSymbolsRx2] = liblte_pcfich(enbConfigRx, rxWaveform); decoded_cfi_liblte(snr_idx) = decoded_cfi_liblte(snr_idx) + (rxCFI == txCFI); enbConfigRx.CFI = rxCFI; [found_liblte, llr, pdcchSymbols2] = liblte_pdcch(enbConfigRx, ueConfig.RNTI, rxWaveform); decoded_liblte(snr_idx) = decoded_liblte(snr_idx)+found_liblte; end fprintf('SNR: %.1f\n',SNRdB) end if (Npackets>1) semilogy(SNR_values,1-decoded/Npackets,'bo-',... SNR_values,1-decoded_cfi/Npackets,'bx:',... SNR_values,1-decoded_liblte/Npackets, 'ro-',... SNR_values,1-decoded_cfi_liblte/Npackets,'rx:') grid on legend('Matlab all','Matlab cfi', 'libLTE all', 'libLTE cfi') xlabel('SNR (dB)') ylabel('BLER') axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1]) else disp(decoded) disp(decoded_liblte) end