BER Performance of PUCCH Format 0

PUCCH Format 0 in 5G is used to transfer 1 or 2 HARQ acknowledgements and/or a Scheduling Request (SR). It occupies 1 Resource Block in the frequency domain and either 1 or 2 symbols in the time domain. These codes are - locally testable, - locally decodable

In this tutorial, we will analyze the bit error rate performance of PUCCH Format 0 for different link conditions characterized by signal to noise ratio(SNR). The content of the tutorial is as follows:

Table of Contents

Import Libraries

Python Libraries

%matplotlib widget
import matplotlib.pyplot as plt
import matplotlib as mpl

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"

import numpy      as np

5G ToolKit Libraries

##
import sys
sys.path.append("../../")

from toolkit5G.SequenceGeneration import CyclicShiftHopping
from toolkit5G.Utils import VectorToBinaryArray

from toolkit5G.PhysicalChannels      import PUCCHFormat0
from toolkit5G.PhysicalChannels      import PUCCHFormat0Decoder
from toolkit5G.PhysicalChannels      import MCSEstimation

Simulation Parameters

The simulation parameters are:

  • nID defines the hopping ID

  • m_CS defines the cyclic shift offset based on the control information carried

  • maxPRBs defines the maximum number of resource blocks

  • numBatches defines Number of Batches

  • indexPUCCH defines the resource index if common resource is configured

  • slotNumber defines the slot number

  • startingPRB defines the index of first Physical Resource Block prior to frequency hopping or for no frequency hopping

  • controlInfo defines the control information carried on PUCCH Format0

  • secondHopPRB defines the index of the first Physical Resource Block after frequency hopping

  • numofSymbols defines the number of symbols

  • numOfInterlaces defines the number of interlaces, if interlaced transmission is enabled for Dedicated resource configuration

  • initialCycShift defines the initial cyclic shift

  • interlaceIndex_0 defines the index of a first interlace, if interlaced transmission is enabled for Dedicated resource configuration

  • interlaceIndex_1 defines the index of a second interlace, if interlaced transmission is enabled for Dedicated resource configuration and numOfInterlaces is two

  • numInterlacedRBs defines the number of interlaced resource blocks, if interlaced transmission is enabled

  • symbolIndex_start defines the starting symbol index

  • pucch_GroupHopping defines if group and/or sequence hopping is enabled/disabled

  • pucch_ResourceCommon defines if common resource/dedicated resource configuration is used

  • intraSlotFreqHopping defines if intraslot frequency hopping is enabled/disabled

  • interlacedTransmission defines if interlaced transmission is enabled/disabled

numBatches             = np.random.randint(1, 1000)
interlacedTransmission = np.random.choice([True, False])

pucch_ResourceCommon   = np.random.choice([True, False])



print("Number of Batches          : "+str(numBatches))
print("Interlaced Transmission    : "+str(interlacedTransmission) )
print("Common Resource Status     : "+str(pucch_ResourceCommon))

if pucch_ResourceCommon == False:
    indexPUCCH             = None
    initialCycShift        = np.random.randint(0, 12)
    symbolIndex_start      = np.random.randint(0, 14)
    if symbolIndex_start == 13:
        numofSymbols = 1
    else:
        numofSymbols = np.random.choice([1, 2])

    print("numofSymbols               : "+str(numofSymbols))
    print("symbolIndex_start          : "+str(symbolIndex_start))
    print("initialCS                  : "+str(initialCycShift))
else:
    indexPUCCH        = np.random.randint(0, 3)
    print("PUCCH Index - Common       : "+str(indexPUCCH))
    initialCycShift   = None
    symbolIndex_start = None
    numofSymbols      = None

if interlacedTransmission == True or numofSymbols == 1:
    intraSlotFreqHopping = False
elif pucch_ResourceCommon == True:
    intraSlotFreqHopping = True
else:
    intraSlotFreqHopping = np.random.choice([True, False])
print("Hopping Status             : "+str(intraSlotFreqHopping))

slotNumber            = np.random.randint(0, 11)
nID                   = np.random.randint(0, 1024)
validHoppingInfo      = np.array(['neither', 'Neither', 'enable' , 'Enable' , 'disable', 'Disable'])
pucch_GroupHopping    = np.random.choice(validHoppingInfo)

controlInfo = np.random.choice(["1-HARQ", "2-HARQ", "SR", "HARQ+SR"])
print("Control Info               : "+str(controlInfo))

if controlInfo == "1-HARQ":
    m_CS  = np.random.choice([0, 6], size = numBatches)

elif controlInfo == "2-HARQ":
    m_CS  = np.random.choice([0, 3, 6, 9], size = numBatches)

elif controlInfo == "SR":
    m_CS = np.random.choice([0], size = numBatches)

elif controlInfo == "HARQ+SR":
    m_CS  = np.random.choice([0, 3, 6, 9], size = numBatches)

print("slotNumber                 : "+str(slotNumber))
print("nID                        : "+str(nID))
print("pucch_GroupHopping Info    : "+str(pucch_GroupHopping))
print("slotNumber                 : "+str(slotNumber))
print("m_CS                       : "+str(m_CS))

if interlacedTransmission == True:
    numInterlacedRBs  = 10 if pucch_ResourceCommon == True else np.random.choice([10, 11])
    print("Number of InterlacedRBs    : "+str(numInterlacedRBs))
else:
    numInterlacedRBs  = None


if pucch_ResourceCommon == False:
    refNum           = np.random.choice([0, 1])
    maxPRBs          = 275
    startingPRB      = int(np.floor(maxPRBs/2) * refNum + np.random.randint(0, np.ceil(maxPRBs/2)))
    print("Starting PRB               : "+str(startingPRB))
    secondHopPRB     = None
    if intraSlotFreqHopping == True:
        secondHopPRB     = int(np.floor(maxPRBs/2) * int(not(refNum)) + np.random.randint(0, np.ceil(maxPRBs/2)))
        print("Second Hop PRB             : "+str(secondHopPRB))
else:
    startingPRB      = None
    secondHopPRB     = None

if interlacedTransmission == True:
    numOfInterlaces  = 1 if pucch_ResourceCommon == True else np.random.choice([1, 2])
    print("Number of interlaces       : "+str(numOfInterlaces))
    print("Number Of Interlaced RBs   : "+str(numInterlacedRBs))
    if pucch_ResourceCommon == False:
        interlaceIndex_0 = np.random.randint(0, 10)
        print("interlaceIndex_0           : "+str(interlaceIndex_0))
        interlaceIndex_1 = None
        if numOfInterlaces == 2:
            interlaceIndex_1 = np.mod(interlaceIndex_0+2, 9)
            print("interlaceIndex_1           : "+str(interlaceIndex_1))

    else:
        interlaceIndex_0 = None
        interlaceIndex_1 = None
else:
    numOfInterlaces  = None
    interlaceIndex_0 = None
    interlaceIndex_1 = None
Number of Batches          : 853
Interlaced Transmission    : False
Common Resource Status     : False
numofSymbols               : 1
symbolIndex_start          : 0
initialCS                  : 8
Hopping Status             : False
Control Info               : 2-HARQ
slotNumber                 : 7
nID                        : 779
pucch_GroupHopping Info    : disable
slotNumber                 : 7
m_CS                       : [0 0 6 0 9 6 6 0 3 3 6 0 0 0 0 9 9 9 3 0 0 9 0 9 9 9 0 9 6 0 6 6 3 9 6 9 9
 0 6 3 6 3 3 9 6 3 6 3 0 3 3 3 0 9 6 3 6 6 6 0 6 6 3 9 0 6 3 6 0 6 9 0 9 3
 9 0 9 6 0 0 3 0 9 3 0 6 6 3 3 9 0 9 9 0 0 9 9 3 0 6 0 9 6 6 3 6 9 3 0 9 9
 0 0 0 0 9 3 3 6 3 9 0 9 9 3 9 3 3 0 3 6 0 0 6 0 9 6 6 0 6 0 6 9 3 6 0 3 3
 9 0 9 0 3 6 6 0 3 3 9 9 3 3 3 9 6 6 9 0 3 3 6 3 6 3 6 0 9 3 9 9 0 3 9 9 9
 6 6 6 0 0 6 0 0 3 6 3 9 3 0 6 0 9 9 0 9 0 9 3 9 9 3 9 9 6 9 6 0 0 0 6 3 6
 9 0 0 0 3 6 9 6 6 0 0 9 3 3 3 0 3 9 3 3 9 9 3 6 9 6 3 9 6 9 3 0 3 9 6 3 0
 0 0 3 3 0 6 9 3 9 0 9 0 6 0 9 3 3 9 0 9 9 6 3 3 9 9 6 0 3 0 6 9 9 0 3 6 9
 3 3 6 6 9 6 9 3 0 9 9 6 0 3 9 9 3 9 9 0 3 0 3 6 9 3 3 0 0 6 3 6 9 9 9 0 0
 3 9 6 9 3 3 9 9 9 0 6 9 3 0 9 0 0 0 9 9 0 9 9 6 6 0 6 0 9 0 0 3 9 6 6 0 3
 3 3 9 3 3 3 0 3 9 9 3 6 9 6 3 3 0 9 9 0 3 0 0 3 3 0 6 6 9 6 9 6 6 0 9 0 0
 6 6 6 9 9 3 3 9 9 6 9 9 3 6 3 9 9 3 6 6 3 0 9 6 3 9 3 0 3 0 6 6 3 9 9 3 3
 3 0 3 0 6 6 6 3 9 0 3 6 6 9 9 0 6 3 0 3 9 3 9 9 9 0 3 0 3 3 3 0 0 3 6 6 0
 6 9 9 3 3 0 6 6 0 6 9 9 0 3 6 6 3 9 9 0 6 3 6 6 3 6 0 9 3 9 6 0 0 6 6 0 9
 3 6 9 0 9 3 6 9 6 6 6 9 9 0 3 9 6 9 0 6 3 9 3 6 9 3 3 3 0 9 3 3 6 3 3 6 3
 0 6 6 6 3 3 0 0 6 6 3 0 3 6 6 6 6 3 0 3 3 9 6 0 9 3 0 9 6 0 9 3 6 9 9 6 6
 9 9 0 6 3 3 6 0 0 3 3 9 0 9 0 0 0 9 0 0 0 3 3 0 9 6 0 0 3 0 3 3 0 3 0 6 9
 3 0 6 0 6 9 3 0 9 6 3 0 0 3 3 0 3 9 0 0 9 9 6 9 6 9 6 0 6 3 0 6 9 9 0 6 3
 6 9 3 6 0 0 3 3 6 0 9 3 3 6 0 9 9 9 0 3 6 3 6 3 0 9 6 0 9 6 9 9 6 6 3 6 0
 9 0 0 0 0 3 0 3 0 9 6 3 3 0 0 6 9 3 3 0 6 0 9 3 9 3 6 0 9 6 9 3 0 0 0 3 3
 6 6 3 6 0 9 0 9 9 6 3 9 9 6 9 6 3 3 6 3 0 6 9 9 9 9 6 9 9 6 9 3 0 3 6 6 6
 6 9 3 0 6 6 3 3 0 3 3 3 3 9 3 0 3 6 3 0 3 9 3 3 9 0 3 6 6 3 9 3 3 0 3 6 3
 6 6 6 9 9 6 3 3 6 3 0 6 3 3 9 9 9 9 9 9 9 6 3 0 3 6 6 0 0 3 9 6 9 9 6 9 9
 9 3]
Starting PRB               : 168

Format 0

This method generates the sequence and maps it onto the resources allocated.

pucchFormat0Obj  = PUCCHFormat0(numBatches, m_CS, controlInfo, nID, slotNumber, pucch_GroupHopping, initialCycShift, numofSymbols, symbolIndex_start)
pucchFormat0Grid = pucchFormat0Obj(intraSlotFreqHopping, interlacedTransmission, pucch_ResourceCommon, indexPUCCH, numInterlacedRBs, startingPRB, secondHopPRB, numOfInterlaces, interlaceIndex_0, interlaceIndex_1)
intraSlotFreqHopping     : False
interlacedTransmission   : False
pucch_ResourceCommon     : False
numBatches               : 853
m_CS                     : [0 0 6 0 9 6 6 0 3 3 6 0 0 0 0 9 9 9 3 0 0 9 0 9 9 9 0 9 6 0 6 6 3 9 6 9 9
 0 6 3 6 3 3 9 6 3 6 3 0 3 3 3 0 9 6 3 6 6 6 0 6 6 3 9 0 6 3 6 0 6 9 0 9 3
 9 0 9 6 0 0 3 0 9 3 0 6 6 3 3 9 0 9 9 0 0 9 9 3 0 6 0 9 6 6 3 6 9 3 0 9 9
 0 0 0 0 9 3 3 6 3 9 0 9 9 3 9 3 3 0 3 6 0 0 6 0 9 6 6 0 6 0 6 9 3 6 0 3 3
 9 0 9 0 3 6 6 0 3 3 9 9 3 3 3 9 6 6 9 0 3 3 6 3 6 3 6 0 9 3 9 9 0 3 9 9 9
 6 6 6 0 0 6 0 0 3 6 3 9 3 0 6 0 9 9 0 9 0 9 3 9 9 3 9 9 6 9 6 0 0 0 6 3 6
 9 0 0 0 3 6 9 6 6 0 0 9 3 3 3 0 3 9 3 3 9 9 3 6 9 6 3 9 6 9 3 0 3 9 6 3 0
 0 0 3 3 0 6 9 3 9 0 9 0 6 0 9 3 3 9 0 9 9 6 3 3 9 9 6 0 3 0 6 9 9 0 3 6 9
 3 3 6 6 9 6 9 3 0 9 9 6 0 3 9 9 3 9 9 0 3 0 3 6 9 3 3 0 0 6 3 6 9 9 9 0 0
 3 9 6 9 3 3 9 9 9 0 6 9 3 0 9 0 0 0 9 9 0 9 9 6 6 0 6 0 9 0 0 3 9 6 6 0 3
 3 3 9 3 3 3 0 3 9 9 3 6 9 6 3 3 0 9 9 0 3 0 0 3 3 0 6 6 9 6 9 6 6 0 9 0 0
 6 6 6 9 9 3 3 9 9 6 9 9 3 6 3 9 9 3 6 6 3 0 9 6 3 9 3 0 3 0 6 6 3 9 9 3 3
 3 0 3 0 6 6 6 3 9 0 3 6 6 9 9 0 6 3 0 3 9 3 9 9 9 0 3 0 3 3 3 0 0 3 6 6 0
 6 9 9 3 3 0 6 6 0 6 9 9 0 3 6 6 3 9 9 0 6 3 6 6 3 6 0 9 3 9 6 0 0 6 6 0 9
 3 6 9 0 9 3 6 9 6 6 6 9 9 0 3 9 6 9 0 6 3 9 3 6 9 3 3 3 0 9 3 3 6 3 3 6 3
 0 6 6 6 3 3 0 0 6 6 3 0 3 6 6 6 6 3 0 3 3 9 6 0 9 3 0 9 6 0 9 3 6 9 9 6 6
 9 9 0 6 3 3 6 0 0 3 3 9 0 9 0 0 0 9 0 0 0 3 3 0 9 6 0 0 3 0 3 3 0 3 0 6 9
 3 0 6 0 6 9 3 0 9 6 3 0 0 3 3 0 3 9 0 0 9 9 6 9 6 9 6 0 6 3 0 6 9 9 0 6 3
 6 9 3 6 0 0 3 3 6 0 9 3 3 6 0 9 9 9 0 3 6 3 6 3 0 9 6 0 9 6 9 9 6 6 3 6 0
 9 0 0 0 0 3 0 3 0 9 6 3 3 0 0 6 9 3 3 0 6 0 9 3 9 3 6 0 9 6 9 3 0 0 0 3 3
 6 6 3 6 0 9 0 9 9 6 3 9 9 6 9 6 3 3 6 3 0 6 9 9 9 9 6 9 9 6 9 3 0 3 6 6 6
 6 9 3 0 6 6 3 3 0 3 3 3 3 9 3 0 3 6 3 0 3 9 3 3 9 0 3 6 6 3 9 3 3 0 3 6 3
 6 6 6 9 9 6 3 3 6 3 0 6 3 3 9 9 9 9 9 9 9 6 3 0 3 6 6 0 0 3 9 6 9 9 6 9 9
 9 3]
controlInfo              : 2-HARQ
nID                      : 779
slotNumber               : 7
pucch_GroupHopping       : disable

initialCyclicShift       : 8
numOfSymbols             : 1
symbolIndexStart         : 0

********************Sequence Generation************************
PUCCH Format0 Sequence   : (853, 1, 12)

startingPRB              : 168
numOfInterlaces          : None

********************Resource Mapping************************
OFDM Grid                : (853, 3300, 14)

Format 0 Decoder

This method decodes the sequences mapped on the OFDM Grid.

pucchFormat0DecoderObj = PUCCHFormat0Decoder(numofSymbols, symbolIndex_start)
pucchFormat0DecoderOp  = pucchFormat0DecoderObj(pucchFormat0Grid, intraSlotFreqHopping, interlacedTransmission, pucch_ResourceCommon, indexPUCCH, numInterlacedRBs, startingPRB, secondHopPRB, numOfInterlaces, interlaceIndex_0, interlaceIndex_1)

M_CS Estimation

This method estimates the cyclic shift offset, thereby estimating the information bits

hardOut = np.random.choice([True, False])
hardOut
False
Obj_mcs      = MCSEstimation(interlacedTransmission, pucch_ResourceCommon, hardOut)
estimatem_CS = Obj_mcs(pucchFormat0DecoderOp, controlInfo, indexPUCCH, nID, slotNumber, symbolIndex_start, numofSymbols, initialCycShift, numInterlacedRBs)
estimatem_CS[0], estimatem_CS[1], m_CS, Obj_mcs.controlInfo
(array([0, 0, 6, 0, 9, 6, 6, 0, 3, 3, 6, 0, 0, 0, 0, 9, 9, 9, 3, 0, 0, 9,
        0, 9, 9, 9, 0, 9, 6, 0, 6, 6, 3, 9, 6, 9, 9, 0, 6, 3, 6, 3, 3, 9,
        6, 3, 6, 3, 0, 3, 3, 3, 0, 9, 6, 3, 6, 6, 6, 0, 6, 6, 3, 9, 0, 6,
        3, 6, 0, 6, 9, 0, 9, 3, 9, 0, 9, 6, 0, 0, 3, 0, 9, 3, 0, 6, 6, 3,
        3, 9, 0, 9, 9, 0, 0, 9, 9, 3, 0, 6, 0, 9, 6, 6, 3, 6, 9, 3, 0, 9,
        9, 0, 0, 0, 0, 9, 3, 3, 6, 3, 9, 0, 9, 9, 3, 9, 3, 3, 0, 3, 6, 0,
        0, 6, 0, 9, 6, 6, 0, 6, 0, 6, 9, 3, 6, 0, 3, 3, 9, 0, 9, 0, 3, 6,
        6, 0, 3, 3, 9, 9, 3, 3, 3, 9, 6, 6, 9, 0, 3, 3, 6, 3, 6, 3, 6, 0,
        9, 3, 9, 9, 0, 3, 9, 9, 9, 6, 6, 6, 0, 0, 6, 0, 0, 3, 6, 3, 9, 3,
        0, 6, 0, 9, 9, 0, 9, 0, 9, 3, 9, 9, 3, 9, 9, 6, 9, 6, 0, 0, 0, 6,
        3, 6, 9, 0, 0, 0, 3, 6, 9, 6, 6, 0, 0, 9, 3, 3, 3, 0, 3, 9, 3, 3,
        9, 9, 3, 6, 9, 6, 3, 9, 6, 9, 3, 0, 3, 9, 6, 3, 0, 0, 0, 3, 3, 0,
        6, 9, 3, 9, 0, 9, 0, 6, 0, 9, 3, 3, 9, 0, 9, 9, 6, 3, 3, 9, 9, 6,
        0, 3, 0, 6, 9, 9, 0, 3, 6, 9, 3, 3, 6, 6, 9, 6, 9, 3, 0, 9, 9, 6,
        0, 3, 9, 9, 3, 9, 9, 0, 3, 0, 3, 6, 9, 3, 3, 0, 0, 6, 3, 6, 9, 9,
        9, 0, 0, 3, 9, 6, 9, 3, 3, 9, 9, 9, 0, 6, 9, 3, 0, 9, 0, 0, 0, 9,
        9, 0, 9, 9, 6, 6, 0, 6, 0, 9, 0, 0, 3, 9, 6, 6, 0, 3, 3, 3, 9, 3,
        3, 3, 0, 3, 9, 9, 3, 6, 9, 6, 3, 3, 0, 9, 9, 0, 3, 0, 0, 3, 3, 0,
        6, 6, 9, 6, 9, 6, 6, 0, 9, 0, 0, 6, 6, 6, 9, 9, 3, 3, 9, 9, 6, 9,
        9, 3, 6, 3, 9, 9, 3, 6, 6, 3, 0, 9, 6, 3, 9, 3, 0, 3, 0, 6, 6, 3,
        9, 9, 3, 3, 3, 0, 3, 0, 6, 6, 6, 3, 9, 0, 3, 6, 6, 9, 9, 0, 6, 3,
        0, 3, 9, 3, 9, 9, 9, 0, 3, 0, 3, 3, 3, 0, 0, 3, 6, 6, 0, 6, 9, 9,
        3, 3, 0, 6, 6, 0, 6, 9, 9, 0, 3, 6, 6, 3, 9, 9, 0, 6, 3, 6, 6, 3,
        6, 0, 9, 3, 9, 6, 0, 0, 6, 6, 0, 9, 3, 6, 9, 0, 9, 3, 6, 9, 6, 6,
        6, 9, 9, 0, 3, 9, 6, 9, 0, 6, 3, 9, 3, 6, 9, 3, 3, 3, 0, 9, 3, 3,
        6, 3, 3, 6, 3, 0, 6, 6, 6, 3, 3, 0, 0, 6, 6, 3, 0, 3, 6, 6, 6, 6,
        3, 0, 3, 3, 9, 6, 0, 9, 3, 0, 9, 6, 0, 9, 3, 6, 9, 9, 6, 6, 9, 9,
        0, 6, 3, 3, 6, 0, 0, 3, 3, 9, 0, 9, 0, 0, 0, 9, 0, 0, 0, 3, 3, 0,
        9, 6, 0, 0, 3, 0, 3, 3, 0, 3, 0, 6, 9, 3, 0, 6, 0, 6, 9, 3, 0, 9,
        6, 3, 0, 0, 3, 3, 0, 3, 9, 0, 0, 9, 9, 6, 9, 6, 9, 6, 0, 6, 3, 0,
        6, 9, 9, 0, 6, 3, 6, 9, 3, 6, 0, 0, 3, 3, 6, 0, 9, 3, 3, 6, 0, 9,
        9, 9, 0, 3, 6, 3, 6, 3, 0, 9, 6, 0, 9, 6, 9, 9, 6, 6, 3, 6, 0, 9,
        0, 0, 0, 0, 3, 0, 3, 0, 9, 6, 3, 3, 0, 0, 6, 9, 3, 3, 0, 6, 0, 9,
        3, 9, 3, 6, 0, 9, 6, 9, 3, 0, 0, 0, 3, 3, 6, 6, 3, 6, 0, 9, 0, 9,
        9, 6, 3, 9, 9, 6, 9, 6, 3, 3, 6, 3, 0, 6, 9, 9, 9, 9, 6, 9, 9, 6,
        9, 3, 0, 3, 6, 6, 6, 6, 9, 3, 0, 6, 6, 3, 3, 0, 3, 3, 3, 3, 9, 3,
        0, 3, 6, 3, 0, 3, 9, 3, 3, 9, 0, 3, 6, 6, 3, 9, 3, 3, 0, 3, 6, 3,
        6, 6, 6, 9, 9, 6, 3, 3, 6, 3, 0, 6, 3, 3, 9, 9, 9, 9, 9, 9, 9, 6,
        3, 0, 3, 6, 6, 0, 0, 3, 9, 6, 9, 9, 6, 9, 9, 9, 3]),
 None,
 array([0, 0, 6, 0, 9, 6, 6, 0, 3, 3, 6, 0, 0, 0, 0, 9, 9, 9, 3, 0, 0, 9,
        0, 9, 9, 9, 0, 9, 6, 0, 6, 6, 3, 9, 6, 9, 9, 0, 6, 3, 6, 3, 3, 9,
        6, 3, 6, 3, 0, 3, 3, 3, 0, 9, 6, 3, 6, 6, 6, 0, 6, 6, 3, 9, 0, 6,
        3, 6, 0, 6, 9, 0, 9, 3, 9, 0, 9, 6, 0, 0, 3, 0, 9, 3, 0, 6, 6, 3,
        3, 9, 0, 9, 9, 0, 0, 9, 9, 3, 0, 6, 0, 9, 6, 6, 3, 6, 9, 3, 0, 9,
        9, 0, 0, 0, 0, 9, 3, 3, 6, 3, 9, 0, 9, 9, 3, 9, 3, 3, 0, 3, 6, 0,
        0, 6, 0, 9, 6, 6, 0, 6, 0, 6, 9, 3, 6, 0, 3, 3, 9, 0, 9, 0, 3, 6,
        6, 0, 3, 3, 9, 9, 3, 3, 3, 9, 6, 6, 9, 0, 3, 3, 6, 3, 6, 3, 6, 0,
        9, 3, 9, 9, 0, 3, 9, 9, 9, 6, 6, 6, 0, 0, 6, 0, 0, 3, 6, 3, 9, 3,
        0, 6, 0, 9, 9, 0, 9, 0, 9, 3, 9, 9, 3, 9, 9, 6, 9, 6, 0, 0, 0, 6,
        3, 6, 9, 0, 0, 0, 3, 6, 9, 6, 6, 0, 0, 9, 3, 3, 3, 0, 3, 9, 3, 3,
        9, 9, 3, 6, 9, 6, 3, 9, 6, 9, 3, 0, 3, 9, 6, 3, 0, 0, 0, 3, 3, 0,
        6, 9, 3, 9, 0, 9, 0, 6, 0, 9, 3, 3, 9, 0, 9, 9, 6, 3, 3, 9, 9, 6,
        0, 3, 0, 6, 9, 9, 0, 3, 6, 9, 3, 3, 6, 6, 9, 6, 9, 3, 0, 9, 9, 6,
        0, 3, 9, 9, 3, 9, 9, 0, 3, 0, 3, 6, 9, 3, 3, 0, 0, 6, 3, 6, 9, 9,
        9, 0, 0, 3, 9, 6, 9, 3, 3, 9, 9, 9, 0, 6, 9, 3, 0, 9, 0, 0, 0, 9,
        9, 0, 9, 9, 6, 6, 0, 6, 0, 9, 0, 0, 3, 9, 6, 6, 0, 3, 3, 3, 9, 3,
        3, 3, 0, 3, 9, 9, 3, 6, 9, 6, 3, 3, 0, 9, 9, 0, 3, 0, 0, 3, 3, 0,
        6, 6, 9, 6, 9, 6, 6, 0, 9, 0, 0, 6, 6, 6, 9, 9, 3, 3, 9, 9, 6, 9,
        9, 3, 6, 3, 9, 9, 3, 6, 6, 3, 0, 9, 6, 3, 9, 3, 0, 3, 0, 6, 6, 3,
        9, 9, 3, 3, 3, 0, 3, 0, 6, 6, 6, 3, 9, 0, 3, 6, 6, 9, 9, 0, 6, 3,
        0, 3, 9, 3, 9, 9, 9, 0, 3, 0, 3, 3, 3, 0, 0, 3, 6, 6, 0, 6, 9, 9,
        3, 3, 0, 6, 6, 0, 6, 9, 9, 0, 3, 6, 6, 3, 9, 9, 0, 6, 3, 6, 6, 3,
        6, 0, 9, 3, 9, 6, 0, 0, 6, 6, 0, 9, 3, 6, 9, 0, 9, 3, 6, 9, 6, 6,
        6, 9, 9, 0, 3, 9, 6, 9, 0, 6, 3, 9, 3, 6, 9, 3, 3, 3, 0, 9, 3, 3,
        6, 3, 3, 6, 3, 0, 6, 6, 6, 3, 3, 0, 0, 6, 6, 3, 0, 3, 6, 6, 6, 6,
        3, 0, 3, 3, 9, 6, 0, 9, 3, 0, 9, 6, 0, 9, 3, 6, 9, 9, 6, 6, 9, 9,
        0, 6, 3, 3, 6, 0, 0, 3, 3, 9, 0, 9, 0, 0, 0, 9, 0, 0, 0, 3, 3, 0,
        9, 6, 0, 0, 3, 0, 3, 3, 0, 3, 0, 6, 9, 3, 0, 6, 0, 6, 9, 3, 0, 9,
        6, 3, 0, 0, 3, 3, 0, 3, 9, 0, 0, 9, 9, 6, 9, 6, 9, 6, 0, 6, 3, 0,
        6, 9, 9, 0, 6, 3, 6, 9, 3, 6, 0, 0, 3, 3, 6, 0, 9, 3, 3, 6, 0, 9,
        9, 9, 0, 3, 6, 3, 6, 3, 0, 9, 6, 0, 9, 6, 9, 9, 6, 6, 3, 6, 0, 9,
        0, 0, 0, 0, 3, 0, 3, 0, 9, 6, 3, 3, 0, 0, 6, 9, 3, 3, 0, 6, 0, 9,
        3, 9, 3, 6, 0, 9, 6, 9, 3, 0, 0, 0, 3, 3, 6, 6, 3, 6, 0, 9, 0, 9,
        9, 6, 3, 9, 9, 6, 9, 6, 3, 3, 6, 3, 0, 6, 9, 9, 9, 9, 6, 9, 9, 6,
        9, 3, 0, 3, 6, 6, 6, 6, 9, 3, 0, 6, 6, 3, 3, 0, 3, 3, 3, 3, 9, 3,
        0, 3, 6, 3, 0, 3, 9, 3, 3, 9, 0, 3, 6, 6, 3, 9, 3, 3, 0, 3, 6, 3,
        6, 6, 6, 9, 9, 6, 3, 3, 6, 3, 0, 6, 3, 3, 9, 9, 9, 9, 9, 9, 9, 6,
        3, 0, 3, 6, 6, 0, 0, 3, 9, 6, 9, 9, 6, 9, 9, 9, 3]),
 '2-HARQ')

Information content based on MCS value

This converts the estimated cyclic shift offest value to the information bits based on the control information transmitted

if controlInfo == "1-HARQ" or controlInfo == "SR":
    len = 1
else:
    len = 2
m_CS[np.where(m_CS==0)] = 0
m_CS[np.where(m_CS==3)] = 1
if controlInfo == '1-HARQ':
    m_CS[np.where(m_CS==6)] = 1
elif controlInfo == '2-HARQ':
    m_CS[np.where(m_CS==6)] = 3
else:
    m_CS[np.where(m_CS==6)] = 2
m_CS[np.where(m_CS==9)] = 3 if controlInfo == 'HARQ+SR' else 2

bin_arr = VectorToBinaryArray(m_CS, len)()
bin_arr.shape
(853, 2)

Simulation

This subsection performs the simulation which involve following steps:

  • Passing the resource grid through the channel

    • Adding noise to the grid with a given SNR

  • PUCCH Format 0 Decoding which involves retrival of sequence from the grid

  • Followed by estimation of cyclic shift offest, using which the information bits are estimated

  • BER computation

The bit error rate (BER) is computed for every combination of SNR \(= \{-30, -20, -10, 0, 10, 20, 30\}\) dB and averaged over numBatches (monteCarloIterations).

SNRdB = np.linspace(-30, 30, 20)
SNR   = 10**(SNRdB/10)

isChannelPerfect = True

BER1 = np.zeros(SNR.size)
BER2 = np.zeros(SNR.size)
BER  = np.zeros(SNR.size)
i = 0
for snr in SNR:

    print("SNR-Index: "+str(i)+"| SNR: "+str(snr))
    n = np.sqrt(0.5/snr)*(np.random.standard_normal(size=pucchFormat0Grid.shape)+1j*np.random.standard_normal(size=pucchFormat0Grid.shape))
    y = pucchFormat0Grid + n

    pucchFormat0DecoderObj = PUCCHFormat0Decoder(numofSymbols, symbolIndex_start, verbose = False)
    pucchFormat0DecoderOp  = pucchFormat0DecoderObj(y, intraSlotFreqHopping, interlacedTransmission, pucch_ResourceCommon, indexPUCCH, numInterlacedRBs, startingPRB, secondHopPRB, numOfInterlaces, interlaceIndex_0, interlaceIndex_1)

    Obj_mcs      = MCSEstimation(interlacedTransmission, pucch_ResourceCommon, hardout = True)
    estimatem_CS = Obj_mcs(pucchFormat0DecoderOp, controlInfo, indexPUCCH, nID, slotNumber, symbolIndex_start, numofSymbols, initialCycShift, numInterlacedRBs)

    if Obj_mcs.numberOfSymb == 1 or Obj_mcs.numberOfSymb == 2:
        BER1[i] = np.mean(np.abs(estimatem_CS[0] - bin_arr))
        print("*************************************************************")
        print("BER1 : "+str(BER1[i]))
        BER2[i] = 0
        if  Obj_mcs.numberOfSymb == 2:
            BER2[i] = np.mean(np.abs(estimatem_CS[1] - bin_arr))
            print("-------------------------------------------------------------")
            print("BER2 : "+str(BER2[i]))

    BER[i] = np.mean((BER1[i], BER2[i]))
    print("-------------------------------------------------------------")
    print("BER  : "+str(BER[i]))
    i = i+1
SNR-Index: 0| SNR: 0.001
*********************************************************
BER1 : 0.5023446658851114
-------------------------------------------------------------
BER  : 0.2511723329425557
SNR-Index: 1| SNR: 0.00206913808111479
*********************************************************
BER1 : 0.4806565064478312
-------------------------------------------------------------
BER  : 0.2403282532239156
SNR-Index: 2| SNR: 0.004281332398719396
*********************************************************
BER1 : 0.5005861664712778
-------------------------------------------------------------
BER  : 0.2502930832356389
SNR-Index: 3| SNR: 0.008858667904100823
*********************************************************
BER1 : 0.5046893317702228
-------------------------------------------------------------
BER  : 0.2523446658851114
SNR-Index: 4| SNR: 0.018329807108324356
*********************************************************
BER1 : 0.4783118405627198
-------------------------------------------------------------
BER  : 0.2391559202813599
SNR-Index: 5| SNR: 0.0379269019073225
*********************************************************
BER1 : 0.4859320046893318
-------------------------------------------------------------
BER  : 0.2429660023446659
SNR-Index: 6| SNR: 0.07847599703514611
*********************************************************
BER1 : 0.48182883939038684
-------------------------------------------------------------
BER  : 0.24091441969519342
SNR-Index: 7| SNR: 0.16237767391887217
*********************************************************
BER1 : 0.4349355216881594
-------------------------------------------------------------
BER  : 0.2174677608440797
SNR-Index: 8| SNR: 0.3359818286283782
*********************************************************
BER1 : 0.36518171160609614
-------------------------------------------------------------
BER  : 0.18259085580304807
SNR-Index: 9| SNR: 0.6951927961775608
*********************************************************
BER1 : 0.1776084407971864
-------------------------------------------------------------
BER  : 0.0888042203985932
SNR-Index: 10| SNR: 1.4384498882876635
*********************************************************
BER1 : 0.016998827667057445
-------------------------------------------------------------
BER  : 0.008499413833528723
SNR-Index: 11| SNR: 2.976351441631318
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 12| SNR: 6.158482110660259
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 13| SNR: 12.742749857031342
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 14| SNR: 26.366508987303583
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 15| SNR: 54.55594781168523
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 16| SNR: 112.88378916846895
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 17| SNR: 233.57214690901213
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 18| SNR: 483.2930238571757
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0
SNR-Index: 19| SNR: 1000.0
*********************************************************
BER1 : 0.0
-------------------------------------------------------------
BER  : 0.0

Performance Evaluation

The script plots SNR in dB vs BER performance for . It can be observed that the control information is received with a reliablilty of

  • BER = \(10^{-2}\) at an SNR value of 0 dB.

Performance Plot

fig, ax = plt.subplots()

ax.semilogy(SNRdB, BER1, "-b", label="Symbol 1 - BER1")
ax.semilogy(SNRdB, BER2, "-r", label="Symbol 2 - BER2")
ax.semilogy(SNRdB, BER, "*-g",label="BER")
ax.legend(loc="upper right")
ax.set_xlabel("Signal to Noise Ratio (dB)", fontsize = 9)
ax.set_ylabel("Bit Error Rate", fontsize = 9)
ax.set_title("BER Performance of PUCCH Format 0")
Text(0.5, 1.0, 'BER Performance of PUCCH Format 0')
Figure