上传文件至「mxpic_router」
This commit is contained in:
+119
-9
@@ -313,7 +313,7 @@ def _route_bundle_links(links: list, pin_map: dict, Route, warnings: list) -> No
|
|||||||
plans.append(plan)
|
plans.append(plan)
|
||||||
by_order[order] = plan
|
by_order[order] = plan
|
||||||
|
|
||||||
_assign_sbend_lstart_spacing(plans)
|
_assign_bend_route_spacing(plans)
|
||||||
|
|
||||||
accepted = []
|
accepted = []
|
||||||
for plan in plans:
|
for plan in plans:
|
||||||
@@ -365,29 +365,78 @@ def _route_bundle_links(links: list, pin_map: dict, Route, warnings: list) -> No
|
|||||||
f"{plan['link'].src_inst}:{plan['link'].src_pin} -> "
|
f"{plan['link'].src_inst}:{plan['link'].src_pin} -> "
|
||||||
f"{plan['link'].dst_inst}:{plan['link'].dst_pin}"
|
f"{plan['link'].dst_inst}:{plan['link'].dst_pin}"
|
||||||
)
|
)
|
||||||
|
if plan.get("route_options", {}).get("length"):
|
||||||
|
warnings.append(
|
||||||
|
f"Applied ubend length {plan['route_options']['length']:g}um to "
|
||||||
|
f"{plan['link'].src_inst}:{plan['link'].src_pin} -> "
|
||||||
|
f"{plan['link'].dst_inst}:{plan['link'].dst_pin}"
|
||||||
|
)
|
||||||
_route_link(plan["link"], pin_map, Route, warnings, plan.get("route_options"))
|
_route_link(plan["link"], pin_map, Route, warnings, plan.get("route_options"))
|
||||||
|
|
||||||
|
|
||||||
def _assign_sbend_lstart_spacing(plans: list) -> None:
|
def _assign_bend_route_spacing(plans: list) -> None:
|
||||||
groups = {}
|
groups = {}
|
||||||
for plan in plans:
|
for plan in plans:
|
||||||
if not plan.get("automatic"):
|
if not plan.get("automatic"):
|
||||||
continue
|
continue
|
||||||
if _route_method_name_for_pins(plan["pin1"], plan["pin2"]) != "sbend_p2p":
|
method_name = _route_method_name_for_pins(plan["pin1"], plan["pin2"])
|
||||||
|
if method_name not in {"sbend_p2p", "ubend_p2p"}:
|
||||||
continue
|
continue
|
||||||
key = _sbend_spacing_group_key(plan)
|
key = _bend_spacing_group_key(plan, method_name)
|
||||||
if key is None:
|
if key is None:
|
||||||
continue
|
continue
|
||||||
groups.setdefault(key, []).append(plan)
|
bucket = groups.setdefault(key, {"method": method_name, "plans": []})
|
||||||
|
bucket["plans"].append(plan)
|
||||||
|
|
||||||
for group in groups.values():
|
for bucket in groups.values():
|
||||||
|
group = bucket["plans"]
|
||||||
if len(group) < 2:
|
if len(group) < 2:
|
||||||
continue
|
continue
|
||||||
axis = _sbend_forward_axis(group[0])
|
axis = _sbend_forward_axis(group[0])
|
||||||
coord_key = "y" if axis == "horizontal" else "x"
|
coord_key = "y" if axis == "horizontal" else "x"
|
||||||
step = _sbend_lstart_step(group)
|
step = _sbend_lstart_step(group)
|
||||||
for plan, rank in _sbend_lstart_ranks(group, coord_key):
|
if bucket["method"] == "sbend_p2p":
|
||||||
plan["route_options"]["Lstart"] = rank * step
|
ranked_plans = _sbend_lstart_ranks(group, coord_key)
|
||||||
|
else:
|
||||||
|
ranked_plans = _ubend_length_ranks(group, coord_key)
|
||||||
|
for plan, rank in ranked_plans:
|
||||||
|
if bucket["method"] == "sbend_p2p":
|
||||||
|
plan["route_options"]["Lstart"] = rank * step
|
||||||
|
else:
|
||||||
|
plan["route_options"]["length"] = rank * step
|
||||||
|
|
||||||
|
_assign_mixed_bend_route_spacing(plans)
|
||||||
|
|
||||||
|
|
||||||
|
def _assign_mixed_bend_route_spacing(plans: list) -> None:
|
||||||
|
groups = {}
|
||||||
|
for plan in plans:
|
||||||
|
if not plan.get("automatic"):
|
||||||
|
continue
|
||||||
|
method_name = _route_method_name_for_pins(plan["pin1"], plan["pin2"])
|
||||||
|
if method_name not in {"sbend_p2p", "ubend_p2p"}:
|
||||||
|
continue
|
||||||
|
key = _mixed_bend_spacing_group_key(plan)
|
||||||
|
if key is None:
|
||||||
|
continue
|
||||||
|
bucket = groups.setdefault(key, {"methods": set(), "plans": []})
|
||||||
|
bucket["methods"].add(method_name)
|
||||||
|
bucket["plans"].append(plan)
|
||||||
|
|
||||||
|
for bucket in groups.values():
|
||||||
|
if len(bucket["methods"]) < 2:
|
||||||
|
continue
|
||||||
|
group = bucket["plans"]
|
||||||
|
axis = _sbend_forward_axis(group[0])
|
||||||
|
coord_key = "y" if axis == "horizontal" else "x"
|
||||||
|
step = _sbend_lstart_step(group)
|
||||||
|
for method_name, plan, rank in _mixed_bend_route_ranks(group, coord_key, step):
|
||||||
|
if method_name == "sbend_p2p":
|
||||||
|
plan["route_options"]["Lstart"] = rank * step
|
||||||
|
plan["route_options"].pop("length", None)
|
||||||
|
else:
|
||||||
|
plan["route_options"]["length"] = rank * step
|
||||||
|
plan["route_options"].pop("Lstart", None)
|
||||||
|
|
||||||
|
|
||||||
def _sbend_lstart_step(group: list) -> float:
|
def _sbend_lstart_step(group: list) -> float:
|
||||||
@@ -413,13 +462,52 @@ def _sbend_lstart_ranks(group: list, coord_key: str) -> list:
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _ubend_length_ranks(group: list, coord_key: str) -> list:
|
||||||
|
spans = [round(abs(_route_coord_delta(plan, coord_key)), 6) for plan in group]
|
||||||
|
nonzero_spans = [span for span in spans if span > 1e-9]
|
||||||
|
if nonzero_spans and len(set(nonzero_spans)) > 1:
|
||||||
|
ordered_spans = sorted(set(spans))
|
||||||
|
return [(plan, ordered_spans.index(round(abs(_route_coord_delta(plan, coord_key)), 6)) + 1) for plan in group]
|
||||||
|
|
||||||
|
center = sum(_route_start_coord(plan, coord_key) for plan in group) / len(group)
|
||||||
|
distances = sorted({round(abs(_route_start_coord(plan, coord_key) - center), 6) for plan in group})
|
||||||
|
return [
|
||||||
|
(plan, distances.index(round(abs(_route_start_coord(plan, coord_key) - center), 6)) + 1)
|
||||||
|
for plan in group
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _mixed_bend_route_ranks(group: list, coord_key: str, step: float) -> list:
|
||||||
|
ubend_plans = [plan for plan in group if _route_method_name_for_pins(plan["pin1"], plan["pin2"]) == "ubend_p2p"]
|
||||||
|
sbend_plans = [plan for plan in group if _route_method_name_for_pins(plan["pin1"], plan["pin2"]) == "sbend_p2p"]
|
||||||
|
ranked = []
|
||||||
|
ubend_ranked = _ubend_length_ranks(ubend_plans, coord_key)
|
||||||
|
for plan, rank in ubend_ranked:
|
||||||
|
ranked.append(("ubend_p2p", plan, rank))
|
||||||
|
first_sbend_rank = _mixed_first_sbend_rank_after_ubends(ubend_ranked, step)
|
||||||
|
for plan, rank in _sbend_lstart_ranks(sbend_plans, coord_key):
|
||||||
|
ranked.append(("sbend_p2p", plan, first_sbend_rank + rank - 1))
|
||||||
|
return ranked
|
||||||
|
|
||||||
|
|
||||||
|
def _mixed_first_sbend_rank_after_ubends(ubend_ranked: list, step: float) -> int:
|
||||||
|
if not ubend_ranked:
|
||||||
|
return 1
|
||||||
|
max_length = max(rank * step for plan, rank in ubend_ranked)
|
||||||
|
max_radius = max((_safe_float(plan["link"].radius, 10.0) or 10.0) for plan, rank in ubend_ranked)
|
||||||
|
total_width = sum((_safe_float(plan["link"].width, 0.5) or 0.5) for plan, rank in ubend_ranked)
|
||||||
|
spacing_slots = len(ubend_ranked) + 1
|
||||||
|
ubend_envelope = max_length + max_radius + total_width + spacing_slots * ROUTE_MIN_SPACING
|
||||||
|
return max(1, math.ceil(ubend_envelope / step))
|
||||||
|
|
||||||
|
|
||||||
def _route_coord_delta(plan: dict, coord_key: str) -> float:
|
def _route_coord_delta(plan: dict, coord_key: str) -> float:
|
||||||
start = plan["points"][0]
|
start = plan["points"][0]
|
||||||
end = plan["points"][-1]
|
end = plan["points"][-1]
|
||||||
return float(end[coord_key]) - float(start[coord_key])
|
return float(end[coord_key]) - float(start[coord_key])
|
||||||
|
|
||||||
|
|
||||||
def _sbend_spacing_group_key(plan: dict):
|
def _bend_spacing_group_key(plan: dict, method_name: str):
|
||||||
link = plan["link"]
|
link = plan["link"]
|
||||||
axis = _sbend_forward_axis(plan)
|
axis = _sbend_forward_axis(plan)
|
||||||
main_key = "x" if axis == "horizontal" else "y"
|
main_key = "x" if axis == "horizontal" else "y"
|
||||||
@@ -433,6 +521,27 @@ def _sbend_spacing_group_key(plan: dict):
|
|||||||
_sbend_span_bucket(plan["points"][0][main_key]),
|
_sbend_span_bucket(plan["points"][0][main_key]),
|
||||||
_sbend_span_bucket(plan["points"][-1][main_key]),
|
_sbend_span_bucket(plan["points"][-1][main_key]),
|
||||||
)
|
)
|
||||||
|
return (
|
||||||
|
method_name,
|
||||||
|
axis,
|
||||||
|
_route_direction_sign(main_delta),
|
||||||
|
route_scope,
|
||||||
|
str(link.xsection or ""),
|
||||||
|
_safe_float(link.width, 0.0),
|
||||||
|
_safe_float(link.radius, 0.0),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _mixed_bend_spacing_group_key(plan: dict):
|
||||||
|
link = plan["link"]
|
||||||
|
axis = _sbend_forward_axis(plan)
|
||||||
|
main_key = "x" if axis == "horizontal" else "y"
|
||||||
|
main_delta = _route_coord_delta(plan, main_key)
|
||||||
|
explicit_group = _link_explicit_route_group(link)
|
||||||
|
if explicit_group:
|
||||||
|
route_scope = ("explicit", explicit_group)
|
||||||
|
else:
|
||||||
|
route_scope = ("start-span", _sbend_span_bucket(plan["points"][0][main_key]))
|
||||||
return (
|
return (
|
||||||
axis,
|
axis,
|
||||||
_route_direction_sign(main_delta),
|
_route_direction_sign(main_delta),
|
||||||
@@ -1143,6 +1252,7 @@ class _NazcaInterconnectRoute:
|
|||||||
width=self._route_width(width),
|
width=self._route_width(width),
|
||||||
radius=self._route_radius(radius),
|
radius=self._route_radius(radius),
|
||||||
xs=self._route_xs(xs),
|
xs=self._route_xs(xs),
|
||||||
|
length=kwargs.get("length", 0),
|
||||||
arrow=arrow,
|
arrow=arrow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user