### Install package in development mode via setup.py Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers Alternative method to install the package in editable mode, functionally equivalent to pip install -e. ```bash sudo -H python setup.py develop ``` -------------------------------- ### Install SignalIntegrity via pip Source: https://github.com/nubis-communications/signalintegrity/wiki/Installation Use pip to install the package in editable mode from the directory containing setup.py. ```bash pip install -e . ``` ```bash sudo -H pip install -e . ``` -------------------------------- ### Run SignalIntegrityApp Source: https://github.com/nubis-communications/signalintegrity/wiki/Installation Launch the GUI application after successful installation. ```bash SignalIntegrity ``` -------------------------------- ### Install SignalIntegrity via setup.py Source: https://github.com/nubis-communications/signalintegrity/wiki/Installation Use the setup.py script directly if pip is unavailable or not preferred. ```bash python setup.py develop ``` ```bash sudo -H python setup.py develop ``` -------------------------------- ### SignalIntegrity Console Script (setup.py install) Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers The bash script created in /usr/local/bin when installing using 'python setup.py install'. It uses pkg_resources to load the entry point for the 'SignalIntegrity' console script. ```python #!/usr/bin/python # EASY-INSTALL-ENTRY-SCRIPT: 'SignalIntegrity==1.0.4','console_scripts','SignalIntegrity' __requires__ = 'SignalIntegrity==1.0.4' import re import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit( load_entry_point('SignalIntegrity==1.0.4', 'console_scripts', 'SignalIntegrity')() ) ``` -------------------------------- ### Initialize and Install SignalIntegrity for Development Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers Commands to initialize a local Git repository, link it to the remote source, pull the development branch, and install the package in editable mode. ```bash git init git remote add origin https://github.com/Nubis-Communications/SignalIntegrity.git git pull origin InNextRelease pip install -e . ``` -------------------------------- ### Launch SignalIntegrityApp Source: https://github.com/nubis-communications/signalintegrity/wiki/Installation Execute this command from the /SignalIntegrity/App directory to start the GUI application. ```bash python SignalIntegrityApp.py ``` -------------------------------- ### Install package in editable mode Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers Installs the package in development mode, creating egg-info and entry scripts. ```bash sudo -H pip install -e . ``` -------------------------------- ### Install PySI App in Editable Mode Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Installs the PySI application in editable mode. This ensures that any changes made to the local code files are immediately reflected in the installation. ```bash pip install -e . ``` -------------------------------- ### Signal Integrity Simulation Setup and Execution Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Sets up and runs signal integrity simulations for both open-loop and closed-loop systems using the si library. Configures simulation parameters like PID gains and frequency ranges. ```python def Responses(P,I,D): argsDict={'PID_P':P,'PID_I':I,'PID_D':D, 'EndFrequency':25e6, 'FrequencyPoints':5000, 'LogarithmicStartFrequency':fs, 'LogarithmicEndFrequency':fe, 'LogarithmicPointsPerDecade':ppd } app = si.App.SignalIntegrityAppHeadless() app.OpenProjectFile('PIDSimulationOpenLoop.si',args=argsDict) (openLoopSourceNames,openLoopOutputWaveformLabels,transferMatrices)=app.Simulate(TransferMatricesOnly=True) OpenLoopFrequencyResponses=transferMatrices.FrequencyResponses() app = si.App.SignalIntegrityAppHeadless() app.OpenProjectFile('PIDSimulation.si',args=argsDict) (closedLoopSourceNames,closedLoopOutputWaveformLabels,transferMatrices)=app.Simulate(TransferMatricesOnly=True) ClosedLoopFrequencyResponses=transferMatrices.FrequencyResponses() ClosedLoopResults={'C':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('VO')][0], 'U':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('VU')][0], 'PID':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('VPID')][0], 'P':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('P')][0], 'I':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('I')][0], 'D':ClosedLoopFrequencyResponses[closedLoopOutputWaveformLabels.index('D')][0] } OpenLoopResults={'PID':OpenLoopFrequencyResponses[openLoopOutputWaveformLabels.index('VPID')][0], 'P':OpenLoopFrequencyResponses[openLoopOutputWaveformLabels.index('P')][0], 'I':OpenLoopFrequencyResponses[openLoopOutputWaveformLabels.index('I')][0], 'D':OpenLoopFrequencyResponses[openLoopOutputWaveformLabels.index('D')][0] } return {'ClosedLoop':ClosedLoopResults,'OpenLoop':OpenLoopResults,'Frequency':f} results=Responses(P,I,D) ``` -------------------------------- ### SignalIntegrity App Script (pip install) Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers The bash script generated in /usr/local/bin when installing via pip on Linux. It imports and runs the main function from SignalIntegrity.App.SignalIntegrityApp. ```python #!/usr/bin/python # -*- coding: utf-8 -*- import re import sys from SignalIntegrity.App.SignalIntegrityApp import main if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit(main()) ``` -------------------------------- ### Install tikzplotlib dependency Source: https://github.com/nubis-communications/signalintegrity/wiki/Installation Manually install the tikzplotlib package to enable LaTeX-style plot exports. ```bash tikzplotlib ``` -------------------------------- ### Logarithmically Spaced Frequency List Generation Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Generates a list of frequencies spaced logarithmically between a start and end frequency. Requires the math module. ```python def Frequencies(fs,fe,N): import math log10fs=math.log10(fs) log10fe=math.log10(fe) f=[10**((log10fe-log10fs)/N*n+log10fs) for n in range(N+1)] return f ``` -------------------------------- ### Import Libraries for Signal Integrity Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Imports the necessary SignalIntegrity library and matplotlib for plotting. Ensure SignalIntegrity is installed and matplotlib is available. ```python import SignalIntegrity as si import matplotlib.pyplot as plt %matplotlib inline ``` -------------------------------- ### Doxygen Configuration: Input Filter Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Specifies the input filter program for Doxygen to process each input file. The filter must not add or remove lines. This example shows the configuration for Linux. ```ini # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = ./doxypy.py ``` -------------------------------- ### Initialize Git Repository Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Initializes a new Git repository in the current directory. This is the first step in setting up a project with Git. ```bash git init ``` -------------------------------- ### Build and Upload to PyPI Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers Commands to build the universal wheel and upload the distribution to PyPI. Use the test repository for initial testing. ```bash python setup.py bdist_wheel --universal ``` ```bash twine upload dist/* ``` ```bash twine upload --repository-url https://test.pypi.org/legacy/ dist/* ``` -------------------------------- ### Create Ubuntu Desktop Launcher Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Creates a desktop launcher for the SignalIntegrity application on Ubuntu. This involves creating a .desktop file with application details. ```bash gnome-desktop-item-edit --create-new ~/Desktop ``` -------------------------------- ### Import SignalIntegrity.Lib Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Import the library using the standard alias 'si' to access all package elements. ```python import SignalIntegrity.Lib as si ``` -------------------------------- ### Read and Write S-Parameter Files Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Demonstrates reading S-parameter data from Touchstone files, accessing response data, resampling, changing reference impedance, and writing to a new file. Ensure the input file exists and the output path is writable. ```python import SignalIntegrity.Lib as si # Read a 4-port S-parameter file with 50 ohm reference impedance sp = si.sp.SParameterFile('device.s4p', Z0=50.0) # Access frequency list and data frequencies = sp.f() # Returns FrequencyList object print(f"Frequency range: {frequencies[0]/1e9:.2f} GHz to {frequencies[-1]/1e9:.2f} GHz") print(f"Number of ports: {sp.m_P}") print(f"Number of frequency points: {len(sp)}") # Get S21 response (port 2 output, port 1 input) s21_response = sp.Response(2, 1) # Returns list of complex values # Get frequency response object for further processing s21_freq_response = sp.FrequencyResponse(2, 1) # Resample to new frequency grid new_frequencies = si.fd.EvenlySpacedFrequencyList(20e9, 1000) # 20 GHz, 1000 points sp_resampled = sp.Resample(new_frequencies) # Change reference impedance to 75 ohms sp.SetReferenceImpedance(75.0) # Write to file with specific format sp.WriteToFile('output.s4p', '# GHz S RI R 50.0') ``` -------------------------------- ### Simulate Closed-Loop System and Extract Transfer Functions Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Initializes the SignalIntegrity application, opens a project file, runs a simulation, and extracts frequency responses. This is used to analyze the closed-loop system's behavior. ```python app = si.App.SignalIntegrityAppHeadless() app.OpenProjectFile('PIDSimulation.si') (sourceNames,outputWaveformLabels,transferMatrices,outputWaveformList)=app.Simulate() Fr=transferMatrices.FrequencyResponses() VOduetoVin=Fr[outputWaveformLabels.index('VO')][sourceNames.index('Vin')] VUduetoVin=Fr[outputWaveformLabels.index('VU')][sourceNames.index('Vin')] ``` -------------------------------- ### Simulate Open-Loop PID System and Extract Responses Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Initializes the SignalIntegrity application for open-loop simulation, opens a specific project file, and extracts the frequency responses for the PID controller and its individual components. This is used to analyze the open-loop behavior. ```python app = si.App.SignalIntegrityAppHeadless() app.OpenProjectFile('PIDSimulationOpenLoop.si') (sourceNames,outputWaveformLabels,transferMatrices,outputWaveformList)=app.Simulate() Fr=transferMatrices.FrequencyResponses() VPIDduetoVin=Fr[outputWaveformLabels.index('VPID')][sourceNames.index('Vin')] PduetoVin=Fr[outputWaveformLabels.index('P')][sourceNames.index('Vin')] IduetoVin=Fr[outputWaveformLabels.index('I')][sourceNames.index('Vin')] DduetoVin=Fr[outputWaveformLabels.index('D')][sourceNames.index('Vin')] ``` -------------------------------- ### Ubuntu Desktop Entry Configuration Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Configuration details for an Ubuntu desktop launcher. This .desktop file specifies application name, icon, and execution command. ```ini #!/usr/bin/env xdg-open [Desktop Entry] Version=1.0 Type=Application Terminal=false Icon[en_US]=/home/peterp/Work/SignalIntegrity/SignalIntegrity/App/icons/png/AppIcon2.ico Name[en_US]=SignalIntegrity Exec=SignalIntegrity Comment[en_US]=Signal Integrity Tools in Python Name=SignalIntegrity Comment=Signal Integrity Tools in Python Icon=/home/peterp/Work/SignalIntegrity/SignalIntegrity/App/icons/png/AppIcon2.ico ``` -------------------------------- ### Create S-Parameters Programmatically Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Shows how to construct S-parameter data from frequency lists and matrices, modeling a transmission line with loss. This is useful for creating custom device models or processing measurement data. Ensure correct physical parameters are used for accurate modeling. ```python import SignalIntegrity.Lib as si import cmath import math # Define frequency list frequencies = [f * 1e9 for f in range(1, 21)] # 1 to 20 GHz # Create S-parameter matrices for each frequency (2-port example) # Model a simple transmission line with loss Z0 = 50.0 length = 0.1 # meters velocity = 2e8 # m/s loss_db_per_m = 0.5 data = [] for f in frequencies: wavelength = velocity / f beta = 2 * math.pi / wavelength alpha = loss_db_per_m / 8.686 * length # Convert dB to nepers gamma = complex(alpha, beta * length) # S-parameters for transmission line s11 = 0j s22 = 0j s21 = cmath.exp(-gamma) s12 = s21 matrix = [[s11, s12], [s21, s22]] data.append(matrix) # Create SParameters object sp = si.sp.SParameters(frequencies, data, Z0=50.0) # Access individual elements print(f"S21 at 10 GHz: {20*math.log10(abs(sp[9][1][0])):.2f} dB") # Write to Touchstone file sp.WriteToFile('transmission_line.s2p') ``` -------------------------------- ### Create Device S-Parameter Models Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Utilizes built-in device models for circuit elements like resistors and transmission lines. Ensure frequency list is appropriate for the device. ```python import SignalIntegrity.Lib as si # Create frequency list f = 10e9 # Single frequency for demonstration # Series impedance (resistor) R = 100 # 100 ohms series_z = si.dev.SeriesZ(R) print(f"Series Z S-matrix:\n{series_z}") # Shunt impedance shunt_z = si.dev.ShuntZTwoPort(R) # Ideal transmission line Zc = 50 # Characteristic impedance Td = 1e-9 # Time delay tline = si.dev.TLineTwoPortLossless(Zc, Td, f) ``` -------------------------------- ### Invoke Doxygen for Windows Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Use this command in the `Doc` directory to generate documentation on Windows. ```bash doxygen SignalIntegrityWindows ``` -------------------------------- ### Execute Coverage Tests Source: https://github.com/nubis-communications/signalintegrity/blob/master/Test/README.md Run the full suite of unit tests using the platform-specific script. ```bash bash CoverageTest.sh ``` ```batch CoverageTest.bat ``` -------------------------------- ### Define Calibration Kit Standards Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Initializes a calibration kit and adds standard definitions (Short, Open, Load, Thru) with their parameters. Requires SignalIntegrity.Lib. ```python import SignalIntegrity.Lib as si # Define calibration kit standards cal_kit = si.m.calkit.CalibrationKit() # Add standards cal_kit['short'] = si.m.calkit.ShortStandard(offsetDelay=0, offsetLoss=0, L0=0, L1=0, L2=0, L3=0) cal_kit['open'] = si.m.calkit.OpenStandard(offsetDelay=0, offsetLoss=0, C0=0, C1=0, C2=0, C3=0) cal_kit['load'] = si.m.calkit.LoadStandard(offsetDelay=0, offsetLoss=0, Z0=50) cal_kit['thru'] = si.m.calkit.ThruStandard(offsetDelay=0, offsetLoss=0) ``` -------------------------------- ### Create and Manipulate Waveforms Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Illustrates creating time-domain waveforms using `Waveform` and `TimeDescriptor`, including step, pulse, and sine functions. It covers waveform arithmetic, delay, differentiation, integration, and I/O operations. Ensure correct time parameters and sample rates are set for accurate signal representation. ```python import SignalIntegrity.Lib as si import math # Create a time descriptor: start time, number of points, sample rate td = si.td.wf.TimeDescriptor(-5e-9, 1000, 100e9) # -5ns start, 1000 points, 100 GS/s # Create waveform with step function step_values = [0.0 if t < 0 else 1.0 for t in td.Times()] step_wf = si.td.wf.Waveform(td, step_values) # Create pulse waveform using built-in class pulse_wf = si.td.wf.PulseWaveform(td, Amplitude=1.0, StartTime=0, PulseWidth=1e-9) # Create sine waveform sine_wf = si.td.wf.SineWaveform(td, Amplitude=1.0, Frequency=5e9, Phase=0) # Waveform arithmetic combined = step_wf * 0.5 + sine_wf * 0.1 # Scale and add # Delay waveform delayed_wf = step_wf.DelayBy(2e-9) # Delay by 2 ns # Calculate derivative and integral derivative_wf = step_wf.Derivative() integral_wf = step_wf.Integral() # Read/write waveforms step_wf.WriteToFile('step.txt') loaded_wf = si.td.wf.Waveform().ReadFromFile('step.txt') # Convert to frequency content freq_content = step_wf.FrequencyContent() ``` -------------------------------- ### Generate Symbolic S-parameters in LaTeX Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Defines a symbolic circuit using a netlist, assigns symbolic S-parameters to components, and generates the analytical solution in LaTeX format. Requires SignalIntegrity.Lib. ```python import SignalIntegrity.Lib as si # Define symbolic circuit symbolic_parser = si.p.SystemDescriptionParser() symbolic_parser.AddLines([ 'device R 2', 'device C 2', 'port 1 R 1', 'port 2 C 2', 'connect R 2 C 1' ]) # Generate symbolic S-parameters system = si.sd.SystemSParametersSymbolic(symbolic_parser.SystemDescription()) system.AssignSParameters('R', si.sy.SeriesZ('R')) system.AssignSParameters('C', si.sy.SeriesZ('1/(s*C)')) # Get symbolic result symbolic_result = system.LaTeXSolution() print(symbolic_result) # LaTeX formatted equations ``` -------------------------------- ### Invoke Doxygen for Linux Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Use this command in the `Doc` directory to generate documentation on Linux. ```bash doxygen SignalIntegrityLinux ``` -------------------------------- ### Calculate B*A Frequency Response and Find 0 dB Crossover Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Calculates the frequency response of the product of the feedback (B) and plant (A) transfer functions. It then identifies the frequency at which the magnitude of B*A crosses 0 dB, a critical point for stability analysis. ```python BA=si.fd.FrequencyDomain(A.Frequencies(),[b*a for a,b in zip(A.Values(),B.Values())]) BAV=BA.Values('dB') BAP=BA.Values('deg') BAF=BA.Frequencies('MHz') for n in range(len(BA)): if BAV[n]<0: zeron=n break print(f'magnitude of B*A crosses 0 dB at frequency = {BAF[n]} MHz') ``` -------------------------------- ### Plot Phase Response: PID, Uncompensated, and Compensated Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Compares the phase responses of the PID controller alone (B/(1+B*A)), the uncompensated plant (A), and the fully compensated system (A*B/(1+B*A)). This illustrates the effect of PID compensation on the system's phase characteristics. ```python plt.cla() plt.semilogx(HPID.Frequencies('MHz'),HPID.Values('deg'),label='B/(1+B*A) = PID') plt.semilogx(A.Frequencies('MHz'),A.Values('deg'),label='A = Uncompensated') plt.semilogx(HCalc.Frequencies('MHz'),HCalc.Values('deg'),label='A*B/(1+B*A) = Compensated') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('phase (deg)') plt.title('effect of PID on phase response') plt.show() ``` -------------------------------- ### Plotting Response Products Phase Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Plots the phase of various response products using semilogx for frequency scaling. Requires data objects with Frequencies and Values methods. ```python plt.cla() plt.semilogx(A.Frequencies('MHz'),A.Values('deg'),label='A') plt.semilogx(B.Frequencies('MHz'),B.Values('deg'),label='B') plt.semilogx(BA.Frequencies('MHz'),BA.Values('deg'),label='B*A') plt.semilogx(BAPlusOne.Frequencies('MHz'),BAPlusOne.Values('deg'),label='B*A+1') plt.semilogx(OneOverBAPlusOne.Frequencies('MHz'),OneOverBAPlusOne.Values('deg'),label='1/(B*A+1)') plt.semilogx(HPID.Frequencies('MHz'),HPID.Values('deg'),label='B/(1+B*A)') plt.semilogx(HCalc.Frequencies('MHz'),HCalc.Values('deg'),label='A*B/(1+B*A)') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('phase (deg)') plt.title('response products phase') plt.show() ``` -------------------------------- ### Set Default Application for File Type Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Sets the default application for a specific file type using the 'mimeopen' command. This associates .si files with the SignalIntegrity application. ```bash mimeopen -d theFile.si ``` -------------------------------- ### Plot Magnitude Response: PID, Uncompensated, and Compensated Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Compares the magnitude responses of the PID controller alone (B/(1+B*A)), the uncompensated plant (A), and the fully compensated system (A*B/(1+B*A)). This illustrates the effect of PID compensation across different frequencies. ```python plt.cla() plt.semilogx(HPID.Frequencies('MHz'),HPID.Values('dB'),label='B/(1+B*A) = PID') plt.semilogx(A.Frequencies('MHz'),A.Values('dB'),label='A = Uncompensated') plt.semilogx(HCalc.Frequencies('MHz'),HCalc.Values('dB'),label='A*B/(1+B*A) = Compensated') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('magnitude (db)') plt.title('effect of PID on magnitude response') plt.show() ``` -------------------------------- ### Virtual Probing with Transfer Matrices Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Calculates transfer matrices for a system defined by a netlist and applies them to input waveforms to determine output at virtual probe points. Requires SignalIntegrity.Lib and waveform objects. ```python import SignalIntegrity.Lib as si # Define system with virtual probe points netlist = """ device T1 2 file channel.s2p device R 2 R 50 port 1 T1 1 connect T1 2 R 1 connect R 2 ground stim m1 1 meas T1 2 output T1 2 """ # Create virtual probe parser frequencies = si.fd.EvenlySpacedFrequencyList(20e9, 1000) parser = si.p.VirtualProbeNumericParser(frequencies) parser.AddLines(netlist.split('\n')) transfer_matrices = parser.TransferMatrices() # Apply to waveform td = si.td.wf.TimeDescriptor(-1e-9, 10000, 100e9) input_wf = si.td.wf.StepWaveform(td, Amplitude=1.0, StartTime=0, RiseTime=50e-12) # Calculate output at virtual probe point output_wfs = transfer_matrices.ProcessWaveforms([input_wf]) output_wf = output_wfs[0] # Plot or save results output_wf.WriteToFile('virtual_probe_output.txt') ``` -------------------------------- ### Deembedding S-parameters using Numeric Parser Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Parses a deembedding netlist and solves for the DUT S-parameters using a numeric parser. Requires SignalIntegrity.Lib and a frequency list. ```python import SignalIntegrity.Lib as si # Define deembedding problem with netlist netlist = """ # Deembedding structure: Fixture - DUT - Fixture device F1 2 file fixture_left.s2p device DUT 2 file measured.s2p device F2 2 file fixture_right.s2p port 1 F1 1 port 2 F2 2 connect F1 2 DUT 1 connect DUT 2 F2 1 system file measured_total.s2p unknown DUT """ # Parse and solve parser = si.p.DeembedderNumericParser( si.fd.EvenlySpacedFrequencyList(20e9, 200) ) parser.AddLines(netlist.split('\n')) dut_sp = parser.Deembed() # Save deembedded result dut_sp.WriteToFile('dut_deembedded.s2p') ``` -------------------------------- ### Parse Netlist and Compute S-Parameters Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Defines circuits using netlist syntax and computes overall S-parameters. Ensure the netlist is correctly formatted and includes ports and connections. ```python import SignalIntegrity.Lib as si # Define a netlist for a simple attenuator circuit netlist = """ # 6 dB Pi attenuator device R1 2 R 16.61 device R2 2 R 66.93 device R3 2 R 16.61 port 1 R1 1 port 2 R3 2 connect R1 2 R2 1 R3 1 connect R2 2 ground """ # Parse and compute S-parameters parser = si.p.SystemSParametersNumericParser( si.fd.EvenlySpacedFrequencyList(10e9, 100) ) parser.AddLines(netlist.split('\n')) sp = parser.SParameters() # Access results s21 = sp.Response(2, 1) s11 = sp.Response(1, 1) import math print(f"Insertion loss: {-20*math.log10(abs(s21[50])):.2f} dB") print(f"Return loss: {-20*math.log10(abs(s11[50])):.2f} dB") # Write results sp.WriteToFile('attenuator.s2p') ``` -------------------------------- ### Generated console script Source: https://github.com/nubis-communications/signalintegrity/wiki/Developers The bash script created in usr/local/bin to handle the console entry point. ```python #!/usr/bin/python # EASY-INSTALL-ENTRY-SCRIPT: 'SignalIntegrity','console_scripts','SignalIntegrity' __requires__ = 'SignalIntegrity' import re import sys from pkg_resources import load_entry_point if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) sys.exit( load_entry_point('SignalIntegrity', 'console_scripts', 'SignalIntegrity')() ) ``` -------------------------------- ### Define Circuit Components and Connections Source: https://github.com/nubis-communications/signalintegrity/blob/master/Test/TestSignalIntegrity/rlc.txt Defines inductors, capacitors, and ground connections, then specifies the netlist topology and ports. ```netlist var $Ll$ x $Cs$ x $Lr$ x device L1 2 L $Ll$ device C1 2 C $Cs$ device L2 2 L $Lr$ device G 1 ground connect L1 2 L2 1 C1 1 connect C1 2 G 1 port 1 L1 1 port 2 L2 2 ``` -------------------------------- ### Specify Application Command for File Association Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Specifies the command to be used when opening files of a certain type. 'SignalIntegrity %f' indicates that the SignalIntegrity application should be launched with the file path as an argument. ```bash SignalIntegrity %f ``` -------------------------------- ### Plot PID Controller Component Outputs Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Visualizes the individual contributions of the Proportional (P), Integral (I), and Derivative (D) components, as well as the combined PID output, over time. This aids in understanding the controller's internal dynamics. ```python P=outputWaveformList[outputWaveformLabels.index('P')] I=outputWaveformList[outputWaveformLabels.index('I')] D=outputWaveformList[outputWaveformLabels.index('D')] PID=outputWaveformList[outputWaveformLabels.index('VPID')] plt.cla() plt.plot(P.Times('us'),P.Values(),label='P') plt.plot(I.Times('us'),I.Values(),label='I') plt.plot(D.Times('us'),D.Values(),label='D') plt.plot(PID.Times('us'),PID.Values(),label='PID') plt.legend() plt.xlim(left=-0.1,right=0.5) plt.ylim(bottom=-2) plt.grid(True,which='both') plt.xlabel('time (us)') plt.ylabel('amplitude (V)') plt.title('output of PID controller') plt.show() ``` -------------------------------- ### Plot Magnitude Response of B*A at 0 dB Crossover Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Visualizes the magnitude response of B*A, highlighting the frequency where it crosses 0 dB with red dashed lines. This plot is essential for determining the gain margin of the system. ```python plt.cla() plt.semilogx(BA.Frequencies('MHz'),BA.Values('dB'),label='B*A') plt.axvline(x=BAF[zeron], color='red', linestyle='--') plt.axhline(y=0, color='red', linestyle='--') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('magnitude (dB)') plt.title('frequency that response product crosses unity gain') plt.show() ``` -------------------------------- ### Doxygen Configuration: Input Filter for Windows Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Specifies the input filter program for Doxygen on Windows. This configuration uses a batch file to call the filter. ```ini INPUT_FILTER = doxypy.bat ``` -------------------------------- ### Calculate 1/(A*B+1) Magnitude and Phase Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Calculates the magnitude (in dB) and phase (in degrees) for the inverse of the A*B+1 transfer function. This is useful for analyzing feedback systems. ```python InvABPlus1dBy=[20.*math.log10(abs(1./(a*b+1))) for a,b in zip(A.Values(),B.Values())] InvABPlus1degy=[180./math.pi*cmath.phase(1/(a*b+1)) for a,b in zip(A.Values(),B.Values())] ``` -------------------------------- ### Interactive Controller Tuning Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Creates an interactive interface using sliders to adjust PID controller parameters (P, I, D) and dynamically update signal integrity plots. This requires the 'update' function to be defined. ```python interact(update,P=(-1000.,1000.),I=(-1000.,1000.),D=(-1000.,1000.)); ``` -------------------------------- ### Plot B/(A*B+1) Magnitude and Phase Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Creates subplots for visualizing the magnitude (dB) and phase (deg) of the B/(A*B+1) transfer function. Requires 'f', 'BInvABPlus1dBy', and 'BInvABPlus1degy'. ```python ax9 = fig.add_subplot(2,3,5) BInvABPlus1dB, = ax9.semilogx(f,BInvABPlus1dBy,color='blue') ax9.grid() plt.ylabel('magnitude (dB)') ax10 = fig.add_subplot(2,3,5,sharex=ax9,frameon=False) BInvABPlus1deg, = ax10.semilogx(f,BInvABPlus1degy,color='red') ax10.yaxis.tick_right() ax10.yaxis.set_label_position('right') plt.ylabel('phase (deg)') plt.title('B/(A*B+1)') ax10.grid() ``` -------------------------------- ### Define Voltage Amplifier Model Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Creates a four-port voltage amplifier model with a specified gain, input impedance, and output impedance. ```python A = 10 Zi = 1e6 # Input impedance Zo = 50 # Output impedance vamp = si.dev.VoltageAmplifierFourPort(A, Zi, Zo) ``` -------------------------------- ### Calculate A*B Magnitude and Phase Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Calculates the magnitude (in dB) and phase (in degrees) of the product of two signals A and B. This is a fundamental step in analyzing open-loop responses. ```python ABdBy=[20.*math.log10(abs(a*b)) for a,b in zip(A.Values(),B.Values())] ABdegy=[180./math.pi*cmath.phase(a*b) for a,b in zip(A.Values(),B.Values())] ``` -------------------------------- ### Define Transmission Line Model Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Instantiates a four-port transmission line model with specified impedance, delay, and frequency. ```python tline_4port = si.dev.TLineFourPort(Zc, Td, f) ``` -------------------------------- ### Configure Git to Use SSH Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Configures Git to use SSH for GitHub connections instead of HTTPS. This is useful for SSH key authentication. ```bash git config --global url."git@github.com:".insteadof "https://github.com/" ``` -------------------------------- ### Plot Input and Output Waveforms Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Plots the input and output waveforms of the system over time. This helps visualize the effect of the PID compensation on the output signal. Ensure the output labels 'VO' and 'VU' are correctly mapped. ```python VO=outputWaveformList[outputWaveformLabels.index('VO')] Vin=outputWaveformList[outputWaveformLabels.index('Vin')] VU=outputWaveformList[outputWaveformLabels.index('VU')] plt.cla() plt.plot(Vin.Times('us'),Vin.Values(),label='input') plt.plot(VO.Times('us'),VO.Values(),label='output PID compensated') plt.plot(VU.Times('us'),VU.Values(),label='output uncompensated') plt.legend() plt.xlim(left=-1,right=20) plt.grid(True,which='both') plt.xlabel('time (us)') plt.ylabel('amplitude (V)') plt.title('input and output waveforms') plt.show() ``` -------------------------------- ### Plot Open-Loop PID Responses Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Plots the magnitude response of the open-loop PID controller and its P, I, and D components on a logarithmic frequency scale. This helps in understanding the contribution of each part to the overall open-loop behavior. ```python plt.cla() plt.semilogx(VPIDduetoVin.Frequencies('MHz'),VPIDduetoVin.Values('dB'),label='PID Open-loop Response') plt.semilogx(PduetoVin.Frequencies('MHz'),PduetoVin.Values('dB'),label='P') plt.semilogx(IduetoVin.Frequencies('MHz'),IduetoVin.Values('dB'),label='I') plt.semilogx(DduetoVin.Frequencies('MHz'),DduetoVin.Values('dB'),label='D') plt.legend() plt.grid(True,which='both') plt.ylim(bottom=-40) plt.xlabel('frequency (MHz)') plt.ylabel('magnitude (dB)') ``` -------------------------------- ### Calculate PID Response Due to Command Input Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Calculates the frequency response of the PID controller's output due to the command input, considering the plant's transfer function. This represents the system's response to the command signal after PID compensation. ```python HPID=si.fd.FrequencyDomain(A.Frequencies(),[b/(1+b*a) for a,b in zip(A.Values(),B.Values())]) ``` -------------------------------- ### Pull Files from Git Branch Source: https://github.com/nubis-communications/signalintegrity/wiki/FAQ Pulls all files from the 'InNextRelease' branch of the remote repository. This branch is where most of the development work is done. ```bash git pull origin InNextRelease ``` -------------------------------- ### Plotting Response Products Magnitude Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Plots the magnitude of response products. Ensure matplotlib is imported and configured. ```python plt.ylabel('magnitude (dB)') plt.title('response products magnitude') plt.show() ``` -------------------------------- ### Define Operational Amplifier Model Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Instantiates an operational amplifier model with high gain, input impedance, and low output impedance. ```python Gain = 1e6 Zi = 1e12 Zo = 0 opamp = si.dev.OperationalAmplifier(Gain, Zi, Zo) ``` -------------------------------- ### Define Mixed-Mode Converter Model Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Initializes a mixed-mode converter for single-ended to differential signal conversion. ```python mm = si.dev.MixedModeConverter() ``` -------------------------------- ### Plot Phase Margin of B*A Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Visualizes the phase response of B*A at the frequency where the magnitude crosses 0 dB. This plot is used to determine the phase margin, a key indicator of system stability. ```python plt.cla() plt.semilogx(BA.Frequencies('MHz'),BA.Values('deg'),label='B*A') plt.axvline(x=BAF[zeron], color='red', linestyle='--') plt.axhline(y=BAP[zeron], color='red', linestyle='--') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('phase (deg)') plt.title('phase margin') plt.show() ``` -------------------------------- ### Interactive Signal Integrity Analysis Plotting Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Sets up an interactive plotting environment using matplotlib and ipywidgets to visualize signal integrity simulation results. This snippet configures plots for open-loop and closed-loop responses, including magnitude and phase. ```python %matplotlib notebook import math,cmath from ipywidgets import * import numpy as np import matplotlib.pyplot as plt results=Responses(P,I,D) B=results['OpenLoop']['PID'] A=results['ClosedLoop']['U'] fig = plt.figure(figsize=(12,6), dpi=80) ax1 = fig.add_subplot(2,3, 1) PdB, = ax1.semilogx(f,results['OpenLoop']['P'].Response('dB'),color='blue',linestyle='--') IdB, = ax1.semilogx(f,results['OpenLoop']['I'].Response('dB'),color='blue',linestyle='--') DdB, = ax1.semilogx(f,results['OpenLoop']['D'].Response('dB'),color='blue',linestyle='--') PIDdB, = ax1.semilogx(f,results['OpenLoop']['PID'].Response('dB'),color='blue') ax1.grid() plt.ylabel('magnitude (dB)') ax2 = fig.add_subplot(2,3,1,sharex=ax1,frameon=False) Pdeg, = ax2.semilogx(f,results['OpenLoop']['P'].Response('deg'),color='red',linestyle='--') Ideg, = ax2.semilogx(f,results['OpenLoop']['I'].Response('deg'),color='red',linestyle='--') Ddeg, = ax2.semilogx(f,results['OpenLoop']['D'].Response('deg'),color='red',linestyle='--') PIDdeg, = ax2.semilogx(f,results['OpenLoop']['PID'].Response('deg'),color='red') ax2.yaxis.tick_right() ax2.yaxis.set_label_position('right') plt.ylabel('phase (deg)') plt.title('PID open-loop response (B)') ax2.grid() ABdBy=[20.*math.log10(abs(a*b)) for a,b in zip(A.Values(),B.Values())] ABdegy=[180./math.pi*cmath.phase(a*b) for a,b in zip(A.Values(),B.Values())] ax3 = fig.add_subplot(2,3,2) ABdB, = ax3.semilogx(f,ABdBy,color='blue') ax3.grid() plt.ylabel('magnitude (dB)') ax4 = fig.add_subplot(2,3,2,sharex=ax3,frameon=False) ABdeg, = ax4.semilogx(f,ABdegy,color='red') ax4.yaxis.tick_right() ax4.yaxis.set_label_position('right') plt.ylabel('phase (deg)') plt.title('A*B') ax4.grid() ABPlus1dBy=[20.*math.log10(abs(a*b+1)) for a,b in zip(A.Values(),B.Values())] ``` -------------------------------- ### Generate Eye Diagram Bitmap Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Generates an eye diagram bitmap from serial data waveforms. Supports jitter/noise analysis and BER estimation. Ensure `prbswf` is a valid waveform object. ```python import SignalIntegrity.Lib as si from SignalIntegrity.Lib.Eye import EyeDiagramBitmap # Assume prbswf is a waveform containing PRBS serial data # For demonstration, create a simple PRBS-like waveform td = si.td.wf.TimeDescriptor(0, 100000, 56e9) # 56 GS/s sampling baud_rate = 28e9 # 28 Gbaud # Create eye diagram bitmap eye = EyeDiagramBitmap( callback=None, cacheFileName=None, YAxisMode='Auto', Rows=200, Cols=200, BaudRate=baud_rate, prbswf=prbswf, # Your serial data waveform EnhancementMode='Auto', Levels=2, # NRZ (use 4 for PAM-4) recover_clock=False ) # Apply jitter and noise effects eye.ApplyJitterNoise( NoiseSigma=0.01, # 10 mV RMS noise JitterSigma=1e-12, # 1 ps RMS jitter DeterministicJitter=0 ) # Auto-align the eye diagram eye.AutoAlign( BERForAlignment=-3, AlignmentMode='Horizontal', HorizontalAlignment='Middle' ) # Compute measurements eye.Measure( BERForMeasure=-6, DecisionMode='Mid', WaveformType='V' ) # Generate bathtub curves and error rate calculations eye.Bathtub() # Access measurements measurements = eye.measDict print(f"Eye height: {measurements['Eye'][0]['Height']['Value']:.4f} V") print(f"Eye width: {measurements['Eye'][0]['Width']['Time']*1e12:.2f} ps") print(f"BER (measured): {measurements['Probabilities']['ErrorRate']['Bit']['Gray']['Measured']:.2e}") # Create annotations eye.Annotations( MeanLevels=True, LevelExtents=True, EyeWidth=True, EyeHeight=True, Contours=True ) # Generate image eye.CreateImage( LogIntensity=True, MinExponentLogIntensity=-6, Color='#00ff00', # Green InvertImage=True, ScaleX=200, ScaleY=200 ) # Save image eye.image.save('eye_diagram.png') ``` -------------------------------- ### Access Current Amplifier Device Source: https://github.com/nubis-communications/signalintegrity/blob/master/Doc/README.md Retrieve single frequency s-parameters for a current amplifier using the 'si.dev' namespace. ```python si.dev.CurrentAmplifier() ``` -------------------------------- ### Plot PID Compensated vs. Calculated Response Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Compares the actual PID compensated frequency response with the theoretically calculated response. This helps validate the PID controller's effectiveness and identify any discrepancies. ```python plt.cla() plt.semilogx(VOduetoVin.Frequencies('MHz'),VOduetoVin.Values('dB'),label='PID Compensated') plt.semilogx(HCalc.Frequencies('MHz'),HCalc.Values('dB'),label='Calculated') plt.legend() plt.grid(True,which='both') plt.xlabel('frequency (MHz)') plt.ylabel('magnitude (dB)') plt.title('comparison of actual and calculated response') plt.show() ``` -------------------------------- ### Convert Frequency Response to Impulse Response Source: https://context7.com/nubis-communications/signalintegrity/llms.txt Converts a frequency response to an impulse response, then to an FIR filter. Useful for filter design. Ensure the frequency response is defined over an appropriate range. ```python import SignalIntegrity.Lib as si import math # Create frequency response (low-pass filter example) frequencies = si.fd.EvenlySpacedFrequencyList(20e9, 200) fc = 5e9 # Cutoff frequency response = [] for f in frequencies: # First-order Butterworth response h = 1.0 / complex(1, f/fc) response.append(h) freq_resp = si.fd.FrequencyResponse(frequencies, response) # Convert to impulse response impulse_resp = freq_resp.ImpulseResponse() # Access impulse response data print(f"Impulse response samples: {len(impulse_resp)}") print(f"Time span: {impulse_resp.td.H} to {impulse_resp.td[-1]} seconds") # Create FIR filter from impulse response fir_filter = impulse_resp.FirFilter() # Apply filter to waveform by convolution td = si.td.wf.TimeDescriptor(-5e-9, 1000, 100e9) input_wf = si.td.wf.PulseWaveform(td, Amplitude=1.0, StartTime=0, PulseWidth=100e-12) output_wf = input_wf * fir_filter # Resample frequency response to new frequency grid new_freq = si.fd.EvenlySpacedFrequencyList(10e9, 500) freq_resp_resampled = freq_resp.Resample(new_freq) # Convert back to verify impulse_resp_2 = freq_resp_resampled.ImpulseResponse() freq_resp_round_trip = impulse_resp_2.FrequencyResponse() ``` -------------------------------- ### Plot Closed-Loop Response Magnitude and Phase Source: https://github.com/nubis-communications/signalintegrity/blob/master/SignalIntegrity/App/Examples/PID/PID Study.ipynb Plots the magnitude (dB) and phase (deg) of the closed-loop response, denoted as A*B/(A*B+1). This uses pre-calculated results from 'results'. ```python ax11 = fig.add_subplot(2,3,6) ABInvABPlus1dB, = ax11.semilogx(f,results['ClosedLoop']['C'].Response('dB'),color='blue') ax11.grid() plt.ylabel('magnitude (dB)') ax12 = fig.add_subplot(2,3,6,sharex=ax11,frameon=False) ABInvABPlus1deg, = ax12.semilogx(f,results['ClosedLoop']['C'].Response('deg'),color='red') ax12.yaxis.tick_right() ax12.yaxis.set_label_position('right') plt.ylabel('phase (deg)') plt.title('A*B/(A*B+1) = closed loop response') ax12.grid() ```