def __init__(self, label="", sigma=1): super().__init__(label=label) self.sym_sigma = sym.Symbol(f"sigma_{self.label}", real=True) self.values = sigma self.set_Z(sigma=self.sym_sigma) self.schem = schem.Drawing(**style) self.schem.add(schem.elements.RBOX, d='right', label=self.description)
def nparalel(el, n, d, lbl): nr = n//2 nl = n - nr # right part dr = schemdraw.Drawing() dr.push() for i in range(nr): dr.add(elm.Line(d="right")) dr.push() dr.add(el(d="right", rgtlabel=lbl[i+nl])) #dr.add(elm.Dot(color="black")) dr.add(elm.Line(d="left")) dr.pop() dr.pop() for i in range(nl): if n > 1: dr.add(elm.Line(d="left")) dr.push() dr.add(el(d="right", rgtlabel=lbl[nl-1-i])) #dr.add(elm.Dot(color="black")) if n > 1: dr.add(elm.Line(d="right")) if i == 0: xy=dr.here dr.pop() d.add(elm.ElementDrawing(dr)) return d, xy
def __init__(self, label="", C=1e-3): super().__init__(label=label) self.sym_C = sym.Symbol(f"C_{self.label}", real=True) self.values = C self.set_Z(A=1 / self.sym_C, n=1) self.schem = schem.Drawing(**style) self.schem.add(schem.elements.CAP, d='right', label=self.description)
def __init__(self, label="", R=10): super().__init__(label=label) self.sym_R = sym.Symbol(f"R_{self.label}", real=True) self.values = R self.set_Z(A=self.sym_R) self.schem = schem.Drawing(**style) self.schem.add(schem.elements.RES, d='right', label=self.description)
def __init__(self, label="", Q=1e-3, n=0.9): super().__init__(label=label) self.sym_Q = sym.Symbol(f"Q_{self.label}", real=True) self.sym_n = sym.Symbol(f"n_{self.label}", real=True) self.values = (Q, n) self.set_Z(A=1 / self.sym_Q, n=self.sym_n) self.schem = schem.Drawing(**style) self.schem.add(schem.elements.CAP, d='right', label=self.description)
def __init__(self): wx.Frame.__init__(self, None) p = wx.Panel(self) fgs = wx.FlexGridSizer(cols=1) d = schemdraw.Drawing() d.add(elm.Resistor()) d.add(elm.SourceV()) data = d.get_imagedata('png') stream = BytesIO(data) img = wx.ImageFromStream(stream) sb = wx.StaticBitmap(p, -1, wx.BitmapFromImage(img)) fgs.Add(sb) p.SetSizerAndFit(fgs) self.Fit()
def __init__(self): QWidget.__init__(self) self.layout = QGridLayout(self) # # self.imgwidget = QLabel(self) # Plot RC filter rc = schemdraw.Drawing() rc.add(elm.Resistor(d='right', label='R', lftlabel='In', rgtlabel='Out')) rc.add(elm.Capacitor(d='down', label='C')) rc.add(elm.Ground(d='right')) rc.draw(show=False) rccanvas = FigureCanvas(rc.draw(show=False).getfig()) self.layout.addWidget(rccanvas,0,0,2,1) self.layout.setMargin(0) self.layout.setSpacing(0) self.InputWidget=Opreator() self.layout.addWidget(self.InputWidget)
def Save_Schematic(circuit, voltages, currents, file_name): d = schemdraw.Drawing() elements = {} elements["0"] = d.add(elm.Ground) drawn = [] directions = ["up", "right", "down", "left"] direc = 0 for key, node in circuit.nodes.items(): if key != "0": for i, branch in enumerate(node.branches): if branch not in drawn: pos, neg = branch.pos_node, branch.neg_node el = None i = int(key) - 1 if branch.element_type == "R": el = elm.Resistor(directions[direc], lblofst = 1, label="Ω={z.real:+0.02f} {z.imag:+0.02f}j\nV={v.real:+0.02f} {v.imag:+0.02f}j" .format(z=branch.impedance, v=voltages[i]), to = elements[neg].start if neg in elements else None) else: el = elm.SourceV(label="V = {}".format(str(branch.voltage))) d.add(el) other_node = neg if key == pos else pos new_node = None if key not in elements: new_node = key elif other_node not in elements: new_node = other_node if new_node is not None: label = "Node {}\nI=".format(new_node) c = currents[int(new_node) - 1] label += "{c.real:+0.02f} {c.imag:+0.02f}j".format(c=c) if isinstance(c, complex) else "V-source" if directions[direc] in ("up", "bottom"): elements[new_node] = d.add(elm.Dot(lblofst = 1, lftlabel=label)) else: elements[new_node] = d.add(elm.Dot(lblofst = 1, botlabel=label)) if neg == "0" and i == len(node.branches) - 1: d.add(elm.Ground) drawn.append(branch) direc = (direc + 1) % 4 #d.draw() d.save('schematics/{}.png'.format(file_name.split("\\")[-1]))
def DrawNE555(self): d = schemdraw.Drawing() IC555def = elm.Ic(pins=[ elm.IcPin(name='TRG', side='left', pin='2'), elm.IcPin(name='THR', side='left', pin='6'), elm.IcPin(name='DIS', side='left', pin='7'), elm.IcPin(name='CTL', side='right', pin='5'), elm.IcPin(name='OUT', side='right', pin='3'), elm.IcPin(name='RST', side='top', pin='4'), elm.IcPin(name='Vcc', side='top', pin='8'), elm.IcPin(name='GND', side='bot', pin='1'), ], edgepadW=.5, edgepadH=1, pinspacing=2, leadlen=1, label='555') T = d.add(IC555def) BOT = d.add(elm.Ground(xy=T.GND)) d.add(elm.Dot) d.add(elm.Resistor(endpts=[T.DIS, T.THR], label='Rb')) d.add(elm.Resistor('u', xy=T.DIS, label='Ra', rgtlabel='+Vcc')) d.add(elm.Line(endpts=[T.THR, T.TRG])) d.add( elm.Capacitor('d', xy=T.TRG, toy=BOT.start, label='C', l=d.unit / 2)) d.add(elm.Line('r', tox=BOT.start)) d.add(elm.Capacitor('d', xy=T.CTL, toy=BOT.start, botlabel='.01$\mu$F')) d.add(elm.Dot(xy=T.DIS)) d.add(elm.Dot(xy=T.THR)) d.add(elm.Dot(xy=T.TRG)) d.add(elm.Line(endpts=[T.RST, T.Vcc])) d.add(elm.Dot) d.add(elm.Line('u', l=d.unit / 4, rgtlabel='+Vcc')) d.add(elm.Resistor('r', xy=T.OUT, label='330')) d.add(elm.LED(flip=True, d='down', toy=BOT.start)) d.add(elm.Line('l', tox=BOT.start)) return FigureCanvas(d.draw(show=False).getfig())
def add_Z(self, circuit_1, circuit_2): # Update Z self.Z = circuit_1.Z + circuit_2.Z # Update description self.description = circuit_1.description self.description += " + " self.description += circuit_2.description # Update schem schem_1 = schem.elements.ElementDrawing(circuit_1.schem) schem_2 = schem.elements.ElementDrawing(circuit_2.schem) self.schem = schem.Drawing(**style) self.schem.add(schem_1) self.schem.add(schem.elements.LINE, d='right', l=schem_unit / 2) self.schem.add(schem_2) self.schem_height = np.max( [circuit_1.schem_height, circuit_2.schem_height]) self.schem_width = circuit_1.schem_width + circuit_2.schem_width
def __init__(self,app): # App configs: self._app = app # Init the panel: wx.Panel.__init__(self, app.frame_main.tabs) # Add a dummy text label: box = wx.BoxSizer(wx.VERTICAL) lbl = wx.StaticText(self,-1,style = wx.ALIGN_CENTER) lbl.SetLabel("This tab\n is for\n setup of the\n DUT limits\n and connections\n and optional temperature setting.\n\n\n BUTTON to load DUT config file") box.Add(lbl,0,wx.ALIGN_CENTER) # Add a dummy circuit / symbol: self._circuit = schemdraw.Drawing() self._circuit.draw(backend='svg') self._circuit += elm.Resistor().label('100KΩ') logging.debug('Need to figure out how to add the circuit symobol to the wx panel...')
def div_Z(self, circuit_1, circuit_2): # Update Z self.Z = 1 / (1 / circuit_1.Z + 1 / circuit_2.Z) # Update description def format(circuit): if type(circuit).__name__ == "Circuit": text = f"({circuit.description})" else: text = f"{circuit.description}" return text self.description = format(circuit_1) self.description += " / " self.description += format(circuit_2) # Update schem schem_1 = schem.elements.ElementDrawing(circuit_1.schem) schem_2 = schem.elements.ElementDrawing(circuit_2.schem) self.schem = schem.Drawing(**style) self.schem.push() c1 = self.schem.add(schem_1) self.schem.pop() self.schem.add(schem.elements.LINE) self.schem.add(schem_2) if circuit_1.schem_width <= circuit_2.schem_width: c2 = self.schem.add(schem.elements.LINE) self.schem.add(schem.elements.LINE, d='right') # xy=c1.at(), tox=c2) else: self.schem.add(schem.elements.LINE) self.schem.add(schem.elements.LINE) self.schem_width = np.max( [circuit_1.schem_width, circuit_2.schem_width]) self.schem_height = circuit_1.schem_height + circuit_2.schem_height
super().__init__(*args, **kwargs) self.segments.append((SegmentCircle([0,0],radius = 0.04,fill=False))) class fullcircle(elm.Element): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.segments.append((SegmentCircle([0, 0], radius = 0.04, fill=True))) class srccircle(elm.Element): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.segments.append((SegmentCircle([0,0],radius = 0.04,fill=False))) self.segments.append((Segment([[0.068,0.068],[-0.068,-0.068]]))) d = schemdraw.Drawing() ########### LEFT PART ###################### M5a = d.add(pmos( lftlabel = 'M5a', color = 'black')) l54a = d.add(smallseg('right', at = M5a.drain)) smallseg1 = d.add(smallseg('left',at = [0,0.13])) M4a = d.add(pmos('right', at = l54a.end, lftlabel = 'M4a', color = 'black')) vcascp1 = d.add(srccircle(at = M4a.gate, rgtlabel='$V_{cascp}$', color = 'black')) l43a = d.add(elm.Line('down', at = M4a.drain)) d.add(fullcircle(at = l43a.center)) vout1 = d.add(smallseg('down', at = l43a.center)) voutp = d.add(blankcircle(at = [-0.543,-3],rgtlabel='Vout+'))
def DirectCoupled_C_Coupled_ShuntResonators(gi, RS, RL, f0, BW, Lres, fstart, fstop, npoints): Nres = len(gi) - 2 # Number of resonators bw = BW / f0 # Calculation of w1, w2, w - 8.11-1 (15) f1 = f0 - BW / 2 f2 = f0 + BW / 2 w1 = 2 * np.pi * f1 w2 = 2 * np.pi * f2 w0 = np.sqrt(w1 * w2) w = (w2 - w1) / w0 # Calculation of GA and GB GA = 1 / RS GB = 1 / RL # Draw circuit schem.use('svg') d = schem.Drawing(inches_per_unit=0.3) _fontsize = 8 # Network rf.stylely() freq = rf.Frequency(start=fstart, stop=fstop, npoints=npoints, unit='MHz') line = rf.media.DefinedGammaZ0(frequency=freq) # Component counter count_C = 0 count_L = 0 count_gnd = 0 params = {} params['Xres'] = Lres params['gi'] = gi params['N'] = Nres params['ZS'] = RS params['ZL'] = RL params['f1'] = f1 params['f2'] = f2 Cseries, Lres, Cres = synthesize_DC_Filter_C_Coupled_Shunt_Resonators( params) # Source port # Drawing: Source port and the first line d += elm.Line(color='white').length(2).linewidth(0) d += elm.Dot().label('ZS = ' + str(RS) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line().length(1).linewidth(1) # Network: Port 1 connections = [] # Network connections L = [] C = [] ground = [] Port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=RS) # First coupling capacitor # Drawing d += elm.Capacitor().right().label(getUnitsWithScale( Cseries[0], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Line().right().length(1).linewidth(1) # Network count_C += 1 C.append(line.capacitor(Cseries[0], name='C' + str(count_C))) connections.append([(Port1, 0), (C[0], 0)]) for i in range(0, Nres): # Resonator # Drawing d.push() d += elm.Line().down().length(1).linewidth(1) d.push() d += elm.Line().left().length(1.5).linewidth(1) d += elm.Capacitor().down().label(getUnitsWithScale( Cres[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) d.pop() d += elm.Line().right().length(1.5).linewidth(1) d += elm.Inductor2(loops=2).down().label( getUnitsWithScale(Lres[i], 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) # Network count_C += 1 C.append(line.capacitor(Cres[i], name='C' + str(count_C))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) count_L += 1 L.append(line.inductor(Lres[i], name='L' + str(count_L))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) # Next coupling capacitor # Drawing d.pop() d += elm.Line().right().length(1.5).linewidth(1) d += elm.Capacitor().right().label(getUnitsWithScale( Cseries[i + 1], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Line().right().length(1.5).linewidth(1) # Network count_C += 1 C.append(line.capacitor(Cseries[i + 1], name='C' + str(count_C))) # Connections connections.append([(C[2 * i], 1), (C[2 * i + 1], 0), (C[2 * i + 2], 0), (L[i], 0)]) connections.append([(C[2 * i + 1], 1), (ground[2 * i], 0)]) connections.append([(L[i], 1), (ground[2 * i + 1], 0)]) # Drawing d += elm.Dot().label('ZL = ' + str(float("{:.2f}".format(RL))) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line(color='white').length(2).linewidth(0) # Network Port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=RL) # Connections connections.append([(C[-1], 1), (Port2, 0)]) return d, connections
def DirectCoupled_C_Coupled_SeriesResonators(params, port_match): gi = params['gi'] f1 = params['f1'] f2 = params['f2'] fstart = params['f_start'] fstop = params['f_stop'] npoints = params['n_points'] RS = params['ZS'] RL = params['ZL'] Nres = len(gi) - 2 # Number of resonators w1 = 2 * np.pi * f1 w2 = 2 * np.pi * f2 w0 = np.sqrt(w1 * w2) w = (w2 - w1) / w0 # Draw circuit schem.use('svg') d = schem.Drawing(inches_per_unit=0.3) _fontsize = 8 # Network rf.stylely() freq = rf.Frequency(start=fstart, stop=fstop, npoints=npoints, unit='MHz') line = rf.media.DefinedGammaZ0(frequency=freq) # Component counter count_C = 0 count_L = 0 count_gnd = 0 syn_params = {} syn_params['gi'] = params['gi'] syn_params['N'] = params['N'] syn_params['ZS'] = params['ZS'] syn_params['ZL'] = params['ZL'] syn_params['f1'] = float(params['f1']) * 1e6 syn_params['f2'] = float(params['f2']) * 1e6 syn_params['Xres'] = [float(i) * 1e-9 for i in params['Xres']] # Resonator inductance Match_source, Match_load, Cinv, Lres, Cres = synthesize_DC_Filter_C_Coupled_Series_Resonators( syn_params) # Source port # Drawing: Source port and the first line d += elm.Line(color='white').length(2).linewidth(0) d += elm.Dot().label('ZS = ' + str(RS) + " \u03A9", fontsize=_fontsize, loc='bottom').linewidth(1) d += elm.Line().length(1).linewidth(1) # Network: Port 1 connections = [] # Network connections L = [] C = [] ground = [] Port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=RS) # First coupling if (port_match[0] == 'C'): # Drawing d += elm.Capacitor().right().label(getUnitsWithScale( Match_source, 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Line().right().length(1).linewidth(1) # Network C.append(line.capacitor(Match_source, name='C' + str(count_C))) connections.append([(Port1, 0), (C[0], 0)]) else: # Drawing d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(Match_source, 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Line().right().length(1).linewidth(1) # Network L.append(line.inductor(Match_source, name='L' + str(count_L))) connections.append([(Port1, 0), (L[0], 0)]) for i in range(0, Nres): # Resonator # Drawing d.push() d += elm.Capacitor().down().label(getUnitsWithScale( Cinv[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) # Network count_C += 1 C.append(line.capacitor(Cinv[i], name='C' + str(count_C))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) d.pop() d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(Lres[i], 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Capacitor().right().label(getUnitsWithScale( Cres[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) count_L += 1 L.append(line.inductor(Lres[i], name='L' + str(count_L))) count_C += 1 C.append(line.capacitor(Cres[i], name='C' + str(count_C))) # Connections if (port_match[0] == 'C'): connections.append([(C[2 * i], 1), (C[2 * i + 1], 0), (L[i], 0)]) connections.append([(L[i], 1), (C[2 * i + 2], 0)]) connections.append([(C[2 * i + 1], 1), (ground[i], 0)]) else: # There's one inductance too much and one capacitor too few if (i == 0): # The first element must connect to the inductor connections.append([(L[0], 1), (C[2 * i], 0), (L[i + 1], 0)]) else: connections.append([(C[2 * i - 1], 1), (C[2 * i], 0), (L[i + 1], 0)]) connections.append([(L[i + 1], 1), (C[2 * i + 1], 0)]) connections.append([(C[2 * i], 1), (ground[i], 0)]) # Drawing d.push() d += elm.Capacitor().down().label(getUnitsWithScale( Cinv[-1], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) count_C += 1 C.append(line.capacitor(Cinv[-1], name='C' + str(count_C))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) d.pop() if (port_match[1] == 'C'): d += elm.Capacitor().right().label(getUnitsWithScale( Match_load, 'Capacitance'), fontsize=_fontsize).linewidth(1) count_C += 1 C.append(line.capacitor(Match_load, name='C' + str(count_C))) else: d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(Match_load, 'Inductance'), fontsize=_fontsize).linewidth(1) count_L += 1 L.append(line.capacitor(Match_load, name='L' + str(count_L))) # Load port # Drawing d += elm.Line().length(1).linewidth(1) d += elm.Dot().label('ZL = ' + str(float("{:.2f}".format(RL))) + " \u03A9", fontsize=_fontsize, loc='bottom').linewidth(1) d += elm.Line(color='white').length(2).linewidth(0) # Network Port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=RL) # Connections if (port_match[1] == 'C'): connections.append([(C[-3], 1), (C[-2], 0), (C[-1], 0)]) connections.append([(C[-2], 1), (ground[-1], 0)]) connections.append([(C[-1], 1), (Port2, 0)]) else: connections.append([(C[-2], 1), (C[-1], 0), (L[-1], 0)]) connections.append([(C[-1], 1), (ground[-1], 0)]) connections.append([(L[-1], 1), (Port2, 0)]) return d, connections
def DirectCoupled_L_Coupled_SeriesResonators(params): gi = params['gi'] RS = params['ZS'] RL = params['ZL'] f1 = params['f1'] f2 = params['f2'] f0 = params['fc'] Magnetic_Coupling = params['Magnetic_Coupling'] fstart = params['f_start'] fstop = params['f_stop'] npoints = params['n_points'] w0 = 2 * np.pi * f0 * 1e6 Nres = len(gi) - 2 # Number of resonators # Draw circuit schem.use('svg') d = schem.Drawing(inches_per_unit=0.3) _fontsize = 8 # Network rf.stylely() freq = rf.Frequency(start=fstart, stop=fstop, npoints=npoints, unit='MHz') line = rf.media.DefinedGammaZ0(frequency=freq) # Component counter count_C = 0 count_L = 0 count_gnd = 0 params['f1'] = params['f1'] * 1e6 params['f2'] = params['f2'] * 1e6 M, Lseries, Cres = synthesize_DC_Filter_L_Coupled_Series_Resonators(params) if (Magnetic_Coupling == 0): # Source port # Drawing: Source port and the first line d += elm.Dot().label('ZS = ' + str(RS) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line().length(1).linewidth(1) # Network: Port 1 connections = [] # Network connections L = [] C = [] ground = [] Port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=RS) # First coupling inductor # Drawing d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(Lseries[0], 'Inductance'), fontsize=_fontsize).linewidth(1) # Network count_L += 1 L.append(line.inductor(Lseries[0], name='L' + str(count_L))) connections.append([(Port1, 0), (L[0], 0)]) for i in range(0, Nres + 1): d.push() # Coupling # Drawing d += elm.Inductor2(loops=2).down().label( getUnitsWithScale(M[i], 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) #Network count_L += 1 L.append(line.inductor(M[i], name='L' + str(count_L))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) d.pop() # Series resonator d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(Lseries[i + 1], 'Inductance'), fontsize=_fontsize).linewidth(1) count_L += 1 L.append(line.inductor(Lseries[i + 1], name='L' + str(count_L))) if (i < Nres): d += elm.Capacitor().right().label( getUnitsWithScale(Cres[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) count_C += 1 C.append(line.capacitor(Cres[i], name='C' + str(count_C))) # Connections if (i == 0): # Then, connect to the first inductor connections.append([(L[0], 1), (L[1], 0), (L[2], 0)]) connections.append([(L[1], 1), (ground[i], 0)]) connections.append([(L[2], 1), (C[i], 0)]) else: # Then, connect to the previous capacitor connections.append([(C[i - 1], 1), (L[2 * i + 1], 0), (L[2 * i + 2], 0)]) connections.append([(L[2 * i + 1], 1), (ground[i], 0)]) if (i < Nres): # The last iteration is the coupling for the load port connections.append([(L[2 * i + 2], 1), (C[i], 0)]) # Drawing d += elm.Line().length(1).linewidth(1) d += elm.Dot().label('ZL = ' + str(float("{:.2f}".format(RL))) + " \u03A9", fontsize=_fontsize).linewidth(1) # Network Port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=RL) # Connections connections.append([(L[-1], 1), (Port2, 0)]) else: # Magnetic coupling Lp = Lseries # Source port # Drawing: Source port and the first line d += elm.Line(color='white').length(2).linewidth(0) d += elm.Dot().label('ZS = ' + str(RS) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line().length(2).linewidth(1) # Network: Port 1 connections = [] # Network connections L = [] C = [] ground = [] count_L = 0 count_C = 0 count_gnd = 0 Port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=RS) for i in range(0, Nres): x = d.add( elm.Transformer( t1=4, t2=4, loop=True, core=True, fontsize=_fontsize).label( getUnitsWithScale(Lp[i], 'Inductance'), loc='left').label( getUnitsWithScale(Lp[i + 1], 'Inductance'), loc='right').label("k = " + str( round(M[i] / np.sqrt(Lp[i] * Lp[i + 1]), 3)), loc='top').flip()) d += elm.Ground().at(x.p1).linewidth(1) d += elm.Ground().at(x.s1).linewidth(1) d += elm.Line().at(x.s2).length(1) d += elm.Capacitor().right().label(getUnitsWithScale( Cres[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Line().length(1) # Network: The transformer is simulated using the uncoupled lumped equivalen (Zverev, Fig. 10.4 (c)) count_L += 1 L.append(line.inductor(Lp[i] - M[i], name='L' + str(count_L))) count_L += 1 L.append(line.inductor(M[i], name='L' + str(count_L))) count_L += 1 L.append(line.inductor(Lp[i + 1] - M[i], name='L' + str(count_L))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) count_C += 1 C.append(line.capacitor(Cres[i], name='C' + str(count_C))) print("L[" + str(3 * i) + "] = ", getUnitsWithScale(Lp[i] - M[i], 'Inductance')) print("L[" + str(3 * i + 1) + "] = ", getUnitsWithScale(M[i], 'Inductance')) print("L[" + str(3 * i + 2) + "] = ", getUnitsWithScale(Lp[i + 1] - M[i], 'Inductance')) print("C[" + str(i) + "] = ", getUnitsWithScale(Cres[i], 'Capacitance')) # Connections if (i == 0): # Connect the first inductor to the source port connections.append([(Port1, 0), (L[0], 0)]) else: # Connect the first inductor to the previous capacitor connections.append([(C[i - 1], 1), (L[3 * i], 0)]) connections.append([(L[3 * i], 1), (L[3 * i + 1], 0), (L[3 * i + 2], 0)]) connections.append([(L[3 * i + 1], 1), (ground[i], 0)]) connections.append([(L[3 * i + 2], 1), (C[i], 0)]) x = d.add( elm.Transformer( t1=4, t2=4, loop=True, core=True, fontsize=_fontsize).label( getUnitsWithScale(Lp[-2], 'Inductance'), loc='left').label( getUnitsWithScale(Lp[-1], 'Inductance'), loc='right').label( "k = " + str(round(M[-1] / np.sqrt(Lp[-2] * Lp[-1]), 3)), loc='top').flip()) d += elm.Ground().at(x.p1).linewidth(1) d += elm.Ground().at(x.s1).linewidth(1) # Network: The transformer is simulated using the uncoupled lumped equivalen (Zverev, Fig. 10.4 (c)) count_L += 1 L.append(line.inductor(Lp[-2] - M[-1], name='L' + str(count_L))) count_L += 1 L.append(line.inductor(M[-1], name='L' + str(count_L))) count_L += 1 L.append(line.inductor(Lp[-1] - M[-1], name='L' + str(count_L))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) print("L[" + str(3 * Nres) + "] = ", getUnitsWithScale(Lp[-2] - M[-1], 'Inductance')) print("L[" + str(3 * Nres + 1) + "] = ", getUnitsWithScale(M[-1], 'Inductance')) print("L[" + str(3 * Nres + 2) + "] = ", getUnitsWithScale(Lp[-1] - M[-1], 'Inductance')) # Load port d += elm.Line().at(x.s2).length(2).linewidth(1) d += elm.Dot().label('ZL = ' + str(RL) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line(color='white').length(2).linewidth(0) Port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=RL) # Connections connections.append([(C[-1], 1), (L[-3], 0)]) connections.append([(L[-3], 1), (L[-2], 0), (L[-1], 0)]) connections.append([(L[-2], 1), (ground[-1], 0)]) connections.append([(L[-1], 1), (Port2, 0)]) return d, connections
def DirectCoupled_QW_Coupled_ShuntResonators(gi, RS, RL, f0, BW, fstart, fstop, npoints): Nres = len(gi) - 2 # Number of resonators params = {} params['gi'] = gi params['N'] = Nres params['ZS'] = RS params['ZL'] = RL params['f1'] = f0 - BW / 2 params['f2'] = f0 + BW / 2 RS, RL, qw, Lres, Cres = synthesize_DC_Filter_QW_Shunt_Resonators(params) # Draw circuit schem.use('svg') d = schem.Drawing() _fontsize = 12 # Network rf.stylely() freq = rf.Frequency(start=fstart, stop=fstop, npoints=npoints, unit='MHz') line = rf.media.DefinedGammaZ0(frequency=freq) # Component counter count_C = 0 count_L = 0 count_TL = 0 count_gnd = 0 # Source port # Drawing: Source port and the first line d += elm.Dot().label('ZS = ' + str(RS) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line().length(1).linewidth(1) # Network: Port 1 connections = [] # Network connections L = [] C = [] TL = [] ground = [] Port1 = rf.Circuit.Port(frequency=freq, name='port1', z0=RS) # Quarter wavelength line beta = freq.w / rf.c Z0_line = rf.media.DefinedGammaZ0(frequency=freq, Z0=RS, gamma=0 + beta * 1j) d += elm.Line().right().length(1).linewidth(1) for i in range(0, Nres): # Resonator # Drawing d.push() d += elm.Line().down().length(1).linewidth(1) d.push() d += elm.Line().left().length(1).linewidth(1) d += elm.Capacitor().down().label(getUnitsWithScale( Cres[i], 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) d.pop() d += elm.Line().right().length(1).linewidth(1) d += elm.Inductor2(loops=2).down().label(getUnitsWithScale( Lres[i], 'Inductance'), fontsize=_fontsize, loc='bottom').linewidth(1) d += elm.Ground().linewidth(1) # Network count_C += 1 C.append(line.capacitor(Cres[i], name='C' + str(count_C))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) count_L += 1 L.append(line.inductor(Lres[i], name='L' + str(count_L))) count_gnd += 1 ground.append( rf.Circuit.Ground(frequency=freq, name='ground' + str(count_gnd), z0=RS)) # Coupling line # Drawing d.pop() d += elm.Line().right().length(2).linewidth(1) d += TransmissionLine().right().label( "l = " + getUnitsWithScale(qw, 'Distance'), fontsize=_fontsize, loc='bottom').label("Z\u2080 = " + str(RS) + " \u03A9 ", loc='top').linewidth(1) d += elm.Line().right().length(2).linewidth(1) count_TL += 1 TL.append( Z0_line.line(Z0_line.theta_2_d(90, deg=True), unit='m', name='TL' + str(count_TL))) if (i == 0): # Connect to the source port connections.append([(Port1, 0), (L[0], 0), (C[0], 0), (TL[0], 0)]) else: # Connect to the previous TL connections.append([(TL[i - 1], 1), (L[i], 0), (C[i], 0), (TL[i], 0)]) connections.append([(C[i], 1), (ground[2 * i], 0)]) connections.append([(L[i], 1), (ground[2 * i + 1], 0)]) # Load port # Drawing d += elm.Dot().label('ZL = ' + str(float("{:.2f}".format(RL))) + " \u03A9", fontsize=_fontsize).linewidth(1) # Network Port2 = rf.Circuit.Port(frequency=freq, name='port2', z0=RL) # Connections connections.append([(Port2, 0), (TL[-1], 1)]) return d, connections
def draw(l,port="z11",rs=0,rl=oo): #example #l=[{type:"r",label:2,dirrection:"right",parallel:False]},{type:"l",label:100,dirrection:"down",parallel:True},{type:"c",label:56,dirrection:"right",parallel:True}] with plt.xkcd(): d ,F= schemdraw.Drawing(inches_per_unit=.5),0 if port=='z11': a0=d.add(elm.Resistor(d='right', label=str(rs)+'$\Omega$',color="red")) if port=='y22': a0=d.add(elm.Resistor(d='up', label=str(rl)+'$\Omega$',color="red")) d.add(elm.Line(d="right")) for q in l: try: if q["label"]==int(q["label"]): q["label"]=int(q["label"]) except: pass if q["dirrection"]=="down" and q["parallel"]: F=F+1 if F<2: d.add(elm.Line(d='right')) d.push() elif q["dirrection"]=="down": d.push() elif q["parallel"] : F=F+1 if F<2: d.push() if q["type"]=="r": d.add(elm.Resistor(d=q["dirrection"], label=str(q["label"])+'$\Omega$')) elif q["type"]=="l": d.add(elm.Inductor(d=q["dirrection"], label=str(q["label"])+"H")) elif q["type"]=="c": d.add(elm.Capacitor(d=q["dirrection"], label=str(q["label"])+'$\mu$F')) elif q["type"]=="w": d.add(elm.Line(d=q["dirrection"])) if q["dirrection"]=="down" and q["parallel"]: if F<2: pass else: d.pop() F=0 elif q["dirrection"]=="right" and q["parallel"]: if F<2: d.pop() d.add(elm.Line(d='down')) else: d.add(elm.Line(d='up')) F=0 elif q["dirrection"]=="down": d.add(elm.Line(d='down')) d.pop() d.add(elm.Line(d='right')) if port=='z11': d.add(elm.Resistor(d='down', label=str(rl)+'$\Omega$',color="red")) d.add(elm.Line(d='down')) d.add(elm.Line('left', tox=a0.start)) d.add(elm.SourceSin(d='up', label='10V')) d.add(elm.Line(d='up')) if port=='y22': d.add(elm.Resistor(d='right', label=str(rs)+'$\Omega$',color="red")) d.add(elm.SourceSin(d='down', label='10V')) d.add(elm.Line(d='down')) d.add(elm.Line('left', tox=a0.start)) d.add(elm.Line(d='up')) d.draw()
def image_maker(path_of_file): d = schemdraw.Drawing() track = False grid = False gmatrix, lmatrix, phdl, vt_coor, ht_coor = cp.chip_placer( path_of_file, d, track, grid) num_row = len(gmatrix) num_col = len(gmatrix[0]) elem_gates = ["And", "Nand", "Or", "Nor", "Xor", "Xnor", "Not"] # adds starting coordinates of each wire for i in range(0, num_col): for j in range(0, num_row): ind = gmatrix[j][i] if ind != -1: chip = phdl["parts"][ind] pin_coord = chip["gate"].absanchors # calculates number of output pins on starting chip num_out_w = 0 for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": num_out_w += 1 o_counter = num_out_w + 1 for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": o_counter -= 1 if not chip["external"][k]["overall"]: abs_paths = [] for l in range(0, len(chip["external"][k]["path"])): abs_path = [] # adds starting coordinates of wires (different for custom/mux gates vs elem gates) # delays adding of special wires # special wires - short wires, horizontal wires, ending gates in adjacent column spec_case = False path_g = chip["external"][k]["path"][l] if len(path_g) == 2: spec_case = True elif path_g[0][0] == path_g[1][0]: spec_case = True elif path_g[-2][1] == i + 1: if gmatrix[j][i + 2] == -1: spec_case = True if spec_case: if chip["name"] in elem_gates: [ox, oy] = list(pin_coord["out"]) if chip["name"] == "Not": abs_path.append([ox + 0.90, oy]) else: abs_path.append([ox, oy]) else: [ox, oy] = list( pin_coord["inR" + str(o_counter)]) abs_path.append([ox, oy]) else: if chip["name"] in elem_gates and not chip[ "custom_pins"]: [ox, oy] = list(pin_coord["out"]) if chip["name"] == "Not": abs_path.append([ox + 0.90, oy]) else: abs_path.append([ox, oy]) else: [ox, oy] = list( pin_coord["inR" + str(o_counter)]) abs_path.append([ox, oy]) abs_path.append([vt_coor[i + 1][0], oy]) vt_coor[i + 1].pop(0) abs_paths.append(abs_path) chip["external"][k]["abs_paths"] = abs_paths # adds special wires to start_v_tracks for i in range(0, num_col): for j in range(0, num_row): ind = gmatrix[j][i] if ind != -1: chip = phdl["parts"][ind] # calculates number of output pins on starting chip num_out_w = 0 for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": num_out_w += 1 o_counter = num_out_w + 1 for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": o_counter -= 1 if not chip["external"][k]["overall"]: for l in range(0, len(chip["external"][k]["path"])): add_tracks = False path_g = chip["external"][k]["path"][l] if len(path_g) == 2: add_tracks = True elif path_g[0][0] == path_g[1][0]: add_tracks = True elif path_g[-2][1] == i + 1: if gmatrix[j][i + 2] == -1: if lmatrix[j][i + 2] != 0: add_tracks = True if add_tracks: if "start_v_tracks" not in chip: chip["start_v_tracks"] = [] chip["start_v_tracks"].append( vt_coor[i + 1][0]) vt_coor[i + 1].pop(0) # adds middle coordinates of each wire for i in range(0, num_col): for j in range(0, num_row): ind = gmatrix[j][i] if ind != -1: chip = phdl["parts"][ind] for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": if not chip["external"][k]["overall"]: for l in range(0, len(chip["external"][k]["path"])): abs_path = chip["external"][k]["abs_paths"][l] # adds middle coordinates of wires path_g = chip["external"][k]["path"][l] curr = abs_path[-1] if len(path_g) != 2: # adds wires to initial horizontal track if necessary if path_g[0][0] == path_g[1][0]: if curr[1] <= ht_coor[path_g[0][0]][0]: curr = [ chip["start_v_tracks"][0], curr[1] ] abs_path.append(curr) chip["start_v_tracks"].pop(0) else: curr = [ chip["start_v_tracks"][-1], curr[1] ] abs_path.append(curr) chip["start_v_tracks"].pop(-1) curr = [ curr[0], ht_coor[path_g[0][0]][0] ] abs_path.append(curr) ht_coor[path_g[0][0]].pop(0) if path_g[-2][1] == i + 1: if gmatrix[j][i + 2] == -1: if lmatrix[j][i + 2] != 0: if curr[1] <= ht_coor[path_g[0] [0]][0]: curr = [ chip["start_v_tracks"] [0], curr[1] ] abs_path.append(curr) chip["start_v_tracks"].pop( 0) else: curr = [ chip["start_v_tracks"] [-1], curr[1] ] abs_path.append(curr) chip["start_v_tracks"].pop( -1) curr = [ curr[0], ht_coor[path_g[0][0]][0] ] abs_path.append(curr) ht_coor[path_g[0][0]].pop(0) curr = [ vt_coor[path_g[0][1]][-1], curr[1] ] abs_path.append(curr) vt_coor[path_g[0][1]].pop(-1) else: curr = [ curr[0], ht_coor[path_g[1][0]][0] ] abs_path.append(curr) ht_coor[path_g[1][0]].pop(0) curr = [ vt_coor[path_g[1][1]][-1], curr[1] ] abs_path.append(curr) vt_coor[path_g[1][1]].pop(-1) else: trigger = False for g in range(0, len(path_g) - 3): if (path_g[g][0] == path_g[g + 1][0]) and ( path_g[g + 1][1] == path_g[g + 2][1]): if path_g[-2][0] == path_g[-1][ 0] and path_g[-1][ 1] == path_g[ g + 1][1] + 1: if path_g[g][1] < path_g[ g + 1][1] and gmatrix[ path_g[g + 1] [0]][path_g[ g + 1][1] + 1] != -1: [cx, cy] = path_g[g + 1] curr = [ vt_coor[cy][0], curr[1] ] vt_coor[cy].pop(0) abs_path.append(curr) trigger = True else: [cx, cy] = path_g[g + 1] curr = [ vt_coor[cy][-1], curr[1] ] vt_coor[cy].pop(-1) abs_path.append(curr) else: [cx, cy] = path_g[g + 1] curr = [ vt_coor[cy][0], curr[1] ] vt_coor[cy].pop(0) abs_path.append(curr) elif (path_g[g][1] == path_g[g + 1][1]) and ( path_g[g + 1][0] == path_g[g + 2][0]): [cx, cy] = path_g[g + 1] curr = [ curr[0], ht_coor[cx][0] ] ht_coor[cx].pop(0) abs_path.append(curr) elif trigger: [cx, cy] = path_g[g + 1] curr = [ curr[0], ht_coor[cx][0] ] ht_coor[cx].pop(0) abs_path.append(curr) curr = [ vt_coor[cy][-1], curr[1] ] vt_coor[cy].pop(-1) abs_path.append(curr) trigger = False # adds end coordinates of each wire colors = ["red", "orange", "green", "blue", "purple"] color_counter = 0 for i in range(0, num_col): for j in range(0, num_row): ind = gmatrix[j][i] if ind != -1: chip = phdl["parts"][ind] for k in range(0, len(chip["internal"])): if chip["external"][k]["inout"] == "out": if not chip["external"][k]["overall"]: color_counter += 1 # runs for each output wire from pin (can be multiple) # indices in parts array used_end_gates = [] for l in range(0, len(chip["external"][k]["path"])): abs_path = chip["external"][k]["abs_paths"][l] # calculates number of input pins on ending chip path_g = chip["external"][k]["path"][l] [er, ec] = path_g[-1] end_chip = phdl["parts"][gmatrix[er][ec]] end_pin_coord = end_chip["gate"].absanchors # counts number of input wires on left side of chip (excluding select pin) num_in_w = 0 for wire in end_chip["external"]: if wire["inout"] == "in" and wire[ "wire_direc"] == "left": num_in_w += 1 # searches for wire index in end chip wire_name = chip["external"][k]["name"] w_ind = -1 a_counter = used_end_gates.count( gmatrix[er][ec]) for n in range(0, len(end_chip["internal"])): if end_chip["external"][n][ "name"] == wire_name: used_end_gates.append(gmatrix[er][ec]) if a_counter == 0: w_ind = n break else: a_counter -= 1 # adds ending coordinates of wires (different for custom/mux gates vs elem gates) last_coord = abs_path[-1] if end_chip[ "name"] in elem_gates and not end_chip[ "custom_pins"]: if end_chip["name"] != "Not": [ox, oy] = list( end_pin_coord["in" + str(w_ind + 1)]) # for special cases if len(path_g) == 2: abs_path.append([ chip["start_v_tracks"][0], last_coord[1] ]) chip["start_v_tracks"].pop(0) last_coord = abs_path[-1] elif path_g[-3][0] == path_g[-2][ 0] and path_g[-2][0] == path_g[ -1][0]: abs_path.append([ vt_coor[path_g[-2][1]][0], last_coord[1] ]) vt_coor[path_g[-2][1]].pop(0) last_coord = abs_path[-1] abs_path.append([last_coord[0], oy]) abs_path.append([ox, oy]) else: [ox, oy] = list(end_pin_coord["in"]) # for special cases if len(path_g) == 2: if last_coord[1] <= oy: abs_path.append([ chip["start_v_tracks"][0], last_coord[1] ]) chip["start_v_tracks"].pop(0) else: abs_path.append([ chip["start_v_tracks"][-1], last_coord[1] ]) chip["start_v_tracks"].pop(-1) last_coord = abs_path[-1] elif path_g[-3][0] == path_g[-2][ 0] and path_g[-2][0] == path_g[ -1][0]: if last_coord[1] <= oy: abs_path.append([ vt_coor[path_g[-2][1]][0], last_coord[1] ]) vt_coor[path_g[-2][1]].pop(0) else: abs_path.append([ vt_coor[path_g[-2][1]][-1], last_coord[1] ]) vt_coor[path_g[-2][1]].pop(-1) last_coord = abs_path[-1] abs_path.append([last_coord[0], oy]) abs_path.append([ox - 0.90, oy]) else: if end_chip["external"][w_ind][ "wire_direc"] == "top": [ox, oy] = list(end_pin_coord["inT1"]) abs_path.append([ox, last_coord[1]]) abs_path.append([ox, oy]) else: nw_ind = num_in_w - w_ind [ox, oy] = list( end_pin_coord["inL" + str(nw_ind)]) # for special cases if len(path_g) == 2: if last_coord[1] <= oy: abs_path.append([ chip["start_v_tracks"][0], last_coord[1] ]) chip["start_v_tracks"].pop(0) else: abs_path.append([ chip["start_v_tracks"][-1], last_coord[1] ]) chip["start_v_tracks"].pop(-1) last_coord = abs_path[-1] elif path_g[-3][0] == path_g[-2][ 0] and path_g[-2][0] == path_g[ -1][0]: if last_coord[1] <= oy: abs_path.append([ vt_coor[path_g[-2][1]][0], last_coord[1] ]) vt_coor[path_g[-2][1]].pop(0) else: abs_path.append([ vt_coor[path_g[-2][1]][-1], last_coord[1] ]) vt_coor[path_g[-2][1]].pop(-1) last_coord = abs_path[-1] abs_path.append([last_coord[0], oy]) abs_path.append([ox, oy]) # adds wires d.add( ef.Wire( abs_path, colors[color_counter % len(colors)]).at([0, 0])) d.draw(backend='svg', show=True)
def draw_circuit(colors): """ Draws a schematic circuit using given colors Parameters ---------- colors: list of strings of colors of each MosFet Returns ------- dr: Drawing object """ #--------------------------Middle branch------------------- dr = schemdraw.Drawing() # VDD and M6 VDD = dr.add(Vdd(toplabel='$V_{DD}$')) I2 = dr.add(Line('down')) dr.labelI_inline(I2, '$2I_{bias}$', d='in') M6 = dr.add(NMos('l', rgtlabel='M6', flip=True, color=colors[5])) dr.add( Bias('left', open=True, l=fetw, lftlabel='$V_{cmfb}$', b=True, lblofst=0.3, at=(M6, 'gate'))) # Left NMos M1a_M1b = dr.add(Dot(at=(M6, 'source'))) I2_l = dr.add(Line('left', l=3 * fetw)) dr.labelI_inline(I2_l, botlabel='$I_{bias}$', d='in', ofst=0.1) M1a = dr.add( NMos('l', bulk=True, rgtlabel='M1a', flip=True, color=colors[0])) dr.add(Dot(open=True, at=(M1a, 'gate'), lftlabel='$V_{in+}$')) # Right NMos I2_r = dr.add(Line('right', at=(M1a_M1b, 'end'), l=3 * fetw)) dr.labelI_inline(I2_r, botlabel='$I_{bias}$', d='in', ofst=0.1) M1b = dr.add(NMos('r', bulk=True, lftlabel='M1b', color=colors[0])) dr.add(Dot(open=True, at=(M1b, 'gate'), rgtlabel='$V_{in-}$')) #-----------------------------Left branch--------------------------- # VDD dr.add(Line('left', at=(VDD, 'end'))) dr.add(Line('left')) dr.add(Line('left')) I1 = dr.add(Line('down', toy=M6.drain / 2)) dr.labelI_inline(I1, '$I_{bias}$', d='in', ofst=0.2) # M5a & M4a M5a = dr.add(NMos('r', lftlabel='M5a', color=colors[4])) M4a = dr.add(NMos('r', lftlabel='M4a', color=colors[3])) dr.add(Dot(at=(M4a, 'source'))) dr.add(Bias('left', open=True, l=fetw, lftlabel='$V_{out-}$', lblofst=0.3)) # M3a & M2a M3a = dr.add(PMos('r', lftlabel='M3a', at=(M4a, 'source'), color=colors[2])) M2a = dr.add(PMos('r', lftlabel='M2a', color=colors[1])) M2a_M3a = dr.add(Dot(at=(M2a, 'source'))) dr.add(Line('down', at=(M1a, 'source'), toy=M2a_M3a.start)) dr.add(Line('left', tox=(M2a_M3a.start))) dr.add(Ground(at=(M2a, 'drain'))) # Biases Vbiasn = dr.add(LineDot('right', at=(M2a, 'gate'), tox=VDD.start)) Vbiasp = dr.add(LineDot('right', at=(M5a, 'gate'))) dr.add( Bias('right', open=True, l=fetw, rgtlabel='$V_{cascp}$', b=True, lblofst=0.1, at=(M4a, 'gate'))) dr.add( Bias('right', open=True, l=fetw, rgtlabel='$V_{cascn}$', b=True, lblofst=0.1, at=(M3a, 'gate'))) dr.add( Bias('up', open=True, l=fetw, toplabel='$V_{biasn}$', b=True, lblofst=0.3, at=(Vbiasn, 'end'))) dr.add( Bias('up', open=True, l=fetw, rgtlabel='$V_{biasp}$', b=True, lblofst=0.3, at=(Vbiasp, 'end'))) #-----------------------------Right branch--------------------------- # VDD dr.add(Line('right', at=(VDD, 'end'))) dr.add(Line('right')) dr.add(Line('right')) I3 = dr.add(Line('down', toy=M6.drain / 2)) dr.labelI_inline(I3, '$I_{bias}$', d='in', ofst=0.2) # M5b & M4b M5b = dr.add(NMos('l', rgtlabel='M5b', flip=True, color=colors[4])) M4b = dr.add( NMos('l', rgtlabel='M4b', flip=True, at=(M5b, 'source'), color=colors[3])) dr.add(Dot(at=(M4b, 'source'))) dr.add(Bias('right', open=True, l=fetw, rgtlabel='$V_{out+}$', lblofst=0.3)) # M3b & M2b M3b = dr.add( PMos('l', rgtlabel='M3b', flip=True, at=(M4b, 'source'), color=colors[2])) M2b = dr.add( PMos('l', rgtlabel='M2b', flip=True, at=(M3b, 'drain'), color=colors[1])) M2b_M3b = dr.add(Dot(at=(M2b, 'source'))) dr.add(Line('down', at=(M1b, 'source'), toy=M2b_M3b.start)) dr.add(Line('right', tox=(M2b_M3b.start))) dr.add(Ground(at=(M2b, 'drain'))) dr.add(Line('left', at=(M2b, 'gate'), tox=VDD.start)) dr.add(Line('left', at=(M5b, 'gate'), tox=Vbiasp.end)) # Biases dr.add( Bias('left', open=True, l=fetw, lftlabel='$V_{cascp}$', b=True, lblofst=0.1, at=(M4b, 'gate'))) dr.add( Bias('left', open=True, l=fetw, lftlabel='$V_{cascn}$', b=True, lblofst=0.1, at=(M3b, 'gate'))) return dr
def redraw(self, elementName=None): # This function takes the element name to be colored in red # Input: # - elementName: the name of the element that need to be High lighted self.d = schemdraw.Drawing() VoltageSource = self.d.add(elm.Vdd(label='V$_{DD}$')) # the right side branch self.d.add(elm.Line(l=7)) # the right side Vdd self.d.add(elm.Arrow(d='down',l=1, botlabel='I$_{bias}$')) if(elementName == 'M5'): M5b = self.d.add(MosfetP(d='right', anchor='source', color='red', rgtlabel='M5b')) # M5b else: M5b = self.d.add(MosfetP(d='right', anchor='source', rgtlabel='M5b')) # M5b self.d.add(elm.Line(d='down', at=M5b.drain, l=1)) if(elementName == 'M4'): M4b = self.d.add(MosfetP(d='right', anchor='source', color='red', rgtlabel='M4b')) # M4b else: M4b = self.d.add(MosfetP(d='right', anchor='source', rgtlabel='M4b')) # M4b self.d.add(elm.Dot(open=True, at=M4b.gate, lftlabel='V$_{cascp}$')) M4bDotM3b = self.d.add(elm.LineDot(d='down', at=M4b.drain, l=1)) self.d.add(elm.Line(d='down', l=1)) if(elementName == 'M3'): M3b = self.d.add(MosfetN(d='right', anchor='drain', color='red', rgtlabel='M3b')) else: M3b = self.d.add(MosfetN(d='right', anchor='drain', rgtlabel='M3b')) self.d.add(elm.Dot(open=True, at=M3b.gate, lftlabel='V$_{cascn}$')) M3bDotM2b = self.d.add(elm.LineDot(d='down', at=M3b.source, l=1)) self.d.add(elm.Line(d='down', l=1)) if(elementName == 'M2'): M2b = self.d.add(MosfetN(d='right', anchor='drain', color='red', rgtlabel='M2b')) else: M2b = self.d.add(MosfetN(d='right', anchor='drain', rgtlabel='M2b')) self.d.add(elm.Line(d='down', at=M2b.source, l=1)) self.d.add(elm.Ground()) # the left side branch self.d.add(elm.Line(d='left',l=7,at=VoltageSource.end)) # the left side Vdd self.d.add(elm.Arrow(d='down',l=1, toplabel='I$_{bias}$')) if(elementName == 'M5'): M5a = self.d.add(MosfetP(d='right', reverse=True, anchor='source', color='red', lftlabel='M5a')) # M5a else: M5a = self.d.add(MosfetP(d='right',reverse=True, anchor='source', lftlabel='M5a')) # M5a self.d.add(elm.Line(d='down', at=M5a.drain, l=1)) if(elementName == 'M4'): M4a = self.d.add(MosfetP(d='right', reverse=True, anchor='source', color='red', lftlabel='M4a')) # M4a else: M4a = self.d.add(MosfetP(d='right',reverse=True, anchor='source', lftlabel='M4a')) # M4a self.d.add(elm.Dot(open=True, at=M4a.gate, rgtlabel='V$_{cascp}$')) M4aDotM3a = self.d.add(elm.LineDot(d='down', at=M4a.drain, l=1)) self.d.add(elm.Line(d='down', l=1)) if(elementName == 'M3'): M3a = self.d.add(MosfetN(d='right', reverse=True, anchor='drain', color='red', lftlabel='M3a')) # M3a else: M3a = self.d.add(MosfetN(d='right',reverse=True, anchor='drain', lftlabel='M3a')) # M3a self.d.add(elm.Dot(open=True, at=M3a.gate, rgtlabel='V$_{cascn}$')) M3aDotM2a = self.d.add(elm.LineDot(d='down', at=M3a.source, l=1)) self.d.add(elm.Line(d='down', l=1)) if(elementName == 'M2'): M2a = self.d.add(MosfetN(d='right', reverse=True, anchor='drain', color='red', lftlabel='M2a')) # M2a else: M2a = self.d.add(MosfetN(d='right',reverse=True, anchor='drain', lftlabel='M2a')) # M2a self.d.add(elm.Line(d='down', at=M2a.source, l=1)) self.d.add(elm.Ground()) # the middle branch self.d.add(elm.Arrow(d='down', at=VoltageSource.end, botlabel='2I$_{bias}$')) if(elementName == 'M6'): M6 = self.d.add(MosfetP(d='right', anchor='source', color='red', rgtlabel='M6')) # M6 else: M6 = self.d.add(MosfetP(d='right', anchor='source', rgtlabel='M6')) # M6 Vcmfb = self.d.add(elm.Dot(open=True, at=M6.gate, lftlabel='V$_{cmfb}$')) M6DotDrain = self.d.add(elm.LineDot(d='down', at=M6.drain, l=1)) # right of the middle branch self.d.add(elm.Line(d='right', l=2)) self.d.add(elm.Arrow(d='down', l=1, botlabel='I$_{bias}$')) if(elementName == 'M1'): M1b = self.d.add(MosfetP(d='right', reverse=True, anchor='source', color='red', lftlabel='M1b')) # M1b else: M1b = self.d.add(MosfetP(d='right', reverse=True, anchor='source', lftlabel='M1b')) # M1b self.d.add(elm.Line(d='down', xy=M1b.drain, toy=M3bDotM2b.end)) self.d.add(elm.Line(to=M3bDotM2b.end)) self.d.add(elm.Dot(xy=M1b.gate, open=True, rgtlabel='V$_{in-}$')) # left of the middle branch self.d.add(elm.Line(d='left', xy=M6DotDrain.end, l=2)) self.d.add(elm.Arrow(d='down', l=1, toplabel='I$_{bias}$')) if(elementName == 'M1'): M1a = self.d.add(MosfetP(d='right', anchor='source', color='red', rgtlabel='M1a')) # M1a else: M1a = self.d.add(MosfetP(d='right', anchor='source', rgtlabel='M1a')) # M1a self.d.add(elm.Line(d='down', xy=M1a.drain, toy=M3aDotM2a.end)) self.d.add(elm.Line(to=M3aDotM2a.end)) self.d.add(elm.Dot(xy=M1a.gate, open=True, lftlabel='V$_{in+}$')) # connections self.d.add(elm.Line(xy=M2b.gate, tox=M6DotDrain.end)) Vbiasn = self.d.add(elm.Dot) self.d.add(elm.Line(to=M2a.gate)) self.d.add(elm.LineDot(d='up', l=1, xy=Vbiasn.start, label='V$_{biasn}$')) self.d.add(elm.Line(xy=M5a.gate, d='right', l=2)) Vbiasp = self.d.add(elm.Dot) self.d.add(elm.Line(to=M5b.gate)) self.d.add(elm.LineDot(d='up', l=1, xy=Vbiasp.start, label='V$_{biasp}$')) # output voltage self.d.add(elm.LineDot(d='right', at=M4bDotM3b.end, rgtlabel='V$_{out+}$')) self.d.add(elm.LineDot(d='left', at=M4aDotM3a.end, lftlabel='V$_{out-}$')) # draw as a figure to handle it to the GUI canvas self.figure = self.d.draw(show=False)
def getCanonicalFilterSchematic(params): # Unpack the dictionary gi = params['gi'] N = params['N'] ZS = params['ZS'] fc = params['fc'] f1 = params['f1'] f2 = params['f2'] FirstElement = params['FirstElement'] Mask = params['Mask'] if (Mask == 'Bandpass' or Mask == 'Bandstop'): w1 = 2 * np.pi * f1 * 1e6 # rad/s w2 = 2 * np.pi * f2 * 1e6 # rad/s w0 = np.sqrt(w1 * w2) Delta = w2 - w1 else: w0 = 2 * np.pi * fc * 1e6 # rad/s print(gi) ################################################## # Draw circuit schem.use('svg') d = schem.Drawing(inches_per_unit=0.3) _fontsize = 8 # Draw the source port and the first line (if needed) d += elm.Line(color='white').length(2).linewidth(0) d += elm.Dot().label('ZS = ' + str(ZS) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line().length(2).linewidth(1) # Draw the filter components for i in range(N): if (((i % 2 == 0) and (FirstElement == 1)) or ((i % 2 != 0) and (FirstElement != 1))): d += elm.Dot() d.push() # Save the drawing point for later # Mask-type transformation if (Mask == 'Lowpass'): d += elm.Capacitor().down().label( getUnitsWithScale(gi[i + 1] / (ZS * w0), 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) elif (Mask == 'Highpass'): d += elm.Inductor2(loops=2).down().label( getUnitsWithScale(ZS / (gi[i + 1] * w0), 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) elif (Mask == 'Bandpass'): d.push() d += elm.Line().down().length(2).linewidth(1) d += elm.Dot() d.push() d += elm.Line().left().length(1).linewidth(1) d += elm.Capacitor().down().label( getUnitsWithScale(gi[i + 1] / (ZS * Delta), 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) d.pop() d += elm.Line().right().length(1).linewidth(1) d += elm.Inductor2(loops=2).down().label( getUnitsWithScale(ZS * Delta / (gi[i + 1] * w0 * w0), 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) d.pop() elif (Mask == 'Bandstop'): d += elm.Dot() d.push() d += elm.Inductor2(loops=2).down().label( getUnitsWithScale(ZS / (gi[i + 1] * Delta), 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Capacitor().down().label( getUnitsWithScale(gi[i + 1] * Delta / (ZS * w0 * w0), 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Ground().linewidth(1) d.pop() d.pop() # Restore the drawing point else: # Mask-type transformation if (Mask == 'Lowpass'): d += elm.Inductor2(loops=2).label( getUnitsWithScale(ZS * gi[i + 1] / w0, 'Inductance'), fontsize=_fontsize).linewidth(1) elif (Mask == 'Highpass'): d += elm.Capacitor().label(getUnitsWithScale( 1 / (gi[i + 1] * w0 * ZS), 'Capacitance'), fontsize=_fontsize).linewidth(1) elif (Mask == 'Bandpass'): d += elm.Inductor2(loops=2).label( getUnitsWithScale(ZS * gi[i + 1] / (Delta), 'Inductance'), fontsize=_fontsize).linewidth(1) d += elm.Capacitor().label(getUnitsWithScale( Delta / (ZS * w0 * w0 * gi[i + 1]), 'Capacitance'), fontsize=_fontsize).linewidth(1) elif (Mask == 'Bandstop'): d.push() d += elm.Inductor2(loops=2).right().label( getUnitsWithScale(gi[i + 1] * ZS * Delta / (w0 * w0), 'Inductance'), fontsize=_fontsize).linewidth(1) d.pop() d += elm.Line().up().length(2).linewidth(1) d += elm.Capacitor().right().label( getUnitsWithScale(1 / (ZS * Delta * gi[i + 1]), 'Capacitance'), fontsize=_fontsize).linewidth(1) d += elm.Line().down().length(2).linewidth(1) # Draw the last line (if needed) and the load port d += elm.Line().right().length(2).linewidth(1) d += elm.Dot().label('ZL = ' + str(float("{:.2f}".format(ZS * gi[-1]))) + " \u03A9", fontsize=_fontsize).linewidth(1) d += elm.Line(color='white').length(2).linewidth(0) return d