Beispiel #1
0
 def make_dffs(rst_types):
     for rst_type in rst_types:
         cell = Cell(f"DFF{rst_type}")
         cell.add_port("D", Direction.Input)
         cell.add_port(rst_type, Direction.Input)
         cell.add_port("C", Direction.Input)
         cell.add_port("Q", Direction.Output)
         library.add_cell(cell)
Beispiel #2
0
        def make_luts(max_size):
            for lut_size in range(1, max_size + 1):
                name = f"LUT{lut_size}"
                init = f"{2 ** lut_size}'h0"
                cell = Cell(name=name, property_map={"INIT": init})

                print(name, init)

                in_ports = list()
                for port in range(lut_size):
                    port_name = f"I{port}"
                    cell.add_port(port_name, Direction.Input)
                    in_ports.append(port_name)

                cell.add_port("O", Direction.Output)
                library.add_cell(cell)

                param = Parameter("INIT", ParameterFormat.VERILOG_HEX, init)
                self.device.add_parameter(name, param)
                self.device.add_lut_cell(name, in_ports, 'INIT')
Beispiel #3
0
def output_interchange(top, capnp_folder, part, f_logical, f_physical, f_xdc):
    """ Output FPGA interchange from top level Module class object.

    top (Module) - Top level module.
    capnp_folder (str) - Path to the interchange capnp folder
    part (str) - Part for physical netlist.
    f_logical (file-like) - File to output logical_netlist.Netlist.
    f_physical (file-like) - File to output physical_netlist.PhysNetlist.

    """
    interchange = Interchange(capnp_folder)

    hdi_primitives = Library('hdi_primitives')
    work = Library('work')
    libraries = {hdi_primitives.name: hdi_primitives, work.name: work}

    top_cell = Cell(top.name)

    # Create source cells for constant nets.  They are required to have some
    # name, so give them one.
    #
    # TODO: Iterate net names on this?  This feels wrong/weird.  Need to
    # handle net name collisions?
    constant_nets = {
        0: "GLOBAL_LOGIC0",
        1: "GLOBAL_LOGIC1",
    }

    top_cell.add_cell_instance(name='VCC', cell_name="VCC")
    top_cell.add_net(constant_nets[1])
    top_cell.connect_net_to_instance(
        net_name=constant_nets[1], instance_name='VCC', port="P")

    top_cell.add_cell_instance(name='GND', cell_name="GND")
    top_cell.add_net(constant_nets[0])
    top_cell.connect_net_to_instance(
        net_name=constant_nets[0], instance_name='GND', port="G")

    # Parse top level port names, and convert to bussed ports as needed.
    create_top_level_ports(top_cell, top, top.root_in, Direction.Input)
    create_top_level_ports(top_cell, top, top.root_out, Direction.Output)
    create_top_level_ports(top_cell, top, top.root_inout, Direction.Inout)

    for wire, width in make_bus(top.wires):
        wire = unescape_verilog_name(wire)
        if width is None:
            top_cell.add_net(name=wire)
        else:
            for idx in range(width + 1):
                top_cell.add_net(name='{}[{}]'.format(wire, idx))

    # Update/create wire_name_net_map from the BELs.
    for site in top.sites:
        for bel in site.bels:
            bel.make_net_map(top=top, net_map=top.wire_name_net_map)

    for sink_wire, source_wire in top.wire_assigns.yield_wires():
        net_name = flatten_wires(source_wire, top.wire_assigns,
                                 top.wire_name_net_map)
        if sink_wire in top.wire_name_net_map:
            assert top.wire_name_net_map[sink_wire] == net_name
        else:
            top.wire_name_net_map[sink_wire] = net_name

    # Create a list of each primative instances to later build up a primative
    # model library.
    hdi_primitives_cells = {}

    # Create cells instances from each bel in the design.
    for site in top.sites:
        for bel in sorted(site.bels, key=lambda bel: bel.priority):
            bel.output_interchange(
                top_cell=top_cell,
                top=top,
                net_map=top.wire_name_net_map,
                constant_nets=constant_nets,
            )

            if bel.parent_cell is not None:
                continue

            if bel.module not in hdi_primitives_cells:
                hdi_primitives_cells[bel.module] = []

            hdi_primitives_cells[bel.module].append(bel)

    # Add top level cell to the work cell library.
    work.add_cell(top_cell)

    # Construct library cells based on data from top module.
    for cellname in hdi_primitives_cells:
        instances = hdi_primitives_cells[cellname]

        cell = Cell(cellname)

        ports = {}
        for instance in instances:
            _, connections, port_is_output = instance.create_connections(top)

            for port in connections:
                if port_is_output[port]:
                    # The current model doesn't handle IO at all, so add
                    # special cases for IO ports in the library.
                    if cellname.startswith('IOBUF') and port == "IO":
                        direction = Direction.Inout
                    else:
                        direction = Direction.Output
                else:
                    direction = Direction.Input

                width = connections[port].bus_width()
                if port in instance.port_width:
                    if width is not None:
                        assert width <= instance.port_width[port], port

                    width = instance.port_width[port]

                if port in ports:
                    port_dir, port_width = ports[port]
                    assert port_dir == direction, (port, direction, port_dir,
                                                   port_width)
                    if width is not None:
                        assert port_width <= width

                        if width > port_width:
                            ports[port] = (direction, width)
                    else:
                        assert port_width is None
                else:
                    ports[port] = (direction, width)

            # Add instances of unconnected ports (as needed).
            for port, direction in instance.port_direction.items():
                width = instance.port_width[port]

                if direction == "output":
                    direction = Direction.Output
                elif direction == "inout":
                    direction = Direction.Inout
                else:
                    assert direction == "input", direction
                    direction = Direction.Input

                if port in ports:
                    assert (direction, width) == ports[port]
                else:
                    ports[port] = (direction, width)

        for port, (direction, width) in ports.items():

            if width is not None:
                cell.add_bus_port(port, direction, start=width - 1, end=0)
            else:
                cell.add_port(port, direction)

        hdi_primitives.add_cell(cell)

    # Make sure VCC and GND primatives are in the library.
    if "VCC" not in hdi_primitives.cells:
        cell = Cell("VCC")
        cell.add_port("P", Direction.Output)

        hdi_primitives.add_cell(cell)

    if "GND" not in hdi_primitives.cells:
        cell = Cell("GND")
        cell.add_port("G", Direction.Output)

        hdi_primitives.add_cell(cell)

    # Logical netlist is complete, output to file now!
    logical_netlist = LogicalNetlist(
        name=top.name,
        property_map={},
        top_instance_name=top.name,
        top_instance=CellInstance(
            cell_name=top.name, view='netlist', property_map={}),
        libraries=libraries,
    ).convert_to_capnp(interchange)
    write_capnp_file(logical_netlist, f_logical)

    physical_netlist = PhysicalNetlist(part=part)

    site_type_pins = {}

    # Convert sites and bels into placement directives and physical nets.
    net_stubs = {}
    sub_cell_nets = {}
    for site in top.sites:
        physical_netlist.add_site_instance(site.site.name, site.site_type())

        for bel in site.bels:
            if bel.site is None or (bel.bel is None
                                    and len(bel.physical_bels) == 0):
                continue

            cell_instance = unescape_verilog_name(bel.get_cell(top))

            # bel.physical_bels is used to represent a transformation that
            # happens from the library cell (e.g. LUT6_2) into lower
            # primatives (LUT6_2 -> (LUT6, LUT5)).
            #
            # Rather than implement generic transformation support, for now
            # models implement the transformation by adding physical bels to
            # generate the correct placement constraints.
            #
            # TODO: Revisit this in the future?
            if len(bel.physical_bels) == 0:
                # Straight forward case, 1 logical Cell -> 1 physical Bel
                placement = Placement(
                    cell_type=bel.module,
                    cell_name=cell_instance,
                    site=bel.site,
                    bel=bel.bel,
                )

                for (bel_name,
                     bel_pin), cell_pin in bel.bel_pins_to_cell_pins.items():
                    placement.add_bel_pin_to_cell_pin(
                        bel_pin=bel_pin,
                        cell_pin=cell_pin,
                        bel=bel_name,
                    )

                physical_netlist.placements.append(placement)
            else:
                # Transformation cases, create a placement constraint for
                # each bel in the physical_bels list.
                #
                # These represent a cell within the primative, hence the "/"
                # when constructing the cell name.
                for phys_bel in bel.physical_bels:
                    placement = Placement(
                        cell_type=phys_bel.module,
                        cell_name=cell_instance + '/' + phys_bel.name,
                        site=bel.site,
                        bel=phys_bel.bel,
                    )

                    for (bel_name, bel_pin
                         ), cell_pin in phys_bel.bel_pins_to_cell_pins.items():
                        placement.add_bel_pin_to_cell_pin(
                            bel_pin=bel_pin,
                            cell_pin=cell_pin,
                            bel=bel_name,
                        )

                    physical_netlist.placements.append(placement)

        # Convert site routing to PhysicalNetlist objects (PhysicalBelPin,
        # PhysicalSitePin, PhysicalSitePip).
        #
        # Note: Calling output_site_routing must be done before
        # output_interchange_nets to ensure that Bel.final_net_names gets
        # populated, as that is computed during Site.output_site_routing.
        new_nets = site.output_site_routing(
            top=top,
            parent_cell=top_cell,
            net_map=top.wire_name_net_map,
            constant_nets=constant_nets,
            sub_cell_nets=sub_cell_nets)

        for site_pin, site_type_pin in site.site_type_pins.items():
            site_type_pins[site.site.name, site_pin] = site_type_pin

        # Extend net stubs with the site routing.
        for net_name in new_nets:
            if net_name not in net_stubs:
                net_stubs[net_name] = []

            net_stubs[net_name].extend(new_nets[net_name])

    # Convert top level routing nets to pip lists and to relevant nets
    for net_name, pips in top.output_interchange_nets(
            constant_nets=constant_nets):
        if net_name not in net_stubs:
            net_stubs[net_name] = []

        for tile, wire0, wire1 in pips:
            # TODO: Better handling of bipips?
            net_stubs[net_name].append(
                PhysicalPipForStitching(
                    tile=tile, wire0=wire0, wire1=wire1, forward=False))

    net_to_type = {}
    for val, net_name in constant_nets.items():
        if val == 0:
            net_to_type[net_name] = PhysicalNetType.Gnd
        else:
            assert val == 1
            net_to_type[net_name] = PhysicalNetType.Vcc

    cursor = top.conn.cursor()
    for net_name in net_stubs:
        sources = []
        stubs = net_stubs[net_name]
        sources, stubs = stitch_stubs(net_stubs[net_name], cursor,
                                      site_type_pins)

        physical_netlist.add_physical_net(
            net_name=sub_cell_nets.get(net_name, net_name),
            sources=sources,
            stubs=stubs,
            net_type=net_to_type.get(net_name, PhysicalNetType.Signal))

    phys_netlist_capnp = physical_netlist.convert_to_capnp(interchange)
    write_capnp_file(phys_netlist_capnp, f_physical)

    for l in top.output_extra_tcl():
        print(l, file=f_xdc)
Beispiel #4
0
def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--schema_dir', required=True)
    parser.add_argument('--library', default="primitives")
    parser.add_argument('device_in')
    parser.add_argument('yosys_json')
    parser.add_argument('device_out')

    args = parser.parse_args()
    interchange = Interchange(args.schema_dir)
    with open(args.device_in, 'rb') as f:
        device = read_capnp_file(interchange.device_resources_schema.Device, f)

    device = device.as_builder()

    with open(args.yosys_json) as f:
        yosys_json = json.load(f)

    prim_lib = Library(args.library)

    assert 'modules' in yosys_json, yosys_json.keys()
    for module_name, module_data in sorted(yosys_json['modules'].items(),
                                           key=lambda x: x[0]):
        # Library should only contain blackboxes
        assert module_data['attributes'].get('blackbox', 0) or \
            module_data['attributes'].get('whitebox', 0), module_name
        property_map = {}
        if 'attributes' in module_data:
            property_map.update(module_data['attributes'])
        if 'parameters' in module_data:
            property_map.update(module_data['parameters'])
        cell = Cell(module_name, property_map)

        for port_name, port_data in module_data['ports'].items():
            if port_data['direction'] == 'input':
                direction = Direction.Input
            elif port_data['direction'] == 'output':
                direction = Direction.Output
            else:
                assert port_data['direction'] == 'inout'
                direction = Direction.Inout

            property_map = {}
            if 'attributes' in port_data:
                property_map = port_data['attributes']

            offset = port_data.get('offset', 0)
            upto = port_data.get('upto', False)

            if is_bus(port_data['bits'], offset, upto):
                end = offset
                start = offset + len(port_data['bits']) - 1

                if upto:
                    start, end = end, start

                cell.add_bus_port(name=port_name,
                                  direction=direction,
                                  start=start,
                                  end=end,
                                  property_map=property_map)
            else:
                cell.add_port(name=port_name,
                              direction=direction,
                              property_map=property_map)
        prim_lib.add_cell(cell)

    libraries = {}
    libraries[args.library] = prim_lib
    # Create the netlist
    netlist = LogicalNetlist(name=args.library,
                             property_map={},
                             top_instance_name=None,
                             top_instance=None,
                             libraries=libraries)

    str_list = [s for s in device.strList]

    netlist_capnp = netlist.convert_to_capnp(interchange,
                                             indexed_strings=str_list)

    # Patch device
    device.primLibs = netlist_capnp

    if len(device.strList) != len(str_list):
        # At least 1 string was added to the list, update the strList.
        device.init('strList', len(str_list))

        for idx, s in enumerate(str_list):
            device.strList[idx] = s

    # Save patched device
    with open(args.device_out, 'wb') as f:
        write_capnp_file(device, f)
    def make_primitives_library(self):

        # Primitives library
        library = Library("primitives")
        self.device.cell_libraries["primitives"] = library

        cell = Cell("LUT")
        cell.add_port("A0", Direction.Input)
        cell.add_port("A1", Direction.Input)
        cell.add_port("A2", Direction.Input)
        cell.add_port("A3", Direction.Input)
        cell.add_port("O", Direction.Output)
        library.add_cell(cell)

        cell = Cell("DFF")
        cell.add_port("D", Direction.Input)
        cell.add_port("R", Direction.Input)
        cell.add_port("C", Direction.Input)
        cell.add_port("Q", Direction.Output)
        library.add_cell(cell)

        cell = Cell("IB")
        cell.add_port("I", Direction.Output)
        cell.add_port("P", Direction.Input)
        library.add_cell(cell)

        cell = Cell("OB")
        cell.add_port("O", Direction.Input)
        cell.add_port("P", Direction.Output)
        library.add_cell(cell)

        cell = Cell("VCC")
        cell.add_port("V", Direction.Output)
        library.add_cell(cell)

        cell = Cell("GND")
        cell.add_port("G", Direction.Output)
        library.add_cell(cell)

        # Macros library
        library = Library("macros")
        self.device.cell_libraries["macros"] = library
Beispiel #6
0
def convert_cell(device, module_name, module_data, library, libraries, modules,
                 verbose, errors, consts):
    for cell_name, cell_data in module_data['cells'].items():
        # Don't import modules that are missing children, they likely aren't
        # important.
        if cell_data['type'] not in modules:
            errors[
                module_name] = 'Failed to import cell type {} because it has a undefined cell {}'.format(
                    module_name, cell_data['type'])
            return

    property_map = {}
    if 'attributes' in module_data:
        property_map = module_data['attributes']

    cell = Cell(module_name, property_map)
    libraries[library].add_cell(cell)

    net_duplicate_names = {}

    def add_net(net_name, net_data, track_duplicates=False):
        property_map = {}
        if 'attributes' in net_data:
            property_map.update(net_data['attributes'])

        offset = net_data.get('offset', 0)
        upto = net_data.get('upto', 0)
        if is_bus(net_data['bits'], offset, upto):
            for bit_index, bit in interp_yosys_net(net_data['bits'], offset,
                                                   upto):
                name = '{}[{}]'.format(net_name, bit_index)
                cell.add_net(name, property_map)

                if bit == '0':
                    cell.connect_net_to_instance(
                        name, make_gnd_cell(cell, module_data, consts),
                        consts.GND_PORT)
                elif bit == '1':
                    cell.connect_net_to_instance(
                        name, make_vcc_cell(cell, module_data, consts),
                        consts.VCC_PORT)
                else:
                    assert isinstance(bit, int), bit

                    if bit in net_bits:
                        if track_duplicates:
                            net_duplicate_names[net_bits[bit]].append(name)
                        continue

                    assert bit not in net_bits, (module_name, bit,
                                                 net_bits.keys())
                    net_bits[bit] = name
                    net_duplicate_names[name] = []
        else:
            cell.add_net(net_name, property_map)

            bit = net_data['bits'][0]
            if bit == '0':
                cell.connect_net_to_instance(
                    net_name, make_gnd_cell(cell, module_data, consts),
                    consts.GND_PORT)
            elif bit == '1':
                cell.connect_net_to_instance(
                    net_name, make_vcc_cell(cell, module_data, consts),
                    consts.VCC_PORT)
            else:
                assert isinstance(bit, int)

                if bit in net_bits:
                    if track_duplicates:
                        net_duplicate_names[net_bits[bit]].append(net_name)
                    return

                assert bit not in net_bits, (module_name, bit, net_bits.keys())
                net_bits[bit] = net_name
                net_duplicate_names[net_name] = []

    net_bits = {}
    for net_name, net_data in module_data['netnames'].items():
        if net_name in module_data['ports']:
            continue

        if net_data.get('hide_name', 0):
            continue

        add_net(net_name, net_data, track_duplicates=False)

    for net_name, net_data in module_data['netnames'].items():
        if net_name not in module_data['ports']:
            continue

        add_net(net_name, net_data, track_duplicates=True)

    for net_name, net_data in module_data['netnames'].items():
        if net_data.get('hide_name', 0) != 1:
            continue

        add_net(net_name, net_data, track_duplicates=False)

    vcc_cell = None
    vcc_net = None

    gnd_cell = None
    gnd_net = None

    def get_net(bit):
        if bit == '0':
            nonlocal gnd_cell
            nonlocal gnd_net
            if gnd_cell is None:
                gnd_cell = make_gnd_cell(cell, module_data, consts)
                net_names = set(cell.nets.keys()) | set(
                    module_data['netnames'].keys())
                gnd_net = create_unique_name(net_names, '$__gnd_net')

                cell.add_net(gnd_net)
                cell.connect_net_to_instance(gnd_net, gnd_cell,
                                             consts.GND_PORT)

            return gnd_net
        elif bit == '1':
            nonlocal vcc_cell
            nonlocal vcc_net
            if vcc_cell is None:
                vcc_cell = make_vcc_cell(cell, module_data, consts)
                net_names = set(cell.nets.keys()) | set(
                    module_data['netnames'].keys())
                vcc_net = create_unique_name(net_names, '$__vcc_net')

                cell.add_net(vcc_net)
                cell.connect_net_to_instance(vcc_net, vcc_cell,
                                             consts.VCC_PORT)

            return vcc_net
        else:
            assert isinstance(bit, int)
            return net_bits[bit]

    for port_name, port_data in module_data['ports'].items():
        if port_data['direction'] == 'input':
            direction = Direction.Input
        elif port_data['direction'] == 'output':
            direction = Direction.Output
        else:
            assert port_data['direction'] == 'inout'
            direction = Direction.Inout

        property_map = {}
        if 'attributes' in port_data:
            property_map = port_data['attributes']

        offset = port_data.get('offset', 0)
        upto = port_data.get('upto', False)

        if is_bus(port_data['bits'], offset, upto):
            end = offset
            start = offset + len(port_data['bits']) - 1

            if upto:
                start, end = end, start

            cell.add_bus_port(
                name=port_name,
                direction=direction,
                start=start,
                end=end,
                property_map=property_map)

            for bit_index, bit in interp_yosys_net(port_data['bits'], offset,
                                                   upto):
                cell.connect_net_to_cell_port(
                    get_net(bit), port_name, bit_index)
        else:
            cell.add_port(
                name=port_name, direction=direction, property_map=property_map)
            cell.connect_net_to_cell_port(
                get_net(port_data['bits'][0]), port_name)

    for cell_name, cell_data in module_data['cells'].items():
        property_map = {}
        if 'attributes' in cell_data:
            property_map.update(cell_data['attributes'])

        if 'parameters' in cell_data:
            property_map.update(cell_data['parameters'])

        convert_parameters(device, cell_name, cell_data['type'], property_map)

        # Set default parameters if not already set from Yosys.
        device.add_default_parameters(cell_data['type'], property_map)

        cell.add_cell_instance(
            name=cell_name,
            cell_name=cell_data['type'],
            property_map=property_map)

        cell_type = modules[cell_data['type']]
        for port_name, bits in cell_data['connections'].items():
            port = cell_type['ports'][port_name]
            offset = port.get('offset', 0)
            upto = port.get('upto', False)

            if is_bus(bits, offset, upto):
                for bit_index, bit in interp_yosys_net(bits, offset, upto):
                    cell.connect_net_to_instance(
                        get_net(bit), cell_name, port_name, bit_index)
            else:
                cell.connect_net_to_instance(
                    get_net(bits[0]), cell_name, port_name)
Beispiel #7
0
def example_logical_netlist():
    hdi_primitives = Library('hdi_primitives')

    cell = Cell('FDRE')
    cell.add_port('D', Direction.Input)
    cell.add_port('C', Direction.Input)
    cell.add_port('CE', Direction.Input)
    cell.add_port('R', Direction.Input)
    cell.add_port('Q', Direction.Output)
    hdi_primitives.add_cell(cell)

    cell = Cell('IBUF')
    cell.add_port('I', Direction.Input)
    cell.add_port('O', Direction.Output)
    hdi_primitives.add_cell(cell)

    cell = Cell('OBUF')
    cell.add_port('I', Direction.Input)
    cell.add_port('O', Direction.Output)
    hdi_primitives.add_cell(cell)

    cell = Cell('BUFG')
    cell.add_port('I', Direction.Input)
    cell.add_port('O', Direction.Output)
    hdi_primitives.add_cell(cell)

    cell = Cell('VCC')
    cell.add_port('P', Direction.Output)
    hdi_primitives.add_cell(cell)

    cell = Cell('GND')
    cell.add_port('G', Direction.Output)
    hdi_primitives.add_cell(cell)

    top = Cell('top')
    top.add_port('i', Direction.Input)
    top.add_port('clk', Direction.Input)
    top.add_port('o', Direction.Output)

    top.add_cell_instance('ibuf', 'IBUF')
    top.add_cell_instance('obuf', 'OBUF')
    top.add_cell_instance('clk_ibuf', 'IBUF')
    top.add_cell_instance('clk_buf', 'BUFG')
    top.add_cell_instance('ff', 'FDRE')
    top.add_cell_instance('VCC', 'VCC')
    top.add_cell_instance('GND', 'GND')

    top.add_net('i')
    top.connect_net_to_cell_port('i', 'i')
    top.connect_net_to_instance('i', 'ibuf', 'I')

    top.add_net('i_buf')
    top.connect_net_to_instance('i_buf', 'ibuf', 'O')
    top.connect_net_to_instance('i_buf', 'ff', 'D')

    top.add_net('o_buf')
    top.connect_net_to_instance('o_buf', 'ff', 'Q')
    top.connect_net_to_instance('o_buf', 'obuf', 'I')

    top.add_net('o')
    top.connect_net_to_instance('o', 'obuf', 'O')
    top.connect_net_to_cell_port('o', 'o')

    top.add_net('clk')
    top.connect_net_to_cell_port('clk', 'clk')
    top.connect_net_to_instance('clk', 'clk_ibuf', 'I')

    top.add_net('clk_ibuf')
    top.connect_net_to_instance('clk_ibuf', 'clk_ibuf', 'O')
    top.connect_net_to_instance('clk_ibuf', 'clk_buf', 'I')

    top.add_net('clk_buf')
    top.connect_net_to_instance('clk_buf', 'clk_buf', 'O')
    top.connect_net_to_instance('clk_buf', 'ff', 'C')

    top.add_net('GLOBAL_LOGIC1')
    top.connect_net_to_instance('GLOBAL_LOGIC1', 'VCC', 'P')
    top.connect_net_to_instance('GLOBAL_LOGIC1', 'ff', 'CE')

    top.add_net('GLOBAL_LOGIC0')
    top.connect_net_to_instance('GLOBAL_LOGIC0', 'GND', 'G')
    top.connect_net_to_instance('GLOBAL_LOGIC0', 'ff', 'R')

    work = Library('work')
    work.add_cell(top)

    logical_netlist = LogicalNetlist(name='top',
                                     top_instance_name='top',
                                     top_instance=CellInstance(
                                         cell_name='top',
                                         view='netlist',
                                         property_map={},
                                     ),
                                     property_map={},
                                     libraries={
                                         'work': work,
                                         'hdi_primitives': hdi_primitives,
                                     })

    return logical_netlist
Beispiel #8
0
    def make_primitives_library(self):

        # Primitives library
        library = Library("primitives")
        self.device.cell_libraries["primitives"] = library

        def make_luts(max_size):
            for lut_size in range(1, max_size + 1):
                name = f"LUT{lut_size}"
                init = f"{2 ** lut_size}'h0"
                cell = Cell(name=name, property_map={"INIT": init})

                print(name, init)

                in_ports = list()
                for port in range(lut_size):
                    port_name = f"I{port}"
                    cell.add_port(port_name, Direction.Input)
                    in_ports.append(port_name)

                cell.add_port("O", Direction.Output)
                library.add_cell(cell)

                param = Parameter("INIT", ParameterFormat.VERILOG_HEX, init)
                self.device.add_parameter(name, param)
                self.device.add_lut_cell(name, in_ports, 'INIT')

        make_luts(4)

        def make_dffs(rst_types):
            for rst_type in rst_types:
                cell = Cell(f"DFF{rst_type}")
                cell.add_port("D", Direction.Input)
                cell.add_port(rst_type, Direction.Input)
                cell.add_port("C", Direction.Input)
                cell.add_port("Q", Direction.Output)
                library.add_cell(cell)

        make_dffs(["S", "R"])

        cell = Cell("IB")
        cell.add_port("I", Direction.Output)
        cell.add_port("P", Direction.Input)
        library.add_cell(cell)

        cell = Cell("OB")
        cell.add_port("O", Direction.Input)
        cell.add_port("P", Direction.Output)
        library.add_cell(cell)

        cell = Cell("VCC")
        cell.add_port("V", Direction.Output)
        library.add_cell(cell)

        cell = Cell("GND")
        cell.add_port("G", Direction.Output)
        library.add_cell(cell)

        # Macros library
        library = Library("macros")
        self.device.cell_libraries["macros"] = library