code wiki / _hdl_build / nx_pcb_twin.nx
nx_pcb_twin.nx source
↩ module page · 33 lines · 2056 B
1// nx_pcb_twin.nx -- LIB: PCB electrical DIGITAL TWIN. The routed board doesn't just have a topology -- it behaves
2// like a REAL board EXACTLY: real units (mils, oz copper, mA) and real copper physics, in EXACT no-float
3// fixed-point. A trace's RESISTANCE / VOLTAGE-DROP / POWER are computed from the standard copper sheet resistance
4// and pinned to the textbook value (a 10-mil-wide, 1-oz, 1-inch trace = 49.1 mOhm), so the model is provably a
5// twin of reality, not an abstraction. S-class exceed angle: DETERMINISTIC + EXACT (integer; float EDA tools round).
6// Composes the ACTUAL routed geometry from nx_pcb_autoroute (trace length = hops x grid pitch). Games/movies later
7// are a LOOSENED mode on this exact engineering core -- never the reverse. never-brick #26: pure arithmetic,
8// guarded against divide-by-zero, deterministic. license_tier: ORIGINAL
9import "nx_syscalls.nx"
10const RSHEET_MAGIC_1000000: i64 = 1000000
11
12// copper sheet resistance @ 1 oz (1.378 mil thick, 20 C): rho_cu/thickness = 1.724 uOhm.cm / 0.0035 cm
13// = 0.4926 mOhm/square ~= 491 uOhm/square (IPC / standard reference). Data-driven constant (rule #11), not a magic number.
14const RSHEET_1OZ_UOHM: i64 = 491
15
16// trace resistance in MICRO-OHMS: R = (Rsheet / oz) * squares ; squares = length_mils / width_mils ;
17// length_mils = hops * pitch_mils. Returns 0-1 on invalid geometry (never-brick: no divide-by-zero).
18func twin_resistance_uohm(hops: i64, pitch_mils: i64, width_mils: i64, oz: i64) -> i64 {
19 if width_mils <= 0 { return 0 - 1 }
20 if oz <= 0 { return 0 - 1 }
21 let length_mils: i64 = hops * pitch_mils
22 return (RSHEET_1OZ_UOHM * length_mils) / (oz * width_mils)
23}
24
25// voltage drop in MICRO-VOLTS across a trace carrying i_ma: V = I*R. (mA * uOhm = nV ; /1000 -> uV)
26func twin_vdrop_uv(r_uohm: i64, i_ma: i64) -> i64 {
27 return (i_ma * r_uohm) / 1000
28}
29
30// power dissipated in MICRO-WATTS: P = I^2 * R. (mA^2 * uOhm = pW ; /1000000 -> uW)
31func twin_power_uw(r_uohm: i64, i_ma: i64) -> i64 {
32 return (i_ma * i_ma * r_uohm) / RSHEET_MAGIC_1000000
33}