diff --git a/mxpic_router/builder.py b/mxpic_router/builder.py index e5f1cb8..553d97f 100644 --- a/mxpic_router/builder.py +++ b/mxpic_router/builder.py @@ -268,9 +268,20 @@ def _allows_pdk_ports_as_pins(pdk_root: str) -> bool: return "/opt_pdk_public/" in f"{normalized}/" or "/opt_pdk_atlas/" in f"{normalized}/" -def _metal_route_pcb_enabled(xsection: str) -> bool: - normalized = str(xsection or "").strip().lower().replace("-", "_") - return normalized in {"metal_1", "metal1", "metal_2", "metal2"} +def _route_pcb_enabled(link: LinkSpec) -> bool: + return str(getattr(link, "family", "") or "").strip().lower() == "electrical" + + +def _route_ordered_pins_for_automatic_link(link: LinkSpec, pin1, pin2): + if len(link.points or []) >= 2: + return pin1, pin2 + point1 = _pin_point(pin1) + point2 = _pin_point(pin2) + if point1 is None or point2 is None: + return pin1, pin2 + if point1["x"] > point2["x"]: + return pin2, pin1 + return pin1, pin2 def _route_bundle_links(links: list, pin_map: dict, Route, warnings: list) -> None: @@ -282,6 +293,7 @@ def _route_bundle_links(links: list, pin_map: dict, Route, warnings: list) -> No if p1 is None or p2 is None: by_order[order] = {"link": link, "adjusted_points": None} continue + p1, p2 = _route_ordered_pins_for_automatic_link(link, p1, p2) points = _route_spacing_reference_points(link, p1, p2) if len(points) < 2: by_order[order] = {"link": link, "adjusted_points": None, "adjusted_offset": None} @@ -335,7 +347,7 @@ def _route_bundle_links(links: list, pin_map: dict, Route, warnings: list) -> No radius=plan["link"].radius or 10, width=plan["link"].width, xs=plan["link"].xsection, - PCB=_metal_route_pcb_enabled(plan["link"].xsection), + PCB=_route_pcb_enabled(plan["link"]), ) if plan.get("automatic"): if _route_guided_straight_link(plan["link"], route, warnings, plan["adjusted_points"]): @@ -473,7 +485,7 @@ def _route_direction_sign(delta: float) -> int: def _sbend_span_bucket(value: float) -> int: - return round(float(value) / ROUTE_SBEND_GROUP_SPAN_GRID) + return math.floor(float(value) / ROUTE_SBEND_GROUP_SPAN_GRID) def _route_group_needs_spacing(group: list) -> bool: @@ -727,7 +739,7 @@ def _point_segment_distance(point: dict, start: dict, end: dict) -> float: def _route_link(link: LinkSpec, pin_map: dict, Route, warnings: list, route_options: dict = None) -> None: - route = Route(radius=link.radius or 10, width=link.width, xs=link.xsection, PCB=_metal_route_pcb_enabled(link.xsection)) + route = Route(radius=link.radius or 10, width=link.width, xs=link.xsection, PCB=_route_pcb_enabled(link)) p1 = pin_map.get((link.src_inst, link.src_pin)) p2 = pin_map.get((link.dst_inst, link.dst_pin)) has_pin_endpoints = bool(link.src_inst or link.src_pin or link.dst_inst or link.dst_pin) @@ -744,6 +756,7 @@ def _route_link(link: LinkSpec, pin_map: dict, Route, warnings: list, route_opti if p1 is None or p2 is None: warnings.append(f"Missing route pin for {link.src_inst}:{link.src_pin} -> {link.dst_inst}:{link.dst_pin}") return + p1, p2 = _route_ordered_pins_for_automatic_link(link, p1, p2) method_name = _route_method_name_for_pins(p1, p2) route_method = getattr(route, method_name, None) if route_method is None: