def nmos_characteristics(Vd, Vg): circuit = Circuit('NMOS Input Characteristic') circuit.include( './app/circuits/libraries/transistor/ptm_65nm_nmos_bulk.mod') # Define the DC supply voltage value Vdd = float(Vd) # Instanciate circuit elements Vgate = circuit.V('gate', 'gatenode', circuit.gnd, u_V(float(Vg))) Vdrain = circuit.V('drain', 'vdd', circuit.gnd, u_V(Vdd)) # M <name> <drain node> <gate node> <source node> <bulk/substrate node> circuit.MOSFET(1, 'vdd', 'gatenode', circuit.gnd, circuit.gnd, model='ptm65nm_nmos') simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.dc(Vdrain=slice(0, Vdd, .01)) figure, ax = plt.subplots(figsize=(20, 10)) ax.plot(analysis['vdd'], u_A(-analysis.Vdrain)) ax.legend('NMOS characteristic') ax.grid() ax.set_xlabel('Vds [V]') ax.set_ylabel('Id [A]') return circuit, analysis, plt
libraries_path = find_libraries() spice_library = SpiceLibrary(libraries_path) circuit = Circuit('NMOS Transistor') circuit.include(spice_library['ptm65nm_nmos']) # Define the DC supply voltage value Vdd = 1.1 # Instanciate circuit elements Vgate = circuit.V('gate', 'gatenode', circuit.gnd, 0 @ u_V) Vdrain = circuit.V('drain', 'vdd', circuit.gnd, u_V(Vdd)) # M <name> <drain node> <gate node> <source node> <bulk/substrate node> circuit.MOSFET(1, 'vdd', 'gatenode', circuit.gnd, circuit.gnd, model='ptm65nm_nmos') #r# We plot the characteristics :math:`Id = f(Vgs)` using a DC sweep simulation. simulator = circuit.simulator(temperature=25, nominal_temperature=25) analysis = simulator.dc(Vgate=slice(0, Vdd, .01)) figure, ax = plt.subplots(figsize=(20, 10)) ax.plot(analysis['gatenode'], u_mA(-analysis.Vdrain)) ax.legend('NMOS characteristic') ax.grid() ax.set_xlabel('Vgs [V]') ax.set_ylabel('Id [mA]')
def define_circuit(self): logger = Logging.setup_logging() circuit_lab = self.circuit circuit = Circuit(circuit_lab["name"]) # for complex circuit elements that requires SPICE library # libraries_path = find_libraries() python_file = os.path.abspath(sys.argv[0]) examples_root = parent_directory_of(python_file) libraries_path = os.path.join(examples_root, 'libraries') spice_library = SpiceLibrary(libraries_path) # return message message = "" # add all elements to the PySpice circuit for element in circuit_lab: if element == "V": for dc_voltage_source in circuit_lab["V"]: circuit.V( dc_voltage_source["id"], circuit.gnd if dc_voltage_source["node1"] == "gnd" else dc_voltage_source["node1"], circuit.gnd if dc_voltage_source["node2"] == "gnd" else dc_voltage_source["node2"], dc_voltage_source["value"] @ u_V) elif element == "VA": for ac_voltage_source in circuit_lab["VA"]: circuit.SinusoidalVoltageSource( ac_voltage_source["id"], circuit.gnd if ac_voltage_source["node1"] == "gnd" else ac_voltage_source["node1"], circuit.gnd if ac_voltage_source["node2"] == "gnd" else ac_voltage_source["node2"], amplitude=ac_voltage_source["amplitude"] @ u_V, frequency=ac_voltage_source["frequency"] @ u_Hz, offset=ac_voltage_source["offset"] @ u_V) elif element == "I": for dc_current_source in circuit_lab["I"]: circuit.I( dc_current_source["id"], circuit.gnd if dc_current_source["node1"] == "gnd" else dc_current_source["node1"], circuit.gnd if dc_current_source["node2"] == "gnd" else dc_current_source["node2"], dc_current_source["value"] @ u_A) elif element == "IA": for ac_current_source in circuit_lab["IA"]: circuit.SinusoidalCurrentSource( ac_current_source["id"], circuit.gnd if ac_current_source["node1"] == "gnd" else ac_current_source["node1"], circuit.gnd if ac_current_source["node2"] == "gnd" else ac_current_source["node2"], amplitude=ac_current_source["amplitude"] @ u_A, frequency=ac_current_source["frequency"] @ u_Hz, offset=ac_current_source["offset"] @ u_A) elif element == "R": for resistor in circuit_lab["R"]: circuit.R( resistor["id"], circuit.gnd if resistor["node1"] == "gnd" else resistor["node1"], circuit.gnd if resistor["node2"] == "gnd" else resistor["node2"], resistor["value"] @ u_Ω) elif element == "L": for inductor in circuit_lab["L"]: circuit.L( inductor["id"], circuit.gnd if inductor["node1"] == "gnd" else inductor["node1"], circuit.gnd if inductor["node2"] == "gnd" else inductor["node2"], inductor["value"] @ u_H) elif element == "C": for capacitor in circuit_lab["C"]: circuit.C( capacitor["id"], circuit.gnd if capacitor["node1"] == "gnd" else capacitor["node1"], circuit.gnd if capacitor["node2"] == "gnd" else capacitor["node2"], capacitor["value"] @ u_F) elif element == "D": for diode in circuit_lab["D"]: try: circuit.include(spice_library[diode["modelType"]]) circuit.X( diode["id"], diode["modelType"], circuit.gnd if diode["node1"] == "gnd" else diode["node1"], circuit.gnd if diode["node2"] == "gnd" else diode["node2"]) except KeyError as e: message += " " + str(e) elif element == "nBJT": for nBJT in circuit_lab["nBJT"]: try: circuit.include(spice_library[nBJT["modelType"]]) circuit.BJT(nBJT["id"], circuit.gnd if nBJT["node1"] == "gnd" else nBJT["node1"], circuit.gnd if nBJT["node2"] == "gnd" else nBJT["node2"], circuit.gnd if nBJT["node3"] == "gnd" else nBJT["node3"], model=nBJT["modelType"]) except KeyError as e: message += " " + str(e) elif element == "pBJT": for pBJT in circuit_lab["pBJT"]: try: circuit.include(spice_library[pBJT["modelType"]]) circuit.BJT(pBJT["id"], circuit.gnd if pBJT["node3"] == "gnd" else pBJT["node3"], circuit.gnd if pBJT["node2"] == "gnd" else pBJT["node2"], circuit.gnd if pBJT["node1"] == "gnd" else pBJT["node1"], model=pBJT["modelType"]) except KeyError as e: message += " " + str(e) elif element == "NMOS": for NMOS in circuit_lab["NMOS"]: try: circuit.include(spice_library[NMOS["modelType"]]) # nodes are: drain, gate, source, bulk circuit.MOSFET(NMOS["id"], circuit.gnd if NMOS["node4"] == "gnd" else NMOS["node4"], circuit.gnd if NMOS["node2"] == "gnd" else NMOS["node2"], circuit.gnd if NMOS["node3"] == "gnd" else NMOS["node3"], circuit.gnd if NMOS["node1"] == "gnd" else NMOS["node1"], model=NMOS["modelType"]) except KeyError as e: message += " " + str(e) elif element == "PMOS": for PMOS in circuit_lab["PMOS"]: try: circuit.include(spice_library[PMOS["modelType"]]) # nodes are: source, gate, drain, bulk circuit.MOSFET(PMOS["id"], circuit.gnd if PMOS["node1"] == "gnd" else PMOS["node1"], circuit.gnd if PMOS["node2"] == "gnd" else PMOS["node2"], circuit.gnd if PMOS["node3"] == "gnd" else PMOS["node3"], circuit.gnd if PMOS["node4"] == "gnd" else PMOS["node4"], model=PMOS["modelType"]) except KeyError as e: message += " " + str(e) # add ammeter as a 0 volt voltage source elif element == "AM": for ammeter in circuit_lab["AM"]: circuit.V( ammeter["id"], circuit.gnd if ammeter["node1"] == "gnd" else ammeter["node1"], circuit.gnd if ammeter["node2"] == "gnd" else ammeter["node2"], ammeter["value"] @ u_V) if not message: self.spice = circuit return message return "Undefined model type:" + message