Example #1
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)
    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)
Example #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)
Example #4
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)
class TLineDifferentialRLGCBalanced(SParameters):
    """s-parameters of analytic balanced differential RLGC (telegrapher's) transmission
    line."""
    def __init__(self, f, R, Rse, L, G, C, df, Cm, dfm, Gm, Lm, Z0=50., K=0):
        """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).
        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)),
            ('TO',
             TLineTwoPortRLGC(f, R, Rse, L - Lm, G + 2 * Gm, C + 2 * Cm,
                              (C * df + 2 * Cm * dfm) / (C + 2 * Cm), Z0, K))
        ]
        SParameters.__init__(self, f, None, Z0)

    def __getitem__(self, n):
        """overloads [n]
        @return list of list s-parameter matrix for the nth frequency element
        """
        for ds in self.m_spdl:
            self.m_sspn.AssignSParameters(ds[0], ds[1][n])
        return self.m_sspn.SParameters()
class TLineDifferentialRLGCUncoupled(SParameters):
    """s-parameters of analytic uncoupled differential RLGC (telegrapher's) transmission
    line."""
    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)),
                     ('TO',TLineTwoPortRLGC(f,Rn,Rsen,Ln,Gn,Cn,dfn,Z0,K))]
        SParameters.__init__(self,f,None,Z0)
    def __getitem__(self,n):
        """overloads [n]
        @return list of list s-parameter matrix for the nth frequency element
        """
        for ds in self.m_spdl:
            self.m_sspn.AssignSParameters(ds[0],ds[1][n])
        return self.m_sspn.SParameters()
    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)
Example #8
0
 def __init__(self,f,Zd,Td,Zc,Tc,Z0=50.):
     """Constructor
     The port numbering is ports 1 and 2 are the plus and minus terminals on
     one side of the line and ports 3 and 4 are the plus and minus terminals
     on the other side of the line.
 
     @param f list of float frequencies
     @param Zd float or complex differential mode impedance
     @param Td float differential (or odd-mode) electrical length (the
     differential-mode propagation time.
     @param Zc float or complex common-mode impedance
     @param Tc float common (or even-mode) electrical length (the common-mode
     propagation time.
     @param Z0 (optional) float or complex reference impedance (defaults to 50 Ohms).
     @note The differential mode impedance is twice the odd-mode impedance.\n
     The common-mode impedance is half the even-mode impedance.\n
     @note The model is appropriate for a balanced transmission line.\n
     @note The s-parameters provided are single-ended.
     @note This device builds a model internally and only solves the model
     on each access to __getitem__().
     """
     import SignalIntegrity.Lib.SParameters.Devices as dev
     from SignalIntegrity.Lib.Devices.MixedModeConverter import MixedModeConverter
     from SignalIntegrity.Lib.SystemDescriptions.SystemSParametersNumeric import SystemSParametersNumeric
     self.m_sspn=SystemSParametersNumeric()
     self.m_spdl=[]
     self.m_sspn.AddDevice('MM1',4,MixedModeConverter())
     self.m_sspn.AddDevice('MM2',4,MixedModeConverter())
     self.m_sspn.AddDevice('D',2), self.m_spdl.append(('D',dev.TLineLossless(f,2,Zd/2.,Td,Z0)))
     self.m_sspn.AddDevice('C',2), self.m_spdl.append(('C',dev.TLineLossless(f,2,Zc*2.,Tc,Z0)))
     self.m_sspn.ConnectDevicePort('MM1',3,'D',1)
     self.m_sspn.ConnectDevicePort('MM2',3,'D',2)
     self.m_sspn.ConnectDevicePort('MM1',4,'C',1)
     self.m_sspn.ConnectDevicePort('MM2',4,'C',2)
     self.m_sspn.AddPort('MM1',1,1)
     self.m_sspn.AddPort('MM1',2,2)
     self.m_sspn.AddPort('MM2',1,3)
     self.m_sspn.AddPort('MM2',2,4)
     SParameters.__init__(self,f,None,Z0)
Example #9
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 SParameters(self, solvetype='block'):
     """compute the s-parameters of the netlist.
     @param solvetype (optional) string how to solve it. (defaults to 'block').
     @return instance of class SParameters as the solution of the network.
     @remark valid solvetype strings are:
     - 'block' - use the block matrix solution method.
     - 'direct' - use the direct method.
     'block' is faster and preferred, but direct is provided as an alternative and
     for testing. (Previously, instances were found where the block method failed,
     but the direct method did not - but this possibility is thought to be impossible
     now.
     """
     # pragma: silent exclude
     if self.CheckCache():
         self.CallBack(100.0)
         return self.sf
     # pragma: include
     self.SystemDescription()
     self.m_sd.CheckConnections()
     spc = self.m_spc
     result = []
     for n in range(len(self.m_f)):
         for d in range(len(spc)):
             if not spc[d][0] is None:
                 self.m_sd.AssignSParameters(spc[d][0], spc[d][1][n])
         result.append(
             SystemSParametersNumeric(
                 self.m_sd).SParameters(solvetype=solvetype))
         # pragma: silent exclude
         if self.HasACallBack():
             progress = self.m_f[n] / self.m_f[-1] * 100.0
             if not self.CallBack(progress):
                 raise SignalIntegrityExceptionSParameters(
                     'calculation aborted')
         # pragma: include
     self.sf = SParameters(self.m_f, result)
     # pragma: silent exclude
     if hasattr(self, 'delayDict'):
         td = [
             self.delayDict[p + 1] if p + 1 in self.delayDict else 0.0
             for p in range(self.sf.m_P)
         ]
         self.sf = PeeledLaunches(self.sf, td, method='exact')
     self.sf = SParametersParser(self.sf, self.m_ul)
     self.CacheResult()
     # pragma: include
     return self.sf
Example #11
0
    def DutUnCalculationAlternate(self,S,portList=None):
        """Un-calcualates the DUT.\n
        This calculates the expected raw measured DUT based on the DUT actually calculated.\n
        @see DutCalculation
        @param S instance of class SParameters of measured DUT from these error-terms.
        @param portList (optional) list of zero based port numbers used for the DUT calcualtion
        @return instance of class SParameters of the raw measured s-parameters that calculated this DUT
        @remark If the portList is None, then it assumed to be a list [0,1,2,P-1] where P is the
        number of ports in sRaw, otherwise ports can be specified where the DUT is connected.
        @deprecated This method utilizes fixtures and embeds them.  Originally, I could not figure out
        how to do this with just the error-terms.  This was figured out finally and is more efficient, but
        this method is retained for comparison of results.
        @see DutUnCalculation
        """
        self.CalculateErrorTerms()
        if portList is None: portList=[p for p in range(self.ports)]
        ports=len(portList)

        sspn=SystemSParametersNumeric()
        sspn.AddDevice('F',2*ports)
        sspn.AddDevice('D',ports)
        for p in range(ports):
            sspn.AddPort('F',p+1,p+1)
            sspn.ConnectDevicePort('F',ports+p+1,'D',p+1)

        rd=[None for n in range(len(self.f))]
        fixtureList=self.Fixtures(portList)
        for n in range(len(self.f)):
            rm=[[None for c in range(ports)] for r in range(ports)]
            sspn.AssignSParameters('D',S[n])
            for p in range(ports):
                sspn.AssignSParameters('F',fixtureList[p][n])
                spp=sspn.SParameters()
                for r in range(ports):
                    rm[r][p]=spp[r][p]
            rd[n]=rm
        return SParameters(self.f,rd)
    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)
class TLineDifferentialRLGCApproximate(SParameters):
    """s-parameters of differential RLGC (telegrapher's) transmission line
    calculated by approximating distributed parameters with a finite number
    of sections specified."""
    rtFraction = .01

    def __init__(self,
                 f,
                 Rp,
                 Rsep,
                 Lp,
                 Gp,
                 Cp,
                 dfp,
                 Rn,
                 Rsen,
                 Ln,
                 Gn,
                 Cn,
                 dfn,
                 Cm,
                 dfm,
                 Gm,
                 Lm,
                 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 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)
        @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.
        """
        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)

    def __getitem__(self, n):
        """overloads [n]
        @return list of list s-parameter matrix for the nth frequency element
        """
        for ds in self.m_spdl:
            self.m_sspn.AssignSParameters(ds[0], ds[1][n])
        sp = self.m_sspn.SParameters()
        if sp == 1: return sp
        lp = [1, 2]
        rp = [3, 4]
        return T2S(linalg.matrix_power(S2T(sp, lp, rp), self.m_K), lp, rp)
class TLineTwoPortRLGCApproximate(SParameters):
    """s-parameters of two port RLGC (telegrapher's) transmission line
    calculated by approximating distributed parameters with a finite number
    of sections specified."""
    rtFraction = .01

    def __init__(self, f, R, Rse, L, G, C, df, Z0=50., K=0):
        """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)
        @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.
        """
        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)

    def __getitem__(self, n):
        """overloads [n]
        @return list of list s-parameter matrix for the nth frequency element
        """
        # pragma: silent exclude
        from numpy import linalg
        from SignalIntegrity.Lib.Conversions import S2T
        from SignalIntegrity.Lib.Conversions import T2S
        # pragma: include
        for ds in self.m_spdl:
            self.m_sspn.AssignSParameters(ds[0], ds[1][n])
        sp = self.m_sspn.SParameters()
        return T2S(linalg.matrix_power(S2T(sp), self.m_K))
Example #15
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)