上传文件至「tests」
This commit is contained in:
+337
-145
@@ -59,10 +59,10 @@ class EdaRouterPinsContractTest(unittest.TestCase):
|
|||||||
self.assertEqual(link.bundle, "output_bus")
|
self.assertEqual(link.bundle, "output_bus")
|
||||||
self.assertEqual(link.points[1], {"x": 50.0, "y": 0.0})
|
self.assertEqual(link.points[1], {"x": 50.0, "y": 0.0})
|
||||||
|
|
||||||
def test_loader_accepts_explicit_link_route_group_metadata(self):
|
def test_loader_accepts_explicit_link_route_group_metadata(self):
|
||||||
from mxpic_router.eda_loader import parse_cell_dict
|
from mxpic_router.eda_loader import parse_cell_dict
|
||||||
|
|
||||||
spec = parse_cell_dict({
|
spec = parse_cell_dict({
|
||||||
"name": "cell_a",
|
"name": "cell_a",
|
||||||
"bundles": {
|
"bundles": {
|
||||||
"output_bus": {
|
"output_bus": {
|
||||||
@@ -76,46 +76,46 @@ class EdaRouterPinsContractTest(unittest.TestCase):
|
|||||||
})
|
})
|
||||||
|
|
||||||
link = spec.bundles["output_bus"].links[0]
|
link = spec.bundles["output_bus"].links[0]
|
||||||
self.assertEqual(link.bundle, "output_bus")
|
self.assertEqual(link.bundle, "output_bus")
|
||||||
self.assertEqual(link.route_group, "stage_1")
|
self.assertEqual(link.route_group, "stage_1")
|
||||||
|
|
||||||
def test_builder_uses_frontend_bundle_key_as_explicit_route_group(self):
|
def test_builder_uses_frontend_bundle_key_as_explicit_route_group(self):
|
||||||
from mxpic_router.builder import _link_explicit_route_group
|
from mxpic_router.builder import _link_explicit_route_group
|
||||||
from mxpic_router.eda_loader import LinkSpec
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_link_explicit_route_group(LinkSpec(bundle="optical_bus")),
|
_link_explicit_route_group(LinkSpec(bundle="optical_bus")),
|
||||||
"optical_bus",
|
"optical_bus",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_link_explicit_route_group(LinkSpec(bundle="free_wires")),
|
_link_explicit_route_group(LinkSpec(bundle="free_wires")),
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_link_explicit_route_group(LinkSpec(bundle="free_wires_metal_1")),
|
_link_explicit_route_group(LinkSpec(bundle="free_wires_metal_1")),
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_link_explicit_route_group(LinkSpec(bundle="output_bus")),
|
_link_explicit_route_group(LinkSpec(bundle="output_bus")),
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_link_explicit_route_group(LinkSpec(bundle="output_bus", route_group="stage_1")),
|
_link_explicit_route_group(LinkSpec(bundle="output_bus", route_group="stage_1")),
|
||||||
"stage_1",
|
"stage_1",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_route_pcb_flag_uses_electrical_family(self):
|
def test_route_pcb_flag_uses_electrical_family(self):
|
||||||
from mxpic_router.builder import _route_pcb_enabled
|
from mxpic_router.builder import _route_pcb_enabled
|
||||||
from mxpic_router.eda_loader import LinkSpec
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
self.assertTrue(_route_pcb_enabled(LinkSpec(xsection="custom_metal_top", family="electrical")))
|
self.assertTrue(_route_pcb_enabled(LinkSpec(xsection="custom_metal_top", family="electrical")))
|
||||||
self.assertTrue(_route_pcb_enabled(LinkSpec(xsection="strip", family="Electrical")))
|
self.assertTrue(_route_pcb_enabled(LinkSpec(xsection="strip", family="Electrical")))
|
||||||
self.assertFalse(_route_pcb_enabled(LinkSpec(xsection="metal_1", family="optical")))
|
self.assertFalse(_route_pcb_enabled(LinkSpec(xsection="metal_1", family="optical")))
|
||||||
self.assertFalse(_route_pcb_enabled(LinkSpec(xsection="metal_2", family="")))
|
self.assertFalse(_route_pcb_enabled(LinkSpec(xsection="metal_2", family="")))
|
||||||
|
|
||||||
def test_port_element_creates_named_io_pins_and_inside_route_pins(self):
|
def test_port_element_creates_named_io_pins_and_inside_route_pins(self):
|
||||||
from mxpic_router.builder import _register_element_pins
|
from mxpic_router.builder import _register_element_pins
|
||||||
from mxpic_router.eda_loader import parse_cell_dict
|
from mxpic_router.eda_loader import parse_cell_dict
|
||||||
|
|
||||||
class FakePlacedPin:
|
class FakePlacedPin:
|
||||||
def __init__(self, name, x, y, a):
|
def __init__(self, name, x, y, a):
|
||||||
@@ -624,9 +624,9 @@ class EdaRouterPinsContractTest(unittest.TestCase):
|
|||||||
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
||||||
self.assertEqual(lstarts, [21.4, 10.7])
|
self.assertEqual(lstarts, [21.4, 10.7])
|
||||||
|
|
||||||
def test_sbend_lstart_spacing_keeps_separate_route_stages_ordered(self):
|
def test_sbend_lstart_spacing_keeps_separate_route_stages_ordered(self):
|
||||||
from mxpic_router.builder import _route_bundle_links
|
from mxpic_router.builder import _route_bundle_links
|
||||||
from mxpic_router.eda_loader import LinkSpec
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
class FakePin:
|
class FakePin:
|
||||||
def __init__(self, x, y, angle):
|
def __init__(self, x, y, angle):
|
||||||
@@ -679,104 +679,296 @@ class EdaRouterPinsContractTest(unittest.TestCase):
|
|||||||
|
|
||||||
_route_bundle_links(links, pin_map, FakeRoute, [])
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
||||||
self.assertEqual(lstarts[:4], [50.0, 100.0, 150.0, 200.0])
|
self.assertEqual(lstarts[:4], [50.0, 100.0, 150.0, 200.0])
|
||||||
self.assertEqual(lstarts[4:], [150.0, 200.0, 100.0, 50.0])
|
self.assertEqual(lstarts[4:], [150.0, 200.0, 100.0, 50.0])
|
||||||
|
|
||||||
def test_automatic_routes_are_ordered_from_lower_x_to_higher_x(self):
|
def test_automatic_routes_are_ordered_from_lower_x_to_higher_x(self):
|
||||||
from mxpic_router.builder import _route_bundle_links
|
from mxpic_router.builder import _route_bundle_links
|
||||||
from mxpic_router.eda_loader import LinkSpec
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
class FakePin:
|
class FakePin:
|
||||||
def __init__(self, x, y, angle):
|
def __init__(self, x, y, angle):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.a = angle
|
self.a = angle
|
||||||
|
|
||||||
class FakeRoute:
|
class FakeRoute:
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def sbend_p2p(self, **kwargs):
|
def sbend_p2p(self, **kwargs):
|
||||||
self.calls.append(("sbend_p2p", kwargs))
|
self.calls.append(("sbend_p2p", kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def put(self):
|
def put(self):
|
||||||
self.calls.append(("put", {}))
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
FakeRoute.calls = []
|
FakeRoute.calls = []
|
||||||
links = [
|
links = [
|
||||||
LinkSpec(src_inst="left_top", src_pin="out", dst_inst="right_top", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="left_top", src_pin="out", dst_inst="right_top", dst_pin="in", width=40, radius=10),
|
||||||
LinkSpec(src_inst="right_mid", src_pin="out", dst_inst="left_mid", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="right_mid", src_pin="out", dst_inst="left_mid", dst_pin="in", width=40, radius=10),
|
||||||
LinkSpec(src_inst="left_bot", src_pin="out", dst_inst="right_bot", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="left_bot", src_pin="out", dst_inst="right_bot", dst_pin="in", width=40, radius=10),
|
||||||
]
|
]
|
||||||
pin_map = {
|
pin_map = {
|
||||||
("left_top", "out"): FakePin(0, 40, 0),
|
("left_top", "out"): FakePin(0, 40, 0),
|
||||||
("right_top", "in"): FakePin(100, 10, 180),
|
("right_top", "in"): FakePin(100, 10, 180),
|
||||||
("right_mid", "out"): FakePin(100, 0, 180),
|
("right_mid", "out"): FakePin(100, 0, 180),
|
||||||
("left_mid", "in"): FakePin(0, 30, 0),
|
("left_mid", "in"): FakePin(0, 30, 0),
|
||||||
("left_bot", "out"): FakePin(0, 20, 0),
|
("left_bot", "out"): FakePin(0, 20, 0),
|
||||||
("right_bot", "in"): FakePin(100, -10, 180),
|
("right_bot", "in"): FakePin(100, -10, 180),
|
||||||
}
|
}
|
||||||
|
|
||||||
_route_bundle_links(links, pin_map, FakeRoute, [])
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
calls = [call[1] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
calls = [call[1] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
||||||
self.assertTrue(all(call["pin1"].x <= call["pin2"].x for call in calls))
|
self.assertTrue(all(call["pin1"].x <= call["pin2"].x for call in calls))
|
||||||
self.assertEqual([call["Lstart"] for call in calls], [150.0, 100.0, 50.0])
|
self.assertEqual([call["Lstart"] for call in calls], [150.0, 100.0, 50.0])
|
||||||
|
|
||||||
def test_sbend_lstart_spacing_keeps_nearby_span_bucket_boundary_routes_together(self):
|
def test_sbend_lstart_spacing_keeps_nearby_span_bucket_boundary_routes_together(self):
|
||||||
from mxpic_router.builder import _route_bundle_links
|
from mxpic_router.builder import _route_bundle_links
|
||||||
from mxpic_router.eda_loader import LinkSpec
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
class FakePin:
|
class FakePin:
|
||||||
def __init__(self, x, y, angle):
|
def __init__(self, x, y, angle):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.a = angle
|
self.a = angle
|
||||||
|
|
||||||
class FakeRoute:
|
class FakeRoute:
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def sbend_p2p(self, **kwargs):
|
def sbend_p2p(self, **kwargs):
|
||||||
self.calls.append(("sbend_p2p", kwargs))
|
self.calls.append(("sbend_p2p", kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def put(self):
|
def put(self):
|
||||||
self.calls.append(("put", {}))
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
FakeRoute.calls = []
|
FakeRoute.calls = []
|
||||||
links = [
|
links = [
|
||||||
LinkSpec(src_inst="r1", src_pin="out", dst_inst="p1", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="r1", src_pin="out", dst_inst="p1", dst_pin="in", width=40, radius=10),
|
||||||
LinkSpec(src_inst="r2", src_pin="out", dst_inst="p2", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="r2", src_pin="out", dst_inst="p2", dst_pin="in", width=40, radius=10),
|
||||||
LinkSpec(src_inst="r3", src_pin="out", dst_inst="p3", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="r3", src_pin="out", dst_inst="p3", dst_pin="in", width=40, radius=10),
|
||||||
LinkSpec(src_inst="r4", src_pin="out", dst_inst="p4", dst_pin="in", width=40, radius=10),
|
LinkSpec(src_inst="r4", src_pin="out", dst_inst="p4", dst_pin="in", width=40, radius=10),
|
||||||
]
|
]
|
||||||
pin_map = {
|
pin_map = {
|
||||||
("r1", "out"): FakePin(2090.95, -1968.2, 0),
|
("r1", "out"): FakePin(2090.95, -1968.2, 0),
|
||||||
("p1", "in"): FakePin(2651.75, -2090.5, 180),
|
("p1", "in"): FakePin(2651.75, -2090.5, 180),
|
||||||
("r2", "out"): FakePin(2087.15, -2073.9, 0),
|
("r2", "out"): FakePin(2087.15, -2073.9, 0),
|
||||||
("p2", "in"): FakePin(2653.25, -2201.4, 180),
|
("p2", "in"): FakePin(2653.25, -2201.4, 180),
|
||||||
("r3", "out"): FakePin(2086.55, -2190.0, 0),
|
("r3", "out"): FakePin(2086.55, -2190.0, 0),
|
||||||
("p3", "in"): FakePin(2647.45, -2312.3, 180),
|
("p3", "in"): FakePin(2647.45, -2312.3, 180),
|
||||||
("r4", "out"): FakePin(2085.85, -2285.2, 0),
|
("r4", "out"): FakePin(2085.85, -2285.2, 0),
|
||||||
("p4", "in"): FakePin(2649.45, -2411.1, 180),
|
("p4", "in"): FakePin(2649.45, -2411.1, 180),
|
||||||
}
|
}
|
||||||
|
|
||||||
_route_bundle_links(links, pin_map, FakeRoute, [])
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
lstarts = [call[1]["Lstart"] for call in FakeRoute.calls if call[0] == "sbend_p2p"]
|
||||||
self.assertEqual(lstarts, [200.0, 150.0, 100.0, 50.0])
|
self.assertEqual(lstarts, [200.0, 150.0, 100.0, 50.0])
|
||||||
|
|
||||||
def test_route_backend_falls_back_to_nazca_interconnect_when_forge_is_absent(self):
|
def test_ubend_spacing_uses_inner_shorter_outer_longer_length_within_bundle(self):
|
||||||
import mxpic_router.builder as builder
|
from mxpic_router.builder import _route_bundle_links
|
||||||
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
class FakeInterconnect:
|
|
||||||
|
class FakePin:
|
||||||
|
def __init__(self, x, y, angle):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.a = angle
|
||||||
|
|
||||||
|
class FakeRoute:
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ubend_p2p(self, **kwargs):
|
||||||
|
self.calls.append(("ubend_p2p", kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put(self):
|
||||||
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
|
FakeRoute.calls = []
|
||||||
|
links = [
|
||||||
|
LinkSpec(src_inst="r1", src_pin="out", dst_inst="p1", dst_pin="in", width=40, radius=10),
|
||||||
|
LinkSpec(src_inst="r2", src_pin="out", dst_inst="p2", dst_pin="in", width=40, radius=10),
|
||||||
|
LinkSpec(src_inst="r3", src_pin="out", dst_inst="p3", dst_pin="in", width=40, radius=10),
|
||||||
|
]
|
||||||
|
pin_map = {
|
||||||
|
("r1", "out"): FakePin(0, 40, 0),
|
||||||
|
("p1", "in"): FakePin(100, 40, 0),
|
||||||
|
("r2", "out"): FakePin(0, 30, 0),
|
||||||
|
("p2", "in"): FakePin(100, 30, 0),
|
||||||
|
("r3", "out"): FakePin(0, 20, 0),
|
||||||
|
("p3", "in"): FakePin(100, 20, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
warnings = []
|
||||||
|
_route_bundle_links(links, pin_map, FakeRoute, warnings)
|
||||||
|
|
||||||
|
calls = [call[1] for call in FakeRoute.calls if call[0] == "ubend_p2p"]
|
||||||
|
self.assertEqual([call["length"] for call in calls], [100.0, 50.0, 100.0])
|
||||||
|
self.assertTrue(all("Lstart" not in call for call in calls))
|
||||||
|
self.assertTrue(any("Applied ubend length 50um" in warning for warning in warnings))
|
||||||
|
|
||||||
|
def test_ubend_spacing_uses_symmetric_nested_lengths_for_even_group(self):
|
||||||
|
from mxpic_router.builder import _route_bundle_links
|
||||||
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
|
class FakePin:
|
||||||
|
def __init__(self, x, y, angle):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.a = angle
|
||||||
|
|
||||||
|
class FakeRoute:
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ubend_p2p(self, **kwargs):
|
||||||
|
self.calls.append(("ubend_p2p", kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put(self):
|
||||||
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
|
FakeRoute.calls = []
|
||||||
|
links = [
|
||||||
|
LinkSpec(src_inst="r1", src_pin="out", dst_inst="p1", dst_pin="in", width=40, radius=10),
|
||||||
|
LinkSpec(src_inst="r2", src_pin="out", dst_inst="p2", dst_pin="in", width=40, radius=10),
|
||||||
|
LinkSpec(src_inst="r3", src_pin="out", dst_inst="p3", dst_pin="in", width=40, radius=10),
|
||||||
|
LinkSpec(src_inst="r4", src_pin="out", dst_inst="p4", dst_pin="in", width=40, radius=10),
|
||||||
|
]
|
||||||
|
pin_map = {
|
||||||
|
("r1", "out"): FakePin(0, 40, 0),
|
||||||
|
("p1", "in"): FakePin(100, 40, 0),
|
||||||
|
("r2", "out"): FakePin(0, 30, 0),
|
||||||
|
("p2", "in"): FakePin(100, 30, 0),
|
||||||
|
("r3", "out"): FakePin(0, 20, 0),
|
||||||
|
("p3", "in"): FakePin(100, 20, 0),
|
||||||
|
("r4", "out"): FakePin(0, 10, 0),
|
||||||
|
("p4", "in"): FakePin(100, 10, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
|
calls = [call[1] for call in FakeRoute.calls if call[0] == "ubend_p2p"]
|
||||||
|
self.assertEqual([call["length"] for call in calls], [100.0, 50.0, 50.0, 100.0])
|
||||||
|
|
||||||
|
def test_ubend_spacing_uses_route_span_for_reversed_port_order(self):
|
||||||
|
from mxpic_router.builder import _route_bundle_links
|
||||||
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
|
class FakePin:
|
||||||
|
def __init__(self, x, y, angle):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.a = angle
|
||||||
|
|
||||||
|
class FakeRoute:
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ubend_p2p(self, **kwargs):
|
||||||
|
self.calls.append(("ubend_p2p", kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put(self):
|
||||||
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
|
FakeRoute.calls = []
|
||||||
|
links = [
|
||||||
|
LinkSpec(src_inst="port_3", src_pin="io1", dst_inst="port_4", dst_pin="io4", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_3", src_pin="io2", dst_inst="port_4", dst_pin="io3", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_3", src_pin="io3", dst_inst="port_4", dst_pin="io2", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_3", src_pin="io4", dst_inst="port_4", dst_pin="io1", width=0.5, radius=10),
|
||||||
|
]
|
||||||
|
pin_map = {
|
||||||
|
("port_3", "io1"): FakePin(1772.6, -2515.2, 0),
|
||||||
|
("port_3", "io2"): FakePin(1772.6, -2525.2, 0),
|
||||||
|
("port_3", "io3"): FakePin(1772.6, -2535.2, 0),
|
||||||
|
("port_3", "io4"): FakePin(1772.6, -2545.2, 0),
|
||||||
|
("port_4", "io1"): FakePin(1771.3, -2399.9, 0),
|
||||||
|
("port_4", "io2"): FakePin(1771.3, -2409.9, 0),
|
||||||
|
("port_4", "io3"): FakePin(1771.3, -2419.9, 0),
|
||||||
|
("port_4", "io4"): FakePin(1771.3, -2429.9, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
|
calls = [call[1] for call in FakeRoute.calls if call[0] == "ubend_p2p"]
|
||||||
|
self.assertEqual([call["length"] for call in calls], [10.5, 21.0, 31.5, 42.0])
|
||||||
|
|
||||||
|
def test_mixed_sbend_and_ubend_spacing_share_route_ranks(self):
|
||||||
|
from mxpic_router.builder import _route_bundle_links
|
||||||
|
from mxpic_router.eda_loader import LinkSpec
|
||||||
|
|
||||||
|
class FakePin:
|
||||||
|
def __init__(self, x, y, angle):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.a = angle
|
||||||
|
|
||||||
|
class FakeRoute:
|
||||||
|
calls = []
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def sbend_p2p(self, **kwargs):
|
||||||
|
self.calls.append(("sbend_p2p", kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def ubend_p2p(self, **kwargs):
|
||||||
|
self.calls.append(("ubend_p2p", kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
|
def put(self):
|
||||||
|
self.calls.append(("put", {}))
|
||||||
|
|
||||||
|
FakeRoute.calls = []
|
||||||
|
links = [
|
||||||
|
LinkSpec(src_inst="port_7", src_pin="io2", dst_inst="port_5", dst_pin="io1", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_7", src_pin="io1", dst_inst="port_5", dst_pin="io2", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_6", src_pin="io2", dst_inst="port_5", dst_pin="io3", width=0.5, radius=10),
|
||||||
|
LinkSpec(src_inst="port_6", src_pin="io1", dst_inst="port_5", dst_pin="io4", width=0.5, radius=10),
|
||||||
|
]
|
||||||
|
pin_map = {
|
||||||
|
("port_7", "io2"): FakePin(2071.8, -2464.4, 0),
|
||||||
|
("port_7", "io1"): FakePin(2071.8, -2454.4, 0),
|
||||||
|
("port_6", "io2"): FakePin(2173.4, -2405.6, 180),
|
||||||
|
("port_6", "io1"): FakePin(2173.4, -2415.6, 180),
|
||||||
|
("port_5", "io1"): FakePin(2074.2, -2513.1, 0),
|
||||||
|
("port_5", "io2"): FakePin(2074.2, -2523.1, 0),
|
||||||
|
("port_5", "io3"): FakePin(2074.2, -2533.1, 0),
|
||||||
|
("port_5", "io4"): FakePin(2074.2, -2543.1, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
_route_bundle_links(links, pin_map, FakeRoute, [])
|
||||||
|
|
||||||
|
calls = [(name, call) for name, call in FakeRoute.calls if name in {"sbend_p2p", "ubend_p2p"}]
|
||||||
|
ubend_lengths = [call["length"] for name, call in calls if name == "ubend_p2p"]
|
||||||
|
sbend_lstarts = [call["Lstart"] for name, call in calls if name == "sbend_p2p"]
|
||||||
|
self.assertEqual(ubend_lengths, [10.5, 21.0])
|
||||||
|
self.assertTrue(max(ubend_lengths) < min(sbend_lstarts))
|
||||||
|
self.assertEqual(sbend_lstarts, [63.0, 73.5])
|
||||||
|
|
||||||
|
def test_route_backend_falls_back_to_nazca_interconnect_when_forge_is_absent(self):
|
||||||
|
import mxpic_router.builder as builder
|
||||||
|
|
||||||
|
class FakeInterconnect:
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
def __init__(self, radius=None, width=None, xs=None, PCB=False):
|
def __init__(self, radius=None, width=None, xs=None, PCB=False):
|
||||||
|
|||||||
Reference in New Issue
Block a user