示例#1
0
def make_bom():
    nl = parse_netlist('process-mbaas.net')

    parts = list(map(process_part, nl.parts))

    part_groups = {}
    for p in parts:
        ref = ''.join([l for l in p['ref'][0] if l in string.ascii_letters])
        k = ref + '-' + p['val'] + '-' + p['fp']
        if p['desc'] is not None:
            k += '-' + p['desc']
        if k in part_groups:
            part_groups[k] += [p]
        else:
            part_groups[k] = [p]

    bom_rows = {}
    for k in part_groups:
        pg = part_groups[k]
        row_key = '-'.join(sorted([refkey(p['ref']) for p in pg]))
        refs = ', '.join(sorted([p['ref'] for p in pg], key=refkey))
        if pg[0]['desc'] is None:
            name = pg[0]['val']
            val = ''
        else:
            name = pg[0]['desc']
            val = pg[0]['val']
        bom_rows[row_key] = dict(refs=refs,
                                 name=name,
                                 val=val,
                                 qty=len(pg),
                                 fp=pg[0]['fp'])

    with open('bom.csv', 'w', newline='') as csvfile:
        w = csv.writer(csvfile)
        w.writerow(['References', 'Component', 'Value', 'Qty', 'Footprint'])
        for k in sorted(bom_rows.keys()):
            row = bom_rows[k]
            w.writerow(
                [row['refs'], row['name'], row['val'], row['qty'], row['fp']])
#documentation https://xesscorp.github.io/kinparse/docs/_build/singlehtml/index.html

from kinparse import parse_netlist

netlist = parse_netlist(
    'kicad-project/test_project_with_uC/test_project_with_uC.net')

print(netlist.version)
print("netlist date: " + netlist.date)

cpu_refs = ['U1']
cpu_values = []

for part in netlist.parts:
    if part.ref in cpu_refs:
        cpu_values.append(part.value)

print(cpu_values)

print(netlist.nets)
示例#3
0
def netlist_to_skidl(netlist_src):

    tab = " " * 4

    def legalize(name):
        """Make a string into a legal python variable name."""
        return re.sub("[^a-zA-Z0-9_]", "_", name)

    def comp_key(comp):
        """Create an ID key from component's major characteristics."""
        chars = [c for c in [comp.lib, comp.name, comp.footprint] if len(c)]
        return legalize("_".join(chars))

    def template_comp_to_skidl(template_comp):
        """Instantiate a component that will be used as a template."""
        ltab = tab

        # Instantiate component template.
        name = comp_key(template_comp)  # python variable name for template.
        lib = template_comp.lib
        part = template_comp.name
        tmpl = "{ltab}{name} = Part('{lib}', '{part}', dest=TEMPLATE".format(**locals())
        footprint = template_comp.footprint
        if len(footprint):
            tmpl += ", footprint='{footprint}'".format(**locals())
        tmpl += ")\n"

        # Set attributes of template using the component fields.
        for fld in template_comp.fields:
            tmpl += "{ltab}setattr({name}, '{fld.name}', '{fld.value}')\n".format(
                **locals()
            )

        return tmpl

    def comp_to_skidl(comp, template_comps):
        """Instantiate components using the component templates."""
        ltab = tab

        # Use the component key to get the template that matches this component.
        template_comp_name = comp_key(comp)
        template_comp = template_comps[template_comp_name]

        # Get the fields for the template.
        template_comp_fields = {fld.name: fld.value for fld in template_comp.fields}

        # Create a legal python variable for storing the instantiated component.
        ref = comp.ref
        legal_ref = legalize(ref)

        # Instantiate the component and its value (if any).
        inst = "{ltab}{legal_ref} = {template_comp_name}(ref='{ref}'".format(**locals())
        if len(comp.value):
            inst += ", value='{comp.value}'".format(**locals())
        inst += ")\n"

        # Set the fields of the instantiated component if they differ from the values in the template.
        for fld in comp.fields:
            if fld.value != template_comp_fields.get(fld.name, ""):
                inst += "{ltab}setattr({legal_ref}, '{fld.name}', '{fld.value}')\n".format(
                    **locals()
                )

        return inst

    def net_to_skidl(net):
        """Instantiate the nets between components."""

        # Build a list of component pins attached to the net.
        pins = []
        for pin in net.pins:
            comp = legalize(pin.ref)  # Name of Python variable storing component.
            pin_num = pin.num  # Pin number of component attached to net.
            pins.append("{comp}['{pin_num}']".format(**locals()))
        pins = ", ".join(pins)  # String the pins into an argument list.

        ltab = tab

        # Instantiate the net, connect the pins to it, and return it.
        return "{ltab}Net('{net.name}').connect({pins})\n".format(**locals())

    def _netlist_to_skidl(ntlst):
        """Convert a netlist into a skidl script."""

        # Sequence of operations:
        #   1. Create a template for each component having a given library, part name and footprint.
        #   2. Instantiate each component using its matching template. Also, set any attributes
        #      for the component that don't match those in the template.
        #   3. Instantiate the nets connecting the component pins.
        #   4. Call the script to instantiate the complete circuit.
        #   5. Generate the netlist for the circuit.

        ltab = tab

        section_div = "#" + "=" * 79
        section_comment = (
            "\n\n{ltab}{section_div}\n{ltab}# {section_desc}\n{ltab}{section_div}\n\n"
        )

        skidl = ""
        skidl += "# -*- coding: utf-8 -*-\n\n"
        skidl += "from skidl import *\n\n\n"
        circuit_name = legalize(ntlst.source)
        skidl += "def {circuit_name}():".format(**locals())

        section_desc = "Component templates."
        skidl += section_comment.format(**locals())
        comp_templates = {comp_key(comp): comp for comp in ntlst.parts}
        template_statements = sorted(
            [template_comp_to_skidl(c) for c in list(comp_templates.values())]
        )
        skidl += "\n".join(template_statements)

        section_desc = "Component instantiations."
        skidl += section_comment.format(**locals())
        comp_inst_statements = sorted(
            [comp_to_skidl(c, comp_templates) for c in ntlst.parts]
        )
        skidl += "\n".join(comp_inst_statements)

        section_desc = "Net interconnections between instantiated components."
        skidl += section_comment.format(**locals())
        net_statements = sorted([net_to_skidl(n) for n in ntlst.nets])
        skidl += "\n".join(net_statements)

        ltab = ""
        section_desc = "Instantiate the circuit and generate the netlist."
        skidl += section_comment.format(**locals())
        ltab = tab
        skidl += 'if __name__ == "__main__":\n'
        skidl += "{ltab}{circuit_name}()\n".format(**locals())
        skidl += "{ltab}generate_netlist()\n".format(**locals())

        return skidl

    return _netlist_to_skidl(parse_netlist(netlist_src))
示例#4
0
def netlist_to_skidl(netlist_src):

    tab = ' ' * 4

    def legalize(name):
        """Make a string into a legal python variable name."""
        return re.sub('[^a-zA-Z0-9_]', '_', name)

    def comp_key(comp):
        """Create an ID key from component's major characteristics."""
        lib = comp.libsource.lib.val
        part = comp.libsource.part.val
        # Do not include the value in the key otherwise every capacitor or
        # resistor value will get its own template.
        try:
            footprint = comp.footprint.val
            return legalize('_'.join([lib, part, footprint]))
        except AttributeError:
            # Component has no assigned footprint.
            return legalize('_'.join([lib, part]))

    def template_comp_to_skidl(template_comp):
        """Instantiate a component that will be used as a template."""
        ltab = tab

        # Instantiate component template.
        name = comp_key(template_comp)  # python variable name for template.
        lib = template_comp.libsource.lib.val
        part = template_comp.libsource.part.val
        try:
            footprint = template_comp.footprint.val
            template_comp_skidl = "{ltab}{name} = Part('{lib}', '{part}', footprint='{footprint}', dest=TEMPLATE)\n".format(
                **locals())
        except AttributeError:
            template_comp_skidl = "{ltab}{name} = Part('{lib}', '{part}', dest=TEMPLATE)\n".format(
                **locals())

        # Set attributes of template using the component fields.
        for fld in template_comp.fields:
            template_comp_skidl += "{ltab}setattr({name}, '{fld.name.val}', '{fld.text}')\n".format(
                **locals())

        return template_comp_skidl

    def comp_to_skidl(comp, template_comps):
        """Instantiate components using the component templates."""
        ltab = tab

        # Use the component key to get the template that matches this component.
        template_comp_name = comp_key(comp)
        template_comp = template_comps[template_comp_name]

        # Get the fields for the template.
        template_comp_fields = {
            fld.name.val: fld.text
            for fld in template_comp.fields
        }

        # Create a legal python variable for storing the instantiated component.
        ref = comp.ref.val
        legal_ref = legalize(ref)

        # Instantiate the component and its value (if any).
        try:
            comp_skidl = "{ltab}{legal_ref} = {template_comp_name}(ref='{ref}', value='{comp.value.val}')\n".format(
                **locals())
        except AttributeError:
            comp_skidl = "{ltab}{legal_ref} = {template_comp_name}(ref='{ref}')\n".format(
                **locals())

        # Set the fields of the instantiated component if they differ from the values in the template.
        for fld in comp.fields:
            if fld.text != template_comp_fields.get(fld.name.val, ''):
                comp_skidl += "{ltab}setattr({legal_ref}, '{fld.name.val}', '{fld.text}')\n".format(
                    **locals())

        return comp_skidl

    def net_to_skidl(net):
        """Instantiate the nets between components."""
        ltab = tab

        code = net.code.val  # Unique code integer for each net.
        name = legalize('net__' + code)  # Python variable name to storing net.
        net_name = net.name.val  # Original net name from netlist.

        # Instantiate the net.
        net_skidl = "{ltab}{name} = Net('{net_name}')\n".format(**locals())

        # Connect component pins to the net.
        net_skidl += "{ltab}{name} += ".format(**locals())
        comp_pins = []
        for n in net.nodes:
            comp_var = legalize(
                n.ref.val)  # Python variable storing component.
            pin_num = n.pin.val  # Pin number of component attached to net.
            comp_pins.append("{comp_var}['{pin_num}']".format(**locals()))
        net_skidl += ', '.join(comp_pins) + '\n'

        return net_skidl

    def _netlist_to_skidl(ntlst):
        """Convert a netlist into a skidl script."""

        # Sequence of operations:
        #   1. Create a template for each component having a given library, part name and footprint.
        #   2. Instantiate each component using its matching template. Also, set any attributes
        #      for the component that don't match those in the template.
        #   3. Instantiate the nets connecting the component pins.
        #   4. Call the script to instantiate the complete circuit.
        #   5. Generate the netlist for the circuit.

        ltab = tab

        section_div = '#' + '=' * 79
        section_comment = "\n\n{ltab}{section_div}\n{ltab}# {section_desc}\n{ltab}{section_div}\n\n"

        skidl = ''
        skidl += '# -*- coding: utf-8 -*-\n\n'
        skidl += 'from skidl import *\n\n\n'
        circuit_name = legalize(ntlst.design.source.val)
        skidl += 'def {circuit_name}():'.format(**locals())

        section_desc = 'Component templates.'
        skidl += section_comment.format(**locals())
        comp_templates = {comp_key(comp): comp for comp in ntlst.components}
        template_statements = sorted(
            [template_comp_to_skidl(c) for c in list(comp_templates.values())])
        skidl += '\n'.join(template_statements)

        section_desc = 'Component instantiations.'
        skidl += section_comment.format(**locals())
        comp_inst_statements = sorted(
            [comp_to_skidl(c, comp_templates) for c in ntlst.components])
        skidl += '\n'.join(comp_inst_statements)

        section_desc = 'Net interconnections between instantiated components.'
        skidl += section_comment.format(**locals())
        net_statements = sorted([net_to_skidl(n) for n in ntlst.nets])
        skidl += '\n'.join(net_statements)

        ltab = ''
        section_desc = 'Instantiate the circuit and generate the netlist.'
        skidl += section_comment.format(**locals())
        ltab = tab
        skidl += 'if __name__ == "__main__":\n'
        skidl += '{ltab}{circuit_name}()\n'.format(**locals())
        skidl += '{ltab}generate_netlist()\n'.format(**locals())

        return skidl

    return _netlist_to_skidl(parse_netlist(netlist_src))
示例#5
0
def main():
    configure_logging()

    footprint = "conservify:TQFP-48_7x7mm_Pitch0.5mm"

    parser = argparse.ArgumentParser(description='')
    parser.add_argument('args', nargs='*')

    args = parser.parse_args()
    working = os.getcwd()

    processed_args = []
    for arg in args.args:
        if os.path.isfile(arg):
            processed_args.append(os.path.abspath(arg))

    combined = {}
    combined[footprint] = PinMap()

    pp = pprint.PrettyPrinter(indent=4, width=1)
    for child_filename in processed_args:
        logger.info("Processing: " + child_filename)
        nl = kinparse.parse_netlist(child_filename)

        netmap = {}
        parts = {}
        for n in nl.nets:
            name = n.name[0]
            connected = len(n.nodes) > 1
            for node in n.nodes:
                ref = node.ref[0]
                pin = node.pin[0]
                refmap = netmap[ref] = netmap.get(ref, {})
                if connected:
                    refmap[pin] = refmap.get(pin, []) + [name]
                else:
                    refmap[pin] = refmap.get(pin, []) + [name + "*"]

        for lp in nl.libparts:
            lp_key = lp.lib[0] + ":" + lp.part[0]
            parts[lp_key] = lp

        for c in nl.components:
            ref = c.ref[0]
            fp = c.footprint[0]
            lp_key = c.libsource[0] + ":" + c.libsource[1]
            if fp == footprint:
                logger.info("Match: ref=%s %s" % (ref, fp))

                part = parts[lp_key]
                for pin in part.pins:
                    num = pin.num[0]
                    name = pin.name[0]
                    nets = ", ".join(netmap[ref][num]).replace("/", "")
                    combined[footprint].add(child_filename, ref, num, name,
                                            nets)
                    if False: logger.info("- %s %s %s" % (num, name, nets))

    for fp, pm in combined.iteritems():
        print("| " + (" | ".join(["Pin"] + pm.boards() + ["Status"])) + " |")
        for pin in pm.pins():
            print("| " + (" | ".join(pm.pin_row(pin))) + " |")
示例#6
0
def kinet2pcb(netlist_origin, brd_filename):
    """Create a .kicad_pcb from a KiCad netlist file."""

    # Get the global and local fp-lib-table file URIs.
    fp_libs = LibURIs(get_global_fp_lib_table_fn(),
                      os.path.join(".", "fp-lib-table"))

    # Create a blank KiCad PCB.
    brd = pcbnew.BOARD()

    # Get the netlist.
    if isinstance(netlist_origin, type('')):
        # Parse the netlist into an object if given a file name string.
        netlist = kinparse.parse_netlist(netlist_origin)
    else:
        # otherwise, the netlist is already an object that can be processed directly.
        netlist = netlist_origin

    # Add the components in the netlist to the PCB.
    for part in netlist.parts:

        # Get the library and footprint name for the part.
        fp_lib, fp_name = part.footprint.split(":")

        # Get the URI of the library directory.
        lib_uri = fp_libs[fp_lib]

        # Create a module from the footprint file.
        fp = pcbnew.FootprintLoad(lib_uri, fp_name)

        # Set the module parameters based on the part data.
        #import pdb; pdb.set_trace()
        fp.SetParent(brd)
        fp.SetReference(part.ref)
        fp.SetValue(part.value)
        # fp.SetTimeStamp(part.sheetpath.tstamps)
        try:
            fp.SetPath(part.sheetpath.names)
        except AttributeError:
            pass

        # Add the module to the PCB.
        brd.Add(fp)

    # Add the nets in the netlist to the PCB.
    cnct = brd.GetConnectivity()
    for net in netlist.nets:

        # Create a net with the current net name.
        pcb_net = pcbnew.NETINFO_ITEM(brd, net.name)

        # Add the net to the PCB.
        brd.Add(pcb_net)

        # Connect the part pins on the netlist net to the PCB net.
        for pin in net.pins:

            # Find the PCB module pad for the current part pin.
            module = brd.FindModuleByReference(pin.ref)
            pad = module.FindPadByName(pin.num)

            # Connect the pad to the PCB net.
            cnct.Add(pad)
            pad.SetNet(pcb_net)

    # Recalculate the PCB part and net data.
    brd.BuildListOfNets()
    cnct.RecalculateRatsnest()
    pcbnew.Refresh()

    # Place the board parts into non-overlapping areas that follow the design hierarchy.
    hierplace.hier_place(brd)

    # Save the PCB into the KiCad PCB file.
    pcbnew.SaveBoard(brd_filename, brd)
示例#7
0
#!/usr/bin/env python2.7
''' This file attempts to get a list of the components from the netlist.
'''

import sys, os, errno
from kinparse import parse_netlist

try:  # Enter fn when running python file. eg: "python rsch.py [fn]"
    fn = sys.argv[1]  # fn=filename
except:
    # If you don't enter a fn, but an existing file matches the
    # keyword below, it will find the file.
    # i.e. "first matching file in ./"
    import glob
    fn = glob.glob('./*.net')[0]

fn_base = os.path.splitext(fn)[0]  # fn without the . extension

print("Loading file: %s" % fn)

# Load netlist
nl = parse_netlist(fn)
print('Netlist generated from: {}'.format(nl.design.source.val))