HARQ event callback

This notebook shows how to define and use a HARQ event callback.

[1]:
import numpy as np
import time

from neoradium import LdpcEncoder, HarqEntity, random, Modem
from neoradium.utils import toLinear

Creating an LDPC Encoder object

[2]:
modulation="16QAM"      # Modulation scheme
codeRate = 490/1024     # Target code rate
numLayers = 1           # To test this with 2 codewords, set this to a value between 5 and 8
ldpcEncoder = LdpcEncoder(baseGraphNo=1,  modulation=modulation, txLayers=numLayers, targetRate=codeRate)
ldpcEncoder.print()     # Print the LDPC encoder's properties

LDPC Encoder Properties:
  Base Graph:         1
  Modulation:         16QAM
  Number of layers:   1
  Target Rate:        0.478515625

Defining a callback function and passing it to the HARQ entity

[3]:
# Define a simple call back function which prints the event information:
def handleEvents(event, harqCW):
    # event: The event string. It can be one of ”RXFAILED”, ”RXSUCCESS”, or ”TIMEOUT”
    # harqCW: The instance of HarqCW class that triggered the event
    print(f"HARQ Process {harqCW.process.id}   CW{harqCW.cwIdx+1}: {event:10s}   curTry: {harqCW.curTry}   RV: {harqCW.rv}   TxBlock: {harqCW.txBlockNo}")

# Create the HARQ entity with "Chase Combining" and 8 processes
harq = HarqEntity(ldpcEncoder, harqType="CC", numProc=8, eventCallback=handleEvents)

Main transmission loop

[4]:
ebNoDb = 3                                                  # Set the Eb/No ratio (dB)
snrDb = ebNoDb + 10*np.log10(ldpcEncoder.qm * codeRate)     # Convert Eb/No to SNR (dB)
snr = toLinear(snrDb)                                       # Linear SNR
noiseStd = np.sqrt(1/snr)                                   # Noise standard deviation

rangen = random.getGenerator(123)                           # Create new random generator and make results reproducible
modem = Modem(modulation)                                   # The Modem instance used for modulation/demodulation
numTransmissions = 50                                       # Total number of transmissions
txBlockSizes = harq.numCW*[10000]                           # Transport block sizes. One per codeword.

harq.reset()                                                # Reset HARQ for each execution of this cell
for t in range(numTransmissions):                           # Run this "numTransmissions" times
    txBlocks = []                                           # Transport blocks. One per codeword.
    for c in range(harq.numCW):
        if harq.needNewData[c]:                             # New transmission.
            txBlocks += [ random.bits(txBlockSizes[c]) ]    # Create random bits for the new transport block
        else:                                               # Retransmission
            txBlocks += [ None ]                            # Set transport block to None to indicate retransmission

    rateMatchedCodeWords = harq.getRateMatchedCodeBlocks(txBlocks)  # Prepare the bitstream for transmission

    llrs = []                                               # Received Log-Likelihood Ratios. One per codeword.
    for c in range(harq.numCW):
        channelOutput = modem.modulate(rateMatchedCodeWords[c])                     # Modulate the codeblocks
        noisyRxSignal = channelOutput + rangen.awgn(channelOutput.shape, noiseStd)  # Add Noise
        llrs += [ modem.getLLRsFromSymbols(noisyRxSignal, noiseStd**2) ]            # Calculate the LLRs for each codeword

    decodedTxBlocks, blockErrors = harq.decodeLLRs(llrs, txBlockSizes)
    harq.goNext()                                           # Get ready for the next transmission
harq.printStats()                                           # Print HARQ entity's statistics
HARQ Process 0   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 0
HARQ Process 1   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 1
HARQ Process 2   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 2
HARQ Process 3   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 3
HARQ Process 4   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 4
HARQ Process 5   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 5
HARQ Process 6   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 6
HARQ Process 7   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 7
HARQ Process 0   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 0
HARQ Process 1   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 1
HARQ Process 2   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 2
HARQ Process 3   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 3
HARQ Process 4   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 4
HARQ Process 5   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 5
HARQ Process 6   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 6
HARQ Process 7   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 7
HARQ Process 0   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 8
HARQ Process 1   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 9
HARQ Process 2   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 10
HARQ Process 3   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 11
HARQ Process 4   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 12
HARQ Process 5   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 13
HARQ Process 6   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 14
HARQ Process 7   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 15
HARQ Process 0   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 8
HARQ Process 1   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 9
HARQ Process 2   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 10
HARQ Process 3   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 11
HARQ Process 4   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 12
HARQ Process 5   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 13
HARQ Process 6   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 14
HARQ Process 7   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 15
HARQ Process 0   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 16
HARQ Process 1   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 17
HARQ Process 2   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 18
HARQ Process 3   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 19
HARQ Process 4   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 20
HARQ Process 5   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 21
HARQ Process 6   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 22
HARQ Process 7   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 23
HARQ Process 0   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 16
HARQ Process 1   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 17
HARQ Process 2   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 18
HARQ Process 3   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 19
HARQ Process 4   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 20
HARQ Process 5   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 21
HARQ Process 6   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 22
HARQ Process 7   CW1: RXSUCCESS    curTry: 1   RV: 0   TxBlock: 23
HARQ Process 0   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 24
HARQ Process 1   CW1: RXFAILED     curTry: 0   RV: 0   TxBlock: 25

HARQ Entity Statistics:
  txBits (per try):     [260000 240000      0      0]
  rxBits (per try):     [     0 240000      0      0]
  txBlocks (per try):   [26 24  0  0]
  rxBlocks (per try):   [ 0 24  0  0]
  numTimeouts:          0
  totalTxBlocks:        50
  totalRxBlocks:        24
  totalTxBits:          500000
  totalRxBits:          240000
  throughput:           48.00%
  bler:                 52.00%
  Average Num. Retries: 1.00%

[ ]:

[ ]: