mirror of https://github.com/lnis-uofu/SOFA.git
145 lines
4.7 KiB
Python
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()
|