Skip to content

Commit

Permalink
feat(gen_tcl): add metrics to evaluate NoC's effects on TNS
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-ke committed Jun 2, 2024
1 parent acfb08f commit 2a089ad
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 40 deletions.
16 changes: 15 additions & 1 deletion run_noc_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@
ilp_noc_selector,
random_selector,
)
from tcl_helper import dump_streams_loc_tcl, export_constraint, gen_vivado_prj_tcl
from tcl_helper import (
dump_neg_paths_summary,
dump_streams_loc_tcl,
export_constraint,
gen_vivado_prj_tcl,
parse_neg_paths,
)
from vh1582_nocgraph import vh1582_nocgraph
from vp1802_nocgraph import vp1802_nocgraph

Expand Down Expand Up @@ -84,6 +90,7 @@ class SelectorEnum(Enum):
CONSTRAINT_TCL = "constraint.tcl"
VIVADO_BD_TCL = "arm_bd.tcl"
VIVADO_PRJ_TCL = "run.tcl"
DUMP_NEG_PATHS_TCL = "dump_neg_paths.tcl"

if device_name == DeviceEnum.VP1802.name:
G = vp1802_nocgraph()
Expand Down Expand Up @@ -257,11 +264,18 @@ class SelectorEnum(Enum):
with open(f"{build_dir}/{VIVADO_PRJ_TCL}", "w", encoding="utf-8") as file:
file.write("\n".join(tcl))

tcl = dump_neg_paths_summary(build_dir)
with open(f"{build_dir}/{DUMP_NEG_PATHS_TCL}", "w", encoding="utf-8") as file:
file.write("\n".join(tcl))

# launch vivado
zsh_cmds = f"""
source ~/.zshrc && amd
cd {build_dir}
vivado -mode batch -source {VIVADO_PRJ_TCL}
vivado -mode batch -source {DUMP_NEG_PATHS_TCL}
"""
print(zsh_cmds)
subprocess.run(["zsh", "-c", zsh_cmds], check=True)

parse_neg_paths(build_dir, list(streams_slots.keys()), noc_streams)
213 changes: 174 additions & 39 deletions tcl_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
RapidStream Contributor License Agreement.
"""

import json
import re

from device import Device
from ir_helper import extract_slot_coord, parse_floorplan
from ir_helper import extract_slot_coord


def print_noc_loc_tcl(node_loc: dict[str, tuple[str, str]]) -> None:
Expand All @@ -34,14 +34,14 @@ def print_noc_loc_tcl(node_loc: dict[str, tuple[str, str]]) -> None:


def dump_streams_loc_tcl(
streams_nodes: dict[str, dict[str, list[str]]], selected: list[str]
streams_nodes: dict[str, dict[str, list[str]]], noc_streams: list[str]
) -> list[str]:
"""Dumps the selected streams' NMU and NSU location tcl.
"""Dumps the NoC streams' NMU and NSU location tcl.
Return a list of tcl commands.
"""
tcl = []
for port_num, s in enumerate(selected):
for port_num, s in enumerate(noc_streams):
slot_nmu_nodes = []
slot_nsu_nodes = []
for n in streams_nodes[s]["src"]:
Expand Down Expand Up @@ -191,38 +191,173 @@ def export_constraint(floorplan: dict[str, list[str]], device: Device) -> list[s
return tcl


def dump_neg_paths_summary(build_dir: str) -> list[str]:
"""Generates tcl commands to dump all negative slack paths in the routed checkpoint.
Returns a list of tcl commands.
"""
tcl = [
f"""
open_checkpoint \
{build_dir}/vivado_proj/vivado_proj.runs/impl_1/top_arm_wrapper_routed.dcp
report_timing_summary -setup -max_paths 1000000 -no_pblock -no_header \
-path_type summary -slack_lesser_than 0 \
-file {build_dir}/neg_paths_summary.rpt
close_design
"""
]
return tcl


def parse_neg_paths(
build_dir: str, inter_slot_streams: list[str], noc_streams: list[str]
) -> None:
"""Parses the inter-slot streams and NoC streams' negative slack paths.
Returns None and prints.
"""

with open(f"{build_dir}/neg_paths_summary.rpt", "r", encoding="utf-8") as f:
content = f.read()

# Find the "Max Delay Paths" section
max_delay_paths_section = re.search(
r"Max Delay Paths(.*?)Pulse Width Checks", content, re.DOTALL
)

# Check if the section is found
if not max_delay_paths_section:
print("Max Delay Paths section not found.")
return

# Extract the section content
lines = max_delay_paths_section.group(1).strip().split("\n")

paths = []
# Iterate over the lines to extract startpoint and endpoint names
for i in range(3, len(lines), 3): # Start from the third line and step by 3
if len(lines) > i + 2:
startpoint = lines[i].strip()
endpoint = lines[i + 1].strip()
slack = lines[i + 2].strip()
assert startpoint != ""
assert endpoint != ""
assert float(slack) < 0
paths.append((startpoint, endpoint, slack))

def get_count_and_slack(
paths: list[tuple[str, str, str]], streams: list[str]
) -> tuple[int, float]:
count = 0
total_slack = 0.0
for startpoint, endpoint, slack in paths:
for s in streams:
if s in startpoint and s in endpoint:
count += 1
total_slack += float(slack)
return count, total_slack

print("Number of failing endpoints:", len(paths))
count, total_slack = get_count_and_slack(paths, inter_slot_streams)
print("Number of inter-slot streams paths with negative slack", count)
print("Total negative slack of inter-slot streams:", total_slack)
count, total_slack = get_count_and_slack(paths, noc_streams)
print("Number of selected streams paths with negative slack:", count)
print("Total negative slack of noc-streams:", total_slack)


if __name__ == "__main__":
from vh1582_nocgraph import vh1582_nocgraph

# autobridge json file to extract
SERPENS_IR = "/home/jakeke/Serpens/vhk158/rs_ch28_noc_vivado/noc_pass.json"
with open(SERPENS_IR, "r", encoding="utf-8") as file:
design = json.load(file)

serpens_floorplan = parse_floorplan(design, "axis_noc_if")

print("Number of modules:", sum(len(v) for v in serpens_floorplan.values()))
print(serpens_floorplan.keys())

D = Device(
name="",
slot_width=2,
slot_height=2,
noc_graph=vh1582_nocgraph(),
nmu_per_slot=[], # generated
nsu_per_slot=[], # generated
cr_mapping=[
[
"CLOCKREGION_X0Y0:CLOCKREGION_X4Y4",
"CLOCKREGION_X0Y5:CLOCKREGION_X4Y7",
],
[
"CLOCKREGION_X5Y0:CLOCKREGION_X9Y4",
"CLOCKREGION_X5Y5:CLOCKREGION_X9Y7",
],
],
)

test_tcl = export_constraint(serpens_floorplan, D)
with open("constraint.tcl", "w", encoding="utf-8") as file:
file.write("\n".join(test_tcl))
import subprocess

DUMP_NEG_PATHS_TCL = "dump_neg_paths.tcl"
TEST_DIR = "/home/jakeke/rapidstream-noc/test/build_a48_empty"
test_tcl = dump_neg_paths_summary(TEST_DIR)
with open(f"{TEST_DIR}/{DUMP_NEG_PATHS_TCL}", "w", encoding="utf-8") as file:
file.write("\n".join(test_tcl))

zsh_cmds = f"""
source ~/.zshrc && amd
vivado -mode batch -source {TEST_DIR}/{DUMP_NEG_PATHS_TCL}
"""
print(zsh_cmds)
subprocess.run(["zsh", "-c", zsh_cmds], check=True)

inter_slot_fifos = [
"PE_inst_Serpens_11_hs_if_din",
"PE_inst_Serpens_26_hs_if_din",
"PE_inst_Serpens_33_hs_if_din",
"Yvec_inst_Serpens_2_hs_if_din",
"Yvec_inst_Serpens_8_hs_if_din",
"fifo_A_Serpens_0_hs_if_din",
"fifo_A_Serpens_10_hs_if_din",
"fifo_A_Serpens_1_hs_if_din",
"fifo_A_Serpens_2_hs_if_din",
"fifo_A_Serpens_33_hs_if_din",
"fifo_A_Serpens_34_hs_if_din",
"fifo_A_Serpens_35_hs_if_din",
"fifo_A_Serpens_36_hs_if_din",
"fifo_A_Serpens_37_hs_if_din",
"fifo_A_Serpens_38_hs_if_din",
"fifo_A_Serpens_39_hs_if_din",
"fifo_A_Serpens_3_hs_if_din",
"fifo_A_Serpens_40_hs_if_din",
"fifo_A_Serpens_41_hs_if_din",
"fifo_A_Serpens_42_hs_if_din",
"fifo_A_Serpens_43_hs_if_din",
"fifo_A_Serpens_44_hs_if_din",
"fifo_A_Serpens_45_hs_if_din",
"fifo_A_Serpens_46_hs_if_din",
"fifo_A_Serpens_47_hs_if_din",
"fifo_A_Serpens_4_hs_if_din",
"fifo_A_Serpens_5_hs_if_din",
"fifo_A_Serpens_6_hs_if_din",
"fifo_A_Serpens_7_hs_if_din",
"fifo_A_Serpens_8_hs_if_din",
"fifo_A_Serpens_9_hs_if_din",
"fifo_X_pe_Serpens_11_hs_if_din",
"fifo_X_pe_Serpens_26_hs_if_din",
"fifo_X_pe_Serpens_33_hs_if_din",
"fifo_Y_pe_Serpens_11_hs_if_din",
"fifo_Y_pe_Serpens_12_hs_if_din",
"fifo_Y_pe_Serpens_13_hs_if_din",
"fifo_Y_pe_Serpens_14_hs_if_din",
"fifo_Y_pe_Serpens_15_hs_if_din",
"fifo_Y_pe_Serpens_16_hs_if_din",
"fifo_Y_pe_Serpens_17_hs_if_din",
"fifo_Y_pe_Serpens_24_hs_if_din",
"fifo_Y_pe_Serpens_25_hs_if_din",
"fifo_Y_pe_Serpens_2_hs_if_din",
"fifo_Y_pe_Serpens_33_hs_if_din",
"fifo_Y_pe_Serpens_34_hs_if_din",
"fifo_Y_pe_Serpens_35_hs_if_din",
"fifo_Y_pe_Serpens_8_hs_if_din",
"fifo_Y_pe_abd_Serpens_3_hs_if_din",
"fifo_Y_pe_abd_Serpens_6_hs_if_din",
"fifo_Y_pe_abd_Serpens_7_hs_if_din",
"fifo_aXvec_Serpens_2_hs_if_din",
"fifo_aXvec_Serpens_8_hs_if_din",
]

selected = [
"PE_inst_Serpens_11_hs_if_din",
"Yvec_inst_Serpens_8_hs_if_din",
"fifo_A_Serpens_0_hs_if_din",
"fifo_A_Serpens_2_hs_if_din",
"fifo_A_Serpens_39_hs_if_din",
"fifo_A_Serpens_3_hs_if_din",
"fifo_A_Serpens_43_hs_if_din",
"fifo_A_Serpens_47_hs_if_din",
"fifo_A_Serpens_7_hs_if_din",
"fifo_X_pe_Serpens_11_hs_if_din",
"fifo_X_pe_Serpens_26_hs_if_din",
"fifo_X_pe_Serpens_33_hs_if_din",
"fifo_Y_pe_Serpens_2_hs_if_din",
"fifo_Y_pe_Serpens_33_hs_if_din",
"fifo_Y_pe_Serpens_34_hs_if_din",
"fifo_Y_pe_Serpens_35_hs_if_din",
"fifo_Y_pe_abd_Serpens_6_hs_if_din",
"fifo_Y_pe_abd_Serpens_7_hs_if_din",
"fifo_aXvec_Serpens_8_hs_if_din",
]

parse_neg_paths(TEST_DIR, inter_slot_fifos, selected)

0 comments on commit 2a089ad

Please sign in to comment.