SOFA/SOFA_A/CommonFiles/generate_clock_connectivity.py

145 lines
4.7 KiB
Python

"""
This cript genertes the clock tree for the FPGA
"""
import logging
import os
import pickle
from copy import deepcopy
from glob import glob
from os import environ
from os.path import basename, dirname, realpath
import matplotlib.pyplot as plt
import networkx as nx
from networkx.drawing.nx_pydot import to_pydot
import spydrnet as sdn
from spydrnet_physical.util import ConnectionPattern, ConnectPointList, ConnectPoint
from svgwrite.container import Group, Style
from spydrnet_physical.util import FPGAGridGen
from copy import deepcopy
logger = logging.getLogger("spydrnet_logs")
PROJ_NAME = basename(dirname(realpath(__file__)))
LAYOUT = environ.get("LAYOUT", "ultimate")
EXTRA_STYLE = """
text{display:none;}
.marker{display:none;}
"""
PROJ_NAME = os.environ["PROJ_NAME"]
RELEASE_DIR = os.environ["RELEASE_DIRECTORY"]
FPGA_SIZE_X = int(os.environ["FPGA_SIZE_X"])
FPGA_SIZE_Y = int(os.environ["FPGA_SIZE_Y"])
LAYOUT = os.environ["LAYOUT"]
SVG_DIR = f"{RELEASE_DIR}/svg"
PICKLE_DIR = f"{RELEASE_DIR}/pickle"
def main():
"""
Main method to create clock tree
"""
fpga_width = FPGA_SIZE_X
fpga_height = FPGA_SIZE_Y
WIDTH = fpga_width + 1
HEIGHT = fpga_height + 1
p_manager = ConnectionPattern(WIDTH, HEIGHT)
l2_patt = p_manager.connections
l2_patt.cursor = (int(WIDTH/2) + 1, 0)
l2_patt.move_y(steps=int(WIDTH/2) + 1)
l2_patt.merge(p_manager.get_htree(WIDTH).translate(0, 0))
l2_patt.set_color("red")
for x in range(2):
for y in range(2):
l2_patt.push_connection_down((3 + (x * 4), 3 + (y * 4)))
svg = p_manager.render_pattern(title=PROJ_NAME, scale=7)
svg.saveas(f"{SVG_DIR}/{PROJ_NAME}_clock0_leve2_clear_tree.svg",
pretty=True, indent=4)
save_svg_with_background(svg,
f"{SVG_DIR}/{PROJ_NAME}_clock0_leve2_tree.svg")
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# level1 connection pattern
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
p_manager = ConnectionPattern(WIDTH, HEIGHT)
l1_patt = p_manager.connections
for x in range(2):
for y in range(2):
xx, yy = 1 + (x * 4), 1 + (y * 5)
pattern = p_manager.get_htree(4, repeat=2, side=1)
pattern.points.remove(pattern.search_to_point((0, 0)))
pattern.points.remove(pattern.search_to_point((0, 1)))
pattern.points.remove(pattern.search_to_point((0, 2)))
pattern.points.remove(pattern.search_to_point((0, 3)))
pattern.points.remove(pattern.search_to_point((0, 4)))
pattern.set_cursor(2,2)
pattern.hold_cursor()
pattern.move_y(steps=2-y)
pattern.move_y(value=-1,steps=1+y)
l1_patt.merge(pattern.translate(xx, yy))
l1_patt.set_color("blue")
l1_patt.trim_borders()
l1_patt.translate(0, -1)
l1_patt.trim_borders()
l1_patt.translate(0, 1)
svg = p_manager.render_pattern(title="L1 Pattern", scale=7)
svg.saveas(f"{SVG_DIR}/{PROJ_NAME}_clock0_leve1_clear_tree.svg",
pretty=True, indent=4)
save_svg_with_background(
svg, f"{SVG_DIR}/{PROJ_NAME}_clock0_leve1_tree.svg")
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Combined all patterns
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
p_manager = ConnectionPattern(WIDTH, HEIGHT)
combine_pattern = p_manager.connections
# combine_pattern.merge(l0_patt)
combine_pattern.merge(l1_patt)
combine_pattern.merge(l2_patt)
svg = p_manager.render_pattern(title="Combined Pattern", scale=7)
svg.saveas(f"{SVG_DIR}/{PROJ_NAME}_clock0_combined_clear_tree.svg",
pretty=True, indent=4)
save_svg_with_background(
svg, f"{SVG_DIR}/{PROJ_NAME}_clock0_combined_tree.svg")
def save_svg_with_background(svg, filename, add_marker=False):
'''
Save SVG floorplan file
'''
fpga = pickle.load(
open(f"{PICKLE_DIR}/{PROJ_NAME}_fpgagridgen.pickle", "rb"))
scalex, scaley = 1, 1
# Add main group
groups = {ele["id"]: ele for ele in svg.elements if isinstance(ele, Group)}
main_group = groups["main"]
for style in [ele for ele in svg.elements if isinstance(ele, Style)]:
fpga.dwg.defs.add(style)
fpga.dwg.defs.add(fpga.dwg.style(EXTRA_STYLE))
connections_dwg = fpga.dwg.add(
Group(id="connection",
transform=f"scale({scalex},-{scaley}) translate(-2, -2)")
)
for ele in main_group.elements:
connections_dwg.add(ele)
fpga.dwg.saveas(filename, pretty=True, indent=4)
logger.info("Saving clock rendering in %s", filename)
if __name__ == "__main__":
main()