■ ■ ■ ■ ■ ■
unit05_amc/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 | + | % DLSCH encoder |
| 13 | + | encDLSCH; |
| 14 | + | |
| 15 | + | % HARQ Process |
| 16 | + | nharq = 8; % number of HARQ processes |
| 17 | + | |
| 18 | + | % RV sequence. This is the sequence that the TX will cycle |
| 19 | + | % through in the RVs |
| 20 | + | rvSeq = [0,3,2,1]'; |
| 21 | + | |
| 22 | + | % TX parameters per HARQ process |
| 23 | + | rvInd; % Index of the RV for the current transmission |
| 24 | + | newDataAvail; % If HARQ process can take new data |
| 25 | + | txBits; % Cell array of TX bits |
| 26 | + | |
| 27 | + | end |
| 28 | + | methods |
| 29 | + | function obj = NRgNBTxFD(carrierConfig, pdschConfig, ... |
| 30 | + | varargin) |
| 31 | + | % Constructor |
| 32 | + | |
| 33 | + | % Save the carrier and PDSCH configuration |
| 34 | + | obj.carrierConfig = carrierConfig; |
| 35 | + | obj.pdschConfig = pdschConfig; |
| 36 | + | |
| 37 | + | % Set parameters from constructor arguments |
| 38 | + | if nargin >= 1 |
| 39 | + | obj.set(varargin{:}); |
| 40 | + | end |
| 41 | + | |
| 42 | + | % Create DLSCH encoder system object |
| 43 | + | obj.encDLSCH = nrDLSCH('MultipleHARQProcesses', true, ... |
| 44 | + | 'TargetCodeRate', obj.targetCodeRate); |
| 45 | + | |
| 46 | + | % Initialize the HARQ process parameters |
| 47 | + | obj.rvInd = zeros(obj.nharq, 1); |
| 48 | + | obj.newDataAvail = ones(obj.nharq,1); |
| 49 | + | |
| 50 | + | % TX bits for each HARQ process |
| 51 | + | obj.txBits = cell(obj.nharq,1); |
| 52 | + | |
| 53 | + | |
| 54 | + | end |
| 55 | + | |
| 56 | + | function setAck(obj, iharq) |
| 57 | + | % Set that the HARQ transmission was received correctly |
| 58 | + | obj.newDataAvail(iharq) = 1; |
| 59 | + | |
| 60 | + | end |
| 61 | + | end |
| 62 | + | methods (Access = protected) |
| 63 | + | |
| 64 | + | function [txGrid, rv, newDat] = stepImpl(obj, iharq) |
| 65 | + | % step implementation. Creates one slot of samples for each |
| 66 | + | % component carrier |
| 67 | + | % |
| 68 | + | % Parameters |
| 69 | + | % ---------- |
| 70 | + | % iharq: HARQ process index to use |
| 71 | + | % |
| 72 | + | % Returns: |
| 73 | + | % -------- |
| 74 | + | % txGrid: OFDM grid of transmitted symbols |
| 75 | + | % rv: Redundancy version for the data |
| 76 | + | % newDat: If new data was transmitted in this slot |
| 77 | + | |
| 78 | + | |
| 79 | + | % Create the OFDM grid representing the array of modulation |
| 80 | + | % symbols to be transmitted |
| 81 | + | txGrid = nrResourceGrid(obj.carrierConfig, ... |
| 82 | + | obj.pdschConfig.NumLayers); |
| 83 | + | |
| 84 | + | |
| 85 | + | % Get indices on where the PDSCH is allocated |
| 86 | + | [pdschInd,pdschInfo] = nrPDSCHIndices(obj.carrierConfig, obj.pdschConfig); |
| 87 | + | |
| 88 | + | |
| 89 | + | if obj.newDataAvail(iharq) |
| 90 | + | % If new data can be transmitted in the HARQ process |
| 91 | + | |
| 92 | + | % Compute the extra overhead from the PT-RS |
| 93 | + | Xoh_PDSCH = 6*obj.pdschConfig.EnablePTRS; |
| 94 | + | |
| 95 | + | % Calculate the transport block size based on the PDSCH |
| 96 | + | % allocation and target code rate |
| 97 | + | obj.trBlkSizes = nrTBS(obj.pdschConfig.Modulation,obj.pdschConfig.NumLayers,... |
| 98 | + | numel(obj.pdschConfig.PRBSet),pdschInfo.NREPerPRB,... |
| 99 | + | obj.targetCodeRate,Xoh_PDSCH); |
| 100 | + | |
| 101 | + | % Generate random bits for each codeword and set the transport |
| 102 | + | % block |
| 103 | + | obj.txBits{iharq} = cell(obj.pdschConfig.NumCodewords, 1); |
| 104 | + | for icw = 1:obj.pdschConfig.NumCodewords |
| 105 | + | |
| 106 | + | % TODO: Create random bits for each codeword |
| 107 | + | % obj.txBits{iharq}{icw} = ... |
| 108 | + | |
| 109 | + | % TODO: Set the transport block to be encoded |
| 110 | + | % obj.echDLSCH.setTransportBlock(...) |
| 111 | + | % You will need to pass the codeword index, icw-1, |
| 112 | + | % and HARQ process ID, iharq-1 |
| 113 | + | end |
| 114 | + | |
| 115 | + | % Set the RV index to zero on the first transmission |
| 116 | + | obj.rvInd(iharq) = 0; |
| 117 | + | |
| 118 | + | % Clear new data flag |
| 119 | + | obj.newDataAvail(iharq) = 0; |
| 120 | + | |
| 121 | + | % Mark that the data |
| 122 | + | newDat = true; |
| 123 | + | else |
| 124 | + | % Mark that this data is a re-transmission |
| 125 | + | newDat = false; |
| 126 | + | end |
| 127 | + | |
| 128 | + | % TODO: Get the redundancy version from the current redundancy |
| 129 | + | % version index, obj.rvInd(iharq). The rv should be |
| 130 | + | % rv = obj.rvSeq(irv+1), |
| 131 | + | % where irv cycles, 0,1,2,3,0,1,2,3,... |
| 132 | + | |
| 133 | + | % Encode the DL-SCH transport block |
| 134 | + | codedTrBlock = obj.encDLSCH(obj.pdschConfig.Modulation, ... |
| 135 | + | obj.pdschConfig.NumLayers, pdschInfo.G, rv, iharq-1); |
| 136 | + | |
| 137 | + | % Increment the RV sequence |
| 138 | + | obj.rvInd(iharq) = obj.rvInd(iharq) + 1; |
| 139 | + | |
| 140 | + | % Modulate the PDSCH modulation |
| 141 | + | pdschSymbols = nrPDSCH(obj.carrierConfig, obj.pdschConfig, ... |
| 142 | + | codedTrBlock); |
| 143 | + | |
| 144 | + | % Map the modulated symbols to the OFDM grid |
| 145 | + | txGrid(pdschInd) = pdschSymbols; |
| 146 | + | |
| 147 | + | end |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | end |
| 152 | + | end |
| 153 | + | |
| 154 | + | |