def __init__(self,f,Rp,Rsep,Lp,Gp,Cp,dfp,Rn,Rsen,Ln,Gn,Cn,dfn,Z0=50.,K=0):
        """Constructor

        ports are 1,2,3,4 is +1,-1, +2, -2

        @param f list of float frequencies
        @param Rp float DC resistance of positive leg (ohms)
        @param Rsep float skin-effect resistance of positive leg (ohms/sqrt(Hz))
        @param Lp float inductance of positive leg (H)
        @param Gp float DC conductance of positive leg to ground (S)
        @param Cp float capacitance of positive leg to ground (F)
        @param dfp float dissipation factor (loss-tangent) of capacitance of positive leg to ground
        @param Rn float DC resistance of negative leg (ohms)
        @param Rsen float skin-effect resistance of negative leg (ohms/sqrt(Hz))
        @param Ln float inductance of negative leg (H)
        @param Gn float DC conductance of negative leg to ground (S)
        @param Cn float capacitance of negative leg to ground (F)
        @param dfn float dissipation factor (loss-tangent) of capacitance of negative leg to ground
        @param Z0 (optional) float reference impedance (defaults to 50 ohms)
        @param K (optional) integer number of sections (defaults to 0).
        If 0 is specified, then an analytic solution is provided otherwise an approximate solution is provided
        with all parametric values divided into the integer number of sections.
        """
        # pragma: silent exclude
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
        from SignalIntegrity.Lib.SParameters.Devices.TLineTwoPortRLGC import TLineTwoPortRLGC
        # pragma: include
        sdp=SystemDescriptionParser()
        sdp.AddLines(['device TP 2','device TN 2',
                      'port 1 TP 1 2 TN 1 3 TP 2 4 TN 2'])
        self.m_sspn=SystemSParametersNumeric(sdp.SystemDescription())
        self.m_spdl=[('TP',TLineTwoPortRLGC(f,Rp,Rsep,Lp,Gp,Cp,dfp,Z0,K)),
                     ('TN',TLineTwoPortRLGC(f,Rn,Rsen,Ln,Gn,Cn,dfn,Z0,K))]
        SParameters.__init__(self,f,None,Z0)
Ejemplo n.º 2
0
 def __init__(self, f=None, args=None):
     """Constructor  
     frequencies may be provided at construction time (or not for symbolic solutions).
     @param f (optional) list of frequencies
     @param args (optional) string arguments for the circuit.
     @remark Arguments are provided on a line as pairs of names and values separated by a space.
     """
     SystemDescriptionParser.__init__(self, f, args)
Ejemplo n.º 3
0
    def __init__(self,
                 f,
                 R,
                 Rse,
                 L,
                 G,
                 C,
                 df,
                 Cm,
                 dfm,
                 Gm,
                 Lm,
                 Z0=50.,
                 K=0,
                 scale=1.):
        """Constructor

        ports are 1,2,3,4 is +1,-1, +2, -2

        @param f list of float frequencies
        @param R float DC resistance of both legs (ohms)
        @param Rse float skin-effect resistance of both legs (ohms/sqrt(Hz))
        @param L float inductance of both legs (H)
        @param G float DC conductance of both legs to ground (S)
        @param C float capacitance of both legs to ground (F)
        @param df float dissipation factor (loss-tangent) of capacitance of both legs to ground
        @param Cm float mutual capacitance (F)
        @param dfm float dissipation factor (loss-tangent) of mutual capacitance (F)
        @param Gm float mutual conductance (S)
        @param Lm float mutual inductance (H)
        @param Z0 (optional) float reference impedance (defaults to 50 ohms)
        @param K (optional) integer number of sections (defaults to 0).
        @param scale (optional) float amount to scale the line by (assuming all other values are per unit)
        If 0 is specified, then an analytic solution is provided otherwise an approximate solution is provided
        with all parametric values divided into the integer number of sections.
        """
        # pragma: silent exclude
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
        from SignalIntegrity.Lib.SParameters.Devices.TLineTwoPortRLGC import TLineTwoPortRLGC
        # pragma: include
        sdp = SystemDescriptionParser()
        sdp.AddLines([
            'device L 4 mixedmode', 'device R 4 mixedmode', 'device TE 2',
            'device TO 2', 'port 1 L 1 2 L 2 3 R 1 4 R 2', 'connect L 3 TO 1',
            'connect R 3 TO 2', 'connect L 4 TE 1', 'connect R 4 TE 2'
        ])
        self.m_sspn = SystemSParametersNumeric(sdp.SystemDescription())
        self.m_spdl = [
            ('TE', TLineTwoPortRLGC(f, R, Rse, L + Lm, G, C, df, Z0, K,
                                    scale)),
            ('TO',
             TLineTwoPortRLGC(f, R, Rse, L - Lm, G + 2 * Gm, C + 2 * Cm,
                              (C * df + 2 * Cm * dfm) / (C + 2 * Cm), Z0, K,
                              scale))
        ]
        SParameters.__init__(self, f, None, Z0)
Ejemplo n.º 4
0
 def _ProcessLines(self):
     """processes all of the lines in a netlist
     @see _ProcessLine() for explanation of parameters and functionality.
     """
     SystemDescriptionParser._ProcessLines(self)
     self.m_sd = VirtualProbe(self.m_sd)
     lines=copy.deepcopy(self.m_ul); self.m_ul=[]
     for line in lines: self._ProcessVirtualProbeLine(line)
     return self
Ejemplo n.º 5
0
    def __init__(self, f, R, Rse, L, G, C, df, Z0=50., K=0, scale=1.):
        """Constructor
        @param f list of float frequencies
        @param R float DC series resistance (ohms)
        @param Rse float series skin-effect resistance (ohms/sqrt(Hz))
        @param L float series inductance (H)
        @param G float DC conductance to ground (S)
        @param C float capacitance to ground (F)
        @param df float dissipation factor (loss-tangent) of capacitance to ground
        @param Z0 (optional) float reference impedance (defaults to 50 ohms)
        @param K (optional) integer number of sections (defaults to zero)
        @param scale (optional) float amount to scale the line by (assuming all other values are per unit)
        @note If K=0 is specified, it is modified to a value that will provided a very good numerical
        approximation.

        The calculation is such that round-trip propagation time (twice the electrical length)
        of any one small section is no more than one percent of the fastest possible risetime.
        """
        R = R * scale
        Rse = Rse * scale
        L = L * scale
        G = G * scale
        C = C * scale
        df = df
        K = int(K * scale + 0.5)
        if K == 0:
            """max possible electrical length"""
            Td = math.sqrt(L * C)
            Rt = 0.45 / f[-1]  # fastest risetime
            """sections such that fraction of risetime less than round trip
            electrical length of one section"""
            K = int(math.ceil(Td * 2 / (Rt * self.rtFraction)))

        self.m_K = K
        # pragma: silent exclude
        from SignalIntegrity.Lib.Devices import SeriesZ
        from SignalIntegrity.Lib.Devices import TerminationG
        from SignalIntegrity.Lib.SParameters.Devices.TerminationC import TerminationC
        from SignalIntegrity.Lib.SParameters.Devices.SeriesL import SeriesL
        from SignalIntegrity.Lib.SParameters.Devices.SeriesRse import SeriesRse
        from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        # pragma: include
        sdp = SystemDescriptionParser().AddLines([
            'device R 2', 'device Rse 2', 'device L 2', 'device C 1',
            'device G 1', 'connect R 2 Rse 1', 'connect Rse 2 L 1',
            'connect L 2 G 1 C 1', 'port 1 R 1 2 G 1'
        ])
        self.m_sspn = SystemSParametersNumeric(sdp.SystemDescription())
        self.m_sspn.AssignSParameters('R', SeriesZ(R / K, Z0))
        self.m_sspn.AssignSParameters('G', TerminationG(G / K, Z0))
        self.m_spdl = [('Rse', SeriesRse(f, Rse / K, Z0)),
                       ('L', SeriesL(f, L / K, Z0)),
                       ('C', TerminationC(f, C / K, Z0, df))]
        SParameters.__init__(self, f, None, Z0)
Ejemplo n.º 6
0
 def _ProcessLines(self):
     """processes all of the lines in a netlist
     @see _ProcessLine() for explanation of parameters and functionality.
     """
     SystemDescriptionParser._ProcessLines(self, ['connect', 'port'])
     self.m_sd = Simulator(self.m_sd)
     lines = copy.deepcopy(self.m_ul)
     self.m_ul = []
     for line in lines:
         self._ProcessSimulatorLine(line)
     lines = copy.deepcopy(self.m_ul)
     self.m_ul = []
     for line in lines:
         SystemDescriptionParser._ProcessLine(self, line, ['port'])
     return self
 def __init__(self, f=None, args=None, callback=None, cacheFileName=None):
     """constructor  
     frequencies may be provided at construction time (or not for symbolic solutions).
     @param f (optional) list of frequencies
     @param args (optional) string arguments for the circuit.
     @param callback (optional) function taking one argument as a callback
     @param cacheFileName (optional) string name of file used to cache results  
     @remark Arguments are provided on a line as pairs of names and values separated by a space.  
     The optional callback is used as described in the class CallBacker.
     """
     SystemDescriptionParser.__init__(self, f, args)
     self.sf = None
     # pragma: silent exclude
     CallBacker.__init__(self, callback)
     LinesCache.__init__(self, 'SParameters', cacheFileName)
Ejemplo n.º 8
0
 def __init__(self,
              f,
              offsetDelay=0.0,
              offsetZ0=50.0,
              offsetLoss=0.0,
              terminationZ0=50.0):
     """Constructor
     @param f list of frequencies
     @param offsetDelay (optional) float electrical length of offset in s (defaults to 0 s)
     @param offsetZ0 (optional) float real characteristic impedance of offset (defaults to 50 ohms)
     @param offsetLoss (optional) float loss due to skin-effect defined in Gohms/s at 1 GHz (defaults to 0).
     @param terminationZ0 (optional) float real impedance of termination.
     The result is that the class becomes the base-class SParameters with the s-parameters
     of a load standard.
     """
     # pragma: silent exclude
     from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
     # pragma: include
     sspn = SystemSParametersNumeric(SystemDescriptionParser().AddLines([
         'device offset 2', 'device R 1', 'port 1 offset 1',
         'connect offset 2 R 1'
     ]).SystemDescription())
     offsetSParameters = Offset(f, offsetDelay, offsetZ0, offsetLoss)
     terminationSParameters = TerminationZ(terminationZ0)
     sp = []
     for n in range(len(f)):
         sspn.AssignSParameters('offset', offsetSParameters[n])
         sspn.AssignSParameters('R', terminationSParameters)
         sp.append(sspn.SParameters())
     SParameters.__init__(self, f, sp)
Ejemplo n.º 9
0
 def _ProcessLines(self):
     """processes all of the lines in a netlist
     @see _ProcessLine() for explanation of parameters and functionality.
     """
     SystemDescriptionParser._ProcessLines(self)
     self.m_spc = {
         key: value.Resample(self.m_f)
         for (key, value) in self.m_spc
     }
     lines = copy.deepcopy(self.m_ul)
     self.m_ul = []
     for i in range(len(lines)):
         line = lines[i]
         self._ProcessCalibrationLine(line)
         # pragma: silent exclude
         if self.HasACallBack():
             progress = (float(i) + 1) / len(lines) * 100.0
             if not self.CallBack(progress):
                 raise SignalIntegrityExceptionCalibration(
                     'calculation aborted')
         # pragma: include
     self.calibration = Calibration(self.ports, self.m_f)
     self.calibration.AddMeasurements(self.calibrationMeasurementList)
     return self
Ejemplo n.º 10
0
    def __init__(self,
                 f,
                 offsetDelay=0.0,
                 offsetZ0=50.0,
                 offsetLoss=0.0,
                 f0=1e9,
                 C0=0.0,
                 C1=0.0,
                 C2=0.0,
                 C3=0.0):
        """Constructor
        @param f list of frequencies
        @param offsetDelay (optional) float electrical length of offset in s (defaults to 0 s)
        @param offsetZ0 (optional) float real characteristic impedance of offset (defaults to 50 ohms)
        @param offsetLoss (optional) float loss due to skin-effect defined in Gohms/s at 1 GHz (defaults to 0).
        @param f0 (optional) float frequency where the offset loss is defined (defaults to 1e9).
        @param C0 (optional) float polynomial coefficient for capacitance of open termination
        @param C1 (optional) float polynomial coefficient for capacitance of open termination
        @param C2 (optional) float polynomial coefficient for capacitance of open termination
        @param C3 (optional) float polynomial coefficient for capacitance of open termination
        The result is that the class becomes the base-class SParameters with the s-parameters
        of a open standard.

        Termination capacitance polynomial is C0+f*(C1+f*(C2+f*C3)).
        """
        # pragma: silent exclude
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        # pragma: include
        sspn = SystemSParametersNumeric(SystemDescriptionParser().AddLines([
            'device offset 2', 'device C 1', 'port 1 offset 1',
            'connect offset 2 C 1'
        ]).SystemDescription())
        offsetSParameters = Offset(f, offsetDelay, offsetZ0, offsetLoss, f0)
        terminationSParameters = TerminationCPolynomial(f, C0, C1, C2, C3)
        sp = []
        for n in range(len(f)):
            sspn.AssignSParameters('offset', offsetSParameters[n])
            sspn.AssignSParameters('C', terminationSParameters[n])
            sp.append(sspn.SParameters())
        SParameters.__init__(self, f, sp)
Ejemplo n.º 11
0
    def __init__(self,
                 f,
                 offsetDelay=0.0,
                 offsetZ0=50.0,
                 offsetLoss=0.0,
                 L0=0.0,
                 L1=0.0,
                 L2=0.0,
                 L3=0.0):
        """Constructor
        @param f list of frequencies
        @param offsetDelay (optional) float electrical length of offset in s (defaults to 0 s)
        @param offsetZ0 (optional) float real characteristic impedance of offset (defaults to 50 Ohms)
        @param offsetLoss (optional) float loss due to skin-effect defined in GOhms/s at 1 GHz (defaults to 0).
        @param L0 (optional) float polynomial coefficient for inductance of short termination
        @param L1 (optional) float polynomial coefficient for inductance of short termination
        @param L2 (optional) float polynomial coefficient for inductance of short termination
        @param L3 (optional) float polynomial coefficient for inductance of short termination
        The result is that the class becomes the base-class SParameters with the s-parameters
        of a short standard.

        Termination inductance polynomial is L0+f*(L1+f*(L2+f*L3)).
        """
        # pragma: silent exclude
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        # pragma: include
        sspn = SystemSParametersNumeric(SystemDescriptionParser().AddLines([
            'device offset 2', 'device L 1', 'port 1 offset 1',
            'connect offset 2 L 1'
        ]).SystemDescription())
        offsetSParameters = Offset(f, offsetDelay, offsetZ0, offsetLoss)
        terminationSParameters = TerminationLPolynomial(f, L0, L1, L2, L3)
        sp = []
        for n in range(len(f)):
            sspn.AssignSParameters('offset', offsetSParameters[n])
            sspn.AssignSParameters('L', terminationSParameters[n])
            sp.append(sspn.SParameters())
        SParameters.__init__(self, f, sp)
    def __init__(self,f, Rp, Rsep, Lp, Gp, Cp, dfp,
                         Rn, Rsen, Ln, Gn, Cn, dfn,
                         Cm, dfm, Gm, Lm, Z0=50., K=0, scale=1.):
        """Constructor

        ports are 1,2,3,4 is +1,-1, +2, -2

        @param f list of float frequencies
        @param Rp float DC resistance of positive leg (ohms)
        @param Rsep float skin-effect resistance of positive leg (ohms/sqrt(Hz))
        @param Lp float inductance of positive leg (H)
        @param Gp float DC conductance of positive leg to ground (S)
        @param Cp float capacitance of positive leg to ground (F)
        @param dfp float dissipation factor (loss-tangent) of capacitance of positive leg to ground
        @param Rn float DC resistance of negative leg (ohms)
        @param Rsen float skin-effect resistance of negative leg (ohms/sqrt(Hz))
        @param Ln float inductance of negative leg (H)
        @param Gn float DC conductance of negative leg to ground (S)
        @param Cn float capacitance of negative leg to ground (F)
        @param dfn float dissipation factor (loss-tangent) of capacitance of negative leg to ground
        @param Cm float mutual capacitance (F)
        @param dfm float dissipation factor (loss-tangent) of mutual capacitance (F)
        @param Gm float mutual conductance (S)
        @param Lm float mutual inductance (H)
        @param Z0 (optional) float reference impedance (defaults to 50 ohms)
        @param K (optional) integer number of sections (defaults to 0)
        @param scale (optional) float amount to scale the line by (assuming all other values are per unit)
        @note If K=0 is specified, it is modified to a value that will provided a very good numerical
        approximation.

        The calculation is such that round-trip propagation time (twice the electrical length)
        of any one small section is no more than one percent of the fastest possible risetime.
        """
        Rp=Rp*scale; Rsep=Rsep*scale; Lp=Lp*scale; Gp=Gp*scale; Cp=Cp*scale; dfp=dfp
        Rn=Rn*scale; Rsen=Rsen*scale; Ln=Ln*scale; Gn=Gn*scale; Cn=Cn*scale; dfn=dfn
        Cm=Cm*scale; dfm=dfm; Gm=Gm*scale; Lm=Lm*scale
        K=int(K*scale+0.5)
        if K==0:
            """max possible electrical length"""
            Td=math.sqrt((max(Lp,Ln)+Lm)*(max(Cp,Cn)+2*Cm))
            Rt=0.45/f[-1] # fastest risetime
            """sections such that fraction of risetime less than round trip electrical
            length of one section"""
            K=int(math.ceil(Td*2/(Rt*self.rtFraction)))

        self.m_K=K
        # pragma: silent exclude
        from SignalIntegrity.Lib.Devices import SeriesG
        from SignalIntegrity.Lib.Devices import SeriesZ
        from SignalIntegrity.Lib.Devices import TerminationG
        import SignalIntegrity.Lib.SParameters.Devices as dev
        from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        # pragma: include
        sdp=SystemDescriptionParser().AddLines([
        'device rsep 2','device rp 2','device lp 2','device gp 1','device cp 1',
        'device rsen 2','device rn 2','device ln 2','device gn 1','device cn 1',
        'device lm 4','device gm 2','device cm 2',
         'connect rp 2 rsep 1','connect rsep 2 lp 1',
         'connect rn 2 rsen 1','connect rsen 2 ln 1',
         'connect lp 2 lm 1','connect ln 2 lm 3',
         'connect lm 2 gp 1 cp 1 gm 1 cm 1','connect lm 4 gn 1 cn 1 gm 2 cm 2',
         'port 1 rp 1 2 rn 1 3 lm 2 4 lm 4'])
        self.m_sspn=SystemSParametersNumeric(sdp.SystemDescription())
        self.m_sspn.AssignSParameters('rp',SeriesZ(Rp/K,Z0))
        self.m_sspn.AssignSParameters('gp',TerminationG(Gp/K,Z0))
        self.m_sspn.AssignSParameters('rn',SeriesZ(Rn/K,Z0))
        self.m_sspn.AssignSParameters('gn',TerminationG(Gn/K,Z0))
        self.m_sspn.AssignSParameters('gm',SeriesG(Gm/K,Z0))
        self.m_spdl=[('rsep',dev.SeriesRse(f,Rsep/K,Z0)),
            ('lp',dev.SeriesL(f,Lp/K,Z0)),('cp',dev.TerminationC(f,Cp/K,Z0,dfp)),
            ('rsen',dev.SeriesRse(f,Rsen/K,Z0)),('ln',dev.SeriesL(f,Ln/K,Z0)),
            ('cn',dev.TerminationC(f,Cn/K,Z0,dfn)),('lm',dev.Mutual(f,Lm/K,Z0)),
            ('cm',dev.SeriesC(f,Cm/K,Z0,dfm))]
        SParameters.__init__(self,f,None,Z0)
Ejemplo n.º 13
0
    def __init__(self,f, wires, R, Rse, df, Cm, Gm, Lm, Z0=50., K=0, scale=1.):
        """Constructor  
        ports are 1,2,3,4, etc. on left and W, W+1, W+2, W+4, etc. on right where W=wires
        and wire 1 is port 1 to P, wire 2 is port 2 to (P+1), etc.  This is a P=2*w port device.
        @param f list of float frequencies
        @param wires integer number of wires
        @param R list of float DC resistance of wire (ohms)
        @param Rse list of float skin-effect resistance of wire (ohms/sqrt(Hz))
        @param df list of list of float dissipation factor (loss-tangent) of capacitance (unitless)
        @param C list of list of float mutual capacitance (self capacitance on diagonal) (F)
        @param G list of list of float mutual conductance (self conductance on diagonal) (S)
        @param L list of list of float mutual inductance (self inductance on diagonal) (H)
        @param Z0 (optional) float reference impedance (defaults to 50 ohms)
        @param K (optional) integer number of sections (defaults to 0)
        @param scale (optional) float amount to scale the line by (assuming all other values are per unit)
        @note If K=0 is specified, it is modified to a value that will provided a very good numerical
        approximation.  

        The calculation is such that round-trip propagation time (twice the electrical length)
        of any one small section is no more than one percent of the fastest possible risetime.
        """
        R=[r*scale for r in R]; Rse=[rse*scale for rse in Rse]; Cm=[[cm*scale for cm in cmr] for cmr in Cm];
        Gm=[[gm*scale for gm in gmr] for gmr in Gm]; Lm=[[lm*scale for lm in lmr] for lmr in Lm]
        K=int(K*scale+0.5)
        if K==0:
            maxL=0.0; maxLm=0.0
            for r in range(len(Lm)):
                for c in range(len(Lm[r])):
                    if r==c: maxL=max(maxL,Lm[r][c])
                    else: maxLm=max(maxLm,Lm[r][c])
            maxC=0.0; maxCm=0.0
            for r in range(len(Cm)):
                for c in range(len(Cm[r])):
                    if r==c: maxC=max(maxC,Cm[r][c])
                    else: maxCm=max(maxCm,Cm[r][c])
            """max possible electrical length and fastest risetime"""
            Td=math.sqrt((maxL+maxLm)*(maxC+2*maxCm)); Rt=0.45/f[-1]
            """sections such that fraction of risetime less than round trip electrical
            length of one section"""
            K=int(math.ceil(Td*2/(Rt*self.rtFraction)))
        self.m_K=K
        # build the netlist
        # pragma: silent exclude
        from SignalIntegrity.Lib.Devices import SeriesG
        from SignalIntegrity.Lib.Devices import SeriesZ
        from SignalIntegrity.Lib.Devices import TerminationG
        import SignalIntegrity.Lib.SParameters.Devices as dev
        from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
        from SignalIntegrity.Lib.Parsers.SystemDescriptionParser import SystemDescriptionParser
        # pragma: include
        # first all of the devices
        sdp=SystemDescriptionParser().AddLines(['device R_'+str(w+1)+' 2' for w in range(wires)])
        sdp.AddLines(['device Rse_'+str(w+1)+' 2' for w in range(wires)])
        sdp.AddLines(['device L_'+str(w+1)+' 2' for w in range(wires)])
        sdp.AddLines(['device G_'+str(w+1)+' 1' for w in range(wires)])
        sdp.AddLines(['device C_'+str(w+1)+' 1' for w in range(wires)])
        for w in range(wires-1):
            for o in range(w+1,wires):
                suffix='_'+str(w+1)+'_'+str(o+1)
                sdp.AddLines(['device M'+suffix+' 4','device C'+suffix+' 2','device G'+suffix+' 2'])
        sdp.AddLines(['port '+str(w+1)+' R_'+str(w+1)+' 1' for w in range(wires)])
        sdp.AddLines(['port '+str(w+wires+1)+' C_'+str(w+1)+' 1' for w in range(wires)])

        # connect all of the devices
        sdp.AddLines(['connect R_'+str(w+1)+' 2 Rse_'+str(w+1)+' 1' for w in range(wires)])
        sdp.AddLines(['connect Rse_'+str(w+1)+' 2 L_'+str(w+1)+' 1' for w in range(wires)])
        for w in range(wires):
            DeviceFromString='L_'+str(w+1)
            DeviceFromPin=2
            CapacitorConductanceConnectionString='C_'+str(w+1)+' 1 G_'+str(w+1)+' 1'
            for o in range(wires):
                if (o==w):
                    continue
                if (o>w):
                    actualFrom=w
                    actualTo=o
                    actualInputPin=1
                    nextOutputPin=2
                    CapacitorConductanceConnectionString+=' C_'+str(w+1)+'_'+str(o+1)+' 1 G_'+str(w+1)+'_'+str(o+1)+' 1'
                else:
                    actualFrom=o
                    actualTo=w
                    actualInputPin=3
                    nextOutputPin=4
                    CapacitorConductanceConnectionString+=' C_'+str(o+1)+'_'+str(w+1)+' 2 G_'+str(o+1)+'_'+str(w+1)+' 2'

                DeviceToString='M_'+str(actualFrom+1)+'_'+str(actualTo+1)
                sdp.AddLine('connect '+DeviceFromString+' '+str(DeviceFromPin)+' '+DeviceToString+' '+str(actualInputPin))
                DeviceFromString=DeviceToString
                DeviceFromPin=nextOutputPin
            # finally, connect this last device output to the capacitances and conductances
            sdp.AddLine('connect '+DeviceFromString+' '+str(DeviceFromPin)+' '+CapacitorConductanceConnectionString)
        # make the system description and assign the s-parameters
        self.m_sspn=SystemSParametersNumeric(sdp.SystemDescription())
        self.NetListLines=sdp.m_lines
        # frequency independent get assigned directly
        for w in range(wires):
            self.m_sspn.AssignSParameters('R_'+str(w+1),SeriesZ(R[w]/K,Z0))
            self.m_sspn.AssignSParameters('G_'+str(w+1),TerminationG(Gm[w][w]/K,Z0))
            for o in range(w+1,wires):
                self.m_sspn.AssignSParameters('G_'+str(w+1)+'_'+str(o+1),SeriesG(Gm[o][w]/K,Z0)) # [o][w] not [w][o] to allow lower triangular
        # now for frequency dependent ones
        self.m_spdl=[]
        for w in range(wires):
            self.m_spdl.append(('Rse_'+str(w+1),dev.SeriesRse(f,Rse[w]/K,Z0)))
            self.m_spdl.append(('C_'+str(w+1),dev.TerminationC(f,Cm[w][w]/K,Z0,df[w][w])))
            self.m_spdl.append(('L_'+str(w+1),dev.SeriesL(f,Lm[w][w]/K,Z0)))
            for o in range(w+1,wires):
                self.m_spdl.append(('M_'+str(w+1)+'_'+str(o+1),dev.Mutual(f,Lm[o][w]/K,Z0))) # see note about [o][w] order above
                self.m_spdl.append(('C_'+str(w+1)+'_'+str(o+1),dev.SeriesC(f,Cm[o][w]/K,Z0,df[o][w])))
        SParameters.__init__(self,f,None,Z0)