{ "cells": [ { "cell_type": "markdown", "id": "1ea4038d-302f-4750-8468-5e35843d23f5", "metadata": {}, "source": [ "## Using HARQ\n", "This notebook shows how to use HARQ functionality in NeoRadium. " ] }, { "cell_type": "code", "execution_count": 1, "id": "e3664f61-6925-4e91-a826-5b49b9057030", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import time\n", "\n", "from neoradium import LdpcEncoder, HarqEntity, random, Modem\n", "from neoradium.utils import toLinear" ] }, { "cell_type": "markdown", "id": "147122ee-42f9-476f-95ec-ffef35a05576", "metadata": {}, "source": [ "### Creating an LDPC Encoder object" ] }, { "cell_type": "code", "execution_count": 2, "id": "bd6bbd98-bba6-40fd-83f4-3847dfc95b68", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "LDPC Encoder Properties:\n", " Base Graph: 1\n", " Modulation: 16QAM\n", " Number of layers: 1\n", " Target Rate: 0.478515625\n", "\n" ] } ], "source": [ "modulation=\"16QAM\" # Modulation scheme\n", "codeRate = 490/1024 # Target code rate\n", "numLayers = 1 # To test this with 2 codewords, set this to a value between 5 and 8\n", "ldpcEncoder = LdpcEncoder(baseGraphNo=1, modulation=modulation, txLayers=numLayers, targetRate=codeRate)\n", "ldpcEncoder.print() # Print the LDPC encoder's properties" ] }, { "cell_type": "markdown", "id": "b8b46858-b580-4f96-8430-7cd8d8faa190", "metadata": {}, "source": [ "### Instantiating a HARQ entity object" ] }, { "cell_type": "code", "execution_count": 3, "id": "565eb2fc-fbe8-449f-a17e-084a38c98422", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "HARQ Entity Properties:\n", " HARQ Type: IR\n", " Num. Processes: 16\n", " Num. Codewords: 1\n", " RV sequence: [0, 2, 3, 1]\n", " maxTries: 4\n", " Encoder:\n", " Base Graph: 1\n", " Modulation: 16QAM\n", " Number of layers: 1\n", " Target Rate: 0.478515625\n", " Decoder:\n", " Base Graph: 1\n", " Modulation: 16QAM\n", " Number of layers: 1\n", "\n" ] } ], "source": [ "harqType = \"IR\" # \"IR\" -> \"Incremental Redundancy\", \"CC\" -> \"Chase Combining\"\n", "numProc = 16 # Number of HARQ processes\n", "harq = HarqEntity(ldpcEncoder, harqType, numProc) # Create the HARQ entity\n", "harq.print() # Print the HARQ entity's properties" ] }, { "cell_type": "markdown", "id": "9300ea01-2949-4ab9-8c91-232f61665bff", "metadata": {}, "source": [ "### Main transmission loop" ] }, { "cell_type": "code", "execution_count": 6, "id": "d9799a06-bfed-44a9-9765-d2b91a2fd760", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tx Bits Rx Bits Throughput(%) TX Blocks RX Blocks BLER(%) Retry Mean time(Sec.)\n", "---------- ---------- ------------- --------- --------- ------- ---------- ----------\n", "10000000 4960000 49.60 1000 496 50.40 1.00 64.76 \n", "HARQ Entity Statistics:\n", " txBits (per try): [5040000 4960000 0 0]\n", " rxBits (per try): [ 0 4960000 0 0]\n", " txBlocks (per try): [504 496 0 0]\n", " rxBlocks (per try): [ 0 496 0 0]\n", " numTimeouts: 0\n", " totalTxBlocks: 1000\n", " totalRxBlocks: 496\n", " totalTxBits: 10000000\n", " totalRxBits: 4960000\n", " throughput: 49.60%\n", " bler: 50.40%\n", " Average Num. Retries: 1.00%\n", "\n" ] } ], "source": [ "ebNoDb = 3 # Set the Eb/No ratio (dB)\n", "snrDb = ebNoDb + 10*np.log10(ldpcEncoder.qm * codeRate) # Convert Eb/No to SNR (dB)\n", "snr = toLinear(snrDb) # Linear SNR\n", "noiseStd = np.sqrt(1/snr) # Noise standard deviation\n", "\n", "rangen = random.getGenerator(123) # Create new random generator and make results reproducible\n", "modem = Modem(modulation) # The Modem instance used for modulation/demodulation\n", "numTransmissions = 1000 # Total number of transmissions\n", "txBlockSizes = harq.numCW*[10000] # Transport block sizes. One per codeword.\n", "\n", "# Print the header lines:\n", "print(\"Tx Bits Rx Bits Throughput(%) TX Blocks RX Blocks BLER(%) Retry Mean time(Sec.)\")\n", "print(\"---------- ---------- ------------- --------- --------- ------- ---------- ----------\")\n", "\n", "t0 = time.time() # Start our timer\n", "harq.reset() # Reset HARQ for each execution of this cell\n", "for t in range(numTransmissions): # Run this \"numTransmissions\" times\n", " txBlocks = [] # Transport blocks. One per codeword.\n", " for c in range(harq.numCW):\n", " if harq.needNewData[c]: # New transmission.\n", " txBlocks += [ random.bits(txBlockSizes[c]) ] # Create random bits for the new transport block\n", " else: # Retransmission\n", " txBlocks += [ None ] # Set transport block to None to indicate retransmission\n", "\n", " rateMatchedCodeWords = harq.getRateMatchedCodeBlocks(txBlocks) # Prepare the bitstream for transmission \n", "\n", " llrs = [] # Received Log-Likelihood Ratios. One per codeword.\n", " for c in range(harq.numCW):\n", " channelOutput = modem.modulate(rateMatchedCodeWords[c]) # Modulate the codeblocks\n", " noisyRxSignal = channelOutput + rangen.awgn(channelOutput.shape, noiseStd) # Add Noise\n", " llrs += [ modem.getLLRsFromSymbols(noisyRxSignal, noiseStd**2) ] # Calculate the LLRs for each codeword\n", "\n", " decodedTxBlocks, blockErrors = harq.decodeLLRs(llrs, txBlockSizes) # Decode the LLRs into transport blocks\n", "\n", " # Print the statistics so far:\n", " print(\"\\r%-10d %-10d %-13.2f %-9d %-9d %-7.2f %-10.2f %-10.2f\"\n", " %(harq.totalTxBits, harq.totalRxBits, harq.throughput, harq.totalTxBlocks, \n", " harq.totalRxBlocks, harq.bler, harq.meanTries, time.time()-t0), end='')\n", " harq.goNext() # Get ready for the next transmission\n", "\n", "harq.printStats() # Print HARQ entity's statistics" ] }, { "cell_type": "code", "execution_count": null, "id": "5c59e178-d232-4a4b-9e11-5d7a3a31973d", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 5 }