Projects STRLCPY wirelesscomm Commits 4f705251
🤬
  • ■ ■ ■ ■ ■
    readme.md
    skipped 56 lines
    57 57   * [Lecture videos](./unit04_coding/readme.md) and in-class exercises
    58 58   * Demo: Uncoded BER on fading channel [[PDF]](./unit04_coding/demo_uncoded.pdf) [[Matlab Live]](./unit04_coding/demo_uncoded.mlx)
    59 59   * Demo: Convolutional coding on a fading channel[[PDF]](./unit04_coding/demo_conv.pdf) [[Matlab Live]](./unit04_coding/demo_conv.mlx)
     60 + * Lab: 5G NR Downlink Throughput with Fading and LDPC coding [[PDF]](./unit04_coding/lab_partial/labPdsch.pdf) [[Matlab Live]](./unit04_coding/lab_partial/labPdsch.mlx)
    60 61  * Unit 5. MAC-Layer Concepts
    61 62  * Unit 6. Channel Estimation and Equalization
    62 63  * Unit 7. Multiple Antennas and Beamforming
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    unit04_coding/lab_partial/FDChan.m
     1 +classdef FDChan < matlab.System
     2 + % Frequency-domain multipath channel
     3 + properties
     4 + % Configuration
     5 + carrierConfig; % Carrier configuration
     6 +
     7 + % Path parameters
     8 + gain; % Path gain in dB
     9 + dly; % Delay of each path in seconds
     10 + aoaAz, aoaEl; % Angle of arrival of each path in degrees
     11 + fd; % Doppler shift for each path
     12 +
     13 + rxVel = [30,0,0]'; % Mobile velocity vector in m/s
     14 + fc = 28e9; % Carrier freq in Hz
     15 +
     16 + gainComplex; % Complex gain of each path
     17 +
     18 + % SNR parameters
     19 + Etx = 1; % average energy per PDSCH symbol
     20 + EsN0Avg = 20; % Avg SNR per RX symbol in dB
     21 +
     22 + % Symbol times
     23 + symStart; % symStart(i) = start of symbol i relative to subframe
     24 +
     25 + end
     26 + methods
     27 + function obj = FDChan(carrierConfig, varargin)
     28 + % Constructor
     29 +
     30 + % Save the carrier configuration
     31 + obj.carrierConfig = carrierConfig;
     32 + 
     33 +
     34 + % Set parameters from constructor arguments
     35 + if nargin >= 1
     36 + obj.set(varargin{:});
     37 + end
     38 +
     39 + % TODO: Create complex path gain for each path
     40 + % obj.gainComplex = ...
     41 +
     42 + % TODO: Compute the Doppler shift for each path
     43 + % obj.fd = ...
     44 +
     45 + % Compute unit vector in direction of each path
     46 +
     47 + % TODO: Compute the vector of
     48 + % symbol times relative to the start of the subframe
     49 + % obj.symStart = ...
     50 +
     51 + end
     52 +
     53 +
     54 + end
     55 + methods (Access = protected)
     56 +
     57 +
     58 + function [rxGrid, chanGrid, noiseVar] = stepImpl(obj, txGrid, sfNum, slotNum)
     59 + % Applies a frequency domain channel and noise
     60 + %
     61 + % Given the TX grid of OFDM REs, txGrid, the function
     62 + % * Computes the channel grid, chanGrid, given the
     63 + % subframe number, sfNum, and slotNum, slotNum.
     64 + % * Computes the noise variance per symbol, noiseVar,
     65 + % for a target SNR
     66 + % * Applies the channel and noise to create the RX grid
     67 + % of symbols, rxGrid.
     68 +
     69 + % TODO
     70 +
     71 + end
     72 +
     73 + end
     74 +end
     75 + 
     76 + 
  • ■ ■ ■ ■ ■ ■
    unit04_coding/lab_partial/NRUERxFD.m
     1 +classdef NRUERxFD < matlab.System
     2 + % 5G NR UR receiver class implemented in frequency domain
     3 + properties
     4 + % Configuration
     5 + carrierConfig; % Carrier configuration
     6 + pdschConfig; % Default PDSCH config
     7 + waveformConfig; % Waveform config
     8 +
     9 + % OFDM grid
     10 + rxGrid;
     11 +
     12 + % Transport block data for last transmission
     13 + targetCodeRate = 490/1024; % Target code rate
     14 + trBlkSizes; % Transport block size
     15 +
     16 + % Received data in last slots
     17 + pdschEq; % Equalized PDSCH symbols
     18 + rxBits; % RX bits
     19 +
     20 + % DLSCH decoder
     21 + decDLSCH;
     22 +
     23 +
     24 + end
     25 + methods
     26 + function obj = NRUERxFD(carrierConfig, pdschConfig, ...
     27 + varargin)
     28 + % Constructor
     29 +
     30 + % Save the carrier and PDSCH configuration
     31 + obj.carrierConfig = carrierConfig;
     32 + obj.pdschConfig = pdschConfig;
     33 +
     34 + % Create the waveform configuration from the carrier
     35 + % configuration
     36 + obj.waveformConfig = nrOFDMInfo(obj.carrierConfig);
     37 +
     38 + % Set parameters from constructor arguments
     39 + if nargin >= 1
     40 + obj.set(varargin{:});
     41 + end
     42 +
     43 + % Create DLSCH decoder
     44 + obj.decDLSCH = nrDLSCHDecoder('MultipleHARQProcesses', false, ...
     45 + 'TargetCodeRate', obj.targetCodeRate, ...
     46 + 'LDPCDecodingAlgorithm', 'Layered belief propagation');
     47 +
     48 + end
     49 + end
     50 + methods (Access = protected)
     51 +
     52 +
     53 + function stepImpl(obj, rxGrid, chanGrid, noiseVar)
     54 + % Demodulates and decodes one slot of data
     55 +
     56 + % Get PDSCH received symbols and channel estimates
     57 + % from received grid
     58 + [pdschInd,pdschInfo] = nrPDSCHIndices(...
     59 + obj.carrierConfig, obj.pdschConfig);
     60 + [pdschRx, pdschHest] = nrExtractResources(pdschInd, rxGrid,...
     61 + chanGrid);
     62 +
     63 + % TODO: Perform the MMSE equalization using the
     64 + % nrEqualizeMMSE() function.
     65 + % Use the PDSCH Rx symbols, PDSCH channel estimate and noise
     66 + % variance as the input. Store the equalized symbols in
     67 + % obj.pdschEq and channel state information in a structure,
     68 + % csi.
     69 + % [obj.pdschEq,csi] = nrEqualizeMMSE(...);
     70 +
     71 +
     72 + % TODO: Get the LLRs with the nrPDSCHDecode() function.
     73 + % Use carrier and PDSCH configuration, the equalized symbols,
     74 + % and the noise variance, noiseVar.
     75 + % [obj.pdschEq,csi] = nrEqualizeMMSE(...);
     76 +
     77 + % Scale LLRs by EbN0.
     78 + % The csi value computed in the nrEqualizeMMSE()
     79 + % function is csi = |pdschHest|^2 + noiseVar.
     80 + % Also, the Eb/N0 = snrEq/Qm where Qm is the number of bits
     81 + % per symbol and snrEq is the SNR after equalization,
     82 + %
     83 + % snrEq = (|pdschHest|^2 + noiseVar)/noiseVar = csi/noiseVar
     84 + %
     85 + % Hence, Eb/N0 = csi/(noiseVar*Qm).
     86 + % Since the LLRs from the nrPDSCHDecode function are
     87 + % already scaled by 1/noiseVar, we multiply them by csi/Qm.
     88 + csi = nrLayerDemap(csi); % CSI layer demapping
     89 + numCW = length(csi);
     90 + for cwIdx = 1:numCW
     91 + Qm = length(dlschLLRs{cwIdx})/length(rxSym{cwIdx}); % bits per symbol
     92 + csi{cwIdx} = repmat(csi{cwIdx}.',Qm,1); % expand by each bit per symbol
     93 + dlschLLRs{cwIdx} = dlschLLRs{cwIdx} .* csi{cwIdx}(:); % scale
     94 + end
     95 +
     96 + % Compute the extra overhead from the PT-RS
     97 + Xoh_PDSCH = 6*obj.pdschConfig.EnablePTRS;
     98 +
     99 + % Calculate the transport block size based on the PDSCH
     100 + % allocation and target code rate
     101 + obj.trBlkSizes = nrTBS(obj.pdschConfig.Modulation,obj.pdschConfig.NumLayers,...
     102 + numel(obj.pdschConfig.PRBSet),pdschInfo.NREPerPRB,...
     103 + obj.targetCodeRate,Xoh_PDSCH);
     104 + obj.decDLSCH.TransportBlockLength = obj.trBlkSizes;
     105 +
     106 + % Reset the soft buffer
     107 + harqId = 0;
     108 + obj.decDLSCH.resetSoftBuffer(harqId);
     109 +
     110 + % TODO: Decode the bits with the obj.decDLSCH() method.
     111 + % Use the scaled LLRs from above. Use a redundancy version,
     112 + % rv = 0, since we are not using HARQ in this lab.
     113 + % rv = 0;
     114 + % obj.rxBit = obj.decDLSCH(...);
     115 +
     116 + end
     117 +
     118 + end
     119 +end
     120 + 
     121 + 
  • ■ ■ ■ ■ ■ ■
    unit04_coding/lab_partial/NRgNBTxFD.m
     1 +classdef NRgNBTxFD < matlab.System
     2 + % 5G NR gNB transmitter class implemented in frequency domain
     3 + properties
     4 + % Configuration
     5 + carrierConfig; % Carrier configuration
     6 + pdschConfig; % PDSCH configuration
     7 +
     8 + % Transport block data for last transmission
     9 + targetCodeRate = 490/1024; % Target code rate
     10 + trBlkSizes; % Transport block size
     11 +
     12 + % Transmitted data in last slots
     13 + txBits; % TX bits
     14 +
     15 + % DLSCH encoder
     16 + encDLSCH;
     17 +
     18 +
     19 + end
     20 + methods
     21 + function obj = NRgNBTxFD(carrierConfig, pdschConfig, ...
     22 + varargin)
     23 + % Constructor
     24 +
     25 + % Save the carrier and PDSCH configuration
     26 + obj.carrierConfig = carrierConfig;
     27 + obj.pdschConfig = pdschConfig;
     28 +
     29 + % Set parameters from constructor arguments
     30 + if nargin >= 1
     31 + obj.set(varargin{:});
     32 + end
     33 +
     34 + % Create DLSCH encoder system object
     35 + obj.encDLSCH = nrDLSCH('MultipleHARQProcesses', false, ...
     36 + 'TargetCodeRate', obj.targetCodeRate);
     37 +
     38 + end
     39 + end
     40 + methods (Access = protected)
     41 +
     42 + function txGrid = stepImpl(obj)
     43 + % step implementation. Creates one slot of samples for each
     44 + % component carrier
     45 +
     46 +
     47 + % Create the OFDM grid representing the array of modulation
     48 + % symbols to be transmitted
     49 + txGrid = nrResourceGrid(obj.carrierConfig, ...
     50 + obj.pdschConfig.NumLayers);
     51 +
     52 +
     53 + % Get indices on where the PDSCH is allocated
     54 + [pdschInd,pdschInfo] = nrPDSCHIndices(obj.carrierConfig, obj.pdschConfig);
     55 +
     56 + % Compute the extra overhead from the PT-RS
     57 + Xoh_PDSCH = 6*obj.pdschConfig.EnablePTRS;
     58 +
     59 + % Calculate the transport block size based on the PDSCH
     60 + % allocation and target code rate
     61 + obj.trBlkSizes = nrTBS(obj.pdschConfig.Modulation,obj.pdschConfig.NumLayers,...
     62 + numel(obj.pdschConfig.PRBSet),pdschInfo.NREPerPRB,...
     63 + obj.targetCodeRate,Xoh_PDSCH);
     64 +
     65 + % Generate random bits for each codeword and set the transport
     66 + % block
     67 + obj.txBits = cell(obj.pdschConfig.NumCodewords, 1);
     68 + for icw = 1:obj.pdschConfig.NumCodewords
     69 + 
     70 + % Create random bits
     71 + obj.txBits{icw} = randi([0 1], obj.trBlkSizes(icw), 1);
     72 +
     73 + % Encode data
     74 + obj.encDLSCH.setTransportBlock(obj.txBits{icw},icw-1);
     75 + end
     76 +
     77 + % Encode the DL-SCH transport blocks. We use a redundancy
     78 + % version (rv) = 0 since we are not simulating HARQ now.
     79 + rv = 0;
     80 + codedTrBlock = obj.encDLSCH(obj.pdschConfig.Modulation, ...
     81 + obj.pdschConfig.NumLayers, pdschInfo.G, rv);
     82 +
     83 + % Modulate the PDSCH modulation
     84 + pdschSymbols = nrPDSCH(obj.carrierConfig, obj.pdschConfig, ...
     85 + codedTrBlock);
     86 +
     87 + % Map the modulated symbols to the OFDM grid
     88 + txGrid(pdschInd) = pdschSymbols;
     89 +
     90 + end
     91 +
     92 + end
     93 +end
     94 + 
     95 + 
  • unit04_coding/lab_partial/labPdsch.mlx
    Binary file.
  • unit04_coding/lab_partial/labPdsch.pdf
    Binary file.
Please wait...
Page is in error, reload to recover