Skip to content

Commit 10e6020

Browse files
authored
Merge pull request #1 from hahaliu2001/rx_v2.0.0
add LLR demodulation algorithm document and code
2 parents 8996b1d + 195e0bb commit 10e6020

17 files changed

+823
-72
lines changed
File renamed without changes.
1.82 MB
Binary file not shown.
1.76 MB
Binary file not shown.

poetry.lock

Lines changed: 70 additions & 70 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

py5gphy/common/nrModulation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def nrModulate(inbits, modtype):
77
mod_data = nrModulate(inbits, modtype)
88
"""
99
modtype = modtype.lower()
10-
assert modtype in ["pi/2-bpsk", "bpsk", "qpsk", "16qam", "64qam", "256qam"], "modulation type is incorrect"
10+
assert modtype in ["pi/2-bpsk", "bpsk", "qpsk", "16qam", "64qam", "256qam", "1024qam"], "modulation type is incorrect"
1111

1212
b = inbits.astype('f') #convert to float32
1313
N = b.size
@@ -37,7 +37,11 @@ def nrModulate(inbits, modtype):
3737
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]))))
3838
+ 1j*(1-2*b[1::8]) * (8 - (1-2*b[3::8])*(4 - (1-2*b[5::8])*(2-(1-2*b[7::8]))))
3939
)/math.sqrt(170)
40-
40+
elif modtype == "1024qam":
41+
assert N % 10 == 0, "length of databits must be multiple of 10"
42+
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])))))
43+
+ 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])))))
44+
)/math.sqrt(682)
4145
return mod_data
4246

4347

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
# -*- coding:utf-8 -*-
2+
import numpy as np
3+
import math
4+
5+
def demod(insymbols,noise_var):
6+
"""1024QAM demodulation
7+
"""
8+
A = 1/math.sqrt(682)
9+
LLR = np.zeros(10*insymbols.size,dtype='f')
10+
LLR[0::10] = LLR_1024qam_bit_0_1(insymbols.real,noise_var,A)
11+
LLR[1::10] = LLR_1024qam_bit_0_1(insymbols.imag,noise_var,A)
12+
13+
LLR[2::10] = LLR_1024qam_bit_2_3(insymbols.real,noise_var,A)
14+
LLR[3::10] = LLR_1024qam_bit_2_3(insymbols.imag,noise_var,A)
15+
16+
LLR[4::10] = LLR_1024qam_bit_4_5(insymbols.real,noise_var,A)
17+
LLR[5::10] = LLR_1024qam_bit_4_5(insymbols.imag,noise_var,A)
18+
19+
LLR[6::10] = LLR_1024qam_bit_6_7(insymbols.real,noise_var,A)
20+
LLR[7::10] = LLR_1024qam_bit_6_7(insymbols.imag,noise_var,A)
21+
22+
LLR[8::10] = LLR_1024qam_bit_8_9(insymbols.real,noise_var,A)
23+
LLR[9::10] = LLR_1024qam_bit_8_9(insymbols.imag,noise_var,A)
24+
25+
hardbits = [0 if a>0 else 1 for a in LLR]
26+
return hardbits,LLR
27+
28+
def LLR_1024qam_bit_0_1(insym, noise_var,A):
29+
""" 1024QAM b0 and b1 LLR"""
30+
LLR = np.zeros(insym.size,dtype='f')
31+
for m in range(insym.size):
32+
r = insym[m]
33+
if r < -30*A:
34+
LLR[m] = 64*A*(r+15*A)/noise_var
35+
elif r < -28*A:
36+
LLR[m] = 60*A*(r+14*A)/noise_var
37+
elif r < -26*A:
38+
LLR[m] = 56*A*(r+13*A)/noise_var
39+
elif r < -24*A:
40+
LLR[m] = 52*A*(r+12*A)/noise_var
41+
elif r < -22*A:
42+
LLR[m] = 48*A*(r+11*A)/noise_var
43+
elif r < -20*A:
44+
LLR[m] = 44*A*(r+10*A)/noise_var
45+
elif r < -18*A:
46+
LLR[m] = 40*A*(r+9*A)/noise_var
47+
elif r < -16*A:
48+
LLR[m] = 36*A*(r+8*A)/noise_var
49+
elif r < -14*A:
50+
LLR[m] = 32*A*(r+7*A)/noise_var
51+
elif r < -12*A:
52+
LLR[m] = 28*A*(r+6*A)/noise_var
53+
elif r < -10*A:
54+
LLR[m] = 24*A*(r+5*A)/noise_var
55+
elif r < -8*A:
56+
LLR[m] = 20*A*(r+4*A)/noise_var
57+
elif r < -6*A:
58+
LLR[m] = 16*A*(r+3*A)/noise_var
59+
elif r < -4*A:
60+
LLR[m] = 12*A*(r+2*A)/noise_var
61+
elif r < -2*A:
62+
LLR[m] = 8*A*(r+1*A)/noise_var
63+
elif r < 2*A:
64+
LLR[m] = 4*A*r/noise_var
65+
elif r < 4*A:
66+
LLR[m] = 8*A*(r-1*A)/noise_var
67+
elif r < 6*A:
68+
LLR[m] = 12*A*(r-2*A)/noise_var
69+
elif r < 8*A:
70+
LLR[m] = 16*A*(r-3*A)/noise_var
71+
elif r < 10*A:
72+
LLR[m] = 20*A*(r-4*A)/noise_var
73+
elif r < 12*A:
74+
LLR[m] = 24*A*(r-5*A)/noise_var
75+
elif r < 14*A:
76+
LLR[m] = 28*A*(r-6*A)/noise_var
77+
elif r < 16*A:
78+
LLR[m] = 32*A*(r-7*A)/noise_var
79+
elif r < 18*A:
80+
LLR[m] = 36*A*(r-8*A)/noise_var
81+
elif r < 20*A:
82+
LLR[m] = 40*A*(r-9*A)/noise_var
83+
elif r < 22*A:
84+
LLR[m] = 44*A*(r-10*A)/noise_var
85+
elif r < 24*A:
86+
LLR[m] = 48*A*(r-11*A)/noise_var
87+
elif r < 26*A:
88+
LLR[m] = 52*A*(r-12*A)/noise_var
89+
elif r < 28*A:
90+
LLR[m] = 56*A*(r-13*A)/noise_var
91+
elif r < 30*A:
92+
LLR[m] = 60*A*(r-14*A)/noise_var
93+
else:
94+
LLR[m] = 64*A*(r-15*A)/noise_var
95+
96+
return LLR
97+
98+
def LLR_1024qam_bit_2_3(insym, noise_var,A):
99+
""" 1024QAM b2 and b3 LLR"""
100+
LLR = np.zeros(insym.size,dtype='f')
101+
for m in range(insym.size):
102+
r = insym[m]
103+
if r < -30*A:
104+
LLR[m] = 32*A*(r+23*A)/noise_var
105+
elif r < -28*A:
106+
LLR[m] = 28*A*(r+22*A)/noise_var
107+
elif r < -26*A:
108+
LLR[m] = 24*A*(r+21*A)/noise_var
109+
elif r < -24*A:
110+
LLR[m] = 20*A*(r+20*A)/noise_var
111+
elif r < -22*A:
112+
LLR[m] = 16*A*(r+19*A)/noise_var
113+
elif r < -20*A:
114+
LLR[m] = 12*A*(r+18*A)/noise_var
115+
elif r < -18*A:
116+
LLR[m] = 8*A*(r+17*A)/noise_var
117+
elif r < -14*A:
118+
LLR[m] = 4*A*(r+16*A)/noise_var
119+
elif r < -12*A:
120+
LLR[m] = 8*A*(r+15*A)/noise_var
121+
elif r < -10*A:
122+
LLR[m] = 12*A*(r+14*A)/noise_var
123+
elif r < -8*A:
124+
LLR[m] = 16*A*(r+13*A)/noise_var
125+
elif r < -6*A:
126+
LLR[m] = 20*A*(r+12*A)/noise_var
127+
elif r < -4*A:
128+
LLR[m] = 24*A*(r+11*A)/noise_var
129+
elif r < -2*A:
130+
LLR[m] = 28*A*(r+10*A)/noise_var
131+
elif r < 0:
132+
LLR[m] = 32*A*(r+9*A)/noise_var
133+
elif r < 2*A:
134+
LLR[m] = 32*A*(-r+9*A)/noise_var
135+
elif r < 4*A:
136+
LLR[m] = 28*A*(-r+10*A)/noise_var
137+
elif r < 6*A:
138+
LLR[m] = 24*A*(-r+11*A)/noise_var
139+
elif r < 8*A:
140+
LLR[m] = 20*A*(-r+12*A)/noise_var
141+
elif r < 10*A:
142+
LLR[m] = 16*A*(-r+13*A)/noise_var
143+
elif r < 12*A:
144+
LLR[m] = 12*A*(-r+14*A)/noise_var
145+
elif r < 14*A:
146+
LLR[m] = 8*A*(-r+15*A)/noise_var
147+
elif r < 18*A:
148+
LLR[m] = 4*A*(-r+16*A)/noise_var
149+
elif r < 20*A:
150+
LLR[m] = 8*A*(-r+17*A)/noise_var
151+
elif r < 22*A:
152+
LLR[m] = 12*A*(-r+18*A)/noise_var
153+
elif r < 24*A:
154+
LLR[m] = 16*A*(-r+19*A)/noise_var
155+
elif r < 26*A:
156+
LLR[m] = 20*A*(-r+20*A)/noise_var
157+
elif r < 28*A:
158+
LLR[m] = 24*A*(-r+21*A)/noise_var
159+
elif r < 30*A:
160+
LLR[m] = 28*A*(-r+22*A)/noise_var
161+
else:
162+
LLR[m] = 32*A*(-r+23*A)/noise_var
163+
164+
return LLR
165+
166+
def LLR_1024qam_bit_4_5(insym, noise_var,A):
167+
""" 1024QAM b4 and b5 LLR"""
168+
LLR = np.zeros(insym.size,dtype='f')
169+
for m in range(insym.size):
170+
r = insym[m]
171+
if r < -30*A:
172+
LLR[m] = 16*A*(r+27*A)/noise_var
173+
elif r < -28*A:
174+
LLR[m] = 12*A*(r+26*A)/noise_var
175+
elif r < -26*A:
176+
LLR[m] = 8*A*(r+25*A)/noise_var
177+
elif r < -22*A:
178+
LLR[m] = 4*A*(r+24*A)/noise_var
179+
elif r < -20*A:
180+
LLR[m] = 8*A*(r+23*A)/noise_var
181+
elif r < -18*A:
182+
LLR[m] = 12*A*(r+22*A)/noise_var
183+
elif r < -16*A:
184+
LLR[m] = 16*A*(r+21*A)/noise_var
185+
elif r < -14*A:
186+
LLR[m] = 16*A*(-r-11*A)/noise_var
187+
elif r < -12*A:
188+
LLR[m] = 12*A*(-r-10*A)/noise_var
189+
elif r < -10*A:
190+
LLR[m] = 8*A*(-r-9*A)/noise_var
191+
elif r < -6*A:
192+
LLR[m] = 4*A*(-r-8*A)/noise_var
193+
elif r < -4*A:
194+
LLR[m] = 8*A*(-r-7*A)/noise_var
195+
elif r < -2*A:
196+
LLR[m] = 12*A*(-r-6*A)/noise_var
197+
elif r < 0:
198+
LLR[m] = 16*A*(-r-5*A)/noise_var
199+
elif r < 2*A:
200+
LLR[m] = 16*A*(r-5*A)/noise_var
201+
elif r < 4*A:
202+
LLR[m] = 12*A*(r-6*A)/noise_var
203+
elif r < 6*A:
204+
LLR[m] = 8*A*(r-7*A)/noise_var
205+
elif r < 10*A:
206+
LLR[m] = 4*A*(r-8*A)/noise_var
207+
elif r < 12*A:
208+
LLR[m] = 8*A*(r-9*A)/noise_var
209+
elif r < 14*A:
210+
LLR[m] = 12*A*(r-10*A)/noise_var
211+
elif r < 16*A:
212+
LLR[m] = 16*A*(r-11*A)/noise_var
213+
elif r < 18*A:
214+
LLR[m] = 16*A*(-r+21*A)/noise_var
215+
elif r < 20*A:
216+
LLR[m] = 12*A*(-r+22*A)/noise_var
217+
elif r < 22*A:
218+
LLR[m] = 8*A*(-r+23*A)/noise_var
219+
elif r < 26*A:
220+
LLR[m] = 4*A*(-r+24*A)/noise_var
221+
elif r < 28*A:
222+
LLR[m] = 8*A*(-r+25*A)/noise_var
223+
elif r < 30*A:
224+
LLR[m] = 12*A*(-r+26*A)/noise_var
225+
else:
226+
LLR[m] = 16*A*(-r+27*A)/noise_var
227+
228+
return LLR
229+
230+
def LLR_1024qam_bit_6_7(insym, noise_var,A):
231+
""" 1024QAM b6 and b7 LLR"""
232+
LLR = np.zeros(insym.size,dtype='f')
233+
for m in range(insym.size):
234+
r = insym[m]
235+
if r < -30*A:
236+
LLR[m] = 8*A*(r+29*A)/noise_var
237+
elif r < -26*A:
238+
LLR[m] = 4*A*(r+28*A)/noise_var
239+
elif r < -24*A:
240+
LLR[m] = 8*A*(r+27*A)/noise_var
241+
elif r < -22*A:
242+
LLR[m] = 8*A*(-r-21*A)/noise_var
243+
elif r < -18*A:
244+
LLR[m] = 4*A*(-r-20*A)/noise_var
245+
elif r < -16*A:
246+
LLR[m] = 8*A*(-r-19*A)/noise_var
247+
elif r < -14*A:
248+
LLR[m] = 8*A*(r+13*A)/noise_var
249+
elif r < -10*A:
250+
LLR[m] = 4*A*(r+12*A)/noise_var
251+
elif r < -8*A:
252+
LLR[m] = 8*A*(r+11*A)/noise_var
253+
elif r < -6*A:
254+
LLR[m] = 8*A*(-r-5*A)/noise_var
255+
elif r < -2*A:
256+
LLR[m] = 4*A*(-r-4*A)/noise_var
257+
elif r < 0:
258+
LLR[m] = 8*A*(-r-3*A)/noise_var
259+
elif r < 2*A:
260+
LLR[m] = 8*A*(r-3*A)/noise_var
261+
elif r < 6*A:
262+
LLR[m] = 4*A*(r-4*A)/noise_var
263+
elif r < 8*A:
264+
LLR[m] = 8*A*(r-5*A)/noise_var
265+
elif r < 10*A:
266+
LLR[m] = 8*A*(-r+11*A)/noise_var
267+
elif r < 14*A:
268+
LLR[m] = 4*A*(-r+12*A)/noise_var
269+
elif r < 16*A:
270+
LLR[m] = 8*A*(-r+13*A)/noise_var
271+
elif r < 18*A:
272+
LLR[m] = 8*A*(r-19*A)/noise_var
273+
elif r < 22*A:
274+
LLR[m] = 4*A*(r-20*A)/noise_var
275+
elif r < 24*A:
276+
LLR[m] = 8*A*(r-21*A)/noise_var
277+
elif r < 26*A:
278+
LLR[m] = 8*A*(-r+27*A)/noise_var
279+
elif r < 30*A:
280+
LLR[m] = 4*A*(-r+28*A)/noise_var
281+
else:
282+
LLR[m] = 8*A*(-r+29*A)/noise_var
283+
284+
return LLR
285+
286+
def LLR_1024qam_bit_8_9(insym, noise_var,A):
287+
""" 1024QAM b8 and b9 LLR"""
288+
LLR = np.zeros(insym.size,dtype='f')
289+
for m in range(insym.size):
290+
r = insym[m]
291+
if r < -28*A:
292+
LLR[m] = 4*A*(r+30*A)/noise_var
293+
elif r < -24*A:
294+
LLR[m] = 4*A*(-r-26*A)/noise_var
295+
elif r < -20*A:
296+
LLR[m] = 4*A*(r+22*A)/noise_var
297+
elif r < -16*A:
298+
LLR[m] = 4*A*(-r-18*A)/noise_var
299+
elif r < -12*A:
300+
LLR[m] = 4*A*(r+14*A)/noise_var
301+
elif r < -8*A:
302+
LLR[m] = 4*A*(-r-10*A)/noise_var
303+
elif r < -4*A:
304+
LLR[m] = 4*A*(r+6*A)/noise_var
305+
elif r < 0:
306+
LLR[m] = 4*A*(-r-2*A)/noise_var
307+
elif r < 4*A:
308+
LLR[m] = 4*A*(r-2*A)/noise_var
309+
elif r < 8*A:
310+
LLR[m] = 4*A*(-r+6*A)/noise_var
311+
elif r < 12*A:
312+
LLR[m] = 4*A*(r-10*A)/noise_var
313+
elif r < 16*A:
314+
LLR[m] = 4*A*(-r+14*A)/noise_var
315+
elif r < 20*A:
316+
LLR[m] = 4*A*(r-18*A)/noise_var
317+
elif r < 24*A:
318+
LLR[m] = 4*A*(-r+22*A)/noise_var
319+
elif r < 28*A:
320+
LLR[m] = 4*A*(r-26*A)/noise_var
321+
else:
322+
LLR[m] = 4*A*(-r+30*A)/noise_var
323+
324+
return LLR
325+
326+
327+
if __name__ == "__main__":
328+
329+
aaa=1
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding:utf-8 -*-
2+
import numpy as np
3+
import math
4+
5+
def demod(insymbols,noise_var):
6+
"""16QAM demodulation
7+
"""
8+
A = 1/math.sqrt(10)
9+
LLR = np.zeros(4*insymbols.size,dtype='f')
10+
LLR[0::4] = LLR_16qam_bit_0_1(insymbols.real,noise_var,A)
11+
LLR[1::4] = LLR_16qam_bit_0_1(insymbols.imag,noise_var,A)
12+
13+
LLR[2::4] = LLR_16qam_bit_2_3(insymbols.real,noise_var,A)
14+
LLR[3::4] = LLR_16qam_bit_2_3(insymbols.imag,noise_var,A)
15+
16+
hardbits = [0 if a>0 else 1 for a in LLR]
17+
return hardbits,LLR
18+
19+
def LLR_16qam_bit_0_1(insym, noise_var,A):
20+
""" 16QAM b0 and b1 LLR"""
21+
LLR = np.zeros(insym.size,dtype='f')
22+
for m in range(insym.size):
23+
r = insym[m]
24+
if r < -2*A:
25+
LLR[m] = 8*A*(r+A)/noise_var
26+
elif r < 2*A:
27+
LLR[m] = 4*A*r/noise_var
28+
else:
29+
LLR[m] = 8*A*(r-A)/noise_var
30+
31+
return LLR
32+
33+
def LLR_16qam_bit_2_3(insym, noise_var,A):
34+
""" 16QAM b2 and b3 LLR"""
35+
LLR = np.zeros(insym.size,dtype='f')
36+
for m in range(insym.size):
37+
r = insym[m]
38+
if r < 0:
39+
LLR[m] = 4*A*(r+2*A)/noise_var
40+
else:
41+
LLR[m] = 4*A*(-r+2*A)/noise_var
42+
43+
return LLR

0 commit comments

Comments
 (0)