Skip to main content

This package holds implementations for some Communication DSP methodology I found useful and informative

Project description

CommDspy

Repository for the communication signal processing package

Developed by: Tomer Geva

Example uses:

Generating OSR1 and OSR n signal

import CommDspy as cdsp
import numpy as np
def tx_example():
    # ==================================================================================================================
    # Local variables
    # ==================================================================================================================
    prbs_type       = cdsp.constants.PrbsEnum.PRBS13
    bits_per_symbol = 2
    bit_order_inv   = False
    inv_msb         = False
    inv_lsb         = False
    pn_inv          = False
    constellation   = cdsp.constants.ConstellationEnum.PAM4
    full_scale      = True
    gray_coding     = False 
    poly_coeff      = cdsp.get_polynomial(prbs_type)
    init_seed       = np.array([1] * prbs_type.value)
    prbs_len        = 25  # can be any number
    # ==================================================================================================================
    # Creating reference pattern
    # ==================================================================================================================
    # --------------------------------------------------------------------------------------------------------------
    # Getting PRBS binary pattern
    # --------------------------------------------------------------------------------------------------------------
    prbs_seq, seed_dut = cdsp.tx.prbs_gen(poly_coeff, init_seed, prbs_len * bits_per_symbol)
    # --------------------------------------------------------------------------------------------------------------
    # Duplicating if needed and coding
    # --------------------------------------------------------------------------------------------------------------
    pattern       = cdsp.tx.bin2symbol(prbs_seq, 2 ** bits_per_symbol, bit_order_inv, inv_msb, inv_lsb, pn_inv)
    pattern       = cdsp.tx.mapping(pattern, constellation, full_scale) if not gray_coding else cdsp.tx.mapping(cdsp.tx.coding_gray(pattern, constellation), constellation, full_scale)

    return pattern
    
pattern = tx_example()
# ==================================================================================================================
# Pulse shaping
# ==================================================================================================================
rolloff     = 0.5
tx_out_rect = cdsp.channel.pulse_shape(pattern,osr=32, span=8, method='rect')
tx_out_sinc = cdsp.channel.pulse_shape(pattern,osr=32, span=8, method='sinc')
tx_out_rcos = cdsp.channel.pulse_shape(pattern,osr=32, span=8, method='rcos', beta=rolloff)
tx_out_rrc  = cdsp.channel.pulse_shape(pattern,osr=32, span=8, method='rrc', beta=rolloff)

Results:

Tx example

Figure 1 - Simple Tx example

The pulse shaped signal can be plotted as an eye diagram as follows:

eye_d, amp_vec = cdsp.eye_diagram(tx_out_rcos, 32, 128, fs_value=3, quantization=2048, logscale=True)

The results can be seen using matplotlib.pyplot functions such as contourf: Eye_pulse_rcos_rolloff_0p5

Figure 2 Eye diagram of PRBS13 after raised cosine pulse shaping with rolloff of 0.5, logscale plot

Eye_pulse_rcos_rolloff_0p5

Figure 3 Eye diagram of PRBS13 after raised cosine pulse shaping with rolloff of 0.9, logscale plot

Passing a signal through channels

The package can be used to pass a signal through different channels

AWGN

Adding white gaussian noise on top of the pulse shaping, this is done by:

rolloff = 0.9
snr     = 30
pattern = tx_example()
ch_out  = cdsp.channel.awgn(pattern, osr=32, span=8, method='rcos', beta=rolloff, snr=snr)
eye_d, amp_vec = cdsp.eye_diagram(ch_out, 32, 128, fs_value=3, quantization=2048, logscale=False)
time_ui = np.linspace(0, 2, 256)

The result can be shown in the form of an eye diagram:

awgn_snr30

Figure 3 AWGN eye diagran, rolloff 0.9 and SNR 30 [dB]

awgn_snr10

Figure 4 AWGN eye diagran, rolloff 0.9 and SNR 10 [dB]

ISI + AWGN channel

The ISI is given via filter parameters a and b where b are FIR parameters and a are IIR parameters.

rolloff = 0.9
snr = 10
b = [0.7]
a = [1, -0.2]
pattern = tx_example()
ch_out = cdsp.channel.awgn_channel(pattern, b, a, osr=32, span=8, method='rcos', beta=rolloff, snr=snr)
eye_d, amp_vec = cdsp.eye_diagram(ch_out, 32, 128, fs_value=3, quantization=1024, logscale=False)

The result can be shown in the form of an eye diagram:

isi_awgn_snr30

Figure 3 ISI & AWGN eye diagran, rolloff 0.9 and SNR 30 [dB]

isi_awgn_snr10

Figure 4 ISI & AWGN eye diagran, rolloff 0.9 and SNR 10 [dB]

Digital oversampling

import numpy as np
import os
import CommDspy as cdsp
import json

# ==================================================================================================================
# Local variables
# ==================================================================================================================
order = 16
beta  = 0.5
# ==================================================================================================================
# Loading data
# ==================================================================================================================
f = open(os.path.join('..','test_data', 'example_channel_full.json'))
data = json.load(f)
f.close()
channel             = np.array(data['channel'])
channel_ui          = data['channel_ui']
channel_sampled     = data['channel_sampled']
osr                 = data['osr']
ch_segment          = channel[order // 2 * osr: -1*(((order // 2)-1) * osr - 1)]
# ==================================================================================================================
# Digital up-sampling DUT
# ==================================================================================================================
channel_upsample_lag, x2, x1 = cdsp.digital_oversample(channel_sampled, osr=osr, order=order, method='lagrange')
channel_upsample_sinc, _, _  = cdsp.digital_oversample(channel_sampled, osr=osr, order=order, method='sinc')
channel_upsample_rcos, _, _  = cdsp.digital_oversample(channel_sampled, osr=osr, order=order, method='rcos', beta=beta)

Results:

channel reconstruction

Figure 5 - channel reconstruction

# Sinc interpolation MSE          = -17.68 [dB]
# Lagrange interpolation MSE      = -23.59 [dB]
# Raised Cosine interpolation MSE = -29.84 [dB]

Simple receiver model

The package supports simple concepts of digital processing receiver models. Example for such a receiver is given in the following:

  1. Generating PRBS13 pattern
  2. Loading the sampled channel from the above example
  3. Passing the signal through the ISI chaneel + adding noise as seen in the previous examples
  4. Defining Continuous Time Linear Equalizer (CTLE) via zeros, poles and DC gain
  5. passing channel output through the CTLE
  6. Computing Rx Feed Forward Equalizer (FFE) and Decision Feedback Equalizer (DFE)
  7. Passing CTLE output through Rx FFE and DFE
import CommDspy as cdsp
import numpy as np
from scipy import signal
import os
import json
def rx_example():
    # ==================================================================================================================
    # Tx + Channel setting
    # ==================================================================================================================
    prbs_type     = cdsp.constants.PrbsEnum.PRBS13
    constellation = cdsp.constants.ConstellationEnum.PAM4
    full_scale    = True
    rolloff = 0.9
    snr     = 10
    osr     = 32
    pattern = tx_example()
    # ==================================================================================================================
    # CTLE settings
    # ==================================================================================================================
    zeros   = [5e8, 11e9]
    poles   = [1e9, 20e9, 25e9]
    dc_gain = -4  # [dB]
    fs      = 53.125e9
    # ==================================================================================================================
    # Rx FFE settings
    # ==================================================================================================================
    ffe_precursors  = 4
    ffe_postcursors = 23
    ffe_len         = ffe_postcursors + ffe_precursors + 1
    dfe_taps        = 1
    # ==================================================================================================================
    # Loading data
    # ==================================================================================================================
    f = open(os.path.join('..', 'test_data', 'example_channel_full.json'))
    data = json.load(f)
    f.close()
    channel_sampled = data['channel_sampled']
    # ==================================================================================================================
    # Passing through channel
    # ==================================================================================================================
    ch_out = cdsp.channel.awgn_channel(pattern, channel_sampled, [1], osr=osr, span=8, method='rcos', beta=rolloff, snr=snr)
    ch_out = ch_out[len(channel_sampled):]
    # ==================================================================================================================
    # Passing through CTLE
    # ==================================================================================================================
    ctle_out = cdsp.rx.ctle(ch_out, zeros, poles, dc_gain, fs=fs, osr=osr)
    # ==================================================================================================================
    # Estimating optimal Rx FFE and passing data through
    # ==================================================================================================================
    ctle_out_mat = cdsp.buffer(ctle_out, osr, 0)
    rx_ffe       = np.zeros(ffe_len)
    err          = float('inf')
    phase        = -1
    for ii, sampled_phase_data in enumerate(ctle_out_mat.T):
        rx_ffe_dfe_cand = cdsp.equalization_estimation_prbs(prbs_type, sampled_phase_data, constellation,
                                                            prbs_full_scale=full_scale,
                                                            ffe_postcursor=ffe_postcursors,
                                                            ffe_precursor=ffe_precursors,
                                                            dfe_taps=dfe_taps,
                                                            normalize=False,
                                                            bit_order_inv=False,
                                                            pn_inv_precoding=False,
                                                            gray_coded=False,
                                                            pn_inv_postmapping=False)
        if rx_ffe_dfe_cand[-1] < err:
            err    = rx_ffe_dfe_cand[-1]
            rx_ffe = rx_ffe_dfe_cand[0]
            rx_dfe = rx_ffe_dfe_cand[1]
            phase  = ii
    # --------------------------------------------------------------------------------------------------------------
    # Passing through the Rx FFE and DFE
    # --------------------------------------------------------------------------------------------------------------
    rx_ffe_ups   = cdsp.upsample(rx_ffe, osr)
    rx_slicer_in = cdsp.rx.ffe_dfe(ctle_out, rx_ffe_ups, rx_dfe,levels=cdsp.get_levels(constellation, full_scale=full_scale), osr=osr, phase=phase)
    
    rx_slicer_in_osr1 = cdsp.rx.ffe_dfe(ctle_out_mat.T[phase], rx_ffe, rx_dfe,levels=cdsp.get_levels(constellation, full_scale=full_scale))
    return rx_slicer_in_osr1

The signal after passing the channel:

ch_out_snr30

Figure 6 Channel output with SNR of 30 [dB], heavy ISI

ch_out_snr10

Figure 6 Channel output with SNR of 10 [dB], heavy ISI

For the example above, the resulted CTLE is:

CTLE_example

Figure 8 CTLE example

And the eye diagram after the CTLE is:

CTLE_out

Figure 9 Eye diagram at the CTLE output

We can see that there is heavy ISI that can not be easily overcome by a CTLE alone, therefore we will use the Rx FFE. The resulting eye diagram after finding the Rx FFE:

ffe_out30

Figure 10 Eye diagram, FFE output with SNR of 30 [dB]

ffe_out30

Figure 11 Eye diagram, FFE output with SNR of 0 [dB]

ffe_out30

Figure 11 Eye diagram, Slicer in (after FFE and 1 tap DFE) with SNR of 10 [dB]

And we can see that the ISI was negated by the CTLE and FFE and DFE.

Geinie error checker

The package allows locking a PRBS data on the true PRBS and use that to check for errors. Example of such usage will be as follows:

  1. passing the Rx FFE result through a slicer
  2. decoding the symbols
  3. converting the symbols bacl to binary
  4. checking for errors
# ==================================================================================================================
# Local variables
# ==================================================================================================================
prbs_type       = cdsp.constants.PrbsEnum.PRBS13
constellation   = cdsp.constants.ConstellationEnum.PAM4
gray_coding     = False
full_scale      = True
rx_ffe_out      = rx_example()
bits_per_symbol = 2
bit_order_inv   = False
inv_msb         = False
inv_lsb         = False
pn_inv          = False
# ==================================================================================================================
# Slicing Rx FFE out to constellation points
# ==================================================================================================================
slicer_out = cdsp.rx.slicer(rx_ffe_out, levels=cdsp.get_levels(constellation, full_scale))
# ==================================================================================================================
# Decoding
# ==================================================================================================================
decoded_dut = cdsp.rx.demapping(slicer_out, constellation) if not gray_coding else cdsp.rx.decoding_gray(cdsp.rx.demapping(slicer_out, constellation), constellation)
# ==================================================================================================================
# Converting to binary
# ==================================================================================================================
bit_vec_dut = cdsp.rx.symbol2bin(decoded_dut, 2 ** bits_per_symbol, bit_order_inv, inv_msb, inv_lsb, pn_inv)
# ==================================================================================================================
# Checking for errors
# ==================================================================================================================
lost_lock, correct_bit_count, error_bit = cdsp.rx.prbs_checker(prbs_type, bit_vec_dut, init_lock=False)
print(f'Lost lock: {lost_lock}')
print(f'Correct bit count: {correct_bit_count}')
print(f'Erred bits: {sum(error_bit)}')

And for the example above with very low noise we getzero errors since the eye is wide open, ever for SNR of 10 dB.

# Lost lock: False
# Correct bit count: 16294
# Erred bits: 0

When Running the code for SNR of 0 [dB] we get:

# Lost lock: False
# Correct bit count: 16272
# Erred bits: 22

And due to the high noise, the eye closed enough to generate 22 errored bits from the entire pattern we passed through the channel

Functions' Description

0. Auxilliaty functions:

0.1. get_polynomial

Function receives the PRBS type enumeration (detailed below) and returns the commonly used generating polymonial coefficients for the PRBS pattern

0.2. get_levels

Function receives the constellation enumeration (detailed below) and returns the levels in the constellation. The function containg a "full_scale" flag. In case this flag is True, the levels are scaled such that random data which is coded to this constellation will have mean power of 1 (0 [dB])

0.3. power

Function receives a signal, returns the mean power of the signal

0.4. rms

Function receives a signal, returns the RMS of the signal

0.5. buffer

Function receives a signal and breaks is into overlapping parts. Function is inputted with:

  • signal - Input numpy array vector to be buffered
  • length - The length of the chunks to be returned, should be a non-zero integer
  • overlap=0 - The number of overlapping symbols in the signal between each rows. Default is 0, i.e. no overlap. for values larger than 0, there will be overlap and for values smaller than 0 the following row will skip the respective number of symbols
  • delay=0 - The number of zero padding to perform over the beginning of the signal
  • clip=False - If False, padding the end of the signal with zeros such that the last row will have "length" length. If True, clips the data to match the length "length" Function returns a 2D numpy array with "length" length rows.

0.6. upsample

Function performs upsampling, i.e. inserting zeros between samples. Function receives the signal and the upsampling rate, returns the upsampled signal

0.7. zoh

Function performs Zero Order Hold (ZOH) to an input signal. Function is inputted with:

  • signal - input signal
  • hold_idx - number of indices to hold

1. Tx sub-package information

1.1. prbs_gen

Function receives polynomial coefficients and an initial seed, creates binary PRBS sequences of the requested length . The function is inputted with:

  • poly_coeff - a coefficent vector for the generating polynomial of the PRBS pattern
  • init_seed - initial seed used to generate the pattern
  • output_length - wanted pattern length

1.2. PrbsIterator

An iterable used to generate the next bit in the given PRBS. during initialization, a seed and the generating polynomial are given to the object. after calling iter(), next() can be used to pop the next bit in the PRBS

1.3. bin2symbol

Function receives a binary sequence and computes the UNCODED symbols matching the binary sequence. The function is inputted wiith:

  • bin_mat - The binary sequence wanted to be converted
  • num_of_symbols - The number of symbols in the UNCODED pattern. NOW ONLY SUPPORTS POWERS OF 2 (2, 4, 8, ...)
  • bit_order_inv=False - Booleans stating if we want to invert the bit order (By default, MSB is the rightmost bit and the LSB is the leftmost bits)
  • inv_msb=False - Boolean stating if we want to invert the msb
  • inv_lsb=False - Boolean stating if we want to invert the lsb
  • pn_inv=False - Boolean stating if we want to invert all bits

1.4. coding_gray

Function used to convert UNCODED symbols into GRAY coded symbols. Function is inputted with:

  • pattern - array of non-negative integers representing the UNCODED symbols
  • constellation=ConstellationEnum.PAM4 - chosen constellation. According to the symbol number in the constellation the GRAY coding will be done

1.5. coding_differential

Function performs differential encoding. The function receives the symbols and returns the appropriate differential encoded symbols:

  • pattern - array of non-negative integers representing symbols
  • constellation=ConstellationEnum.PAM4 - chosen constellation. According to the number of symbols in the constellation the differential encoding will be done w.r.t. the modulo operation.

1.6. coding_manchester

Function performs manchester encoding. Function is inputted with a binary pattern and outputs the pattern in manchester encoding. Note that the output is twice the length of the input. This requires doubling the bandwidth or slower data transfer rates due to the coding rate being 0.5

1.7. coding_bipolar

Function perform bipolar encoding. Function is inputted with a binary pattern and outputs the pattern in bipolar encoding. This bipolar encoding resuces the SNR due to the addition of another level but allows slight error detection

1.8. coding_mlt3

Function perform Multi-Level-Transmit 3 encoding. Function is inputted with a binary pattern and outputs the pattern in MLT-3 encoding. This encoding scheme reduces the SNR due to the introduction of a 3rd level but reduced the minimal cycle to 4 UI from 2 UI thus reduction the nyquist frequency as well.

1.9. coding_differential_manchester

Function performs differential manchester encoding. Function is inputted with a binary pattern and outputs the pattern in differential manchester encoding. Note that the output is twice the length of the input. This requires doubling the bandwidth or slower data transfer rates due to the coding rate being 0.5

1.10. mapping

Function used to map the symbols to their matching constellation levels . This is usually done as the last step prior to pulse shaping and transmission. Function is inputted with:

  • signal - Ihe signal to be mapped, should be UNCODED symbols array
  • constellation - The constellation we want to map to signal to
  • full_scale - Indicating if we want to use default levels such that the mean power of the signal will be 1 (0 [dB])
  • levels=None - Optional, if not None uses the levels given instead of the default levels
  • pn_inv=False - Indicating if we want to invert the signal after the mapping

2. Rx sub-package information

2.1. slicer

Function receives data matrix from the slicer input and performs the slicing operation.

  • slicer_in_mat - Inputs to slice
  • levels=None - constellation points. The decision thresholds are at the midpoints to the constellations. If the user does not insert levels it assumes [-3,-1,1,3]

2.2. demapping

Function performs de-mapping, i.e. converts the levels of the constellation to their respective integer value levels. Function is inputted with:

  • :param - Numpy array of constellation symbols.
    • If PAM4 assuming that the constellation is [-3x,-x,x,3x]
    • If NRZ assuming that the constellation is [-x,x]
    • If OOK assuming that the constellation is [0, x]
  • constellation - The constellation we want to map to signal to
  • pn_inv: indicating if we want to invert the signal prior to de-mapping

2.3. decoding_gray

Function receives GRAY coded symbols and performs decoding to UNCODED symbols. Function is inputted with:

  • pattern - array of non-negative integers representing the GRAY coded symbols
  • constellation=ConstellationEnum.PAM4 - chosen constellation. According to the symbol number in the constellation the GRAY decoding will be done

2.4. decoding_differential

Function performs differential decoding. The function receives the coded symbols and returns the appropriate decoded symbols:

  • pattern - array of non-negative integers representing coded symbols
  • constellation=ConstellationEnum.PAM4 - chosen constellation. According to the number of symbols in the constellation the differential decoding will be done w.r.t. the modulo operation.

2.5. decoding_manchester

Function perform manchester decoding. Function is inputted a binary sequence and returns the decoded bits. Note that te returned signal will have half the length of the input signal

2.6. decoding_bipolar

Function performs bipolar decoding. Function is inputted with the coded levels, i.e. 0, 1, 2 and returns the decoded binary symbols in the pattern either with or without error correction

2.7. decoding_mlt3

Function perform MLT-3 decoding. function receives the different levels, i.e. 0,1,2 ane returns the underlying binary symbols of the signal.

2.8. decoding_differential_manchester

Function perform differential manchester decoding. Function is inputted a binary sequence and returns the decoded bits. Note that te returned signal will have half the length of the input signal

2.9. symbol2bin

Function receives an UNCODED symbol sequence, returns the binary representation of the symbol sequence

  • symbol_mat - The binary sequence wanted to be converted
  • num_of_symbols - The number of symbols in the UNCODED pattern. NOW ONLY SUPPORTS 2 and 4
  • bit_order_inv=False - Booleans stating if we want to invert the bit order (By default, MSB is the rightmost bit and the LSB is the leftmost bits)
  • inv_msb=False - Boolean stating if we want to invert the msb
  • inv_lsb=False - Boolean stating if we want to invert the lsb
  • pn_inv=False - Boolean stating if we want to invert all bits

2.10. prbs_checker

Function receives a slicer out capture matrix (or slicer in matrix after offine slicing) and does the following:

  1. builds a reference PRBS sequence
  2. synchronizes on the pattern
  3. checks BER
  4. returns the "lost lock" indication, nunber of correct bits and the vector with '0' in the correct locations, '1' in the error locations

The function is inputted with:

  • prbs_type - Enumeration stating the type of PRBS we used for the data-in
  • data_in - The data we want to check the errors on
  • init_lock - indicating if the data-in is aligned with the reference PRBS (with init seed of ones)
  • loss_th=100 - number of erred bit in the data to consider loss of PRBS lock

2.11. prbs_ana_econ

Does the same as prbs_ana but, this function is more memory efficient at the cost of longer runtime

2.12. ctle

Function passes an input signal through a CTLE defined via the poles, zeros and DC gain. Function is inputted with:

  • signal - input signal to pass through the CTLE
  • zeros - list of frequencies where there are zeros in [Hz]. If the given zeros are positive, multiply by -1 to enforce stability
  • poles - list of frequencies where there are poles in [Hz]. If the given poles are positive, multiply by -1 to enforce stability
  • dc_gain - gain in [dB] for the DC frequencies
  • fs - Symbol frequency, 1/Ts
  • osr - Over Sampling Rate the input signal 'sig'
  • zi - Initial condition for the CTLE, Default is None, where we start with zeros

2.13. get_ctle_filter

Function computed the IIR coefficients for the digital equivalent for the CTLE defined via the zeros, poles and DC gain. Function is inputted with

  • zeros - list of frequencies where there are zeros in [Hz]. If the given zeros are positive, multiply by -1 to enforce stability
  • poles - list of frequencies where there are poles in [Hz]. If the given poles are positive, multiply by -1 to enforce stability
  • dc_gain - gain in [dB] for the DC frequencies
  • fs - Symbol frequency, 1/Ts
  • osr - Over Sampling Rate the input signal 'sig'

2.14 ffe_dfe

Function passes the input signal through the FFE and DFE. Function is inputted with:

  • input_signal - input signal to pass through the FFE-DFE
  • ffe_taps - Numpy array containing the FFE taps to be used. If None, without any FFE
  • dfe_taps - Numpy array containing the DFE taps to be used. If None, without and DFE taps
  • levels - Levels used in the transmission. if None assuming levels of [-3,-1,1,3]
  • osr - Over Sampling Rate w.r.t the signal. This is needed only for the DFE buffer calculations
  • phase - Indicates at which the signal will be sampled for the DFE. Assuming that the first input is at phase 0 and there are OSR phases in total

Read the respective description for further information

3. Channel sub-package information

3.0. Various pulse generators

The package supports all the pulses written in 3.1. The function names are:

  • rrc_pulse
  • rcos_pulse
  • sinc_pulse
  • rect_pulse Read the respective description for further information

3.1. pulse_shape

Function useed to perform pulse shaping to the inputted discrete signal. Function is inputted with:

  • signal - Input signal in OSR 1 for the pulse shaping
  • osr - The wanted Over Sampling Rate after the shaping
  • span - The span of the pulse, the span is symmetrical, i.e. a span of 8 means 8 symbols back and 8 symbols forward
  • method - The shape of the pulse. can be either:
    • 'rect' - rectangular pulse
    • 'sinc' - sinc pulse
    • 'rcos' - raised cosine pulse with roll-off parameter beta
    • 'rrc' - root raised cosine pulse with rolloff parameter beta

This function simulated a perfect channel, i.e. ch[n] = delta[n] therefore at the end of the channel we only have the pulse shaping.

3.2. awgn

Function that adds Additive White Gaussian Noise in a power to create a wanted SNR. Function is inputted with:

  • signal - input we and to add the AWGN to
  • snr - the SNR of the signal w.r.t the added noise

3.3. awgn_channel

Function that passes a signal through a discrete-time channel and adds AWGN to the output. Function is inputted with:

  • signal - the signal we want to pass through the channel
  • b - The polynomial coefficients of the channel's nominator
  • a - The polynomial coefficients of the channel's denominator. if a[0] is not 1, all a and b coefficients are normalized by a[0]
  • snr=None - The AWGN SNR to be added to the channel output, If None, does not add noise at all

4. Signal analysis

4.1. channel_estimation_prbs

Function which performs channel estimation, assuming that the original pattern is a PRBS pattern using the get_polynomial generating polynomials. Function is inputted with:

  • prbs_type - Enumeration stating the type of PRBS used to generate the original data
  • signal - Channel output data we use to estimate the channel
  • constellation - Constellation used in the coding of the symbols
  • prbs_full_scale=False - Flag stating if the transmission has a mean power of 1 (0 [dB])
  • channel_postcursor=500 - Number of postcursors we want to use for the channel estimation
  • channel_precursor=19 - Number of precursors we want to use for the channel estimation
  • normalize=False - If ture, normalizes the channel impulse response ot have a peak value of 1
  • bit_order_inv=False - Boolean indicating if the bit order in the signal generation is flipped
  • pn_inv_precoding=False - Boolean indicating if the P and N were flipped in the signal capture process before the coding
  • code=CodingEnum.UNCODED - Enumeration of the coding type used in the signal, taken from CommDspy.constants.CodingEnum
  • pn_inv_postcoding=False - Boolean indicating if the P and N were flipped in the signal capture process after the coding

Function returns the channel impulse response and the sum of squared residuals between the "signal" and the estimated channel's output

4.2. equalization_estimation_prbs

Function which preform equalization over the input signal, estimation the MMSE equalizer to be used to invert the ISI in the signal and recover the original data, using either an FFE or/and a DFE with controllable number of taps. Function is inputted with:

  • prbs_type- Type of PRBS used. This variable should be an enumeration from the toolbox. In the case of PRBSxQ patterns, use the bits_per_symbol to generate the pattern
  • signal - The signal we want to use to estimate the channel
  • constellation - Enumeration stating the constellation. Should be taken from CommDspy.constants.ConstellationEnum
  • ffe_postcursor: Number of postcursors in the FFE estimation
  • ffe_precursor: Number of precursors in the FFE estimation
  • dfe_taps: Number of postcursors in the DFE estimation
  • normalize: Boolean stating if the user wants to normalize the Rx FFE such that the peak will have value of 1
  • regularization: String indicating the regularization in the computation of the equalizer. Can be either:
    • 'None' - Ordinary Least Squares (OLS) solving without regularization
    • 'ridge' - Applying ridge regression, L2 regularization
    • 'lasso' - Applying lasso regression, L1 regularization
  • reg_lambda: If regularization is not 'None', and reg_lambda != 0, applies the wanted regularization with a regularization factor of reg_lambda

The Following flags are only relevant for constellation with multiple bits per symbol:

  • prbs_full_scale: Boolean stating if we want the levels to be scaled such that the mean power of the levels at the reference pattern will be 1 (0 [dB]), i.e. that the PRBS pattern will be coded to power of 0 [dB]
  • bit_order_inv: Boolean indicating if the bit order in the signal generation is flipped.
  • pn_inv_precoding: Boolean indicating if the P and N were flipped in the signal capture process before the coding.
  • gray_coded: Boolean indicating if the signal is GRAY coded, if False, UNCODED
  • pn_inv_postcoding: Boolean indicating if the P and N were flipped in the signal capture process after the mapping.

Function returns:

  • ffe: The equalization FFE, normalized such that the cursor will have a value of 1
  • dfe: The equalization DFE
  • dig_gain: The digital gain of the system. Note that this is highly dependant on the constellation
  • ls_err: Sum of squared residuals
  • mse: normalized MSE, meaning the MSE divided by the variance of the constellation, in dB units

4.3. equalization_estimation

Function computes the linear equalizer with optimal results in the MSE sence with some regulations. The function is inputted with:

  • reference_signal - reference signal used for the equalization
  • signal - input signal we want to pass through the equalizer
    1. signal and reference_signal MUST have the same length
    2. signal and reference_signal MUST be synchronized
  • ffe_postcursor - Number of postcursors in the FFE estimation
  • ffe_precursor - Number of precursors in the FFE estimation
  • dfe_taps - Number of postcursors in the DFE estimation
  • normalize - Boolean stating if the user wants to normalize the Rx FFE such that the peak will have value of 1
  • regularization - String indicating the regularization in the computation of the equalizer. Can be either:
    • 'None' - Ordinary Least Squares (OLS) solving without regularization
    • 'ridge' - Applying ridge regression, L2 regularization
    • 'lasso' - Applying lasso regression, L1 regularization* reg_lambda:
  • If regularization is not 'None', and reg_lambda != 0, applies the wanted regularization with a regularization factor of reg_lambda

4.3. dig_delay_lagrange_coeffs

Function uses Lagrange interpolation polynomials to produce digital delay filter coefficients. Function is inputted with:

  • n - The order of the filter
  • alpha - the fractional delay wanted. alpha must be between 0 and 1
  • forward - Boolean stating the favorite location when the filter order is odd. If filter order is 1 then forward must be True for the function to work

4.4. dig_delay_sinc_coeffs

Function uses sinc interpolation to produce digital delay filter coefficients. Function is inputted with:

  • n - The order of the filter
  • alpha - the fractional delay wanted. alpha must be between 0 and 1
  • forward - Boolean stating the favorite location when the filter order is odd. If filter order is 1 then forward must be True for the function to work

4.5. dig_delay_rcos_coeffs

Function uses raised cosine interpolation to produce digital delay filter coefficients. Function is inputted with:

  • n - The order of the filter
  • alpha - the fractional delay wanted. alpha must be between 0 and 1
  • forward - Boolean stating the favorite location when the filter order is odd. If filter order is 1 then forward must be True for the function to work
  • beta - rolloff factor for the raised cosine

4.5. digital_oversample

Function performs digital oversampling by applyting digital delat filters and fusing the results into 1 flattened array. Function is inputted with:

  • signal_vec - Input signal for oversampling
  • osr - Over sampling rate wanted, should be an integer
  • order - Order of the filter to be computed
  • method - the method of interpolation, can be:
    • 'lagrange'
    • 'sinc'
    • 'rcos'
  • beta=0 - rolloff factor in case the method chosen is 'rcos'

4.6. eye_diagram

Function computed the eye diagram of a signal. Function is inputted with:

  • signal - Input signal to plot the eye diagram
  • osr_in - Over Sampling Rate of the signal
  • osr_diag - Over Sampling used to plot the eye, if larger than osr_in then performing sinc interpolation
  • fs_value=1 - the limits of the eye diagram
  • quantization=256 - resolution of the amplitudes in the eye diagram is computed by: 2*fs_value / qualtization
  • logscale=False - If True, returns the eye diagram with logscale values

5. Misc

5.1.PrbsEnum

Enumeration for the PRBS type used

  • PRBS7
  • PRBS9
  • PRBS11
  • PRBS13
  • PRBS15
  • PRBS31

5.2. ConstellationEnum

Enumeration for the constellations used

  • NRZ - Non-Return to Zero, assuming constellation of [-1, 1]
  • OOK - On Off Keying, assuming constellation of [0, 1]
  • PAM4 - Pulse Amplitude Modulation 4, assuming constellation of [-3, -1, 1, 3]

5.4. EYE_COLORMAP

A maplotlib colormap object to plot the eye diagrams

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

CommDspy-0.1.2.tar.gz (1.1 MB view hashes)

Uploaded source

Built Distribution

CommDspy-0.1.2-py3-none-any.whl (40.0 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Huawei Huawei PSF Sponsor Microsoft Microsoft PSF Sponsor NVIDIA NVIDIA PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page