board
OCuLink Riser for the Supermicro AIOM Slot
Public Unreviewedby John Lauer
Passive OCP NIC 3.0 SFF card that breaks a Supermicro AIOM slot's PCIe x16 into four OCuLink 4i ports (4 x4, Gen4): 6-layer, 85 ohm, length-matched, DRC-clean KiCad project with Gerbers, BOM and CPL.
main
John Lauer
README: component table per the wiki format, open-source section, no duplicate hero; generators at gen/
39a59ef
7d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
#!/usr/bin/env python3
"""Adom-style IC symbols (adom-symbol create: functional pin groups, the 3D-chip outline baked in) for the
riser's ICs. Pin numbers and names from the manufacturer datasheets (TI SN74LV165A SCLS402, TI TPS3808 SBVS050,
TI SN74LVC125A SCAS290, TI TPD4E05U06 SLVSBO7, ROHM BR24H64xxx-5AC)."""
import json, os, subprocess
OUT = os.path.join(os.path.dirname(__file__), "..", "kicad", "lib", "adom-symbols")
P = lambda n, num, t, g, side=None: dict(name=n, number=str(num), type=t, group=g, **({"side": side} if side else {}))
ICS = {
"SN74LV165APWR": dict(manufacturer="Texas Instruments", package="TSSOP-16", description="8-bit parallel-load shift register (OCP NIC 3.0 scan chain SR0)",
datasheetUrl="https://www.ti.com/lit/ds/symlink/sn74lv165a.pdf", pins=[
P("A", 11, "input", "PARALLEL IN", "left"), P("B", 12, "input", "PARALLEL IN", "left"), P("C", 13, "input", "PARALLEL IN", "left"),
P("D", 14, "input", "PARALLEL IN", "left"), P("E", 3, "input", "PARALLEL IN", "left"), P("F", 4, "input", "PARALLEL IN", "left"),
P("G", 5, "input", "PARALLEL IN", "left"), P("H", 6, "input", "PARALLEL IN", "left"),
P("SER", 10, "input", "SERIAL", "right"), P("QH", 9, "output", "SERIAL", "right"), P("~{QH}", 7, "output", "SERIAL", "right"),
P("SH/~{LD}", 1, "input", "CONTROL", "right"), P("CLK", 2, "input", "CONTROL", "right"), P("CLK_INH", 15, "input", "CONTROL", "right"),
P("VCC", 16, "power_in", "POWER", "right"), P("GND", 8, "power_in", "POWER", "left")]),
"BR24H64FJ-5ACE2": dict(manufacturer="ROHM Semiconductor", package="SOP-J8", description="64 Kbit I2C EEPROM, 2-byte addressing (OCP NIC 3.0 FRU)",
datasheetUrl="https://fscdn.rohm.com/en/products/databook/datasheet/ic/memory/eeprom/br24h64xxx-5ac-e.pdf", pins=[
P("A0", 1, "input", "ADDRESS", "left"), P("A1", 2, "input", "ADDRESS", "left"), P("A2", 3, "input", "ADDRESS", "left"),
P("WP", 7, "input", "CONTROL", "left"), P("SDA", 5, "bidirectional", "I2C", "right"), P("SCL", 6, "input", "I2C", "right"),
P("VCC", 8, "power_in", "POWER", "right"), P("GND", 4, "power_in", "POWER", "left")]),
"TPS3808G33DBV": dict(manufacturer="Texas Instruments", package="SOT-23-6 (DBV)", description="Voltage supervisor 3.07 V with manual reset and programmable delay",
datasheetUrl="https://www.ti.com/lit/ds/symlink/tps3808.pdf", pins=[
P("SENSE", 5, "input", "MONITOR", "left"), P("~{MR}", 3, "input", "MONITOR", "left"), P("CT", 4, "passive", "DELAY", "left"),
P("~{RESET}", 1, "open_collector", "OUTPUT", "right"), P("VDD", 6, "power_in", "POWER", "right"), P("GND", 2, "power_in", "POWER", "left")]),
"SN74LVC125APWR": dict(manufacturer="Texas Instruments", package="TSSOP-14", description="Quad bus buffer with 3-state outputs, Ioff",
datasheetUrl="https://www.ti.com/lit/ds/symlink/sn74lvc125a.pdf", pins=[
P("1A", 2, "input", "INPUTS", "left"), P("2A", 5, "input", "INPUTS", "left"), P("3A", 9, "input", "INPUTS", "left"), P("4A", 12, "input", "INPUTS", "left"),
P("~{1OE}", 1, "input", "ENABLES", "left"), P("~{2OE}", 4, "input", "ENABLES", "left"), P("~{3OE}", 10, "input", "ENABLES", "left"), P("~{4OE}", 13, "input", "ENABLES", "left"),
P("1Y", 3, "tri_state", "OUTPUTS", "right"), P("2Y", 6, "tri_state", "OUTPUTS", "right"), P("3Y", 8, "tri_state", "OUTPUTS", "right"), P("4Y", 11, "tri_state", "OUTPUTS", "right"),
P("VCC", 14, "power_in", "POWER", "right"), P("GND", 7, "power_in", "POWER", "left")]),
"TPD4E05U06QDQARQ1": dict(manufacturer="Texas Instruments", package="USON-10 (DQA)", description="4-channel ESD protection, 0.5 pF",
datasheetUrl="https://www.ti.com/lit/ds/symlink/tpd4e05u06.pdf", pins=[
P("D1+", 1, "passive", "PROTECTED", "left"), P("D1-", 2, "passive", "PROTECTED", "left"), P("D2+", 4, "passive", "PROTECTED", "left"), P("D2-", 5, "passive", "PROTECTED", "left"),
P("NC", 6, "no_connect", "NC", "right"), P("NC", 7, "no_connect", "NC", "right"), P("NC", 9, "no_connect", "NC", "right"), P("NC", 10, "no_connect", "NC", "right"),
P("GND", 3, "power_in", "GROUND", "left"), P("GND", 8, "power_in", "GROUND", "left")]),
}
if __name__ == "__main__":
for name, d in ICS.items():
spec = dict(symbolName=name, pinCount=len(d["pins"]), referencePrefix="U", **d)
jf = os.path.join(OUT, name + ".create.json")
json.dump(spec, open(jf, "w"), indent=1)
r = subprocess.run(["adom-symbol", "create", "--file", jf, "--out", os.path.join(OUT, name)], capture_output=True, text=True)
tail = [l for l in (r.stdout + r.stderr).splitlines() if l.strip()][-3:]
print(name, r.returncode, " | ".join(tail)[:300])
def snap_pins(path, grid=2.54):
"""adom-symbol 1.2.2 spaces pin groups by non-grid gaps; snap every pin end onto the grid of the first pin
(moves of at most half a grid step) so KiCad ERC sees on-grid connection points."""
import re
txt = open(path).read()
m = re.search(r'\(pin \w+ \w+ \(at ([-\d.]+) ([-\d.]+) ', txt)
y0 = float(m.group(2))
def fix(mm):
x, y = float(mm.group(1)), float(mm.group(2))
yn = y0 + round((y - y0) / grid) * grid
return f"(at {x:.2f} {yn:.2f} "
txt = re.sub(r'(?<=\(pin )(\w+ \w+ )\(at ([-\d.]+) ([-\d.]+) ', lambda mm: mm.group(1) + fix(type("M", (), {"group": lambda s, i: mm.group(i + 1)})()), txt)
open(path, "w").write(txt)
if __name__ == "__main__":
for name in ICS:
snap_pins(os.path.join(OUT, name, name + ".kicad_sym"))
print("pins snapped")