tscircuit/ti
ti tscircuit library
- Version
- 1.0.186
- License
- unset
- Stars
- 0
tests/RadarFrontEndProcessing.test.tsx
/// <reference types="node" />
import assert from "node:assert/strict";
import { test } from "node:test";
import { Circuit } from "@tscircuit/core";
import {
AWR1843ARBGALPQ1,
AWR1843ARBGALPQ1_BALLS,
CHS01TA,
RADAR_FRONT_END_INTERFACE_NETS,
RadarClock_FW4000044Q,
RadarFrontEndProcessing,
RadarQspiFlash_MX25V1635FZNQ,
TiChipComponents,
TiSubcircuitComponents,
} from "../index.ts";
type TestCircuit = InstanceType<typeof Circuit>;
function getPort(circuit: TestCircuit, componentName: string, pin: string) {
const component = circuit.db.source_component.getWhere({
name: componentName,
});
assert.ok(component, componentName);
const port = circuit.db.source_port
.list({ source_component_id: component.source_component_id })
.find((candidate) => candidate.port_hints?.includes(pin));
assert.ok(port, `${componentName}.${pin}`);
return port;
}
function getConnectedIds(circuit: TestCircuit, start: string) {
const connected = new Set([start]);
let previousSize = 0;
while (connected.size !== previousSize) {
previousSize = connected.size;
for (const trace of circuit.db.source_trace.list()) {
const ids = [
...trace.connected_source_port_ids,
...trace.connected_source_net_ids,
];
if (ids.some((id) => connected.has(id))) {
for (const id of ids) connected.add(id);
}
}
}
return connected;
}
function assertPinsConnected(
circuit: TestCircuit,
a: [component: string, pin: string],
b: [component: string, pin: string],
) {
const aPort = getPort(circuit, ...a);
const bPort = getPort(circuit, ...b);
assert.ok(
getConnectedIds(circuit, aPort.source_port_id).has(bPort.source_port_id),
`${a.join(".")} must connect to ${b.join(".")}`,
);
}
function assertPinNet(
circuit: TestCircuit,
component: string,
pin: string,
netName: string,
) {
const net = circuit.db.source_net.getWhere({ name: netName });
assert.ok(net, netName);
assert.ok(
getConnectedIds(
circuit,
getPort(circuit, component, pin).source_port_id,
).has(net.source_net_id),
`${component}.${pin} must connect to ${netName}`,
);
}
function assertNoErrors(circuit: TestCircuit) {
assert.deepEqual(
circuit
.getCircuitJson()
.filter((element) => element.type.endsWith("_error")),
[],
);
}
test("radar exports the exact 180-ball ALP device", async () => {
assert.equal(TiChipComponents.AWR1843ARBGALPQ1, AWR1843ARBGALPQ1);
assert.equal(
TiSubcircuitComponents.RadarFrontEndProcessing,
RadarFrontEndProcessing,
);
assert.equal(AWR1843ARBGALPQ1_BALLS.length, 180);
assert.equal(
new Set(AWR1843ARBGALPQ1_BALLS.map(({ ball }) => ball)).size,
180,
);
const circuit = new Circuit();
circuit.add(
<board routingDisabled schematicDisabled>
<AWR1843ARBGALPQ1 name="U2" />
</board>,
);
await circuit.renderUntilSettled();
assertNoErrors(circuit);
const component = circuit.db.source_component.getWhere({ name: "U2" });
assert.ok(component);
assert.equal(
circuit.db.source_port.list({
source_component_id: component.source_component_id,
}).length,
180,
);
assert.equal(circuit.db.pcb_smtpad.list().length, 180);
assert.equal(getPort(circuit, "U2", "A1").pin_number, 1);
assert.equal(getPort(circuit, "U2", "J2").pin_number, 86);
assert.equal(getPort(circuit, "U2", "V18").pin_number, 180);
});
test("CHS-01TA has a standalone default reference", async () => {
const circuit = new Circuit({
platform: {
pcbDisabled: true,
routingDisabled: true,
schematicDisabled: true,
},
});
circuit.add(<CHS01TA />);
await circuit.renderUntilSettled();
assertNoErrors(circuit);
assert.ok(circuit.db.source_component.getWhere({ name: "S1" }));
});
test("40 MHz radar clock matches the TI crystal connectivity", async () => {
const circuit = new Circuit({
platform: { pcbDisabled: true, routingDisabled: true },
});
circuit.add(<RadarClock_FW4000044Q />);
await circuit.renderUntilSettled();
assertNoErrors(circuit);
assert.deepEqual(
circuit.db.source_component
.list()
.map(({ name }) => name)
.sort(),
["C14", "C71", "Y1"],
);
assertPinsConnected(circuit, ["Y1", "XTAL_P"], ["C14", "pin1"]);
assertPinsConnected(circuit, ["Y1", "XTAL_N"], ["C71", "pin1"]);
assertPinNet(circuit, "Y1", "XTAL_P", "AR_XTAL_P");
assertPinNet(circuit, "Y1", "XTAL_N", "AR_XTAL_N");
assertPinNet(circuit, "Y1", "CASE_1", "GND");
assertPinNet(circuit, "Y1", "CASE_2", "GND");
});
test("QSPI flash preserves the five series paths and two named power islands", async () => {
const circuit = new Circuit({
platform: { pcbDisabled: true, routingDisabled: true },
});
circuit.add(<RadarQspiFlash_MX25V1635FZNQ />);
await circuit.renderUntilSettled();
assertNoErrors(circuit);
assert.deepEqual(
circuit.db.source_component
.list()
.map(({ name }) => name)
.sort(),
[
"C100",
"C101",
"R43",
"R44",
"R45",
"R46",
"R47",
"R48",
"R49",
"R6",
"U9",
].sort(),
);
assertPinsConnected(circuit, ["U9", "CS"], ["R43", "pin1"]);
assertPinsConnected(circuit, ["U9", "SCLK"], ["R47", "pin2"]);
assertPinsConnected(circuit, ["U9", "SI_SIO0"], ["R6", "pin2"]);
assertPinsConnected(circuit, ["U9", "SO_SIO1"], ["R46", "pin2"]);
assertPinsConnected(circuit, ["U9", "WP_SIO2"], ["R48", "pin2"]);
assertPinsConnected(circuit, ["U9", "HOLD_SIO3"], ["R49", "pin2"]);
assertPinNet(circuit, "R47", "pin1", "AR_QSPI_CLK");
assertPinNet(circuit, "R6", "pin1", "AR_QSPI_D0");
assertPinNet(circuit, "R46", "pin1", "AR_QSPI_D1");
assertPinNet(circuit, "R43", "pin2", "PMIC_3V3");
assertPinNet(circuit, "U9", "VCC", "PMIC_3V3");
assertPinNet(circuit, "U9", "GND", "GND");
assertPinNet(circuit, "U9", "EP_GND", "GND");
});
test("composite includes one SoC, one clock, and one QSPI flash", {
timeout: 30_000,
}, async () => {
const circuit = new Circuit({
platform: {
pcbDisabled: true,
routingDisabled: true,
schematicDisabled: true,
},
});
circuit.add(<RadarFrontEndProcessing />);
await circuit.renderUntilSettled();
assertNoErrors(circuit);
const names = circuit.db.source_component.list().map(({ name }) => name);
assert.equal(names.filter((name) => name === "U2").length, 1);
assert.equal(names.filter((name) => name === "Y1").length, 1);
assert.equal(names.filter((name) => name === "U9").length, 1);
for (const expected of ["C14", "C71", "C100", "C101", "R43", "R49"]) {
assert.ok(names.includes(expected), expected);
}
for (const interfaceName of RADAR_FRONT_END_INTERFACE_NETS) {
assert.ok(
circuit.db.source_port.getWhere({ name: interfaceName }),
interfaceName,
);
}
const sclPort = circuit.db.source_port.getWhere({ name: "AR_SCL" });
const supplyPort = circuit.db.source_port.getWhere({ name: "PMIC_3V3" });
const groundPort = circuit.db.source_port.getWhere({ name: "GND" });
assert.ok(sclPort);
assert.ok(supplyPort);
assert.ok(groundPort);
assert.ok(
getConnectedIds(circuit, sclPort.source_port_id).has(
getPort(circuit, "U2", "G3").source_port_id,
),
);
assert.ok(
getConnectedIds(circuit, supplyPort.source_port_id).has(
getPort(circuit, "U9", "VCC").source_port_id,
),
);
assert.ok(
getConnectedIds(circuit, groundPort.source_port_id).has(
getPort(circuit, "Y1", "CASE_1").source_port_id,
),
);
assertPinsConnected(circuit, ["U2", "V10"], ["R85", "pin1"]);
assertPinsConnected(circuit, ["U2", "M3"], ["R84", "pin1"]);
assertPinsConnected(circuit, ["U2", "U10"], ["R83", "pin1"]);
});