Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/algorithm/LLR_demodulation_for5G_CN.pdf
Binary file not shown.
Binary file added docs/algorithm/LLR_demodulation_for5G_EN.pdf
Binary file not shown.
140 changes: 70 additions & 70 deletions poetry.lock

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions py5gphy/common/nrModulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def nrModulate(inbits, modtype):
mod_data = nrModulate(inbits, modtype)
"""
modtype = modtype.lower()
assert modtype in ["pi/2-bpsk", "bpsk", "qpsk", "16qam", "64qam", "256qam"], "modulation type is incorrect"
assert modtype in ["pi/2-bpsk", "bpsk", "qpsk", "16qam", "64qam", "256qam", "1024qam"], "modulation type is incorrect"

b = inbits.astype('f') #convert to float32
N = b.size
Expand Down Expand Up @@ -37,7 +37,11 @@ def nrModulate(inbits, modtype):
mod_data = ((1-2*b[0::8]) * (8 - (1-2*b[2::8])*(4 - (1-2*b[4::8])*(2-(1-2*b[6::8]))))
+ 1j*(1-2*b[1::8]) * (8 - (1-2*b[3::8])*(4 - (1-2*b[5::8])*(2-(1-2*b[7::8]))))
)/math.sqrt(170)

elif modtype == "1024qam":
assert N % 10 == 0, "length of databits must be multiple of 10"
mod_data = ((1-2*b[0::10]) * (16 - (1-2*b[2::10])*(8 - (1-2*b[4::10])*(4 - (1-2*b[6::10])*(2-(1-2*b[8::10])))))
+ 1j*(1-2*b[1::10]) * (16 - (1-2*b[3::10])*(8 - (1-2*b[5::10])*(4 - (1-2*b[7::10])*(2-(1-2*b[9::10])))))
)/math.sqrt(682)
return mod_data


Expand Down
329 changes: 329 additions & 0 deletions py5gphy/demodulation/demod_1024qam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
# -*- coding:utf-8 -*-
import numpy as np
import math

def demod(insymbols,noise_var):
"""1024QAM demodulation
"""
A = 1/math.sqrt(682)
LLR = np.zeros(10*insymbols.size,dtype='f')
LLR[0::10] = LLR_1024qam_bit_0_1(insymbols.real,noise_var,A)
LLR[1::10] = LLR_1024qam_bit_0_1(insymbols.imag,noise_var,A)

LLR[2::10] = LLR_1024qam_bit_2_3(insymbols.real,noise_var,A)
LLR[3::10] = LLR_1024qam_bit_2_3(insymbols.imag,noise_var,A)

LLR[4::10] = LLR_1024qam_bit_4_5(insymbols.real,noise_var,A)
LLR[5::10] = LLR_1024qam_bit_4_5(insymbols.imag,noise_var,A)

LLR[6::10] = LLR_1024qam_bit_6_7(insymbols.real,noise_var,A)
LLR[7::10] = LLR_1024qam_bit_6_7(insymbols.imag,noise_var,A)

LLR[8::10] = LLR_1024qam_bit_8_9(insymbols.real,noise_var,A)
LLR[9::10] = LLR_1024qam_bit_8_9(insymbols.imag,noise_var,A)

hardbits = [0 if a>0 else 1 for a in LLR]
return hardbits,LLR

def LLR_1024qam_bit_0_1(insym, noise_var,A):
""" 1024QAM b0 and b1 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -30*A:
LLR[m] = 64*A*(r+15*A)/noise_var
elif r < -28*A:
LLR[m] = 60*A*(r+14*A)/noise_var
elif r < -26*A:
LLR[m] = 56*A*(r+13*A)/noise_var
elif r < -24*A:
LLR[m] = 52*A*(r+12*A)/noise_var
elif r < -22*A:
LLR[m] = 48*A*(r+11*A)/noise_var
elif r < -20*A:
LLR[m] = 44*A*(r+10*A)/noise_var
elif r < -18*A:
LLR[m] = 40*A*(r+9*A)/noise_var
elif r < -16*A:
LLR[m] = 36*A*(r+8*A)/noise_var
elif r < -14*A:
LLR[m] = 32*A*(r+7*A)/noise_var
elif r < -12*A:
LLR[m] = 28*A*(r+6*A)/noise_var
elif r < -10*A:
LLR[m] = 24*A*(r+5*A)/noise_var
elif r < -8*A:
LLR[m] = 20*A*(r+4*A)/noise_var
elif r < -6*A:
LLR[m] = 16*A*(r+3*A)/noise_var
elif r < -4*A:
LLR[m] = 12*A*(r+2*A)/noise_var
elif r < -2*A:
LLR[m] = 8*A*(r+1*A)/noise_var
elif r < 2*A:
LLR[m] = 4*A*r/noise_var
elif r < 4*A:
LLR[m] = 8*A*(r-1*A)/noise_var
elif r < 6*A:
LLR[m] = 12*A*(r-2*A)/noise_var
elif r < 8*A:
LLR[m] = 16*A*(r-3*A)/noise_var
elif r < 10*A:
LLR[m] = 20*A*(r-4*A)/noise_var
elif r < 12*A:
LLR[m] = 24*A*(r-5*A)/noise_var
elif r < 14*A:
LLR[m] = 28*A*(r-6*A)/noise_var
elif r < 16*A:
LLR[m] = 32*A*(r-7*A)/noise_var
elif r < 18*A:
LLR[m] = 36*A*(r-8*A)/noise_var
elif r < 20*A:
LLR[m] = 40*A*(r-9*A)/noise_var
elif r < 22*A:
LLR[m] = 44*A*(r-10*A)/noise_var
elif r < 24*A:
LLR[m] = 48*A*(r-11*A)/noise_var
elif r < 26*A:
LLR[m] = 52*A*(r-12*A)/noise_var
elif r < 28*A:
LLR[m] = 56*A*(r-13*A)/noise_var
elif r < 30*A:
LLR[m] = 60*A*(r-14*A)/noise_var
else:
LLR[m] = 64*A*(r-15*A)/noise_var

return LLR

def LLR_1024qam_bit_2_3(insym, noise_var,A):
""" 1024QAM b2 and b3 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -30*A:
LLR[m] = 32*A*(r+23*A)/noise_var
elif r < -28*A:
LLR[m] = 28*A*(r+22*A)/noise_var
elif r < -26*A:
LLR[m] = 24*A*(r+21*A)/noise_var
elif r < -24*A:
LLR[m] = 20*A*(r+20*A)/noise_var
elif r < -22*A:
LLR[m] = 16*A*(r+19*A)/noise_var
elif r < -20*A:
LLR[m] = 12*A*(r+18*A)/noise_var
elif r < -18*A:
LLR[m] = 8*A*(r+17*A)/noise_var
elif r < -14*A:
LLR[m] = 4*A*(r+16*A)/noise_var
elif r < -12*A:
LLR[m] = 8*A*(r+15*A)/noise_var
elif r < -10*A:
LLR[m] = 12*A*(r+14*A)/noise_var
elif r < -8*A:
LLR[m] = 16*A*(r+13*A)/noise_var
elif r < -6*A:
LLR[m] = 20*A*(r+12*A)/noise_var
elif r < -4*A:
LLR[m] = 24*A*(r+11*A)/noise_var
elif r < -2*A:
LLR[m] = 28*A*(r+10*A)/noise_var
elif r < 0:
LLR[m] = 32*A*(r+9*A)/noise_var
elif r < 2*A:
LLR[m] = 32*A*(-r+9*A)/noise_var
elif r < 4*A:
LLR[m] = 28*A*(-r+10*A)/noise_var
elif r < 6*A:
LLR[m] = 24*A*(-r+11*A)/noise_var
elif r < 8*A:
LLR[m] = 20*A*(-r+12*A)/noise_var
elif r < 10*A:
LLR[m] = 16*A*(-r+13*A)/noise_var
elif r < 12*A:
LLR[m] = 12*A*(-r+14*A)/noise_var
elif r < 14*A:
LLR[m] = 8*A*(-r+15*A)/noise_var
elif r < 18*A:
LLR[m] = 4*A*(-r+16*A)/noise_var
elif r < 20*A:
LLR[m] = 8*A*(-r+17*A)/noise_var
elif r < 22*A:
LLR[m] = 12*A*(-r+18*A)/noise_var
elif r < 24*A:
LLR[m] = 16*A*(-r+19*A)/noise_var
elif r < 26*A:
LLR[m] = 20*A*(-r+20*A)/noise_var
elif r < 28*A:
LLR[m] = 24*A*(-r+21*A)/noise_var
elif r < 30*A:
LLR[m] = 28*A*(-r+22*A)/noise_var
else:
LLR[m] = 32*A*(-r+23*A)/noise_var

return LLR

def LLR_1024qam_bit_4_5(insym, noise_var,A):
""" 1024QAM b4 and b5 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -30*A:
LLR[m] = 16*A*(r+27*A)/noise_var
elif r < -28*A:
LLR[m] = 12*A*(r+26*A)/noise_var
elif r < -26*A:
LLR[m] = 8*A*(r+25*A)/noise_var
elif r < -22*A:
LLR[m] = 4*A*(r+24*A)/noise_var
elif r < -20*A:
LLR[m] = 8*A*(r+23*A)/noise_var
elif r < -18*A:
LLR[m] = 12*A*(r+22*A)/noise_var
elif r < -16*A:
LLR[m] = 16*A*(r+21*A)/noise_var
elif r < -14*A:
LLR[m] = 16*A*(-r-11*A)/noise_var
elif r < -12*A:
LLR[m] = 12*A*(-r-10*A)/noise_var
elif r < -10*A:
LLR[m] = 8*A*(-r-9*A)/noise_var
elif r < -6*A:
LLR[m] = 4*A*(-r-8*A)/noise_var
elif r < -4*A:
LLR[m] = 8*A*(-r-7*A)/noise_var
elif r < -2*A:
LLR[m] = 12*A*(-r-6*A)/noise_var
elif r < 0:
LLR[m] = 16*A*(-r-5*A)/noise_var
elif r < 2*A:
LLR[m] = 16*A*(r-5*A)/noise_var
elif r < 4*A:
LLR[m] = 12*A*(r-6*A)/noise_var
elif r < 6*A:
LLR[m] = 8*A*(r-7*A)/noise_var
elif r < 10*A:
LLR[m] = 4*A*(r-8*A)/noise_var
elif r < 12*A:
LLR[m] = 8*A*(r-9*A)/noise_var
elif r < 14*A:
LLR[m] = 12*A*(r-10*A)/noise_var
elif r < 16*A:
LLR[m] = 16*A*(r-11*A)/noise_var
elif r < 18*A:
LLR[m] = 16*A*(-r+21*A)/noise_var
elif r < 20*A:
LLR[m] = 12*A*(-r+22*A)/noise_var
elif r < 22*A:
LLR[m] = 8*A*(-r+23*A)/noise_var
elif r < 26*A:
LLR[m] = 4*A*(-r+24*A)/noise_var
elif r < 28*A:
LLR[m] = 8*A*(-r+25*A)/noise_var
elif r < 30*A:
LLR[m] = 12*A*(-r+26*A)/noise_var
else:
LLR[m] = 16*A*(-r+27*A)/noise_var

return LLR

def LLR_1024qam_bit_6_7(insym, noise_var,A):
""" 1024QAM b6 and b7 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -30*A:
LLR[m] = 8*A*(r+29*A)/noise_var
elif r < -26*A:
LLR[m] = 4*A*(r+28*A)/noise_var
elif r < -24*A:
LLR[m] = 8*A*(r+27*A)/noise_var
elif r < -22*A:
LLR[m] = 8*A*(-r-21*A)/noise_var
elif r < -18*A:
LLR[m] = 4*A*(-r-20*A)/noise_var
elif r < -16*A:
LLR[m] = 8*A*(-r-19*A)/noise_var
elif r < -14*A:
LLR[m] = 8*A*(r+13*A)/noise_var
elif r < -10*A:
LLR[m] = 4*A*(r+12*A)/noise_var
elif r < -8*A:
LLR[m] = 8*A*(r+11*A)/noise_var
elif r < -6*A:
LLR[m] = 8*A*(-r-5*A)/noise_var
elif r < -2*A:
LLR[m] = 4*A*(-r-4*A)/noise_var
elif r < 0:
LLR[m] = 8*A*(-r-3*A)/noise_var
elif r < 2*A:
LLR[m] = 8*A*(r-3*A)/noise_var
elif r < 6*A:
LLR[m] = 4*A*(r-4*A)/noise_var
elif r < 8*A:
LLR[m] = 8*A*(r-5*A)/noise_var
elif r < 10*A:
LLR[m] = 8*A*(-r+11*A)/noise_var
elif r < 14*A:
LLR[m] = 4*A*(-r+12*A)/noise_var
elif r < 16*A:
LLR[m] = 8*A*(-r+13*A)/noise_var
elif r < 18*A:
LLR[m] = 8*A*(r-19*A)/noise_var
elif r < 22*A:
LLR[m] = 4*A*(r-20*A)/noise_var
elif r < 24*A:
LLR[m] = 8*A*(r-21*A)/noise_var
elif r < 26*A:
LLR[m] = 8*A*(-r+27*A)/noise_var
elif r < 30*A:
LLR[m] = 4*A*(-r+28*A)/noise_var
else:
LLR[m] = 8*A*(-r+29*A)/noise_var

return LLR

def LLR_1024qam_bit_8_9(insym, noise_var,A):
""" 1024QAM b8 and b9 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -28*A:
LLR[m] = 4*A*(r+30*A)/noise_var
elif r < -24*A:
LLR[m] = 4*A*(-r-26*A)/noise_var
elif r < -20*A:
LLR[m] = 4*A*(r+22*A)/noise_var
elif r < -16*A:
LLR[m] = 4*A*(-r-18*A)/noise_var
elif r < -12*A:
LLR[m] = 4*A*(r+14*A)/noise_var
elif r < -8*A:
LLR[m] = 4*A*(-r-10*A)/noise_var
elif r < -4*A:
LLR[m] = 4*A*(r+6*A)/noise_var
elif r < 0:
LLR[m] = 4*A*(-r-2*A)/noise_var
elif r < 4*A:
LLR[m] = 4*A*(r-2*A)/noise_var
elif r < 8*A:
LLR[m] = 4*A*(-r+6*A)/noise_var
elif r < 12*A:
LLR[m] = 4*A*(r-10*A)/noise_var
elif r < 16*A:
LLR[m] = 4*A*(-r+14*A)/noise_var
elif r < 20*A:
LLR[m] = 4*A*(r-18*A)/noise_var
elif r < 24*A:
LLR[m] = 4*A*(-r+22*A)/noise_var
elif r < 28*A:
LLR[m] = 4*A*(r-26*A)/noise_var
else:
LLR[m] = 4*A*(-r+30*A)/noise_var

return LLR


if __name__ == "__main__":

aaa=1
43 changes: 43 additions & 0 deletions py5gphy/demodulation/demod_16qam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding:utf-8 -*-
import numpy as np
import math

def demod(insymbols,noise_var):
"""16QAM demodulation
"""
A = 1/math.sqrt(10)
LLR = np.zeros(4*insymbols.size,dtype='f')
LLR[0::4] = LLR_16qam_bit_0_1(insymbols.real,noise_var,A)
LLR[1::4] = LLR_16qam_bit_0_1(insymbols.imag,noise_var,A)

LLR[2::4] = LLR_16qam_bit_2_3(insymbols.real,noise_var,A)
LLR[3::4] = LLR_16qam_bit_2_3(insymbols.imag,noise_var,A)

hardbits = [0 if a>0 else 1 for a in LLR]
return hardbits,LLR

def LLR_16qam_bit_0_1(insym, noise_var,A):
""" 16QAM b0 and b1 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < -2*A:
LLR[m] = 8*A*(r+A)/noise_var
elif r < 2*A:
LLR[m] = 4*A*r/noise_var
else:
LLR[m] = 8*A*(r-A)/noise_var

return LLR

def LLR_16qam_bit_2_3(insym, noise_var,A):
""" 16QAM b2 and b3 LLR"""
LLR = np.zeros(insym.size,dtype='f')
for m in range(insym.size):
r = insym[m]
if r < 0:
LLR[m] = 4*A*(r+2*A)/noise_var
else:
LLR[m] = 4*A*(-r+2*A)/noise_var

return LLR
Loading