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)
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)
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)