def shaping_filter(upsampler, Ns, alpha, Fif, Fs):
    """To give the symbols a shape, a convolution is made between the upsampled symbols and the impulse response of a square root raised cosine filter.
    It also arranges the information in a defined frequency spectrum and is projected in a way to reduce the intersymbol interference.

    Parameters
    ----------
    upsampler : int
        Upsampled symbols.
    Ns : int
        Number of symbols.
    alpha : float
        Roll-off factor. Numbers between 0-1.
    Fif : float
        Intermediary frequency.
    Fs : float
        Sampling frequency

    Returns
    -------
    shaped_signal : 1D array of floats
        Signal convoluted with a SRRC filter impulse response.
    x_axis : 1D array of floats
        Data domain.
    y_response : 1D array of floats
        Array with the amplitudes varying regarding the domain.
    """
    [x_axis, y_response] = cp.rrcosfilter(Ns, alpha, 2 / Fif, Fs)
    shaped_signal = np.convolve(upsampler, y_response, 'full')
    return (shaped_signal, x_axis, y_response)
 def __init__(self, carrierFreq, upsamplingFactor, sampleRate, fi=0):
     """
         sampleRate - sample rate of output stream (eg. PLUTO) 
     """
     self.carrierFreq = carrierFreq
     self.upsamplingFactor = upsamplingFactor
     self.fi = fi
     self.sampleRate = sampleRate
     self.psfFilter = cp.rrcosfilter(
         int(self.upsamplingFactor) * 10, 0.35,
         self.upsamplingFactor / self.sampleRate, self.sampleRate)[1]
     self.sampleTime = 1 / self.sampleRate
     self.currentTime = 0
     self._MAPPING_TABLE_QAM16 = {
         # TODO: check corectness of the table
         (0, 0, 0, 0): -3 - 3j,
         (0, 0, 0, 1): -3 - 1j,
         (0, 0, 1, 0): -3 + 3j,
         (0, 0, 1, 1): -3 + 1j,
         (0, 1, 0, 0): -1 - 3j,
         (0, 1, 0, 1): -1 - 1j,
         (0, 1, 1, 0): -1 + 3j,
         (0, 1, 1, 1): -1 + 1j,
         (1, 0, 0, 0): 3 - 3j,
         (1, 0, 0, 1): 3 - 1j,
         (1, 0, 1, 0): 3 + 3j,
         (1, 0, 1, 1): 3 + 1j,
         (1, 1, 0, 0): 1 - 3j,
         (1, 1, 0, 1): 1 - 1j,
         (1, 1, 1, 0): 1 + 3j,
         (1, 1, 1, 1): 1 + 1j
     }
 def __init__(self, carrierFreq: int, sampleRate: int, upsamplingFactor=8):
     self.carrierFreq = carrierFreq
     self.upsamplingFactor = upsamplingFactor
     self.sampleRate = sampleRate
     self.psfFilter = cp.rrcosfilter(
         int(self.upsamplingFactor) * 10, 0.35,
         self.upsamplingFactor / self.sampleRate, self.sampleRate)[1]
Exemple #4
0
def gfdm_rx_fft2(y, filtertype, alpha, M, K, L, N, QAM, J):
    '''
    y: transmitted gfdm-block (length: M*K samples)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter
    Low-complexity receiver implementation as proposed by G.Fettweis
    (based on sparse frequency Domain Processing)

    output: demodulated samples in original order (first K samples in timeslot 1, second K ...)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K, alpha, K, 1)
    h = np.roll(h, h.shape[-1] / 2)
    H_rx = np.fft.fft(h)
    H_sparse = np.concatenate((H_rx[0:M * L / 2], H_rx[-M * L / 2:]))
    y_ifft = np.array([])
    y = (1.0 / K) * y
    # Transfer input to frequency domain and center around 0th frequency bin
    y_f = np.fft.fftshift(np.fft.fft(y))
    # Filter and superposition in frequency domain
    Y_fs = gfdm_rx_filsup(y_f, H_sparse, M, K, L)
    # Demodulate per subcarrier
    y_ifft = gfdm_rx_demod(Y_fs, K)
    if J > 0:
        y_ifft = gfdm_rx_sic(K, M, J, H_sparse, y_ifft, Y_fs, QAM)
        y_ifft = np.reshape(y_ifft, (K * M))
    # Sort output in timeslot,subcarrier order
    y_ifft = reshape_input(y_ifft, K, M)
    return y_ifft
Exemple #5
0
 def __init__(self, carrierFreq, symbolLength, fi, sampleRate, numOfPeriods):
     self.carrierFreq = carrierFreq
     self.symbolLength = symbolLength
     self.fi = fi
     self.sampleRate = sampleRate
     self.numOfPeriods = numOfPeriods
     self.psfFilter = cp.rrcosfilter(int(self.symbolLength) * 10 , 0.35, self.symbolLength / self.sampleRate, self.sampleRate)[1]
Exemple #6
0
def gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor=1.):
    N = oversampling_factor
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    return h
Exemple #7
0
def gfdm_rx_fft2(y, filtertype, alpha, M, K, L, N, QAM,J):
    '''
    y: transmitted gfdm-block (length: M*K samples)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter
    Low-complexity receiver implementation as proposed by G.Fettweis
    (based on sparse frequency Domain Processing)

    output: demodulated samples in original order (first K samples in timeslot 1, second K ...)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K, alpha, K, 1)
    h = np.roll(h, h.shape[-1]/2)
    H_rx = np.fft.fft(h)
    H_sparse = np.concatenate((H_rx[0:M*L/2], H_rx[-M*L/2:]))
    y_ifft = np.array([])
    y = (1.0/K)*y
    # Transfer input to frequency domain and center around 0th frequency bin
    y_f = np.fft.fftshift(np.fft.fft(y))
    # Filter and superposition in frequency domain
    Y_fs = gfdm_rx_filsup(y_f, H_sparse, M, K, L)
    # Demodulate per subcarrier
    y_ifft = gfdm_rx_demod(Y_fs, K)
    if J>0:
        y_ifft = gfdm_rx_sic(K,M,J,H_sparse,y_ifft,Y_fs,QAM)
        y_ifft = np.reshape(y_ifft,(K*M))
    # Sort output in timeslot,subcarrier order
    y_ifft = reshape_input(y_ifft, K, M)
    return y_ifft
Exemple #8
0
def gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor=1.):
    N = oversampling_factor
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, 1. * K * N, 1. )
    return h
Exemple #9
0
 def __init__(self, carrierFreq, symbolLength, sampleRate):
     self.carrierFreq = carrierFreq
     self.symbolLength = symbolLength
     self.sampleRate = sampleRate
     self.sampleTime = 1 / self.sampleRate
     self.psfFilter = cp.rrcosfilter(
         int(self.symbolLength) * 10, 0.35,
         self.symbolLength / self.sampleRate, self.sampleRate)[1]
Exemple #10
0
def gfdm_tx_fft2(x, filtertype, alpha, M, K, L, N):
    '''
    x: Input-Array (length: M*K symbols)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter

    Low-complexity transmitter implementation as proposed by G. Fettweis
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K, alpha, K, 1)
    h = np.roll(h, h.shape[-1] / 2)
    H = np.fft.fft(h)
    H_sparse = np.concatenate((H[0:(M * L) / 2], H[-(M * L) / 2:]))
    # Sort Input subcarrierwise
    x = reshape_input(x, M, K)
    x_out = np.zeros((M * K) + (L - 1) * M, dtype='complex')
    for k in xrange(K):
        # M rows and L columns with respective FFT output
        # pick symbols per subcarrier
        x_k = x[k * M:((k + 1) * M)]
        # perform fft and switch to frequency domain
        x_f = np.fft.fft(x_k)
        # copy values of M-point DFT to obtain MK-point DFT
        x_f_L = np.tile(x_f, L)
        # make data-vector 'sparse'
        #x_f_L = np.concatenate((x_f_K[0:(M*L)/2], x_f_K[-(M*L)/2:]))
        # filter with sparse filter taps in frequency domain
        x_fil = np.multiply(x_f_L, H_sparse)
        # Add data-vector to correct position -max neg frequency : 0 :
        # max_pos_frequency
        x_out[k * M:(k + L) *
              M] = x_out[k * M:(L + k) * M] + np.fft.fftshift(x_fil)
    # Add 'oversampled' parts of first subcarrier to end and 'oversampled' parts
    # of last subcarrier to start
    x_first = x_out[0:(L - 1) * M / 2]
    x_last = x_out[-(L - 1) * M / 2:]
    x_out = x_out[(L - 1) * M / 2:-(L - 1) * M / 2]
    x_out[0:(L - 1) * M / 2] = x_out[0:(L - 1) * M / 2] + x_last
    x_out[-(L - 1) * M / 2:] = x_out[-(L - 1) * M / 2:] + x_first
    x_t = np.fft.ifft(np.fft.ifftshift(x_out))
    x_t = (1.0 / K) * x_t
    return x_t
Exemple #11
0
def gfdm_tx_fft2(x, filtertype, alpha, M, K, L, N):
    '''
    x: Input-Array (length: M*K symbols)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter

    Low-complexity transmitter implementation as proposed by G. Fettweis
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K, alpha, K, 1)
    h = np.roll(h, h.shape[-1]/2)
    H = np.fft.fft(h)
    H_sparse = np.concatenate((H[0:(M*L)/2], H[-(M*L)/2:]))
    # Sort Input subcarrierwise
    x = reshape_input(x, M, K)
    x_out = np.zeros((M*K)+(L-1)*M, dtype='complex')
    for k in xrange(K):
        # M rows and L columns with respective FFT output
        # pick symbols per subcarrier
        x_k = x[k*M:((k+1)*M)]
        # perform fft and switch to frequency domain
        x_f = np.fft.fft(x_k)
        # copy values of M-point DFT to obtain MK-point DFT
        x_f_L = np.tile(x_f, L)
        # make data-vector 'sparse'
        #x_f_L = np.concatenate((x_f_K[0:(M*L)/2], x_f_K[-(M*L)/2:]))
        # filter with sparse filter taps in frequency domain
        x_fil = np.multiply(x_f_L, H_sparse)
        # Add data-vector to correct position -max neg frequency : 0 :
        # max_pos_frequency
        x_out[k*M:(k+L)*M] = x_out[k*M:(L+k)*M] + np.fft.fftshift(x_fil)
    # Add 'oversampled' parts of first subcarrier to end and 'oversampled' parts
    # of last subcarrier to start
    x_first = x_out[0:(L-1)*M/2]
    x_last = x_out[-(L-1)*M/2:]
    x_out = x_out[(L-1)*M/2:-(L-1)*M/2]
    x_out[0:(L-1)*M/2] = x_out[0:(L-1)*M/2] + x_last
    x_out[-(L-1)*M/2:] = x_out[-(L-1)*M/2:] + x_first
    x_t = np.fft.ifft(np.fft.ifftshift(x_out))
    x_t = (1.0/K)*x_t
    return x_t
Exemple #12
0
def main():
    seedI = [0, 1, 0, 1, 0, 1, 0, 1, 1]
    # Filtro SRRC
    rrcos = commpy.rrcosfilter(OVERSAMPLING * NBAUDS, ROLL_OFF,
                               1. / SYMBOL_RATE, SAMPLE_RATE)[1]
    rrcos = rrcos / np.sqrt(OVERSAMPLING)
    fixed_rrcos = arrayFixedInt(8, 7, rrcos)
    #for ptr in range(len(rrcos)):
    #    print ptr, rrcos[ptr], '\t', fixed_rrcos[ptr].fValue

    prbs_r = prbs9.prbs9(seedI)
    tx_r = tx.tx(fixed_rrcos)
    rx_r = rx.rx(fixed_rrcos)

    prbs_r.reset()
    tx_r.reset()
    rx_r.reset()

    out_prbs = prbs_r.prbs_out
    tx_r.print_buffer()
    tx_r.run(out_prbs, 1)

    enable_prbs = 0
    enable_tx = 1
    enable_rx = 1
    counter = 0

    #cables
    out_prbs = 0
    out_tx = 0
    for clk in range(511):
        if counter == 0:
            enable_prbs = 1
        else:
            enable_prbs = 0
        counter = (counter + 1) % 4

        prbs_r.new_bit(enable_prbs)
        out_prbs = prbs_r.prbs_out

        #tx_r.print_buffer()
        tx_r.run(out_prbs, enable_tx)
        out_tx = tx_r.tx_out

        rx_r.run(out_tx, enable_rx)
        print rx_r.rx_out.fValue
Exemple #13
0
def gfdm_tx_fft(x, filtertype, alpha, M, K):
    '''
        Realization of GFDM-Transmitter in FFT:
            Required input: x a np.array of length M*K
            FFT is applied in shifted version (zero-frequency term is centered)
            First symbol is on -freq_max and last symbol ist on freq_max
            h: Prototype-filter impulse response
            s_e[n]:[s_0[n] 0{M-1} s_1[n] .... s_N-1[n] 0{M-1}]
            x[n] = h (*) (IFFT(s_e[n]))
            x_gfdm = sum_M(circshift(x[n],nN))
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K, alpha, K, 1)
    # Initialization of output vector
    x_out = np.zeros(M * K, dtype='complex')
    # circulary move filter window to symbol 0
    h = np.roll(h, -(M * K / 2))
    # for each gfdm-block
    # for each timeslot
    for m in xrange(M):
        # select the K next symbols
        #symbols = np.fft.ifftshift(x[(m*K):(m+1)*K])
        symbols = np.fft.ifftshift(np.array([x[k * M + m] for k in xrange(K)]))
        # transform K symbols to K carriertones in time-domain
        sym_t = np.fft.ifft(symbols)
        sym_te = np.array([])
        # Repeat result M-times in a vector
        for m2 in xrange(M):
            sym_te = np.concatenate((sym_te, sym_t))
        # multipy with transmit filter -> better convolve?
        sym_te = np.convolve(sym_te, h, mode='same')
        #sym_te = np.multiply(sym_te,h)
        # shift result m*K samples to the right and add it up to the result
        # vector
        x_out = np.add(x_out, np.roll(sym_te, m * K))

    return x_out
Exemple #14
0
def gfdm_tx_fft(x, filtertype, alpha, M, K):
    '''
        Realization of GFDM-Transmitter in FFT:
            Required input: x a np.array of length M*K
            FFT is applied in shifted version (zero-frequency term is centered)
            First symbol is on -freq_max and last symbol ist on freq_max
            h: Prototype-filter impulse response
            s_e[n]:[s_0[n] 0{M-1} s_1[n] .... s_N-1[n] 0{M-1}]
            x[n] = h (*) (IFFT(s_e[n]))
            x_gfdm = sum_M(circshift(x[n],nN))
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K, alpha, K, 1)
    # Initialization of output vector
    x_out = np.zeros(M*K, dtype='complex')
    # circulary move filter window to symbol 0
    h = np.roll(h, -(M*K/2))
    # for each gfdm-block
        # for each timeslot
    for m in xrange(M):
        # select the K next symbols
        #symbols = np.fft.ifftshift(x[(m*K):(m+1)*K])
        symbols = np.fft.ifftshift(np.array([x[k*M+m] for k in xrange(K)]))
        # transform K symbols to K carriertones in time-domain
        sym_t = np.fft.ifft(symbols)
        sym_te = np.array([])
        # Repeat result M-times in a vector
        for m2 in xrange(M):
            sym_te = np.concatenate((sym_te, sym_t))
        # multipy with transmit filter -> better convolve?
        sym_te = np.convolve(sym_te, h, mode='same')
        #sym_te = np.multiply(sym_te,h)
        # shift result m*K samples to the right and add it up to the result
        # vector
        x_out = np.add(x_out, np.roll(sym_te, m*K))

    return x_out
Exemple #15
0
def transmitMatrix(filtertype, alpha, M, K, N):
    '''
        Create Convolution Matrix for pulse shaping

        filtertype : (rrc,rc)
        alpha : roll-off-factor
        sampling_rate : sampling rate (in Hz)
        symbol_period : symbol period (in s)
        M : number of symbol time slots
        K : number of subcarriers

        h_matrix: array of impulse responses for time slot (0...M-1)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, N * K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, N * K, 1)
    # Move filter cyclic
    G_tx = np.array(
        [np.roll(h, m - (M * K * N / 2)) for m in xrange(M * K * N)])
    S_mn = samplingMatrix(M, K * N)
    S_nm = samplingMatrix(K, M)
    if N > 1:
        # if oversampling is specified add zeros to samplingMatrix
        S_nm = np.insert(S_nm,
                         M * K / 2,
                         np.zeros((M * K * (N - 1), K), dtype='complex'),
                         axis=0)
    W_H = fourierMatrix(M * K * N).conj().transpose()
    # Resample Filter
    G_tx_s = np.dot(G_tx, S_mn)
    # Resample FourierMatrix
    W_s = np.dot(S_nm.transpose(), W_H)
    # compute and use all elements of the main diagonal W_s.dot(G_tx_s)
    A = np.array([(np.kron(W_s.transpose()[n], G_tx_s[n]))
                  for n in xrange(K * M * N)])

    return A
Exemple #16
0
def transmitMatrix(filtertype, alpha, M, K, N):
    '''
        Create Convolution Matrix for pulse shaping

        filtertype : (rrc,rc)
        alpha : roll-off-factor
        sampling_rate : sampling rate (in Hz)
        symbol_period : symbol period (in s)
        M : number of symbol time slots
        K : number of subcarriers

        h_matrix: array of impulse responses for time slot (0...M-1)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K*N, alpha, N*K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K*N, alpha, N*K, 1)
    # Move filter cyclic
    G_tx = np.array([np.roll(h, m - (M*K*N/2)) for m in xrange(M*K*N)])
    S_mn = samplingMatrix(M, K*N)
    S_nm = samplingMatrix(K, M)
    if N > 1:
        # if oversampling is specified add zeros to samplingMatrix
        S_nm = np.insert(
            S_nm, M * K / 2, np.zeros((M * K * (N - 1), K), dtype='complex'),
            axis=0)
    W_H = fourierMatrix(M*K*N).conj().transpose()
    # Resample Filter
    G_tx_s = np.dot(G_tx, S_mn)
    # Resample FourierMatrix
    W_s = np.dot(S_nm.transpose(), W_H)
    # compute and use all elements of the main diagonal W_s.dot(G_tx_s)
    A = np.array([(np.kron(W_s.transpose()[n], G_tx_s[n]))
                 for n in xrange(K*M*N)])

    return A
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1,
                1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1]
__OUTPUT_BITS = [1 if x > 0 else 0 for x in __INPUT_BITS]
__PSF = cp.rrcosfilter(int(__SYMBOL_LENGTH_IN_BITS)*10 , 0.35, __SYMBOL_LENGTH_IN_BITS / __SAMPLE_RATE , __SAMPLE_RATE)[1]


########################################################################################################################
#       FUNCTIONS
########################################################################################################################

def __filterSignal(inSig):
    filtered = np.convolve(__PSF, inSig)
    filtered = filtered[int(__SYMBOL_LENGTH_IN_BITS*5): -int(__SYMBOL_LENGTH_IN_BITS*5)+1]
    return filtered

def __calcSignal():
    numOfBitsPerSig = int(len(__INPUT_BITS) / 2)

    sigI = np.zeros([int(len(__INPUT_BITS) * __SYMBOL_LENGTH_IN_BITS / 2)])
def main():
    ## PRBS
    seedI = [0, 1, 0, 1, 0, 1, 0, 1, 1]
    seedQ = [0, 1, 1, 1, 1, 1, 1, 1, 1]

    new_prbsI = seedI
    new_prbsQ = seedQ

    bit_re_o = 0
    bit_im_o = 0

    log_prbs_re = []
    log_prbs_im = []

    ## Transmisor
    count_coef = 0
    conv_tx_re = DeFixedInt(roundMode='round',
                            signedMode='S',
                            intWidth=8,
                            fractWidth=7,
                            saturateMode='wrap')
    conv_tx_im = DeFixedInt(roundMode='round',
                            signedMode='S',
                            intWidth=8,
                            fractWidth=7,
                            saturateMode='wrap')

    # Reg input
    reg_tx_re_i = [0 for i in range(24)]
    reg_tx_im_i = [0 for i in range(24)]

    # Output
    tx_re_o = DeFixedInt(9, 7)
    tx_im_o = DeFixedInt(9, 7)

    log_tx_re = []
    log_tx_im = []

    ## Receptor
    conv_rx_re = DeFixedInt(roundMode='round',
                            signedMode='S',
                            intWidth=8,
                            fractWidth=7,
                            saturateMode='wrap')
    conv_rx_im = DeFixedInt(roundMode='round',
                            signedMode='S',
                            intWidth=8,
                            fractWidth=7,
                            saturateMode='wrap')

    # Reg input
    reg_rx_re_i = [DeFixedInt(9, 7) for i in range(24)]
    reg_rx_im_i = [DeFixedInt(9, 7) for i in range(24)]

    # Output
    rx_re_o = DeFixedInt(9, 7)
    rx_im_o = DeFixedInt(9, 7)
    log_rx_re = []
    log_rx_im = []

    ## DOWN

    down_re = 0
    down_im = 0
    down_re_o = 0
    down_im_o = 0
    log_down_re = []
    log_down_im = []

    ## BER
    ber_mult = 0
    ber_re_i = 0
    ber_im_i = 0

    ber_re_tx = [0 for i in range(511 * 2)]
    ber_im_tx = [0 for i in range(511 * 2)]
    error_re = 0
    error_im = 0
    led = 0
    # Filtro SRRC
    rrcos = commpy.rrcosfilter(OVERSAMPLING * NBAUDS, ROLL_OFF,
                               1. / SYMBOL_RATE, SAMPLE_RATE)[1]
    rrcos = rrcos / np.sqrt(OVERSAMPLING)
    fixed_rrcos = arrayFixedInt(8, 7, rrcos)
    #for ptr in range(len(rrcos)):
    #    print ptr, rrcos[ptr], '\t', fixed_rrcos[ptr].fValue

    for clk in range(511):

        ########################################################################
        #PRBS
        # Este modulo se ejecuta cada 4 ciclos de reloj, la salida son dos bits,
        # uno para y el otro para Q
        if clk % 4 == 0:
            new_prbsI = prbs(new_prbsI)
            new_prbsQ = prbs(new_prbsQ)
            print new_prbsI[8]

        ########################################################################

        ########################################################################
        #CONVOLUCION TX
        reg_tx_re_i.pop(0)
        reg_tx_re_i.insert(23, bit_re_o)
        reg_tx_im_i.pop(0)
        reg_tx_im_i.insert(23, bit_im_o)
        #print reg_tx_re_i
        coef = []

        for j in range(count_coef, count_coef + 21, 4):
            coef.append(j)
        #print coef
        if count_coef == 3:
            count_coef = 0
        else:
            count_coef += 1
        conv_tx_re = conv_tx(coef, reg_tx_re_i, fixed_rrcos)
        conv_tx_im = conv_tx(coef, reg_tx_im_i, fixed_rrcos)
        #print conv_tx_re.fValue
        ########################################################################

        ########################################################################
        # MODULO RECEPTOR
        # input 1 bit de la senal transmitida que lo coloca en un shift register
        # para convolucionar con rrcos
        reg_rx_re_i.pop(0)
        reg_rx_re_i.insert(23, tx_re_o)
        reg_rx_im_i.pop(0)
        reg_rx_im_i.insert(23, tx_im_o)
        conv_rx_re = convolve(reg_rx_re_i, fixed_rrcos)
        conv_rx_im = convolve(reg_rx_im_i, fixed_rrcos)

        ########################################################################

        ########################################################################
        # DOWN
        # offset de 1 a 4
        offset = 2
        if (clk + offset) % 4 == 0:
            if (conv_rx_re.fValue) > 0:
                down_re = 1
            else:
                down_re = 0
            if (conv_rx_im.fValue) > 0:
                down_im = 1
            else:
                down_im = 0

        ########################################################################

        ########################################################################
        # BER
        if clk % 4 == 0:

            ber_re_tx.insert(0, bit_re_o)
            ber_re_tx.pop()
            ber_im_tx.insert(0, bit_im_o)
            ber_im_tx.pop()

            ber_re_i = down_re_o
            ber_im_i = down_im_o

            if ber_re_tx[ber_mult] ^ ber_re_i != 0:
                error_re += 1
            if ber_im_tx[ber_mult] ^ ber_im_i != 0:
                error_re += 1
            if (clk / 4) % 511 == 0 and clk != 0:
                #print log_prbs_re
                #print log_down_re
                #print ber_mult
                #print error_re
                if error_re == 0:
                    led = 1
                else:
                    ber_mult += 1
                    error_re = 0
                    led = 0

        ########################################################################
        bit_re_o = new_prbsI[8]
        bit_im_o = new_prbsQ[8]
        log_prbs_re.append(new_prbsI[8])
        log_prbs_im.append(new_prbsQ[8])

        tx_re_o = conv_tx_re
        tx_im_o = conv_tx_im
        log_tx_re.append(conv_tx_re)
        log_tx_im.append(conv_tx_im)

        rx_re_o = conv_rx_re
        rx_im_o = conv_rx_im
        log_rx_re.append(conv_rx_re)
        log_rx_im.append(conv_rx_im)

        down_re_o = down_re
        down_im_o = down_im
        log_down_re.append(down_re)
        log_down_im.append(down_im)

    float_tx_re = ff(log_tx_re)
    float_tx_im = ff(log_tx_im)
    float_rx_re = ff(log_rx_re)
    float_rx_im = ff(log_rx_im)

    plt.figure(0)
    plt.title("square root raised cosine")
    plt.plot(rrcos)
    plt.figure(1)
    plt.title("senal transmitida real")
    plt.plot(float_tx_re[:200])
    plt.figure(2)
    plt.title("senal transmitida imaginaria")
    plt.plot(float_tx_im[:200])
    plt.figure(3)
    plt.title("senal recibida real")
    plt.plot(float_rx_re[:200])
    plt.figure(4)
    plt.title("senal recibida imaginaria")
    plt.plot(float_rx_im[:200])
    plt.figure(5)
    plt.title('constelacion')
    plt.plot(log_down_re, log_down_im, '.')
    eyediagram(float_rx_re[14:], 4, 1, OVERSAMPLING)
    plt.show()
    """