AnasSarkiz/Game-Boy-Enhance

This code defines a hardware schematic featuring a CPU with associated power, clock, and interface components, including specialized chips, crystals, connectors, and passive components, all structured for circuit design and simulation.

Version
1.0.3
License
unset
Stars
0

scripts/audit-s4-cpu.py

"""Verify S4 procurement identity and unchanged supplier geometry in the preview."""

import csv
import hashlib
import json
import re
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent


def main():
    imported = (ROOT / "s4/imports/T113_S3.tsx").read_text()
    circuit_path = ROOT / "dist/s4/previews/cpu-package/circuit.json"
    circuit = json.loads(circuit_path.read_text())
    components = [entry for entry in circuit if entry["type"] == "source_component"]
    assert len(components) == 1, "Expected the isolated CPU package inspection"
    cpu = components[0]
    assert cpu["manufacturer_part_number"] == "T113M4020DC0", "Wrong CPU MPN"
    assert cpu["supplier_part_numbers"] == {"jlcpcb": ["C41411351"]}, "Wrong ordering identity"
    assert not any(entry["type"] in ["pcb_trace", "pcb_via"] for entry in circuit), "Preview must remain unrouted"
    assert all(not entry.get("do_not_place", False) for entry in circuit), "DNP is prohibited"

    source_ports = [entry for entry in circuit if entry["type"] == "source_port"]
    assert len(source_ports) == 129, "Expected exactly 129 physical CPU ports"
    ports = {str(entry["pin_number"]): entry for entry in source_ports}
    assert set(ports) == {str(pin) for pin in range(1, 130)}, "Missing or duplicate CPU ports"
    with (ROOT / "s4/reports/reference-cpu-pins.csv").open() as handle:
        reference_pins = list(csv.DictReader(handle))
    for pin in reference_pins:
        reference_label = re.sub(r"_\d+
quot;, "", pin["reference_pin_function"]) assert ports[pin["physical_pin"]]["name"] == reference_label, f"Reference pin mismatch: {pin}" ground = next(entry for entry in circuit if entry["type"] == "source_net" and entry["name"] == "GND") for pin_number in ["91", "129"]: assert ports[pin_number]["subcircuit_connectivity_map_key"] == ground["subcircuit_connectivity_map_key"] assert ports["106"]["do_not_connect"] is True assert not ports["106"].get("subcircuit_connectivity_map_key"), "NC pin connected" pads = [entry for entry in circuit if entry["type"] == "pcb_smtpad"] assert len(pads) == 129 imported_pads = re.findall(r"<smtpad\b.*?/>", imported, re.DOTALL) assert len(imported_pads) == 129 for original in imported_pads: pin_number = re.search(r'portHints=\{\["pin(\d+)"\]\}', original).group(1) compiled = next(pad for pad in pads if pad["port_hints"] == [f"pin{pin_number}"]) for jsx_name, compiled_name in [("pcbX", "x"), ("pcbY", "y"), ("width", "width"), ("height", "height")]: millimeters = float(re.search(rf'{jsx_name}="([^"]+)mm"', original).group(1)) assert abs(compiled[compiled_name] - millimeters) < 1e-9, f"Changed supplier pad {pin_number}" assert compiled["shape"] == re.search(r'shape="([^"]+)"', original).group(1) courtyards = [entry for entry in circuit if entry["type"] == "pcb_courtyard_outline"] assert len(courtyards) == 1 assert courtyards[0]["outline"] == json.loads(re.search(r"<courtyardoutline outline=\{(\[.*?\])\}", imported).group(1)) assert any(entry["type"] == "schematic_sheet" for entry in circuit) assert any(entry["type"] == "schematic_text" and entry["text"] == "S4 — SUPPLIER PACKAGE / PIN MAP CHECK ONLY" for entry in circuit), "Missing rendered functional section heading" errors = [entry for entry in circuit if entry["type"].endswith("_error")] warnings = [entry for entry in circuit if entry["type"].endswith("_warning")] # This deliberately unwired fixture must now fail connection DRC. It checks # that customizing the S4 component strengthens, rather than hides, checks. required_unwired_pins = {20, 26, 28, 29, 30, 34, 46, 48, 49, 50, 51, 65, 66, 77, 81, 83, 89, 97, 107, 116, 117, 128} assert len(errors) == len(required_unwired_pins) assert all(entry["type"] == "source_pin_must_be_connected_error" for entry in errors) pin_numbers_by_port_id = {port["source_port_id"]: port["pin_number"] for port in source_ports} assert {pin_numbers_by_port_id[entry["source_port_id"]] for entry in errors} == required_unwired_pins report = { "scope": "isolated_cpu_package_and_negative_connection_test", "expected_missing_connection_errors_verified": len(errors), "manufacturer_part_number": cpu["manufacturer_part_number"], "supplier_part_numbers": cpu["supplier_part_numbers"], "geometry_source": "JLCPCB C5197687 / T113-S3", "import_sha256": hashlib.sha256(imported.encode()).hexdigest(), "compiled_circuit_sha256": hashlib.sha256(circuit_path.read_bytes()).hexdigest(), "unchanged_supplier_pads_and_courtyard": True, "pins_matching_reference": len(reference_pins), "ground_pins": [91, 129], "unconnected_inspection_pins": sum(not port.get("subcircuit_connectivity_map_key") for port in source_ports), "copper_trace_count": sum(entry["type"] == "pcb_trace" for entry in circuit), "dnp_count": sum(bool(entry.get("do_not_place")) for entry in circuit), "errors": errors, "warnings": [{"type": entry["type"], "message": entry["message"]} for entry in warnings], "s4_package_and_electrical_qualification_complete": False, "console_board_implemented": False, } (ROOT / "s4/reports/cpu-package-inspection.json").write_text(json.dumps(report, indent=2) + "\n") print(json.dumps(report, indent=2)) if __name__ == "__main__": main()