Example #1
0
def main():

    parser = argparse.ArgumentParser(description='Convert a circuit file to PySpice')

    parser.add_argument('circuit_file', # metavar='circuit_file',
                        help='.cir file')

    parser.add_argument('-o', '--output',
                        default=None,
                        help='Output file')

    parser.add_argument('--ground',
                        type=int,
                        default=0,
                        help='Ground node')

    parser.add_argument('--build',
                        default=False, action='store_true',
                        help='Build circuit')

    args = parser.parse_args()

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

    parser = SpiceParser(path=args.circuit_file)

    if args.build:
        parser.build_circuit()

    circuit = parser.to_python_code(ground=args.ground)
    if args.output is not None:
        with open(args.output, 'w') as f:
            f.write(circuit)
    else:
        print(circuit)
Example #2
0
def main():

    # Monkeypatch the exec_command() to not bail if it detects an 'error' in stderr,
    # these 'errors' don't seem to actually prevent the sim from working correctly
    Shared.NgSpiceShared.exec_command = exec_command

    libraries_path = find_libraries()
    spice_library = SpiceLibrary(libraries_path)

    directory_path = Path(__file__).resolve().parent
    kicad_netlist_path = directory_path.joinpath(
        'wien-bridge-oscillator-sim.cir')
    parser = SpiceParser(path=str(kicad_netlist_path))
    circuit = parser.build_circuit(ground=0)
    simulator = circuit.simulator(temperature=25, nominal_temperature=25)
    analysis = simulator.transient(step_time=10 @ u_us, end_time=60 @ u_ms)

    v_sine_out = analysis['SINE_OUT']
    first_index_of_interest = np.where(
        v_sine_out.abscissa.as_ndarray() > 0.04)[0][0]

    fig, ax = plt.subplots(1, figsize=(10, 5))
    ax.plot(v_sine_out.abscissa.as_ndarray()[first_index_of_interest:],
            v_sine_out.as_ndarray()[first_index_of_interest:])
    ax.legend(('SINE_OUT', ), loc=(.8, .8))
    ax.grid()
    ax.set_xlabel('Time (s)')
    ax.set_ylabel('Voltage (V)')

    plt.tight_layout()
    plt.savefig('v-sine-out.png')
Example #3
0
def main():

    # Monkeypatch the exec_command() to not bail if it detects an 'error' in stderr,
    # these 'errors' don't seem to actually prevent the sim from working correctly
    Shared.NgSpiceShared.exec_command = exec_command

    libraries_path = find_libraries()
    spice_library = SpiceLibrary(libraries_path)

    directory_path = Path(__file__).resolve().parent
    kicad_netlist_path = directory_path.joinpath('simulation.cir')

    netlist_without_quotes_path = Path('./simulation-without-quotes.cir')
    remove_include_quotes(kicad_netlist_path, netlist_without_quotes_path)

    parser = SpiceParser(path=str(netlist_without_quotes_path))
    circuit = parser.build_circuit(ground=0)
    simulator = circuit.simulator(temperature=25, nominal_temperature=25)
    analysis = simulator.transient(step_time=100 @ u_ps, end_time=100 @ u_ns)

    v_out = analysis['OUT']

    fig, ax = plt.subplots(1, figsize=(10, 5))
    ax.plot(v_out.abscissa.as_ndarray() * 1e9, v_out.as_ndarray())
    ax.legend(('OUT', ), loc=(.8, .8))
    ax.grid()
    ax.set_xlabel('Time (ns)')
    ax.set_ylabel('Voltage (V)')

    plt.tight_layout()
    plt.savefig('out.png')
Example #4
0
 def parser_netlist(self):
     """
     解析netlist
     :return:self.circurt属性绑定解析的netlist电路
     """
     parser = SpiceParser(path=self._path)
     self.circuit = parser.build_circuit()
     print(str(self.circuit))
Example #5
0
def circuit_gft(prb):
    circuit_file = SpiceParser(source=prb[0])
    circuit = circuit_file.build_circuit()
    circuit.parameter('prb', str(prb[1]))
    # Fixme: simulate with Xyce, CI !!!
    simulator = circuit.simulator(simulator='xyce-serial')
    simulator.save(['all'])
    return simulator
Example #6
0
def is_valid_netlist(textfile, name=None):
    try:
        parser = SpiceParser(source=textfile)
        circuit = parser.build_circuit()
        return len(circuit.elements) > 0
    except:
        if name:
            print(f'invalid spice file: {name}', file=sys.stderr)
        return False
Example #7
0
def main():

    # Monkeypatch the exec_command() to not bail if it detects an 'error' in stderr,
    # these 'errors' don't seem to actually prevent the sim from working correctly
    Shared.NgSpiceShared.exec_command = exec_command

    libraries_path = find_libraries()
    spice_library = SpiceLibrary(libraries_path)

    directory_path = Path(__file__).resolve().parent
    kicad_netlist_path = directory_path.joinpath('schematic.cir')

    netlist_without_quotes_path = Path('./simulation-without-quotes.cir')
    remove_include_quotes(kicad_netlist_path, netlist_without_quotes_path)

    parser = SpiceParser(path=str(netlist_without_quotes_path))
    circuit = parser.build_circuit(ground=0)
    simulator = circuit.simulator(temperature=25, nominal_temperature=25)
    # analysis = simulator.transient(step_time=100@u_us, end_time=1000@u_ms)
    analysis = simulator.ac(start_frequency=100@u_mHz, stop_frequency=10@u_kHz, number_of_points=50,  variation='dec')

    v_out = analysis['v_out']
    mag = 20*np.log10(np.abs(v_out.as_ndarray()))
    print(mag)
    freq = analysis.frequency.as_ndarray()

    r1_Ohms = 2e3
    r2_Ohms = 10e3
    ratio = r2_Ohms / (r1_Ohms + r2_Ohms)
    ratio_dB = 20*np.log10(ratio)
    ratio_dB = -1.75
    r_parallel = (r1_Ohms * r2_Ohms) / (r1_Ohms + r2_Ohms)
    c_F = 10e-6
    fc = 1 / (2*np.pi*r_parallel*c_F)
    print(ratio_dB)

    fig, ax = plt.subplots(1, figsize=(10, 7))
    ax.plot(freq, mag, label='$V_{OUT}$')
    # ax.legend(('$V_{OUT}$',), loc=(.8,.8))
    ax.grid()
    ax.set_xscale('log')
    ax.set_xlabel('Frequency (Hz)')
    ax.set_ylabel('Voltage Magnitude (dB)')
    ax.axvline(fc, color='C2', label='$f_c$')
    ax.axhline(ratio_dB, color='C1', label=f'{ratio_dB:.2f}dB (DC gain)')
    ax.axhline(ratio_dB - 3.0, color='C1', label=f'{ratio_dB - 3:.2f}dB (DC gain - 3dB)')
    ax.legend()
    plt.tight_layout()
    plt.savefig('out.png')
Example #8
0
def fetch_graphs(files, min_edges=0):
    filenames = h.valid_netlist_sources(files)
    source = next(filenames)

    parser = SpiceParser(source=source)
    circuit = parser.build_circuit()
    (nodes, edges) = h.get_nodes_edges(circuit)

    # TODO: randomly remove one each time until it is empty
    graphs = []
    while len(edges) > min_edges:
        graphs.append((nodes, edges))
        (nodes, edges) = a.remove_random_node(nodes, edges)

    return graphs
Example #9
0
def build_cgraph_lib(ffn_netlist, dir_graph_out=None, ground=0, remove_dummy=False, dir_node_edge_list=None, dir_lib_out=None, 
                    guess_by_name=True, add_edge_annotation=False):
    """
        ffn_netlist: full file path of netlist to parse
        dir_graph_out: directory path to save the resulting circuit topology graph in yaml format
        dir_lib_out: directory path to save circuit topology graph lib in pickle format
        remove_dummy: when True, remove dummy mos
        guess_by_name: when True, some attributes such as signal type is inferred/guessed from net/instance name
        add_edge_annotation: when True, add matching/group edge constraints to the graph

        return dict (i.e. {circuit_name:networkx.Graph})
    """
    from PySpice.Spice.Parser import SpiceParser
    parser = SpiceParser(path=ffn_netlist)
    circuit = parser.build_circuit(ground=ground)
    
    cgraph_dict = {}
    top_name, ext = os.path.splitext(os.path.basename(ffn_netlist))
    G = build_cgraph(circuit, top_name, guess_by_name=guess_by_name, add_edge_annotation=add_edge_annotation)
    cgraph_dict[top_name] = G

    for c in (circuit.subcircuits):
        for e in (c.elements):
            G = build_cgraph(c, c.name, guess_by_name=guess_by_name, add_edge_annotation=add_edge_annotation)
        cgraph_dict[c.name] = G

    for name, G in cgraph_dict.items():
        if(dir_graph_out is not None):
            nx.write_yaml(G, os.path.join(dir_graph_out, "%s.yaml" % name))
        
        if(dir_node_edge_list is not None):
            node_number = {}
            with open(os.path.join(dir_node_edge_list, "%s.nodelist" % name), 'w') as f:
                for ii, n in enumerate(G.nodes()):
                    f.write("%s %d\n" % (n, ii))
                    node_number[n]=ii
            with open(os.path.join(dir_node_edge_list, "%s.edgelist" % name), 'w') as f:
                for e in G.edges():
                    f.write('%s %s\n' % (node_number[e[0]], node_number[e[1]]))

    if(dir_lib_out is not None):
        with open(os.path.join(dir_lib_out, "%s.cgraph.pkl" % top_name), 'wb') as f:
            pickle.dump(cgraph_dict, f, -1)
    return cgraph_dict
Example #10
0
def main():

    # Monkeypatch the exec_command() to not bail if it detects an 'error' in stderr,
    # these 'errors' don't seem to actually prevent the sim from working correctly
    Shared.NgSpiceShared.exec_command = exec_command

    libraries_path = find_libraries()
    spice_library = SpiceLibrary(libraries_path)

    directory_path = Path(__file__).resolve().parent
    kicad_netlist_path = directory_path.joinpath('schematic.cir')

    netlist_without_quotes_path = Path('./simulation-without-quotes.cir')
    remove_include_quotes(kicad_netlist_path, netlist_without_quotes_path)

    parser = SpiceParser(path=str(netlist_without_quotes_path))
    circuit = parser.build_circuit(ground=0)
    simulator = circuit.simulator(temperature=25, nominal_temperature=25)
    analysis = simulator.transient(step_time=1 @ u_us, end_time=1000 @ u_us)
    # analysis = simulator.ac(start_frequency=100@u_mHz, stop_frequency=10@u_kHz, number_of_points=50,  variation='dec')

    v_in = analysis['/v_in']
    v_out = analysis['v_out']

    fig, ax = plt.subplots(1, figsize=(7, 5))
    ax.plot(v_in.abscissa.as_ndarray() * 1e6,
            v_in.as_ndarray(),
            label='$v_{in}$')
    ax.plot(v_out.abscissa.as_ndarray() * 1e6,
            v_out.as_ndarray(),
            label='$v_{out}$')
    ax.axhline(-5.0, ls='--', color='C0')
    ax.axhline(5.0, ls='--', color='C0')
    ax.axhline(0, ls='--', color='C1')
    ax.axhline(3.3, ls='--', color='C1')
    ax.grid()
    ax.set_xlabel('Time [us]')
    ax.set_ylabel('Voltage [V]')
    ax.legend()
    plt.tight_layout()
    plt.savefig('out.png')
Example #11
0
def netlist_as_graph(textfile):
    parser = SpiceParser(source=textfile)
    circuit = parser.build_circuit()
    component_list = components(circuit)
    adj = {}

    for element in circuit.elements:
        element_id = component_list.index(element)

        if element_id not in adj:
            adj[element_id] = []

        nodes = [pin.node for pin in element.pins]
        node_ids = [component_list.index(node) for node in nodes]
        adj[element_id].extend(node_ids)

        for node_id in node_ids:
            if node_id not in adj:
                adj[node_id] = []
            adj[node_id].append(element_id)

    adj = nx.adjacency_matrix(nx.from_dict_of_lists(adj)).toarray()
    return component_list, adj
Example #12
0
        super().__init__()

        self.R('load', 'output', 'x', 10 @ u_Ω)


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

#!# We read the generated netlist.
kicad_netlist_path = os.path.join(os.path.realpath(os.path.dirname(__file__)),
                                  'kicad-pyspice-example',
                                  'kicad-pyspice-example.cir')
parser = SpiceParser(path=kicad_netlist_path)

#!# We build the circuit and translate the ground (5 to 0).
circuit = parser.build_circuit(ground=5)

#!# We include the operational amplifier module.
circuit.include(spice_library['LMV981'])

#!# We define the subcircuits.
for subcircuit in (PowerIn(), Opamp(), JackIn(), JackOut()):
    circuit.subcircuit(subcircuit)

# print(str(circuit))

#!# We perform a transient simulation.
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.transient(step_time=100 @ u_us, end_time=3 @ u_ms)

figure = plt.figure(1, (20, 10))
Example #13
0
    def __init__(self):

        super().__init__()

        self.R('load', 'output', 'x', 10)

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

#!# We read the generated netlist.
kicad_netlist_path = os.path.join(os.path.realpath(os.path.dirname(__file__)),
                                  'kicad-pyspice-example',
                                  'kicad-pyspice-example.cir')
parser = SpiceParser(path=kicad_netlist_path)

#!# We build the circuit and translate the ground (5 to 0).
circuit = parser.build_circuit(ground=5)

#!# We include the operational amplifier module.
circuit.include(spice_library['LMV981'])

#!# We define the subcircuits.
for subcircuit in (PowerIn(), Opamp(), JackIn(), JackOut()):
    circuit.subcircuit(subcircuit)

# print(str(circuit))

#!# We perform a transient simulation.
simulator = circuit.simulator(temperature=25, nominal_temperature=25)
analysis = simulator.transient(step_time=milli(.1), end_time=milli(3))

figure = plt.figure(1, (20, 10))
Example #14
0
#
#.lib CMOS_035_Spice_Model.lib tt
#
#.end
# """

source = """
.title Test
V1 vp GND dc 1.65 ac 0.5
M7 Vout /6 VDD VDD p_33 l=0.9u w=25.9u
M6 Vout /3 GND GND n_33 l=1.4u w=92.04u
M2 /3 vp /1 VDD p_33 l=0.9u w=51.78u
M1 /2 vn /1 VDD p_33 l=0.9u w=51.78u
M4 /3 /2 GND GND n_33 l=1.4u w=46.02u
M3 /2 /2 GND GND n_33 l=1.4u w=46.02u
M5 /1 /6 VDD VDD p_33 l=0.9u w=12.95u
V0 VDD GND 3.3
M8 /6 /6 VDD VDD p_33 l=0.9u w=1.3u
I1 /6 GND 10u
.lib CMOS_035_Spice_Model.lib tt
""".strip()

parser = SpiceParser(source=source)
circuit = parser.build_circuit()
source2 = str(circuit)
for line1, line2 in zip(source.splitlines(), source2.splitlines()):
    print('-' * 100)
    print(line1 + '|')
    print(line2 + '|')
    assert (line1 == line2)
####################################################################################################

circuit = Circuit('STM AN1476: Low-Cost Power Supply For Home Appliances')

circuit.include(spice_library['1N4148'])
# 1N5919B: 5.6 V, 3.0 W Zener Diode Voltage Regulator
circuit.include(spice_library['d1n5919brl'])

ac_line = circuit.AcLine('input', 'out', 'in', rms_voltage=230, frequency=50)
circuit.R('load', 'out', circuit.gnd, kilo(1))
circuit.C('load', 'out', circuit.gnd, micro(220))
circuit.X('D1', '1N4148', circuit.gnd, 1)
circuit.D(1, circuit.gnd, 1, model='DIODE1', off=True)
circuit.X('Dz1', 'd1n5919brl', 1, 'out')
circuit.C('ac', 1, 2, nano(470))
circuit.R('ac', 2, 'in', 470) # Fixme: , m=1, temperature='{25}'

source = str(circuit)
print(source)

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

parser = SpiceParser(source=source)
bootstrap_circuit = parser.build_circuit()

bootstrap_source = str(bootstrap_circuit)
print(bootstrap_source)

assert(source == bootstrap_source)
Example #16
0
#
#.lib CMOS_035_Spice_Model.lib tt
#
#.end
# """

source = """
.title Test
V1 vp GND dc 1.65 ac 0.5
M7 Vout /6 VDD VDD p_33 l=0.9u w=25.9u
M6 Vout /3 GND GND n_33 l=1.4u w=92.04u
M2 /3 vp /1 VDD p_33 l=0.9u w=51.78u
M1 /2 vn /1 VDD p_33 l=0.9u w=51.78u
M4 /3 /2 GND GND n_33 l=1.4u w=46.02u
M3 /2 /2 GND GND n_33 l=1.4u w=46.02u
M5 /1 /6 VDD VDD p_33 l=0.9u w=12.95u
V0 VDD GND 3.3
M8 /6 /6 VDD VDD p_33 l=0.9u w=1.3u
I1 /6 GND 10u
.lib CMOS_035_Spice_Model.lib tt
""".strip()

parser = SpiceParser(source=source)
circuit = parser.build_circuit()
source2 = str(circuit)
for line1, line2 in zip(source.splitlines(), source2.splitlines()):
    print('-'*100)
    print(line1 + '|')
    print(line2 + '|')
    assert(line1 == line2)
Example #17
0
# 1N5919B: 5.6 V, 3.0 W Zener Diode Voltage Regulator
circuit.include(spice_library['d1n5919brl'])

ac_line = circuit.AcLine('input', 'out', 'in', rms_voltage=230, frequency=50)
circuit.R('load', 'out', circuit.gnd, kilo(1))
circuit.C('load', 'out', circuit.gnd, micro(220))
circuit.X('D1', '1N4148', circuit.gnd, 1)
circuit.D(1, circuit.gnd, 1, model='DIODE1', off=True)
circuit.X('Dz1', 'd1n5919brl', 1, 'out')
circuit.C('ac', 1, 2, nano(470))
circuit.R('ac', 2, 'in', 470, m=1, temperature='{25}')

source = str(circuit)
print(source)

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

parser = SpiceParser(source=source)
bootstrap_circuit = parser.build_circuit()

bootstrap_source = str(bootstrap_circuit)
print(bootstrap_source)

assert (source == bootstrap_source)

####################################################################################################
#
# End
#
####################################################################################################