import math | |
import numpy as np | |
class IqSignals: | |
def __init__(self, params, NidCell, is_TDD): | |
pi = math.pi | |
## ------------------ PSS INIT (B) ------------------ | |
print "\n" | |
print "Generating Primary Synchronization Signal....", | |
#Compute physical layer identity Nid2 in range [0:2] | |
Nid2 = NidCell % 3 | |
#Identify root index from Nid2 | |
if(Nid2 == 0): | |
u = 25 | |
elif(Nid2 == 1): | |
u = 29 | |
elif(Nid2 == 2): | |
u = 34 | |
self.PSS_TD_complex = [0] * 62 | |
# The PSS is a sequence of complex symbols, 62 symbols long | |
for n in xrange(0, 62): | |
if n <= 30: | |
phase_coeff = -pi*u*(n+1)*n/63.0 | |
else: | |
phase_coeff = -pi*u*(n+1)*(n+2)/63.0 | |
self.PSS_TD_complex[n] = np.vectorize(complex)(math.cos(phase_coeff),math.sin(phase_coeff)) | |
self.PSS_TD_complex_pad = [0] * 72 | |
self.PSS_TD_complex_pad[5:67] = self.PSS_TD_complex | |
self.PSS_TD_complex_pad_fftSize_wShift = [0] * params.PSS_FFT_size | |
self.PSS_TD_complex_pad_fftSize_wShift[1:37] = self.PSS_TD_complex_pad[36:] | |
self.PSS_TD_complex_pad_fftSize_wShift[params.PSS_FFT_size-36:] = self.PSS_TD_complex_pad[:36] | |
self.PSS_TD_complex_pad_fftSize_wShift_ifft = np.fft.ifft(self.PSS_TD_complex_pad_fftSize_wShift) | |
#Define indices location of PSS in half-frame resource grid (TODO!) | |
print "Done." | |
## ------------------ PSS INIT (B) ------------------ | |
## See http://www.sharetechnote.com/html/Handbook_LTE_SSS.html < Matlab code for SSS Generation > | |
## ------------------ SSS INIT (B) ------------------ | |
#Compute physical layer cell-identity group Nid1 ( range LTE:[0:167], NR:[0:335]) | |
print "Generating Secondary Synchronization Signal....", | |
#Compute physical layer cell-identity group Nid1 ( range [0:167] ) | |
Nid1 = math.floor(NidCell/3.0) | |
# Define indices m0 and m1 | |
q_prime = math.floor(Nid1/30.0) | |
q_ = math.floor( (Nid1 + 0.5*q_prime*(q_prime+1.0)) / 30.0 ) | |
m_prime = Nid1 + q_*(q_+1)/2 | |
m0 = int(m_prime % 31) | |
m1 = int((m0 + math.floor(m_prime/31.0) + 1.0) % 31) | |
#print ['q_prime',q_prime,'q_',q_,'m_prime',m_prime,'m0',m0,'m1',m1] | |
# **** Generate sequences s0^(m0)[n] and s1^(m1)[n] **** | |
# Compute m-sequence s_tilde | |
x_s = [0] * 31 | |
x_s[4] = 1 | |
for i_ in xrange(0,26): | |
x_s[i_+5] = (x_s[i_+2] + x_s[i_]) % 2 | |
# Matlab: s_tilde = 1 - 2*x_s | |
s_tilde = [1-2*x for x in x_s] | |
# Compute s0_m0 and s1_m1 from s_tilde with different cyclic shifts | |
self.s0_ = [0] * 31 | |
self.s1_ = [0] * 31 | |
for i_ in xrange(0,31): | |
self.s0_[i_] = s_tilde[(i_ + m0) % 31] | |
self.s1_[i_] = s_tilde[(i_ + m1) % 31] | |
# **** Generate scrambling sequences c0[n] and c1[n] **** | |
# Compute m-sequence c_tilde | |
x_c = [0] * 31 | |
x_c[4] = 1 | |
for i_ in xrange(0,26): | |
x_c[i_+5] = (x_c[i_+3] + x_c[i_]) % 2 | |
# Matlab: c_tilde = 1 - 2*x_c | |
c_tilde = [1-2*x for x in x_c] | |
# Compute c0_ and c1_ from c_tilde with different cyclic shifts | |
self.c0_ = [0] * 31 | |
self.c1_ = [0] * 31 | |
for i_ in xrange(0,31): | |
self.c0_[i_] = c_tilde[(i_ + Nid2) % 31] | |
self.c1_[i_] = c_tilde[(i_ + Nid2 + 3) % 31] | |
# **** Generate scrambling sequences z1^(m0)[n] and z1^(m1)[n] **** | |
# Compute m-sequence z_tilde | |
x_z = [0] * 31 | |
x_z[4] = 1 | |
for i_ in xrange(0,26): | |
x_z[i_+5] = (x_z[i_+4] + x_z[i_+2] + x_z[i_+1] + x_z[i_]) % 2 | |
# Matlab: z_tilde = 1 - 2*x_z | |
z_tilde = [1-2*x for x in x_z] | |
# Compute z1_m0 and z1_m1 from z_tilde with different cyclic shifts | |
self.z1_m0 = [0] * 31 | |
self.z1_m1 = [0] * 31 | |
for i_ in xrange(0,31): | |
self.z1_m0[i_] = z_tilde[(i_ + (m0%8)) % 31] | |
self.z1_m1[i_] = z_tilde[(i_ + (m1%8)) % 31] | |
#Define indices location of SSS in half-frame resource grid | |
self.SSS_k_index_start = 0 -31 + 12*params.numRB/2 | |
self.SSS_k_index_end = 61 -31 + 12*params.numRB/2 | |
if (is_TDD == 1): | |
self.SSS_l_column = 13 | |
else: | |
self.SSS_l_column = 5 | |
print "Done." | |
## ------------------ SSS INIT (E) ------------------ | |
######################################################################## | |
# ------------------ SYNCHRONIZATION SIGNALS INIT (E) -----------------# | |
######################################################################## | |
################################################################################ | |
# ------------------ CELL-SPECIFIC REFERENCE SIGNALS INIT (B) -----------------# | |
################################################################################ | |
print "Generating Cell-Specific Reference Signals....", | |
N_c = 1600 | |
NmaxRB = 110 | |
seqLength = 4*NmaxRB | |
real_vec = np.zeros((2*NmaxRB,20*(params.Ncp_type+6))) | |
imag_vec = np.zeros((2*NmaxRB,20*(params.Ncp_type+6))) | |
self.CSRS_mat = np.vectorize(complex)(real_vec,imag_vec) | |
for kk in xrange(0, 20): | |
for ii in xrange(0,(params.Ncp_type+6)): | |
c_init = 1024 * ( 7 * ( kk + 1 ) + 1 + ii ) * (2*NidCell+1) + 2*NidCell + params.Ncp_type | |
#print c_init | |
# x_1 initialization | |
x_1 = [0] * (seqLength + N_c + 31) | |
x_1[0] = 1 | |
x_2 = [0] * (seqLength + N_c + 31) | |
# # Initializes x_2 using c_init (converts to binary form) | |
# i = 0; | |
# while (c_init >= 1): | |
# x_2[i] = c_init % 2 | |
# c_init = math.floor(c_init / 2) | |
# i = i +1 | |
# Initializes x_2 using c_init (converts to binary form) | |
i = 30; | |
while (c_init >= 1): | |
x2_val = math.floor(c_init/math.pow(2,i)) | |
x_2[i] = x2_val | |
c_init = c_init - x2_val*math.pow(2,i) | |
i = i - 1 | |
# Generation of x_1[n] and x_2[n] | |
for n in xrange(0,seqLength + N_c): | |
x_1[n+31] = (x_1[n+3] + x_1[n]) % 2 | |
x_2[n+31] = (x_2[n+3] + x_2[n+2] + x_2[n+1] + x_2[n]) % 2 | |
# Generation of Gold PN sequence: c_seq[n] = (x_1[n+Nc] + x_2[n+Nc])mod2 | |
c_seq = np.zeros((seqLength,1)) | |
for nn in xrange(0,seqLength): | |
c_seq[nn] = (x_1[nn+N_c] + x_2[nn + N_c]) % 2 | |
# Generation of QPSK-based CSRS | |
ref_sig_seq = np.sqrt(0.5) * np.vectorize(complex)(1-2*c_seq[0:4*NmaxRB:2],1-2*c_seq[1:4*NmaxRB:2]) | |
self.CSRS_mat[:,kk*(6+params.Ncp_type)+ii] = ref_sig_seq[:,0] | |
self.NmaxRB = NmaxRB | |
print "Done." |