Пример #1
0
#r# ================

#r# This example show a CEM simulation.

# Fixme: retrieve PDF reference and complete

####################################################################################################

import os

import matplotlib.pyplot as plt

####################################################################################################

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

####################################################################################################

from PySpice.Doc.ExampleTools import find_libraries
from PySpice.Probe.Plot import plot
from PySpice.Spice.Library import SpiceLibrary
from PySpice.Spice.Netlist import Circuit
from PySpice.Unit import *

####################################################################################################

libraries_path = find_libraries()
spice_library = SpiceLibrary(libraries_path)

####################################################################################################
Пример #2
0
#!/usr/bin/env python3
#coding=utf-8

import sys
import os

import numpy, random, math

import  traceback
import time, datetime


## Spice logger is disabled
import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging(config_file="logging.yml")

from PySpice.Spice.Netlist import Circuit
from PySpice.Unit.Units import *

import matplotlib.pyplot as plt
try:
    import networkx
except:
    print("Networkx library not installed. No graph will be produced")

from PySpice.Spice.Library import SpiceLibrary
from PySpice.Plot.BodeDiagram import bode_diagram
from PySpice.Spice.Netlist import Circuit

import deap
from deap import base, tools, creator
Пример #3
0
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
####################################################################################################

####################################################################################################

import math
import unittest

import numpy as np
from numpy import testing as np_test

####################################################################################################

import PySpice.Logging.Logging as Logging
logger = Logging.setup_logging()

####################################################################################################

from PySpice.Probe.WaveForm import *
from PySpice.Unit import *

####################################################################################################


class TestUnits(unittest.TestCase):

    ##############################################

    @staticmethod
    def _test_unit_values(values, true_array):
Пример #4
0
    def check_installation(self):
        """Tool to check PySpice is correctly installed.

        """

        import ctypes.util

        try:
            print('Load PySpice module')
            import PySpice
            print('loaded {} version {}'.format(PySpice.__file__,
                                                PySpice.__version__))
        except ModuleNotFoundError:
            print('PySpice module not found')
            return

        import PySpice.Logging.Logging as Logging
        logger = Logging.setup_logging(logging_level='INFO')

        from PySpice.Config import ConfigInstall
        from PySpice.Spice.NgSpice.Shared import NgSpiceShared

        ##############################################

        message = '''
        NgSpiceShared configuration is
          NgSpiceShared.NGSPICE_PATH = {0.NGSPICE_PATH}
          NgSpiceShared.LIBRARY_PATH = {0.LIBRARY_PATH}
        '''
        print(message.format(NgSpiceShared))

        ##############################################

        if ConfigInstall.OS.on_windows:
            print('OS is Windows')
            library = NgSpiceShared.LIBRARY_PATH
        elif ConfigInstall.OS.on_osx:
            print('OS is OSX')
            library = 'ngspice'
        elif ConfigInstall.OS.on_linux:
            print('OS is Linux')
            library = 'ngspice'
        else:
            raise NotImplementedError

        library_path = ctypes.util.find_library(library)
        print('Found in library search path: {}'.format(library_path))

        ##############################################

        print('\nLoad NgSpiceShared')
        ngspice = NgSpiceShared(verbose=True)

        if ConfigInstall.OS.on_linux:
            # For Linux see DLOPEN(3)
            # Apparently there is no simple way to get the path of the loaded library ...
            # But we can look in the process maps
            pid = os.getpid()
            maps_path = '/proc/{}/maps'.format(pid)
            with open(maps_path) as fh:
                for line in fh:
                    if '.so' in line and 'ngspice' in line:
                        parts = [x for x in line.split() if x]
                        path = parts[-1]
                        print('loaded {}'.format(path))
                        break

        message = '''
        Ngspice version is {0.ngspice_version}
          has xspice: {0.has_xspice}
          has cider {0.has_cider}
        '''
        print(message.format(ngspice))

        command = 'version -f'
        print('> ' + command)
        print(ngspice.exec_command(command))

        print()
        print('PySpice should work as expected')
Пример #5
0
def script():
    logger = Logging.setup_logging()
    libraries_path = find_libraries()
    print(libraries_path)
    spice_library = SpiceLibrary(libraries_path)
    print(spice_library)
    circuit = Circuit('Diode Characteristic Curve')
    circuit.include(spice_library['1N4148'])
    print(spice_library['1N4148'])

    # def defaultCircuitParams():
    circuit.V('input', 'in', circuit.gnd, 10 @ u_V)
    circuit.R(1, 'in', 'out', 1 @ u_Ω)  # not required for simulation
    circuit.X('D1', '1N4148', 'out', circuit.gnd)

    # Voltage and Resistance in 10e-06, X is diode type
    # def setCircuitParams(V, R, X):
    #     circuit.V('input', 'in', circuit.gnd, V@u_V)
    #     circuit.R(1, 'in', 'out', R@u_Ω) # not required for simulation
    #     circuit.X('D1', X, 'out', circuit.gnd)

    #r# We simulate the circuit at these temperatures: 0, 25 and 100 °C.

    # Fixme: Xyce ???
    temperatures = [0, 25, 100] @ u_Degree
    analyses = {}

    # def simulateTemp():
    for temperature in temperatures:
        simulator = circuit.simulator(temperature=temperature,
                                      nominal_temperature=temperature)
        analysis = simulator.dc(Vinput=slice(-2, 5, .01))
        analyses[float(temperature)] = analysis

    ####################################################################################################

    #r# We plot the characteristic curve and compare it to the Shockley diode model:
    #r#
    #r# .. math::
    #r#
    #r#     I_d = I_s \left( e^{\frac{V_d}{n V_T}} - 1 \right)
    #r#
    #r# where :math:`V_T = \frac{k T}{q}`
    #r#
    #r# In order to scale the reverse biased region, we have to do some hack with Matplotlib.
    #r#
    silicon_forward_voltage_threshold = .7

    shockley_diode = ShockleyDiode(Is=4e-9, degree=25)

    def two_scales_tick_formatter(value, position):
        if value >= 0:
            return '{} mA'.format(value)
        else:
            return '{} nA'.format(value / 100)

    formatter = ticker.FuncFormatter(two_scales_tick_formatter)

    figure, (ax1, ax2) = plt.subplots(2, figsize=(20, 10))

    ax1.set_title('1N4148 Characteristic Curve ')
    ax1.set_xlabel('Voltage [V]')
    ax1.set_ylabel('Current')
    ax1.grid()
    ax1.set_xlim(-2, 2)
    ax1.axvspan(-2, 0, facecolor='green', alpha=.2)
    ax1.axvspan(0,
                silicon_forward_voltage_threshold,
                facecolor='blue',
                alpha=.1)
    ax1.axvspan(silicon_forward_voltage_threshold,
                2,
                facecolor='blue',
                alpha=.2)
    ax1.set_ylim(-500, 750)  # Fixme: round
    ax1.yaxis.set_major_formatter(formatter)
    Vd = analyses[25].out
    # compute scale for reverse and forward region
    forward_region = Vd >= 0 @ u_V
    reverse_region = np.invert(forward_region)
    scale = reverse_region * 1e11 + forward_region * 1e3
    #?# check temperature
    for temperature in temperatures:
        analysis = analyses[float(temperature)]
        ax1.plot(Vd, -analysis.Vinput * scale)
    ax1.plot(Vd, shockley_diode.I(Vd) * scale, 'black')
    ax1.legend(['@ {} °C'.format(temperature)
                for temperature in temperatures] +
               ['Shockley Diode Model Is = 4 nA'],
               loc=(.02, .8))
    ax1.axvline(x=0, color='black')
    ax1.axhline(y=0, color='black')
    ax1.axvline(x=silicon_forward_voltage_threshold, color='red')
    ax1.text(-1, -100, 'Reverse Biased Region', ha='center', va='center')
    ax1.text(1, -100, 'Forward Biased Region', ha='center', va='center')

    #r# Now we compute and plot the static and dynamic resistance.
    #r#
    #r# .. math::
    #r#
    #r#   \frac{d I_d}{d V_d} = \frac{1}{n V_T}(I_d + I_s)
    #r#
    #r# .. math::
    #r#
    #r#   r_d = \frac{d V_d}{d I_d} \approx \frac{n V_T}{I_d}

    ax2.set_title('Resistance @ 25 °C')
    ax2.grid()
    ax2.set_xlim(-2, 3)
    ax2.axvspan(-2, 0, facecolor='green', alpha=.2)
    ax2.axvspan(0,
                silicon_forward_voltage_threshold,
                facecolor='blue',
                alpha=.1)
    ax2.axvspan(silicon_forward_voltage_threshold,
                3,
                facecolor='blue',
                alpha=.2)
    analysis = analyses[25]
    static_resistance = -analysis.out / analysis.Vinput
    dynamic_resistance = np.diff(-analysis.out) / np.diff(analysis.Vinput)
    ax2.semilogy(analysis.out, static_resistance, basey=10)
    ax2.semilogy(analysis.out[10:-1], dynamic_resistance[10:], basey=10)
    ax2.axvline(x=0, color='black')
    ax2.axvline(x=silicon_forward_voltage_threshold, color='red')
    ax2.axhline(y=1, color='red')
    ax2.text(-1.5, 1.1, 'R limitation = 1 Ω', color='red')
    ax2.legend(['{} Resistance'.format(x) for x in ('Static', 'Dynamic')],
               loc=(.05, .2))
    ax2.set_xlabel('Voltage [V]')
    ax2.set_ylabel('Resistance [Ω]')

    plt.tight_layout()
    plt.show()
Пример #6
0
    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