pybert package¶
Submodules¶
pybert.cdr module¶
Behavioral model of a “bang-bang” clock data recovery (CDR) unit.
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 17 June 2014
This Python script provides a behavioral model of a “bang-bang” clock data recovery (CDR) unit. The class defined, here, is intended for integration into the larger PyBERT framework.
Copyright (c) 2019 by David Banas; All rights reserved World wide.
-
class
pybert.cdr.
CDR
(delta_t: float, alpha: float, ui: float, n_lock_ave: int = 500, rel_lock_tol: float = 0.01, lock_sustain: int = 500)[source]¶ Bases:
object
A class providing behavioral modeling of a ‘bang- bang’ clock data recovery (CDR) unit.
-
adapt
(samples: Sequence[float]) → Tuple[float, bool][source]¶ Adapt period/phase, according to 3 samples.
Should be called, when the clock has just struck.
- Synopsis:
(ui, locked) = adapt(samples)
- Parameters
samples –
A list of 3 samples of the input waveform, as follows:
at the last clock time
at the last unit interval boundary time
at the current clock time
- Returns
The new unit interval estimate, in seconds. locked:
Boolean flag indicating ‘locked’ status.
- Return type
ui
-
property
locked
¶ The current locked state.
-
property
ui
¶ The current unit interval estimate.
-
pybert.dfe module¶
Behavioral model of a decision feedback equalizer (DFE).
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 17 June 2014
This Python script provides a behavioral model of a decision feedback equalizer (DFE). The class defined, here, is intended for integration into the larger PyBERT framework.
Copyright (c) 2014 by David Banas; All rights reserved World wide.
-
class
pybert.dfe.
DFE
(n_taps, gain, delta_t, alpha, ui, n_spb, decision_scaler, mod_type=0, bandwidth=100000000000.0, n_ave=10, n_lock_ave=500, rel_lock_tol=0.01, lock_sustain=500, ideal=True)[source]¶ Bases:
object
Behavioral model of a decision feedback equalizer (DFE).
-
decide
(x)[source]¶ Make the bit decisions, according to modulation type.
- Parameters
x (float) – The signal value, at the decision time.
- Returns
The members of the returned tuple are:
- decision:
One of:
{-1, 1} (NRZ)
{-1, 0, +1} (Duo-binary)
{-1, -1/3, +1/3, +1} (PAM-4)
according to what the ideal signal level should have been. (‘decision_scaler’ normalized)
bits: The list of bits recovered.
- Return type
tuple(float, [int])
- Raises
Exception – If the requested modulation type is unknown.
-
run
(sample_times, signal)[source]¶ Run the DFE on the input signal.
- Parameters
sample_times ([float]) – Vector of time values at wich corresponding signal values were sampled.
signal ([float]) – Vector of sampled signal values.
- Returns
The members of the returned tuple, in order, are:
- res([float]):
Samples of the summing node output, taken at the times given in sample_times.
- tap_weights([[float]]):
List of list of tap weights showing how the DFE adapted over time.
- ui_ests([float]):
List of unit interval estimates, showing how the CDR adapted.
- clocks([int]):
List of mostly zeros with ones at the recovered clocking instants. Useful for overlaying the clock times on signal waveforms, in plots.
- lockeds([bool]):
List of Booleans indicating state of CDR lock.
- clock_times([float]):
List of clocking instants, as recovered by the CDR.
- bits([int]):
List of recovered bits.
- Return type
tuple(([float], [[float]], [float], [int], [bool], [float], [int]))
- Raises
Exception – If the requested modulation type is unknown.
-
step
(decision, error, update)[source]¶ Step the DFE, according to the new decision and error inputs.
- Parameters
decision (float) – Current slicer output.
error (float) – Difference between summing node and slicer outputs.
update (bool) – If true, update tap weights.
- Returns
New backward filter output value.
- Return type
res(float)
-
pybert.pybert module¶
Bit error rate tester (BERT) simulator, written in Python.
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 17 June 2014
Testing by: Mark Marlett <mark.marlett@gmail.com>
This Python script provides a GUI interface to a BERT simulator, which can be used to explore the concepts of serial communication link design.
Copyright (c) 2014 by David Banas; All rights reserved World wide.
-
class
pybert.pybert.
CoOptThread
[source]¶ Bases:
pybert.pybert.StoppableThread
Used to run co-optimization in its own thread, in order to preserve GUI responsiveness.
-
class
pybert.pybert.
PyBERT
(run_simulation=True)[source]¶ Bases:
traits.has_traits.HasTraits
A serial communication link bit error rate tester (BERT) simulator with a GUI interface.
Useful for exploring the concepts of serial communication link design.
-
R0
= None¶ Channel skin effect resistance (Ohms/m).
-
Rdc
= None¶ Channel d.c. resistance (Ohms/m).
-
Theta0
= None¶ Channel loss tangent (unitless).
-
Z0
= None¶ Channel characteristic impedance, in LC region (Ohms).
-
Zref
= None¶ Reference (or, nominal) channel impedance.
-
alpha
= None¶ CDR integral branch magnitude (unitless).
-
bit_errs
= None¶ # of bit errors observed in last run.
-
bit_rate
= None¶ (Gbps)
-
cac
= None¶ Rx a.c. coupling capacitance (uF)
-
calc_chnl_h
()[source]¶ Calculates the channel impulse response.
- Also sets, in ‘self’:
- chnl_dly:
group delay of channel
- start_ix:
first element of trimmed response
- t_ns_chnl:
the x-values, in ns, for plotting ‘chnl_h’
- chnl_H:
channel frequency response
- chnl_s:
channel step response
- chnl_p:
channel pulse response
-
cfg_file
= None¶ PyBERT configuration data storage file (File).
-
ch_file
= None¶ Channel file name.
-
chnl_dly
= None¶ Estimated channel delay (s).
-
chnl_valid
= None¶ Channel file is valid.
-
cin
= None¶ Rx parasitic input capacitance (pF)
-
coopt_thread
= None¶ EQ co-optimization thread.
-
cout
= None¶ Tx parasitic output capacitance (pF)
-
ctle_file
= None¶ CTLE response file (when use_ctle_file = True).
-
ctle_mode
= None¶ CTLE mode (‘Off’, ‘Passive’, ‘AGC’, ‘Manual’).
-
ctle_mode_tune
= None¶ EQ optimizer CTLE mode (‘Off’, ‘Passive’, ‘AGC’, ‘Manual’).
-
ctle_offset
= None¶ CTLE d.c. offset (dB)
-
ctle_offset_tune
= None¶ EQ optimizer CTLE d.c. offset (dB).
-
data_file
= None¶ PyBERT results data storage file (File).
-
debug
= None¶ Send log messages to terminal, as well as console, when True. (Default = False)
-
decision_scaler
= None¶ DFE slicer output voltage (V).
-
delta_t
= None¶ CDR proportional branch magnitude (ps).
-
do_sweep
= None¶ Run sweeps? (Default = False)
-
eye_bits
= None¶ # of bits used to form eye. (Default = last 20%)
-
f_step
= None¶ Frequency step to use when constructing H(f). (Default = 10 MHz)
-
gain
= None¶ DFE error gain (unitless).
-
impulse_length
= None¶ Impulse response length. (Determined automatically, when 0.)
-
instructions
= "<H2>PyBERT User's Guide</H2>\n\n <H3>Note to developers</H3>\n\n This is NOT for you. Instead, open 'pybert/doc/_build/html/index.html' in a browser.\n\n <H3>PyBERT User Help Options</H3>\n\n <UL>\n\n <LI>Hover over any user-settable value in the <em>Config.</em> tab, for help message.</LI>\n\n <LI>Peruse the <em>General Tips</em> & <em>Help by Tab</em> sections, below.</LI>\n\n <LI>Visit the PyBERT FAQ at: https://github.com/capn-freako/PyBERT/wiki/pybert_faq.</LI>\n\n <LI>Send e-mail to David Banas at capn.freako@gmail.com.</LI>\n\n </UL>\n\n <H3>General Tips</H3>\n\n <H4>Main Window Status Bar</H4>\n\n The status bar, just above the <em>Run</em> button, gives the following information, from left to right:.<p>\n\n (Note: the individual pieces of information are separated by vertical bar, or 'pipe', characters.)\n\n <UL>\n\n <LI>Current state of, and/or activity engaged in by, the program.</LI>\n\n <LI>Simulator performance, in mega-samples per minute. A 'sample' corresponds to a single value in the signal vector being processed.</LI>\n\n <LI>The observed delay in the channel; can be used as a sanity check, if you know your channel.</LI>\n\n <LI>The number of bit errors detected in the last successful simulation run.</LI>\n\n <LI>The average power dissipated by the transmitter, assuming perfect matching to the channel ,no reflections, and a 50-Ohm system impedance.</LI>\n\n <LI>The jitter breakdown for the last run. (Taken at DFE output.)</LI>\n\n </UL>\n\n <H3>Help by Tab</H3>\n\n <H4>Config.</H4>\n\n This tab allows you to configure the simulation.\n\n Hover over any user configurable element for a help message.\n\n"¶
-
l_ch
= None¶ Channel length (m).
-
lock_sustain
= None¶ CDR hysteresis to use in determining lock.
-
log
(msg, alert=False, exception=None)[source]¶ Log a message to the console and, optionally, to terminal and/or pop-up dialog.
-
max_iter
= None¶ EQ optimizer max. # of optimization iterations.
-
mod_type
= None¶ 0 = NRZ; 1 = Duo-binary; 2 = PAM-4
-
n_ave
= None¶ DFE # of averages to take, before making tap corrections.
-
n_lock_ave
= None¶ CDR # of averages to take in determining lock.
-
n_taps
= None¶ DFE # of taps.
-
n_taps_tune
= None¶ EQ optimizer # DFE taps.
-
nbits
= None¶ Number of bits to simulate.
-
nspb
= None¶ Signal vector samples per bit.
-
num_sweeps
= None¶ Number of sweeps to run.
-
padded
= None¶ Zero pad imported Touchstone data? (Default = False)
-
pattern_len
= None¶ PRBS pattern length.
-
peak_freq
= None¶ CTLE peaking frequency (GHz)
-
peak_freq_tune
= None¶ EQ optimizer CTLE peaking freq. (GHz).
-
peak_mag
= None¶ CTLE peaking magnitude (dB)
-
peak_mag_tune
= None¶ EQ optimizer CTLE peaking mag. (dB).
-
plotdata
= <chaco.array_plot_data.ArrayPlotData object>¶
-
pn_freq
= None¶ Periodic noise frequency (MHz).
-
pn_mag
= None¶ Periodic noise magnitude (V).
-
rel_lock_tol
= None¶ CDR relative tolerance to use in determining lock.
-
rel_power
= None¶ Tx power dissipation (W).
-
reraise
= True¶
-
rin
= None¶ Rx input impedance (Ohm)
-
rn
= None¶ Standard deviation of Gaussian random noise (V).
-
rs
= None¶ Tx source impedance (Ohms)
-
rx_ami_file
= None¶ (File)
-
rx_ami_valid
= None¶ (Bool)
-
rx_bw
= None¶ CTLE bandwidth (GHz).
-
rx_bw_tune
= None¶ EQ optimizer CTLE bandwidth (GHz).
-
rx_dll_file
= None¶ (File)
-
rx_dll_valid
= None¶ (Bool)
-
rx_has_getwave
= None¶ (Bool)
-
rx_ibis_file
= None¶ (File)
-
rx_ibis_valid
= None¶ (Bool)
-
rx_opt_thread
= None¶ Rx EQ optimization thread.
-
rx_use_ami
= None¶ (Bool)
-
rx_use_getwave
= None¶ (Bool)
-
rx_use_ibis
= None¶ (Bool)
-
status
= None¶ PyBERT status (String).
-
sum_bw
= None¶ DFE summing node bandwidth (Used when sum_ideal=False.) (GHz).
-
sum_ideal
= None¶ True = use an ideal (i.e. - infinite bandwidth) summing node (Bool).
-
thresh
= None¶ Threshold for identifying periodic jitter components (sigma).
-
tx_ami_file
= None¶ (File)
-
tx_ami_valid
= None¶ (Bool)
-
tx_dll_file
= None¶ (File)
-
tx_dll_valid
= None¶ (Bool)
-
tx_has_getwave
= None¶ (Bool)
-
tx_ibis_file
= None¶ (File)
-
tx_ibis_valid
= None¶ (Bool)
-
tx_opt_thread
= None¶ Tx EQ optimization thread.
-
tx_tap_tuners
= None¶ EQ optimizer list of TxTapTuner objects.
-
tx_taps
= None¶ List of TxTapTuner objects.
-
tx_use_ami
= None¶ (Bool)
-
tx_use_getwave
= None¶ (Bool)
-
tx_use_ibis
= None¶ (Bool)
-
use_ch_file
= None¶ Import channel description from file? (Default = False)
-
use_ctle_file
= None¶ For importing CTLE impulse/step response directly.
-
use_dfe
= None¶ True = use a DFE (Bool).
-
use_dfe_tune
= None¶ EQ optimizer DFE select (Bool).
-
v0
= None¶ Channel relative propagation velocity (c).
-
vod
= None¶ Tx differential output voltage (V)
-
w0
= None¶ Channel transition frequency (rads./s).
-
windowed
= None¶ Apply windowing to the Touchstone data? (Default = False)
-
-
class
pybert.pybert.
RxOptThread
[source]¶ Bases:
pybert.pybert.StoppableThread
Used to run Rx tap weight optimization in its own thread, in order to preserve GUI responsiveness.
-
class
pybert.pybert.
StoppableThread
[source]¶ Bases:
threading.Thread
Thread class with a stop() method.
The thread itself has to check regularly for the stopped() condition.
All PyBERT thread classes are subclasses of this class.
-
class
pybert.pybert.
TxOptThread
[source]¶ Bases:
pybert.pybert.StoppableThread
Used to run Tx tap weight optimization in its own thread, in order to preserve GUI responsiveness.
-
class
pybert.pybert.
TxTapTuner
(name='(noname)', enabled=False, min_val=0.0, max_val=0.0, value=0.0, steps=0)[source]¶ Bases:
traits.has_traits.HasTraits
Object used to populate the rows of the Tx FFE tap tuning table.
-
pybert.pybert.
randint
(low, high=None, size=None, dtype='l')¶ Return random integers from low (inclusive) to high (exclusive).
Return random integers from the “discrete uniform” distribution of the specified dtype in the “half-open” interval [low, high). If high is None (the default), then results are from [0, low).
- Parameters
low (int or array-like of ints) – Lowest (signed) integers to be drawn from the distribution (unless
high=None
, in which case this parameter is one above the highest such integer).high (int or array-like of ints, optional) – If provided, one above the largest (signed) integer to be drawn from the distribution (see above for behavior if
high=None
). If array-like, must contain integer valuessize (int or tuple of ints, optional) – Output shape. If the given shape is, e.g.,
(m, n, k)
, thenm * n * k
samples are drawn. Default is None, in which case a single value is returned.dtype (dtype, optional) –
Desired dtype of the result. All dtypes are determined by their name, i.e., ‘int64’, ‘int’, etc, so byteorder is not available and a specific precision may have different C types depending on the platform. The default value is ‘np.int’.
New in version 1.11.0.
- Returns
out – size-shaped array of random integers from the appropriate distribution, or a single such random int if size not provided.
- Return type
int or ndarray of ints
See also
random.random_integers()
similar to randint, only for the closed interval [low, high], and 1 is the lowest value if high is omitted.
Examples
>>> np.random.randint(2, size=10) array([1, 0, 0, 0, 1, 1, 0, 0, 1, 0]) # random >>> np.random.randint(1, size=10) array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Generate a 2 x 4 array of ints between 0 and 4, inclusive:
>>> np.random.randint(5, size=(2, 4)) array([[4, 0, 2, 1], # random [3, 2, 2, 0]])
Generate a 1 x 3 array with 3 different upper bounds
>>> np.random.randint(1, [3, 5, 10]) array([2, 2, 9]) # random
Generate a 1 by 3 array with 3 different lower bounds
>>> np.random.randint([1, 5, 7], 10) array([9, 8, 7]) # random
Generate a 2 by 4 array using broadcasting with dtype of uint8
>>> np.random.randint([1, 3, 5, 7], [[10], [20]], dtype=np.uint8) array([[ 8, 6, 9, 7], # random [ 1, 16, 9, 12]], dtype=uint8)
pybert.pybert_cfg module¶
Simulation configuration data encapsulation, for PyBERT.
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 5 May 2017
This Python script provides a data structure for encapsulating the simulation configuration data of a PyBERT instance. It was first created, as a way to facilitate easier pickling, so that a particular configuration could be saved and later restored.
Copyright (c) 2017 by David Banas; All rights reserved World wide.
pybert.pybert_cntrl module¶
Default controller definition for PyBERT class.
Original author: David Banas <capn.freako@gmail.com>
Original date: August 24, 2014 (Copied from pybert.py, as part of a major code cleanup.)
Copyright (c) 2014 David Banas; all rights reserved World wide.
-
pybert.pybert_cntrl.
my_run_simulation
(self, initial_run=False, update_plots=True)[source]¶ Runs the simulation.
- Parameters
self (PyBERT) – Reference to an instance of the PyBERT class.
initial_run (Bool) – If True, don’t update the eye diagrams, since they haven’t been created, yet. (Optional; default = False.)
update_plots (Bool) – If True, update the plots, after simulation completes. This option can be used by larger scripts, which import pybert, in order to avoid graphical back-end conflicts and speed up this function’s execution time. (Optional; default = True.)
-
pybert.pybert_cntrl.
my_run_sweeps
(self)[source]¶ Runs the simulation sweeps.
- Parameters
self (PyBERT) – Reference to an instance of the PyBERT class.
-
pybert.pybert_cntrl.
normal
(loc=0.0, scale=1.0, size=None)¶ Draw random samples from a normal (Gaussian) distribution.
The probability density function of the normal distribution, first derived by De Moivre and 200 years later by both Gauss and Laplace independently 2, is often called the bell curve because of its characteristic shape (see the example below).
The normal distributions occurs often in nature. For example, it describes the commonly occurring distribution of samples influenced by a large number of tiny, random disturbances, each with its own unique distribution 2.
- Parameters
loc (float or array_like of floats) – Mean (“centre”) of the distribution.
scale (float or array_like of floats) – Standard deviation (spread or “width”) of the distribution. Must be non-negative.
size (int or tuple of ints, optional) – Output shape. If the given shape is, e.g.,
(m, n, k)
, thenm * n * k
samples are drawn. If size isNone
(default), a single value is returned ifloc
andscale
are both scalars. Otherwise,np.broadcast(loc, scale).size
samples are drawn.
- Returns
out – Drawn samples from the parameterized normal distribution.
- Return type
ndarray or scalar
See also
scipy.stats.norm()
probability density function, distribution or cumulative density function, etc.
Notes
The probability density for the Gaussian distribution is
\[p(x) = \frac{1}{\sqrt{ 2 \pi \sigma^2 }} e^{ - \frac{ (x - \mu)^2 } {2 \sigma^2} },\]where \(\mu\) is the mean and \(\sigma\) the standard deviation. The square of the standard deviation, \(\sigma^2\), is called the variance.
The function has its peak at the mean, and its “spread” increases with the standard deviation (the function reaches 0.607 times its maximum at \(x + \sigma\) and \(x - \sigma\) 2). This implies that numpy.random.normal is more likely to return samples lying close to the mean, rather than those far away.
References
- 1
Wikipedia, “Normal distribution”, https://en.wikipedia.org/wiki/Normal_distribution
- 2(1,2,3)
P. R. Peebles Jr., “Central Limit Theorem” in “Probability, Random Variables and Random Signal Principles”, 4th ed., 2001, pp. 51, 51, 125.
Examples
Draw samples from the distribution:
>>> mu, sigma = 0, 0.1 # mean and standard deviation >>> s = np.random.normal(mu, sigma, 1000)
Verify the mean and the variance:
>>> abs(mu - np.mean(s)) 0.0 # may vary
>>> abs(sigma - np.std(s, ddof=1)) 0.1 # may vary
Display the histogram of the samples, along with the probability density function:
>>> import matplotlib.pyplot as plt >>> count, bins, ignored = plt.hist(s, 30, density=True) >>> plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) * ... np.exp( - (bins - mu)**2 / (2 * sigma**2) ), ... linewidth=2, color='r') >>> plt.show()
Two-by-four array of samples from N(3, 6.25):
>>> np.random.normal(3, 2.5, size=(2, 4)) array([[-4.49401501, 4.00950034, -1.81814867, 7.29718677], # random [ 0.39924804, 4.68456316, 4.99394529, 4.84057254]]) # random
pybert.pybert_data module¶
Simulation results data encapsulation, for PyBERT.
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 9 May 2017
This Python script provides a data structure for encapsulating the simulation results data of a PyBERT instance. It was first created, as a way to facilitate easier pickling, so that a particular result could be saved and later restored, as a reference waveform.
Copyright (c) 2017 by David Banas; All rights reserved World wide.
pybert.pybert_help module¶
User instructions for PyBERT class.
Original author: David Banas <capn.freako@gmail.com>
Original date: April 15, 2015 (Copied from pybert.py.)
Copyright (c) 2015 David Banas; all rights reserved World wide.
pybert.pybert_plot module¶
Plot definitions for PyBERT class.
Original author: David Banas <capn.freako@gmail.com>
Original date: February 21, 2015 (Copied from pybert.py, as part of a major code cleanup.)
Copyright (c) 2015 David Banas; all rights reserved World wide.
pybert.pybert_util module¶
General purpose utilities for PyBERT.
Original author: David Banas <capn.freako@gmail.com>
Original date: September 27, 2014 (Copied from pybert_cntrl.py.)
Copyright (c) 2014 David Banas; all rights reserved World wide.
-
pybert.pybert_util.
calc_G
(H, Rs, Cs, Zc, RL, Cp, CL, ws)[source]¶ Calculates fully loaded transfer function of complete channel.
- Inputs:
H unloaded transfer function of interconnect
Rs source series resistance
Cs source parallel (parasitic) capacitance
Zc frequency dependent characteristic impedance of the interconnect
RL load resistance (differential)
Cp load parallel (parasitic) capacitance (single ended)
CL load series (d.c. blocking) capacitance (single ended)
ws frequency sample points vector
- Outputs:
G frequency dependent transfer function of channel
-
pybert.pybert_util.
calc_eye
(ui, samps_per_ui, height, ys, y_max, clock_times=None)[source]¶ Calculates the “eye” diagram of the input signal vector.
- Parameters
ui (float) – unit interval (s)
samps_per_ui (int) – # of samples per unit interval
height (int) – height of output image data array
ys ([float]) – signal vector of interest
y_max (float) – max. +/- vertical extremity of plot
- Keyword Arguments
clock_times ([float]) – (optional) vector of clock times to use for eye centers. If not provided, just use mean zero-crossing and assume constant UI and no phase jumps. (This allows the same function to be used for eye diagram creation, for both pre and post-CDR signals.)
- Returns: The “heat map” representing the eye diagram. Each grid
location contains a value indicating the number of times the signal passed through that location.
-
pybert.pybert_util.
calc_gamma
(R0, w0, Rdc, Z0, v0, Theta0, ws)[source]¶ Calculates propagation constant from cross-sectional parameters.
The formula’s applied are taken from Howard Johnson’s “Metallic Transmission Model” (See “High Speed Signal Propagation”, Sec. 3.1.)
- Inputs:
R0 skin effect resistance (Ohms/m)
w0 cross-over freq.
Rdc d.c. resistance (Ohms/m)
Z0 characteristic impedance in LC region (Ohms)
v0 propagation velocity (m/s)
Theta0 loss tangent
ws frequency sample points vector
- Outputs:
gamma frequency dependent propagation constant
Zc frequency dependent characteristic impedance
-
pybert.pybert_util.
calc_gamma_RLGC
(R, L, G, C, ws)[source]¶ Calculates propagation constant from R, L, G, and C.
- Inputs:
R resistance per unit length (Ohms/m)
L inductance per unit length (Henrys/m)
G conductance per unit length (Siemens/m)
C capacitance per unit length (Farads/m)
ws frequency sample points vector
- Outputs:
gamma frequency dependent propagation constant
Zc frequency dependent characteristic impedance
-
pybert.pybert_util.
calc_jitter
(ui, nui, pattern_len, ideal_xings, actual_xings, rel_thresh=6, num_bins=99, zero_mean=True)[source]¶ Calculate the jitter in a set of actual zero crossings, given the ideal crossings and unit interval.
Inputs:
ui : The nominal unit interval.
nui : The number of unit intervals spanned by the input signal.
pattern_len : The number of unit intervals, before input symbol stream repeats.
ideal_xings : The ideal zero crossing locations of the edges.
actual_xings : The actual zero crossing locations of the edges.
rel_thresh : (optional) The threshold for determining periodic jitter spectral components (sigma).
num_bins : (optional) The number of bins to use, when forming histograms.
zero_mean : (optional) Force the mean jitter to zero, when True.
Outputs:
jitter : The total jitter.
t_jitter : The times (taken from ‘ideal_xings’) corresponding to the returned jitter values.
isi : The peak to peak jitter due to intersymbol interference.
dcd : The peak to peak jitter due to duty cycle distortion.
pj : The peak to peak jitter due to uncorrelated periodic sources.
rj : The standard deviation of the jitter due to uncorrelated unbounded random sources.
tie_ind : The data independent jitter.
thresh : Threshold for determining periodic components.
jitter_spectrum : The spectral magnitude of the total jitter.
tie_ind_spectrum : The spectral magnitude of the data independent jitter.
spectrum_freqs : The frequencies corresponding to the spectrum components.
hist : The histogram of the actual jitter.
hist_synth : The histogram of the extrapolated jitter.
bin_centers : The bin center values for both histograms.
-
pybert.pybert_util.
find_crossing_times
(t, x, min_delay: float = 0.0, rising_first: bool = True, min_init_dev: float = 0.1, thresh: float = 0.0)[source]¶ Finds the threshold crossing times of the input signal.
- Parameters
t ([float]) – Vector of sample times. Intervals do NOT need to be uniform.
x ([float]) – Sampled input vector.
min_delay (float) – Minimum delay required, before allowing crossings. (Helps avoid false crossings at beginning of signal.) (Optional; default = 0.)
rising_first (bool) – When True, start with the first rising edge found. (Optional; default = True.) When this option is True, the first rising edge crossing is the first crossing returned. This is the desired behavior for PyBERT, because we always initialize the bit stream with [0, 0, 1, 1], in order to provide a known synchronization point for jitter analysis.
min_init_dev (float) – The minimum initial deviation from zero, which must be detected, before searching for crossings. Normalized to maximum input signal magnitude. (Optional; default = 0.1.)
thresh (float) – Vertical crossing threshold.
Returns: an array of signal threshold crossing times.
-
pybert.pybert_util.
find_crossings
(t, x, amplitude, min_delay: float = 0.0, rising_first: bool = True, min_init_dev=0.1, mod_type=0)[source]¶ Finds the crossing times in a signal, according to the modulation type.
- Parameters
t ([float]) – The times associated with each signal sample.
x ([float]) – The signal samples.
amplitude (float) – The nominal signal amplitude. (Used for determining thresholds, in the case of some modulation types.)
min_delay (float) – The earliest possible sample time we want returned. (Optional; default = 0.)
rising_first (bool) – When True, start with the first rising edge found. When this option is True, the first rising edge crossing is the first crossing returned. This is the desired behavior for PyBERT, because we always initialize the bit stream with [0, 1, 1], in order to provide a known synchronization point for jitter analysis. (Optional; default = True.)
min_init_dev (float) – The minimum initial deviation from zero, which must be detected, before searching for crossings. Normalized to maximum input signal magnitude. (Optional; default = 0.1.)
mod_type (int) – The modulation type. Allowed values are: {0: NRZ, 1: Duo-binary, 2: PAM-4} (Optional; default = 0.)
Returns: The signal threshold crossing times.
-
pybert.pybert_util.
import_channel
(filename, sample_per, padded=False, windowed=False)[source]¶ Read in a channel file.
- Parameters
filename (str) – Name of file from which to import channel description.
sample_per (float) – Sample period of signal vector (s).
padded (Bool) – (Optional) Zero pad s4p data, such that fmax >= 1/(2*sample_per)? (Default = False)
windowed (Bool) – (Optional) Window s4p data, before converting to time domain? (Default = False)
Returns: Imported channel impulse, or step, response.
-
pybert.pybert_util.
import_freq
(filename, sample_per, padded=False, windowed=False, f_step=10000000.0)[source]¶ Read in a single ended 4-port Touchstone file, and extract the differential throughput step response, resampling as appropriate, via linear interpolation.
- Parameters
filename (str) – Name of Touchstone file to read in.
sample_per (float) – New sample interval
padded (Bool) – (Optional) Zero pad s4p data, such that fmax >= 1/(2*sample_per)? (Default = False)
windowed (Bool) – (Optional) Window s4p data, before converting to time domain? (Default = False)
Returns: Resampled step response waveform.
-
pybert.pybert_util.
import_time
(filename, sample_per)[source]¶ Read in a time domain waveform file, resampling as appropriate, via linear interpolation.
- Parameters
filename (str) – Name of waveform file to read in.
sample_per (float) – New sample interval
Returns: Resampled waveform.
-
pybert.pybert_util.
interp_time
(ts, xs, sample_per)[source]¶ Resample time domain data, using linear interpolation.
- Parameters
ts ([float]) – Original time values.
xs ([float]) – Original signal values.
sample_per (float) – System sample period.
Returns: Resampled waveform.
-
pybert.pybert_util.
lfsr_bits
(taps, seed)[source]¶ Given a set of tap indices and a seed, generate a PRBS.
- Parameters
taps ([int]) – The set of fed back taps. (Largest determines order of generator.)
seed (int) – The initial value of the shift register.
- Returns
A PRBS generator object with a next() method, for retrieving the next bit in the sequence.
-
pybert.pybert_util.
make_ctle
(rx_bw, peak_freq, peak_mag, w, mode='Passive', dc_offset=0)[source]¶ Generate the frequency response of a continuous time linear equalizer (CTLE), given the:
signal path bandwidth,
peaking specification
list of frequencies of interest, and
operational mode/offset.
We use the ‘invres()’ function from scipy.signal, as it suggests itself as a natural approach, given our chosen use model of having the user provide the peaking frequency and degree of peaking.
That is, we define our desired frequency response using one zero and two poles, where:
- The pole locations are equal to:
the signal path natural bandwidth, and
the user specified peaking frequency.
The zero location is chosen, so as to provide the desired degree of peaking.
Inputs:
rx_bw The natural (or, unequalized) signal path bandwidth (Hz).
- peak_freq The location of the desired peak in the frequency
response (Hz).
peak_mag The desired relative magnitude of the peak (dB). (mag(H(0)) = 1)
w The list of frequencies of interest (rads./s).
- mode The operational mode; must be one of:
‘Off’ : CTLE is disengaged.
‘Passive’: Maximum frequency response has magnitude one.
‘AGC’ : Automatic gain control. (Handled by calling routine.)
‘Manual’ : D.C. offset is set manually.
- dc_offset The d.c. offset of the CTLE gain curve (dB).
(Only valid, when ‘mode’ = ‘Manual’.)
Outputs:
- w, H The resultant complex frequency response, at the
given frequencies.
-
pybert.pybert_util.
make_uniform
(t, jitter, ui, nbits)[source]¶ Make the jitter vector uniformly sampled in time, by zero-filling where necessary.
The trick, here, is creating a uniformly sampled input vector for the FFT operation, since the jitter samples are almost certainly not uniformly sampled. We do this by simply zero padding the missing samples.
Inputs:
t : The sample times for the ‘jitter’ vector.
jitter : The input jitter samples.
ui : The nominal unit interval.
nbits : The desired number of unit intervals, in the time domain.
Output:
y : The uniformly sampled, zero padded jitter vector.
y_ix : The indices where y is valid (i.e. - not zero padded).
-
pybert.pybert_util.
moving_average
(a, n=3)[source]¶ Calculates a sliding average over the input vector.
- Parameters
a ([float]) – Input vector to be averaged.
n (int) – Width of averaging window, in vector samples. (Optional; default = 3.)
- Returns: the moving average of the input vector, leaving the input
vector unchanged.
-
pybert.pybert_util.
pulse_center
(p, nspui)[source]¶ Determines the center of the pulse response, using the “Hula Hoop” algorithm (See SiSoft/Tellian’s DesignCon 2016 paper.)
- Parameters
p ([Float]) – The single bit pulse response.
nspui (Int) – The number of vector elements per unit interval.
- Returns
- The estimated index at which the clock will
sample the main lobe.
- thresh(Float): The vertical threshold at which the main lobe is
UI wide.
- Return type
clock_pos(Int)
-
pybert.pybert_util.
sdd_21
(ntwk)[source]¶ Given a 4-port single-ended network, return its differential throughput.
- Parameters
ntwk (skrf.Network) – 4-port single ended network.
Returns: Sdd[2,1].
-
pybert.pybert_util.
trim_impulse
(g, min_len=0, max_len=1000000)[source]¶ - Trim impulse response, for more useful display, by:
clipping off the tail, after 99.8% of the total power has been captured (Using 99.9% was causing problems; I don’t know why.), and
setting the “front porch” length equal to 20% of the total length.
Inputs:
g impulse response
min_len (optional) minimum length of returned vector
max_len (optional) maximum length of returned vector
Outputs:
g_trim trimmed impulse response
start_ix index of first returned sample
pybert.pybert_view module¶
Default view definition for PyBERT class.
Original author: David Banas <capn.freako@gmail.com>
Original date: August 24, 2014 (Copied from pybert.py, as part of a major code cleanup.)
Copyright (c) 2014 David Banas; all rights reserved World wide.
Module contents¶
A package of Python modules, used by the PyBERT application.
Original Author: David Banas <capn.freako@gmail.com>
Original Date: 17 June 2014
Testing by: Mark Marlett <mark.marlett@gmail.com>
The application source is divided among several files, as follows:
- pybert.py - This file. The M in MVC, it contains:
independent variable declarations
default initialization
the definitions of those dependent variables, which are handled automatically by the Traits/UI machinery.
- pybert_view.py - The V in MVC, it contains the main window layout definition, as
well as the definitions of user invoked actions (i.e.- buttons).
- pybert_cntrl.py - The C in MVC, it contains the definitions for those dependent
variables, which are updated not automatically by the Traits/UI machinery, but rather by explicit user action (i.e. - button clicks).
pybert_help.py - Contents for the “Help” tab of the GUI.
pybert_plot.py - Contains all plot definitions.
pybert_util.py - Contains general purpose utility functionality.
- pybert_cfg.py - Defines the data structure for storing PyBERT
configurations, so they may be saved and later restored.
- pybert_data.py - Defines the data structure for storing PyBERT
simulation results, so they may be saved and later recalled as reference waveforms for comparison.
dfe.py - Contains the decision feedback equalizer model.
cdr.py - Contains the clock data recovery unit model.
Copyright (c) 2014 by David Banas; All rights reserved World wide.