Skip PE-PWR/PE-VIA without datasheet current (2.61.1).

Trace-width vs current runs only with I_load/Imax/I_abs. Missing I is a
skip, not INFO INSUFFICIENT, not USB 500 mA, not Iout_max-as-load.
This commit is contained in:
2026-09-21 12:11:52 +02:00
parent 6dc04b5cc7
commit c6abdae762
12 changed files with 115 additions and 64 deletions
+13
View File
@@ -607,3 +607,16 @@ def test_does_not_use_layout_geometry():
assert "LayoutPad" not in src
assert "LayoutSegment" not in src
assert "LayoutZone" not in src
def test_usbc_vbus_does_not_invent_usb_500ma():
"""No typical USB current and no PE-PWR check without datasheet I."""
findings = check_interface_classes(_usbc_device_graph())
blob = " ".join(
" ".join(filter(None, (f.finding, f.why, f.facts, f.requirement, f.inference)))
for f in findings
).lower()
assert "500 ma" not in blob
assert "500ma" not in blob
assert "0.5 a" not in blob
assert not any(f.rule_id in {"PE-PWR-001", "PE-VIA-001"} for f in findings)
+36 -1
View File
@@ -515,9 +515,44 @@ def test_power_trace_skips_without_i_load():
graph.components["U1"].specs.values["i_load_a"] = None # type: ignore[union-attr]
graph.components["U1"].specs = None
findings = check_pcb_power_traces(graph, cmap, layout)
assert findings == []
def test_power_trace_skips_iout_max_as_load():
from backend.periscopex.pcb_power_thermal import check_pcb_power_traces
graph, cmap, layout = _ldo_graph_layout(i_load=10)
graph.components["U1"].specs.values.clear() # type: ignore[union-attr]
graph.components["U1"].specs.values["iout_max_a"] = 10.0 # type: ignore[union-attr]
graph.components["U1"].specs.values["tj_max"] = 150.0 # type: ignore[union-attr]
findings = check_pcb_power_traces(graph, cmap, layout)
assert findings == []
def test_power_trace_uses_imax_when_i_load_absent():
from backend.periscopex.pcb_power_thermal import check_pcb_power_traces
graph, cmap, layout = _ldo_graph_layout(i_load=10)
vals = graph.components["U1"].specs.values # type: ignore[union-attr]
vals.pop("i_load_a", None)
vals["i_max"] = 10.0
findings = check_pcb_power_traces(graph, cmap, layout)
assert findings
assert findings[0].rule_id == "PE-PWR-001"
assert findings[0].evidence_status == "INSUFFICIENT"
assert findings[0].status == "ERROR"
def test_power_trace_uses_i_abs_when_i_load_absent():
from backend.periscopex.pcb_power_thermal import check_pcb_power_traces
graph, cmap, layout = _ldo_graph_layout(i_load=10)
vals = graph.components["U1"].specs.values # type: ignore[union-attr]
vals.pop("i_load_a", None)
vals["i_abs"] = 10.0
findings = check_pcb_power_traces(graph, cmap, layout)
assert findings
assert findings[0].rule_id == "PE-PWR-001"
assert findings[0].status == "ERROR"
def test_kelvin_sense_pin_on_shared_net():
+3 -5
View File
@@ -307,7 +307,7 @@ def test_fb1_blm_is_bead_not_dcr_resistor():
assert getattr(dcr.specs, "value_ohms", None) is None
def test_via_current_insufficient_without_i_load():
def test_via_current_skips_without_i_load():
from backend.periscopex.models import LayoutStackup
cons = ComponentConstraints(
@@ -339,11 +339,9 @@ def test_via_current_insufficient_without_i_load():
],
)
findings = check_pcb_via_current(graph, {"LDO1": cons}, layout)
assert findings and findings[0].rule_id == "PE-VIA-001"
assert findings[0].evidence_status == "INSUFFICIENT"
assert findings == []
pwr = check_pcb_power_traces(graph, {"LDO1": cons}, layout)
assert pwr and pwr[0].rule_id == "PE-PWR-001"
assert pwr[0].evidence_status == "INSUFFICIENT"
assert pwr == []
def test_thinking_reasoning_content_echo_still_present():