6.12. Implementing memeory bank protocol on Tile02

This example demonstate how to create a tile strcuture from Verilog netlist obtained from OpenFPGA

../_images/_tile02_mb_floorplan.svg
import glob
import logging
from pathlib import Path
import tempfile
from itertools import chain
from os import path

import spydrnet as sdn
from spydrnet_physical import PROP
from spydrnet_physical.util import (FloorPlanViz, Tile02,
                                    sram_configuration,
                                    GridFloorplanGen, OpenFPGA)


logger = logging.getLogger('spydrnet_logs')
sdn.enable_file_logging(LOG_LEVEL='INFO')


STYLE_SHEET = '''
    symbol[id*='tile'] * {number:01; fill:#d9d9f3;}
    .over_util {fill:#b22222 !important}
    text{font-family: Lato; font-size: 15px;}
'''


def main():
    proj = '../homogeneous_k6n10_standalone_fabric'
    source_files = glob.glob(f'{proj}/*_Verilog/lb/*.v')
    source_files += glob.glob(f'{proj}/*_Verilog/routing/*.v')
    source_files += glob.glob(f'{proj}/*_Verilog/sub_module/*.v')
    source_files += glob.glob(f'{proj}/*_Verilog/fpga_top.v')

    # Temporary fix to read multiple verilog files
    with tempfile.NamedTemporaryFile(suffix=".v") as fp:
        for each_verilog in source_files:
            with open(each_verilog, "r", encoding="UTF-8") as fpv:
                fp.write(str.encode(" ".join(fpv.readlines())))
        fp.seek(0)
        netlist = sdn.parse(fp.name)

    fpga = OpenFPGA(grid=[4, 4], netlist=netlist)
    fpga.design_top_stat()

    # Convert wires to bus structure
    fpga.create_grid_clb_bus()
    fpga.create_grid_io_bus()
    fpga.create_sb_bus()
    fpga.create_cb_bus()

    # Remove undriven nets
    fpga.remove_undriven_nets()
    fpga.remove_config_chain()

    # Convert top level independent nets to bus
    for i in chain(fpga.top_module.get_instances("grid_clb*"),
                   fpga.top_module.get_instances("grid_io*"),
                   fpga.top_module.get_instances("sb_*")):
        for p in filter(lambda x: True, i.reference.ports):
            if p.size > 1 and (i.check_all_scalar_connections(p)):
                cable_list = []
                for pin in p.pins[::-1]:
                    cable_list.append(i.pins[pin].wire.cable)
                cable = fpga.top_module.combine_cables(
                    f"{i.name}_{p.name}", cable_list)
                cable.is_downto = False

    # Before Creating Tiles
    # fpga.design_top_stat()

    # Merge grid IOs
    fpga.merge_all_grid_ios()
    # Create area-optimized tiles
    fpga.register_tile_generator(Tile02)
    fpga.create_tiles()
    merge_wl_bl_ports(fpga)

    # Add configuration circuit
    logger.handlers[0].setLevel(logging.DEBUG)
    fpga.register_config_generator(sram_configuration)
    # fpga.config_creator.print_configuration_bit_matrix()
    fpga.config_creator.set_wl_distribution([4, 4, 4, 4, 4])
    logger.info("word_line_rows = %s", fpga.config_creator.word_line_rows)
    logger.info("bit_line_cols  = %s", fpga.config_creator.bit_line_cols)
    fpga.config_creator.remove_bl_wl_lines()
    fpga.add_configuration_scheme()
    logger.handlers[0].setLevel(logging.INFO)

    with open("_instance_hierarchy.txt", "w", encoding="UTF-8") as fp:
        fp.write(fpga.hierarchy(fpga.netlist.top_instance, max_depth=3))
    with open("_instance_hierarchy.txt", "w", encoding="UTF-8") as fp:
        fp.write(fpga.hierarchy(
            next(fpga.top_module.get_definitions("tile")), max_depth=10))
    # After Creating Tiles
    # fpga.design_top_stat()

    for each in fpga.top_module.get_definitions("*"):
        each.properties["LABEL"] = each.properties.get("CONFIG_BITS", 0)

Following section is for rendering only

    # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    #           Floorplan visualization
    # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    # Create grid plan
    grid_plan = GridFloorplanGen(5, 5, grid_x=220, grid_y=220)

    grid_plan.offset_x = 10
    grid_plan.offset_y = 10
    grid_plan.set_column_width(1, 120)
    grid_plan.set_row_height(1, 120)

    for module in fpga.top_module.get_definitions("*tile*"):
        module.data[PROP]["WIDTH"] = 200
        module.data[PROP]["HEIGHT"] = 200
        module.data[PROP]["COLOR"] = "#E6BA95"

    for module in fpga.top_module.get_definitions("*bottom*tile"):
        module.data[PROP]["HEIGHT"] = 100

    for module in fpga.top_module.get_definitions("*left*tile"):
        module.data[PROP]["WIDTH"] = 100

    for xi in range(5, 0, -1):
        for yi in range(5, 0, -1):
            x_offset, y_offset = 10, 10
            points = grid_plan.get_x_y(xi-1, yi-1)
            try:
                inst = next(fpga.top_module.get_instances(f"*_{xi}__{yi}_*"))
            except StopIteration:
                continue

            inst.data[PROP]['LOC_X'] = points[0] + x_offset
            inst.data[PROP]['LOC_Y'] = points[1] + y_offset

    fpga.top_module.data[PROP]["WIDTH"] = grid_plan.width + 20
    fpga.top_module.data[PROP]["HEIGHT"] = grid_plan.height + 20

    fpga.save_shaping_data("*", scale=0.01, filename="_tile01_shaping.txt")

    # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    #                   Visualize floorplan
    # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
    fp = FloorPlanViz(fpga.top_module)
    fp.compose(skip_connections=True, skip_pins=True)
    fp.custom_style_sheet = STYLE_SHEET
    dwg = fp.get_svg()
    dwg.add(grid_plan.render_grid(return_group=True))
    dwg.saveas("_tile02_mb_floorplan.svg", pretty=True, indent=4)

    # Save netlist
    base_dir = "_output_tile04"
    Path(base_dir).mkdir(parents=True, exist_ok=True)
    fpga.save_netlist("sb*", path.join(base_dir, "routing"))
    fpga.save_netlist("cb*", path.join(base_dir, "routing"))
    fpga.save_netlist("grid*", path.join(base_dir, "lb"))
    fpga.save_netlist("*tile*", path.join(base_dir, "tiles"))
    fpga.save_netlist("fpga_top", path.join(base_dir))


def merge_wl_bl_ports(fpga: OpenFPGA):
    W, H = fpga.fpga_size
    for module in fpga.top_module.get_definitions("*"):
        bl_ports = list(module.get_ports("bl*"))
        if bl_ports:
            for bl in bl_ports[::-1]:
                module.split_port(bl)
            module.combine_ports("bl", list(module.get_ports("bl*"))[::-1])
        wl_ports = list(module.get_ports("wl*"))
        if wl_ports:
            for wl in wl_ports[::-1]:
                module.split_port(wl)
            module.combine_ports("wl", list(module.get_ports("wl*"))[::-1])


if __name__ == "__main__":
    main()

6.12.1. Output Shaping File

      INSTANCE              MODULE          LOC_X      LOC_Y    SHAPE BBOX_PT  POINTS              
 = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     tile_2__2_              tile               1.40       1.40   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_2__3_              tile               1.40       3.60   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_2__4_              tile               1.40       5.80   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_3__2_              tile               3.60       1.40   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_3__3_              tile               3.60       3.60   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_3__4_              tile               3.60       5.80   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_4__2_              tile               5.80       1.40   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_4__3_              tile               5.80       3.60   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_4__4_              tile               5.80       5.80   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_5__2_           right_tile            8.00       1.40   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_5__3_           right_tile            8.00       3.60   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_5__4_           right_tile            8.00       5.80   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_2__5_            top_tile             1.40       8.00   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_3__5_            top_tile             3.60       8.00   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_4__5_            top_tile             5.80       8.00   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_1__5_         top_left_tile           0.20       8.00   rect     4    0.000  0.000  0.000  2.000  1.000  2.000  1.000  0.000
     tile_5__5_         top_right_tile          8.00       8.00   rect     4    0.000  0.000  0.000  2.000  2.000  2.000  2.000  0.000
     tile_1__1_        bottom_left_tile         0.20       0.20   rect     4    0.000  0.000  0.000  1.000  1.000  1.000  1.000  0.000
     tile_5__1_       bottom_right_tile         8.00       0.20   rect     4    0.000  0.000  0.000  1.000  2.000  1.000  2.000  0.000
     tile_1__2_           left_tile             0.20       1.40   rect     4    0.000  0.000  0.000  2.000  1.000  2.000  1.000  0.000
     tile_1__3_           left_tile             0.20       3.60   rect     4    0.000  0.000  0.000  2.000  1.000  2.000  1.000  0.000
     tile_1__4_           left_tile             0.20       5.80   rect     4    0.000  0.000  0.000  2.000  1.000  2.000  1.000  0.000
     tile_2__1_          bottom_tile            1.40       0.20   rect     4    0.000  0.000  0.000  1.000  2.000  1.000  2.000  0.000
     tile_3__1_          bottom_tile            3.60       0.20   rect     4    0.000  0.000  0.000  1.000  2.000  1.000  2.000  0.000
     tile_4__1_          bottom_tile            5.80       0.20   rect     4    0.000  0.000  0.000  1.000  2.000  1.000  2.000  0.000
      fpga_top             fpga_top             0.00       0.00   rect     4    0.000  0.000  0.000  10.200  10.200  10.200  10.200  0.000

Total running time of the script: ( 0 minutes 0.000 seconds)

Gallery generated by Sphinx-Gallery