Main Content

nrPUCCHDecode

Decode PUCCH modulation symbols

Since R2021b

    Description

    [uciBits,symbols,detMet] = nrPUCCHDecode(carrier,pucch,ouci,sym) decodes physical uplink control channel (PUCCH) format-specific decoding and returns the uplink control information (UCI) bits, uciBits, as defined in TS 38.211 Sections 6.3.2.3 to 6.3.2.6 for all PUCCH formats. The function also returns received constellation symbols, symbols, and the detection metric, detMet. Input carrier specifies the carrier configuration. Input pucch specifies the format-specific PUCCH configuration. Input ouci specifies the uncoded UCI bits. When the number of UCI bits is less than 12, the function performs discontinuous transmission (DTX) detection by finding the normalized correlation coefficient of all of the possible reference sequences and then compares the maximum value against a threshold.

    example

    [uciBits,symbols,detMet] = nrPUCCHDecode(carrier,pucch,ouci,sym,nVar) specifies the variance of additive white Gaussian noise (AWGN) on the received symbols.

    [uciBits,symbols,detMet] = nrPUCCHDecode(___,'DetectionThreshold',detectionThreshold) specifies the detection threshold to perform DTX in addition to any of the input argument combinations in the previous syntaxes.

    example

    Examples

    collapse all

    Create a default carrier configuration object.

    carrier = nrCarrierConfig;

    Specify a 15 kHz carrier with a normal cyclic prefix. Set the slot number to 63.

    carrier.SubcarrierSpacing = 15;
    carrier.CyclicPrefix = 'normal';
    carrier.NSlot = 63;

    Create a default PUCCH format 0 configuration object.

    pucch = nrPUCCH0Config;

    Specify the first symbol index in the PUCCH transmission slot as 11 and the number of allocated PUCCH symbols as 2. Enable intraslot frequency hopping and group hopping. Set the hopping identity to 512 and the initial cyclic shift to 5.

    pucch.SymbolAllocation = [11 2];
    pucch.FrequencyHopping = 'intraSlot';
    pucch.GroupHopping = 'enable';
    pucch.HoppingID = 512;
    pucch.InitialCyclicShift = 5;

    Specify a transmission without hybrid automatic repeat request acknowledgment (HARQ-ACK) and with a positive scheduling request (SR).

    ack = zeros(0,1);
    sr = 1;           % Positive SR transmission

    Generate PUCCH format 0 modulation symbols.

    sym = nrPUCCH(carrier,pucch,{ack sr});

    Decode the PUCCH format 0 modulation symbols.

    uci = nrPUCCHDecode(carrier,pucch,[numel(ack) numel(sr)],sym); 

    Verify that the received UCI bits match the transmitted UCI bits.

    isequal(uci{1},ack)
    ans = logical
       1
    
    
    isequal(uci{2},sr)
    ans = logical
       1
    
    

    Create a default carrier configuration object.

    carrier = nrCarrierConfig;

    Specify a 60 kHz carrier with an extended cyclic prefix. Set the slot number to 7.

    carrier.SubcarrierSpacing = 60;
    carrier.CyclicPrefix = 'extended';
    carrier.NSlot = 7;

    Create a default PUCCH format 1 configuration object.

    pucch = nrPUCCH1Config;

    Specify the first symbol index in the PUCCH transmission slot as 3 and the number of allocated PUCCH symbols as 9. Enable intraslot frequency hopping and group hopping. Set the hopping identity to 512, the initial cyclic shift to 9, and the orthogonal cover code index to 1.

    pucch.SymbolAllocation = [3 9];
    pucch.FrequencyHopping = 'intraSlot';
    pucch.GroupHopping = 'enable';
    pucch.HoppingID = 512;
    pucch.InitialCyclicShift = 9;
    pucch.OCCI = 1;

    Generate PUCCH format 1 modulation symbols for 1-bit UCI.

    uci = 1;
    sym = nrPUCCH(carrier,pucch,uci);

    Decode the PUCCH format 1 modulation symbols with a detection threshold of 0.7.

    rxUCI = nrPUCCHDecode(carrier,pucch,numel(uci),sym,'DetectionThreshold',0.7);

    Verify that the received UCI bits match the transmitted UCI bits.

    isequal(rxUCI{1},uci)
    ans = logical
       1
    
    

    Create a default carrier configuration object.

    carrier = nrCarrierConfig;

    Create a default PUCCH format 2 configuration object.

    pucch = nrPUCCH2Config;

    Specify the data scrambling identity as 1000 and the radio network temporary identifier as 160.

    pucch.NID = 1000;
    pucch.RNTI = 160;

    Get random UCI bits.

    ouci = 20;
    uci = randi([0 1],ouci,1);

    Encode the UCI bits.

    uciCW = nrUCIEncode(uci,100);

    Generate PUCCH modulation format 2 symbols.

    sym = nrPUCCH(carrier,pucch,uciCW);

    Decode the PUCCH modulation format 2 symbols.

    rxUCI = nrPUCCHDecode(carrier,pucch,ouci,sym);

    Verify that the received UCI bits match the transmitted UCI bits.

    isequal(uciCW,double(rxUCI{1}<0))
    ans = logical
       1
    
    

    Create a default carrier configuration object.

    carrier = nrCarrierConfig;

    Specify a 30 kHz carrier with an extended cyclic prefix. Set the number of resource blocks in the carrier resource grid to 80.

    carrier.SubcarrierSpacing = 30;
    carrier.NSizeGrid = 80;

    Create a default PUCCH format 3 configuration object.

    pucch = nrPUCCH3Config;

    Specify the modulation scheme as pi/2-BPSK, the physical resource blocks (PRB) allocation of the PUCCH to range from 70 to 74 (occupying 5 resource blocks), and the radio network temporary identifier as 2560.

    pucch.Modulation = 'pi/2-BPSK';
    pucch.PRBSet = 70:74;
    pucch.RNTI = 2560;

    Generate PUCCH format 3 resource element indices.

    [pucchIndices,pucchInfo] = nrPUCCHIndices(carrier,pucch);
    G = pucchInfo.G;                                          % Rate-matched length

    Get random UCI bits.

    ouci = 30;
    uciBits = randi([0 1],ouci,1);

    Encode the UCI bits.

    codedUCI = nrUCIEncode(uciBits,G);

    Generate PUCCH format 3 modulated symbols.

    sym = nrPUCCH(carrier,pucch,codedUCI);

    Generate demodulation reference signal (DM-RS) symbols and indices.

    dmrsSym = nrPUCCHDMRS(carrier,pucch);
    dmrsInd = nrPUCCHDMRSIndices(carrier,pucch);

    Create a resource grid. Map the PUCCH symbols and the DM-RS symbols to the grid.

    resGrid = nrResourceGrid(carrier);
    resGrid(pucchIndices) = sym;
    resGrid(dmrsInd) = dmrsSym;

    Perform orthogonal frequency division multiplexing (OFDM) modulation.

    txWaveform = nrOFDMModulate(carrier,resGrid);

    Perform back-to-back decoding.

    rxWaveform = txWaveform;
    rxGrid = nrOFDMDemodulate(carrier,rxWaveform);

    Extract PUCCH format 3 symbols from the received grid.

    rxSym = nrExtractResources(pucchIndices,rxGrid);

    Decode the PUCCH format 3 modulation symbols, and then decode the UCI bits.

    rxUCI = nrPUCCHDecode(carrier,pucch,ouci,rxSym);
    rxUCIBits = nrUCIDecode(rxUCI{1},ouci);

    Verify that the received UCI bits match the transmitted UCI bits.

    isequal(uciBits,rxUCIBits)
    ans = logical
       1
    
    

    Create a default carrier configuration object, and then set the cell identity as 140.

    carrier = nrCarrierConfig;
    carrier.NCellID = 140;

    Create a default PUCCH format 4 configuration object.

    pucch = nrPUCCH4Config;

    Specify the spreading factor as 4, the OCCI as 3, and the radio network temporary identifier as 750.

    pucch.SpreadingFactor = 4;
    pucch.OCCI = 3;
    pucch.RNTI = 750;

    Get random UCI bits.

    ouci = 20;
    uci = randi([0 1],ouci,1);

    Encode the UCI bits.

    uciCW = nrUCIEncode(uci,60);

    Generate PUCCH modulation format 4 symbols.

    sym = nrPUCCH(carrier,pucch,uciCW);

    Decode the PUCCH modulation format 4 symbols.

    rxUCI = nrPUCCHDecode(carrier,pucch,ouci,sym);

    Verify that the received UCI bits match the transmitted UCI bits.

    isequal(uciCW,double(rxUCI{1}<0))
    ans = logical
       1
    
    

    Compare the transmission and reception of PUCCH formats 0 and 2 for two different user equipments.

    Carrier Configuration

    Create a default carrier configuration object, and then set the cell identity to 10.

    carrier = nrCarrierConfig;
    carrier.NCellID = 10;

    PUCCH Configuration

    Create a PUCCH format 0 configuration object with the specified properties for user equipment (UE) 1.

    pucch0 = nrPUCCH0Config;
    pucch0.PRBSet = 0;
    pucch0.HoppingID = 0;

    Create a PUCCH format 2 configuration object with the specified properties for UE 2.

    pucch2 = nrPUCCH2Config;
    pucch2.PRBSet = 0;
    pucch2.RNTI = 10;

    Channel Propagation Model Configuration

    Define the channel configuration structure using an nrTDLChannel System object.

    channel = nrTDLChannel;
    channel.NumReceiveAntennas = 4;
    info1 = nrOFDMInfo(carrier);
    channel.SampleRate = info1.SampleRate;                         % Set waveform sample rate
    chInfo = info(channel);
    maxChDelay = chInfo.MaximumChannelDelay;

    Noise Configuration

    Normalize the noise power of the carrier, and the configure the random number generator.

    SNRdB = 21.0;
    SNR = 10^(SNRdB/20);
    N = 1/(SNR*sqrt(double(info1.Nfft)))/sqrt(2.0);
    rng('default');

    PUCCH Symbols and Indices Generation for Format 0 and Format 2

    Specify the HARQ-ACK bits for PUCCH format 0.

    hi1 = [0;1];
    disp('hi1:');
    hi1:
    
    disp(hi1.');
         0     1
    

    Generate PUCCH format 0 modulation symbols.

    pucch0Sym = nrPUCCH(carrier,pucch0,hi1);

    Generate DM-RS symbols for PUCCH formats 0 and 2.

    pucch0DMRSSym = nrPUCCHDMRS(carrier,pucch0);
    pucch2DRSSym = nrPUCCHDMRS(carrier,pucch2);

    Generate PUCCH format 2 resource element indices.

    [pucch2Ind,pucch2Info] = nrPUCCHIndices(carrier,pucch2);

    Create channel quality information (CQI) bits.

    cqi = [0; 1; 1; 0; 0; 1];
    disp('cqi:');
    cqi:
    
    disp(cqi.');
         0     1     1     0     0     1
    

    Encode the CQI bits.

    codedcqi = nrUCIEncode(cqi,pucch2Info.G);

    Generate PUCCH format 2 modulation symbols.

    pucch2Sym = nrPUCCH(carrier,pucch2,codedcqi);

    PUCCH Index Generation for Format 0 and Format 2

    Generate PUCCH indices for formats 0 and 2.

    pucch0Indices = nrPUCCHIndices(carrier,pucch0);    
    pucch2Indices = nrPUCCHIndices(carrier,pucch2);        

    Generate DM-RS indices for PUCCH formats 0 and 2.

    pucch0DMRSIndices = nrPUCCHDMRSIndices(carrier,pucch0);  
    pucch2DMRSIndices = nrPUCCHDMRSIndices(carrier,pucch2);

    Transmission with PUCCH Format 0

    Create a resource grid. Map the PUCCH symbols and DM-RS symbols of format 0 to the grid.

    grid1 = nrResourceGrid(carrier);
    grid1(pucch0Indices) = pucch0Sym;
    grid1(pucch0DMRSIndices) = pucch0DMRSSym;

    Perform OFDM modulation and pass the waveform through the tapped delay line (TDL) channel.

    txwave1 = nrOFDMModulate(carrier,grid1);
    txwave1 = [txwave1; zeros(maxChDelay,size(txwave1,2))];
    [rxwave1,pathGains1,sampleTimes1] = channel(txwave1);

    Transmission with PUCCH Format 2

    Create a resource grid. Map the PUCCH symbols and DM-RS symbols of format 2 to the grid.

    grid2 = nrResourceGrid(carrier);
    grid2(pucch2Indices) = pucch2Sym;            
    grid2(pucch2DMRSIndices) = pucch2DRSSym; 

    Perform OFDM modulation, and then pass the waveform through the TDL channel.

    txwave2 = nrOFDMModulate(carrier,grid2);
    release(channel);
    channel.Seed = 15;
    txwave2 = [txwave2; zeros(maxChDelay,size(txwave2,2))];
    [rxwave2,pathGains,sampleTimes] = channel(txwave2);

    Reception at Base Station

    Add AWGN to the received signal.

    rxwave = rxwave1 + rxwave2;                                  % Add both the faded signals      
    noise = N*complex(randn(size(rxwave)),randn(size(rxwave)));
    rxwave = rxwave + noise;

    Demodulate the received signal and extract PUCCH format 0 RE indices.

    rxgrid1 = nrOFDMDemodulate(carrier,rxwave(1:end,:));
    rxpucch0 = nrExtractResources(pucch0Indices,rxgrid1);

    Decode PUCCH Format 0 Symbols

    Decode the PUCCH format 0 symbols.

    rxhi1 = nrPUCCHDecode(carrier,pucch0,length(hi1),rxpucch0);
    disp('rxhi1:');
    rxhi1:
    
    disp(rxhi1{1}.');
       0   1
    

    Verify that the received HARQ-ACK bits match the transmitted HARQ-ACK bits.

    if isequal(hi1,rxhi1{1})
        disp('PUCCH format 0 data decoded')
    else
        disp('PUCCH format 0 data not decoded')
    end
    PUCCH format 0 data decoded
    

    Decode PUCCH Format 2 Symbols

    Estimate the timing offset for the transmission, and then perform the OFDM demodulation on the received waveform.

    [t,mag] = nrTimingEstimate(carrier,rxwave,pucch2DMRSIndices,pucch2DRSSym);
    if t > maxChDelay
        t = 0;
    end
    rxgrid2 = nrOFDMDemodulate(carrier,rxwave(1+t:end,:));

    Get the practical channel estimate, and then extract PUCCH format 2 RE indices.

    [H2, n0] = nrChannelEstimate(carrier,rxgrid2,pucch2DMRSIndices,pucch2DRSSym);
    [pucchrx2, pucchH2] = nrExtractResources(pucch2Indices,rxgrid2,H2);

    Perform minimum mean square error (MMSE) equalization on the extracted PUCCH format 2 resource elements.

    pucch2eq = nrEqualizeMMSE(pucchrx2,pucchH2,n0);

    Decode the PUCCH format 2 modulation symbols, and then decode the CQI bits.

    rxcodedcqi = nrPUCCHDecode(carrier,pucch2,length(cqi),pucch2eq);
    rxcqi = nrUCIDecode(rxcodedcqi{1},length(cqi));
    disp('rxcqi:');
    rxcqi:
    
    disp(rxcqi.');
       0   1   1   0   0   1
    

    Verify that the received CQI bits match the transmitted CQI bits.

    if isequal(cqi,rxcqi)
        disp('PUCCH format 2 data decoded')
    else
        disp('PUCCH format 2 data not decoded')
    end
    PUCCH format 2 data decoded
    

    Input Arguments

    collapse all

    Carrier configuration parameters for a specific OFDM numerology, specified as an nrCarrierConfig object. This function uses only these properties of the nrCarrierConfig object.

    PUCCH configuration parameters, specified as one of these options.

    For PUCCH formats 0 to 3 and operation with shared spectrum channel access for frequency range 1 (FR1), set the corresponding Interlacing property to true, and use the RBSetIndex and InterlaceIndex object properties to specify the allocated frequency resources. In addition, for PUCCH formats 2 and 3, you can use the SpreadingFactor and OCCI properties with single-interlace configurations. (since R2023b)

    Number of uncoded UCI bits, specified as a nonnegative integer or depending on the format type.

    • For format 0, you must specify a nonnegative integer or a two-element vector of nonnegative integers.

      • When you specify this value as a scalar, the uncoded UCI bits represents the hybrid automatic repeat request acknowledgment (HARQ-ACK) bits.

      • When you specify this value as a vector, the first element represents the HARQ-ACK bits, and the second element represents the scheduling request (SR) bit.

    • For format 1, you must specify a nonnegative integer. When you specify this value, the uncoded UCI bits represents the HARQ-ACK bits or SR bits.

    • For formats 2, 3, and 4, the uncoded UCI bits represents the number of UCI bits in both parts.

    Data Types: double

    PUCCH modulation symbols for the specified format, returned as a complex-valued column vector or complex-valued matrix.

    For formats 0 and 1, the sym argument must be a matrix with the number of columns equal to the number of receive antennas. For formats 2, 3, and 4, the sym argument must be a column vector.

    Data Types: single | double
    Complex Number Support: Yes

    Noise variance, specified as a nonnegative scalar. The function scales the symbols with the variance of additive white Gaussian noise (AWGN). The default value corresponds to an signal to noise ratio (SNR) of 100 dB, assuming unit signal power.

    When the noise variance value is less than 1e-10, the function uses the value of 1e-10.

    Data Types: double

    Detection threshold, specified as [] or a scalar in range from 0 to 1. When you do not specify the input or you set it to [], the function selects one of these default values based on the format type.

    • For format 0, the default value is 0.49 for one OFDM symbol and 0.42 for two OFDM symbols.

    • For format 1, the default value is 0.22.

    • For formats 2, 3, and 4, the default value is 0.45.

    Data Types: double

    Output Arguments

    collapse all

    UCI bits, returned as a one- or two-element cell array depending on the format type. For format 0 and 1, the data type of uciBits is int8. For format 2, 3, and 4, uciBits inherits the data type of the sym input.

    • For format 0, uciBits is a one- or two-element cell array with UCI hard bits.

      • For a one-element cell array, the function returns the HARQ-ACK hard bits.

      • For a two-element cell array, the function returns the first element as HARQ-ACK hard bits and the second element as SR bit.

      PUCCH format 0 decoding involves DTX detection followed by finding the sequence that has the maximum normalized correlation metric.

    • For format 1, uciBits is a one-element cell array with UCI hard bits. PUCCH format 1 decoding involves DTX detection followed by matched filtering.

    • For formats 2, 3, and 4, uciBits is a one-element cell array with UCI soft bits. For PUCCH formats 2, 3, and 4, UCI soft bits are returned post DTX detection (applicable up to 12 uncoded uci bits) and inverse processing of PUCCH encoding.

    Data Types: cell

    Received constellation symbols, returned as a column-valued column vector. symbols inherits the data type of the sym input.

    Data Types: double | single
    Complex Number Support: Yes

    Detection metric, returned as an integer. For PUCCH formats 2, 3, and 4, when the ouci input is not in the range from 3 to 11, this output is 0.

    Data Types: double | single

    References

    [1] 3GPP TS 38.211. “NR; Physical channels and modulation.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

    Extended Capabilities

    Version History

    Introduced in R2021b

    expand all