diff --git a/docs/product/.gitignore b/docs/product/.gitignore index 01ccb0b..889f5e0 100644 --- a/docs/product/.gitignore +++ b/docs/product/.gitignore @@ -1,4 +1,4 @@ # Build outputs — regenerate with build.py -tt-datasheet.html -tt-datasheet.pdf -.tt-datasheet.chrome.html +tt-datasheet*.html +tt-datasheet*.pdf +.tt-datasheet*.chrome.html diff --git a/docs/product/assets/archivo.woff2 b/docs/product/assets/archivo.woff2 index a31bef9..70646c6 100644 Binary files a/docs/product/assets/archivo.woff2 and b/docs/product/assets/archivo.woff2 differ diff --git a/docs/product/assets/bar-texture.png b/docs/product/assets/bar-texture.png new file mode 100644 index 0000000..d0e8865 Binary files /dev/null and b/docs/product/assets/bar-texture.png differ diff --git a/docs/product/assets/supporters/WIT.png b/docs/product/assets/supporters/WIT.png new file mode 100644 index 0000000..3975175 Binary files /dev/null and b/docs/product/assets/supporters/WIT.png differ diff --git a/docs/product/assets/supporters/chipfoundry.png b/docs/product/assets/supporters/chipfoundry.png new file mode 100644 index 0000000..abc5882 Binary files /dev/null and b/docs/product/assets/supporters/chipfoundry.png differ diff --git a/docs/product/assets/supporters/swisschips.png b/docs/product/assets/supporters/swisschips.png new file mode 100644 index 0000000..4759bef Binary files /dev/null and b/docs/product/assets/supporters/swisschips.png differ diff --git a/docs/product/assets/supporters/texplained.jpg b/docs/product/assets/supporters/texplained.jpg new file mode 100644 index 0000000..e5c5280 Binary files /dev/null and b/docs/product/assets/supporters/texplained.jpg differ diff --git a/docs/product/assets/supporters/tillitis.png b/docs/product/assets/supporters/tillitis.png new file mode 100644 index 0000000..b8a280f Binary files /dev/null and b/docs/product/assets/supporters/tillitis.png differ diff --git a/docs/product/assets/supporters/waferspace.png b/docs/product/assets/supporters/waferspace.png new file mode 100644 index 0000000..765e66d Binary files /dev/null and b/docs/product/assets/supporters/waferspace.png differ diff --git a/docs/product/build.py b/docs/product/build.py index 0945681..5402973 100644 --- a/docs/product/build.py +++ b/docs/product/build.py @@ -173,6 +173,33 @@ def as_data_uri_payload(path: Path) -> str: return base64.b64encode(path.read_bytes()).decode() +def check_glyph_coverage(content: dict, font: Path) -> None: + """Warn about characters the embedded font cannot draw. + + The font is subset, so a stray character silently falls back to whatever the + renderer has to hand — a different typeface mid-word, or a blank box in the + PDF. Needs fontTools; skipped quietly when it isn't installed, since it is + not a runtime dependency of the build. + """ + try: + from fontTools.ttLib import TTFont + except ImportError: + return + + covered = set(TTFont(font).getBestCmap()) + missing: dict[str, str] = {} + for path, text in walk_strings(content): + for char in text: + if ord(char) > 0x20 and ord(char) not in covered: + missing.setdefault(char, path) + + for char, path in sorted(missing.items()): + logging.warning( + f"{path}: U+{ord(char):04X} {char!r} is not in the embedded font " + "and will fall back to another typeface" + ) + + def prepare_supporters(supporters: dict, assets: Path) -> None: """Inline each supporter logo and work out its per-item sizing.""" height = supporters.get("logo_height", "8.5mm") @@ -321,8 +348,14 @@ def main() -> None: prepare_table(key, content[key]) assets = HERE / "assets" + check_glyph_coverage(content, assets / content["assets"]["font"]) content["font_b64"] = as_data_uri_payload(assets / content["assets"]["font"]) content["photo_b64"] = as_data_uri_payload(assets / content["assets"]["photo"]) + + texture = content["theme"].get("bar_texture") + if texture: + content["bar_texture_b64"] = as_data_uri_payload(assets / texture) + content["theme"].setdefault("bar_texture_opacity", 0.55) if "supporters" in content: prepare_supporters(content["supporters"], assets) diff --git a/docs/product/datasheet-universities.yaml b/docs/product/datasheet-universities.yaml new file mode 100644 index 0000000..334b924 --- /dev/null +++ b/docs/product/datasheet-universities.yaml @@ -0,0 +1,296 @@ +# --------------------------------------------------------------------------- +# Tiny Tapeout datasheet — UNIVERSITY EDITION. +# +# python3 docs/product/build.py --config docs/product/datasheet-universities.yaml \ +# --out docs/product/tt-datasheet-universities.html --pdf +# +# Same template and assets as datasheet.yaml; the difference is audience. This +# one is written for a department buying for a cohort, so it speaks in "we/our +# students", leads on per-student cost, and answers procurement and calendar +# questions an individual buyer never asks. Editing notes are in datasheet.yaml. +# --------------------------------------------------------------------------- + +doc: + title: Tiny Tapeout for Universities + wordmark: Tiny Tapeout + wordmark_sub: "" + tag: FOR UNIVERSITIES + ref: "" + page2_title: Electrical Specifications + +theme: + brand: "#0c66ab" # header bars and table header rows + red: "#ec3013" + tag_bg: "#fef244" + tag_fg: "#040371" + ink: "#141414" + ink_mid: "#55545f" + ink_faint: "#86858f" + ground: "#f2f1f4" + rule: "#c9c8d0" + rule_hard: "#141414" + # Chip-layout texture over the header bars, from the tt-datasheet-artwork repo. + # Blank the filename for flat bars; raise/lower the opacity for more or + # less texture (0.35 subtle, 0.55 balanced, 0.75 strong). + bar_texture: bar-texture.png + bar_texture_opacity: 0.55 + heading_size: 23pt + body_size: 8.3pt + +assets: + photo: demoboard.jpg + font: archivo.woff2 + +# -------------------------------------------------------------------------- +# PAGE 1 +# -------------------------------------------------------------------------- + +hero: + eyebrow: "" # short line above the headline; blank to hide + heading: Put your class on silicon from €70 a student + body: >- + Students submit designs onto regular shuttles with a few clicks. Hundreds of + designs are combined into a multi project chip and manufactured on an open + source PDK. The cohort shares a set of easy to use demoboards to test their + designs. + photo_alt: Tiny Tapeout demoboard with a QFN-64 packaged ASIC on a breakout board + photo_caption: "" + +features: + - kicker: 01 · Curriculum + title: Teaching material included + body: >- + Workshops, a digital design guide, HDL templates and worked testbenches, + plus open IP to teach from: a RISC-V CPU, an FPGA and an analog FPGA. + - kicker: 02 · IT footprint + title: Nothing to install + body: >- + The flow runs in GitHub Actions. Any student laptop with a browser is + enough — no lab images, no EDA seats, no licence server. + - kicker: 03 · Cohort + title: One board serves many + body: >- + A single demoboard selects any project on the die over USB, so a class + shares hardware instead of buying one board per student. + - kicker: 04 · Process + title: Three PDKs, no NDAs + body: >- + SkyWater SKY130, IHP sg13g2 and GlobalFoundries gf180mcu — 10+ shuttles a + year across the three open-source PDKs. + - kicker: 05 · I/O + title: 26 pins, plus analog + body: >- + Clock, reset, 8 dedicated inputs, 8 dedicated outputs and 8 bidirectional + pins — plus up to 6 analog pins where the process allows. + - kicker: 06 · Flexibility + title: Use your own EDA tools + body: >- + Any toolchain, commercial or open source, as long as the GDS and LEF can + be published. Verilog officially supported, VHDL and Chisel by the + community. + +quotes: + heading: "" # blank keeps the quotes as a band with no heading + items: + - text: >- + “Tiny Tapeout has been an exciting game changer for my students and the + broader microelectronics community. It helps us attract much-needed new + talents into a field that has previously failed to provide highly + accessible on-ramps.” + name: Prof. Boris Murmann + affiliation: Chair, IEEE Solid-State Circuits Society · University of Hawai‘i + - text: >- + “Tiny Tapeout is genius! It allows students, hobbyists, and + professionals to easily create custom silicon circuit blocks, supporting + digital, analog, or mixed-signal… indispensable for modern IC design + education!” + name: Prof. Harald Pretl + affiliation: Senior Principal Engineer, Intel · JKU Linz + +pricing: + heading: What a cohort costs + note: "" + columns: + - {label: Item, width: "27%", style: name} + - {label: What it buys you} + - {label: From, width: "22%", style: price} + rows: + - ["1 tile", + "Roughly 1,000 standard cells — one design, one student. Dimensions vary by PDK, see page 2.", + "€70"] + - ["Analog pin", + "Multiplexed analog pad access for mixed signal work. Minimum project size of 2 tiles applies.", + "€100 / pin, max 6"] + - ["Demoboard PCB", + "Packaged chip on an RP2350 demoboard. Any board can select any project, so a class shares them.", + "€300 each"] + - ["Postage & packing", + "Flat rate worldwide, charged once per demoboard.", + "€15"] + footnote: >- + A class of 25, each submitting one design, sharing 5 demoboards for + testing: 25 tiles (€1,750) + 5 boards (€1,500) + postage (5 × €15) = €3,325, + or €133 a student. Every extra student after that is €70. Orders over + €10,000 receive 10% off. Price your own cohort at + app.tinytapeout.com/calculator, + or email + education@tinytapeout.com + for a quote. + +faq: + heading: What departments ask + note: FULL FAQ AT TINYTAPEOUT.COM/FAQ + items: + - q: How does this fit our academic calendar? + a: >- + Fabrication takes 6–9 months and delivery up to a year, so a design + submitted in one academic year returns in the next. That return becomes + a bring-up module in its own right: students test parts documented by + their peers, where gaps in testing and documentation show up + immediately. + - q: How do we pay? + a: >- + We invoice institutions directly, accept purchase orders and issue + written quotes your finance office can approve against. VAT invoices are + available. + - q: Do our students need prior experience? + a: >- + No. The guided workshops take a beginner from logic gates to a submitted + design, and thousands of past projects are public to learn from. + - q: Who owns the work? + a: >- + Every design is published publicly under Apache-2.0, so Tiny Tapeout + does not suit confidential or commercially sensitive research. Full + terms at tinytapeout.com/terms. + +institutions: + # US-only for this sheet. The individual datasheet keeps the full + # international list; the non-US entries are still there if you need them. + label: Already teaching with Tiny Tapeout + items: + - Carnegie Mellon University + - New York University + - UC Santa Cruz + - UC San Diego + - San Jose State University + - Oklahoma State University + +contact: + label: Talk to us + lines: + - education@tinytapeout.com + - Quotes · purchase orders · invoicing + +# -------------------------------------------------------------------------- +# PAGE 2 — identical specifications to the individual sheet, with procurement +# added to the ordering table. +# -------------------------------------------------------------------------- + +process: + heading: Process & fabrication + note: TILE DIMENSIONS PER PDK + columns: + - {label: PDK, width: "19%", style: name} + - {label: Foundry, width: "21%"} + - {label: Node, width: "20%", style: num} + - {label: 1×1 tile area, width: "24%", style: mono} + - {label: Analog support} + rows: + - ["SKY130A", "SkyWater", "130 nm", "161.00 × 111.52 µm", "Full"] + - ["ihp-sg13g2", "IHP", "130 nm BiCMOS", "202.08 × 154.98 µm", "Partial"] + - ["gf180mcuD", "GlobalFoundries", "180 nm", "346.64 × 160.72 µm", "Partial"] + footnote: >- + One tile holds approximately 1,000 standard cells. Larger designs are + built from multi-tile blocks, up to 8×4 on SKY130A and ihp-sg13g2 and + up to 4×4 on gf180mcuD; the sizes available in between differ per PDK. + Analog projects require a minimum height of 2 tiles. + +ratings: + heading: Absolute maximum ratings + note: DIGITAL I/O + columns: + - {label: Parameter, width: "40%", style: name} + - {label: Min, width: "13%", style: num} + - {label: Typ, width: "13%", style: num} + - {label: Max, width: "13%", style: num} + - {label: Unit} + rows: + - ["I/O supply voltage", "1.71", "3.30", "5.50", "V"] + - ["Input frequency", "—", "—", "66", "MHz"] + - ["Output toggle frequency", "—", "—", "33", "MHz"] + - ["Output drive strength, source/sink", "—", "4", "—", "mA"] + - ["Demoboard clock generator", "1", "—", "66.5 M", "Hz"] + - ["Pad-to-tile round-trip latency", "—", "—", "20", "ns"] + - ["Clock insertion delay, pad to logic", "—", "—", "10", "ns"] + - ["Pin-to-pin latency variance", "—", "—", "2", "ns"] + footnote: >- + Characterised on SKY130A using the sky130_ef_io_gpiov2_pad cell; + ratings differ per PDK. Inputs are not 5 V tolerant despite the supply + range. Full per-process figures at + tinytapeout.com/specs. + +gpio: + heading: GPIO pin map + columns: + - {label: Signal, width: "34%", style: mono} + - {label: Width, width: "14%", style: num center} + - {label: Direction, width: "22%"} + - {label: Function} + rows: + - ["clk", "1", "Input", "Clock"] + - ["rst_n", "1", "Input", "Reset, active low"] + - ["ui_in[7:0]", "8", "Input", "General purpose"] + - ["uo_out[7:0]", "8", "Output", "General purpose"] + - ["uio[7:0]", "8", "Bidirectional", "Per-pin direction control"] + linkline: >- + 26 I/O PINS TOTAL · + TINYTAPEOUT.COM/SPECS/GPIO + +analog: + heading: Analog I/O + note: OPTIONAL + columns: + - {label: Parameter, style: name} + - {label: Value, width: "34%", style: mono} + rows: + - ["Analog pins, maximum", "6 · ua[0:5]"] + - ["Series resistance, pad to project", "< 500 Ω"] + - ["Parasitic capacitance", "< 5 pF"] + - ["Current per pin, maximum", "4 mA"] + - ["VDPWR digital supply", "1.8 V"] + - ["VAPWR analog supply", "3.3 V"] + linkline: >- + TINYTAPEOUT.COM/SPECS/ANALOG + +ordering: + heading: Ordering information + note: EDUCATION@TINYTAPEOUT.COM + headless: true + columns: + - {width: "27%", style: name} + - {} + rows: + - ["Shuttle cadence", + "10+ shuttles per year across the three processes. Check tinytapeout.com/chips for the schedule."] + - ["Lead time", + "6–9 months in fabrication, then assembly, test and fulfilment."] + - ["Payment", + "Invoices, purchase orders and written quotes for institutions. VAT invoices available."] + - ["Volume discount", + "10% off orders over €10,000. Price a cohort at app.tinytapeout.com/calculator, or email us for a quote."] + - ["Deliverable", + "Silicon area only for remote or shared test, or area plus demoboard kits: packaged chip, RP2350 demoboard and breakout board."] + - ["Design tools", + "Supplied open-source LibreLane flow running in GitHub Actions, or any commercial or open-source toolchain of your own."] + - ["Minimum submission", + "GDS + LEF, produced with any tools, in a public repository under Apache-2.0. Your tools must permit publishing them."] + +disclaimer: + label: Disclaimer + body: >- + Specifications are indicative and subject to change between shuttles. + Electrical characteristics are quoted for the SKY130A process unless stated + otherwise — consult tinytapeout.com/specs for the process you intend to use. + Every submitted design is published publicly under Apache-2.0. Full terms and + conditions of sale are published at + tinytapeout.com/terms. diff --git a/docs/product/datasheet.html.mustache b/docs/product/datasheet.html.mustache index fa91063..1e779a1 100644 --- a/docs/product/datasheet.html.mustache +++ b/docs/product/datasheet.html.mustache @@ -10,7 +10,7 @@ } :root { - --navy: {{theme.navy}}; + --brand: {{theme.brand}}; --red: {{theme.red}}; --tag-bg: {{theme.tag_bg}}; --tag-fg: {{theme.tag_fg}}; @@ -68,15 +68,32 @@ body { /* ---------- masthead ---------- */ .bar { - background: var(--navy); + background: var(--brand); color: #fff; display: flex; align-items: center; gap: 5mm; padding: 4.2mm 12mm; flex: none; + position: relative; + overflow: hidden; } +/* Chip-layout texture over the bar. The traces are black, so they darken the + bar and push contrast with the white type up rather than down. */ +{{#bar_texture_b64}} +.bar::before { + content: ""; + position: absolute; + inset: 0; + background: url(data:image/png;base64,{{&bar_texture_b64}}) center / cover no-repeat; + opacity: {{theme.bar_texture_opacity}}; + pointer-events: none; +} + +.bar > * { position: relative; } +{{/bar_texture_b64}} + .bar__logo { width: 11mm; height: 11mm; flex: none; display: block; } .bar__word { @@ -86,7 +103,7 @@ body { line-height: 1; } -.bar__word span { display: block; font-size: var(--t-micro); font-weight: 600; letter-spacing: 0.14em; color: #9a99d6; margin-top: 1.1mm; } +.bar__word span { display: block; font-size: var(--t-micro); font-weight: 600; letter-spacing: 0.14em; color: rgba(255, 255, 255, 0.72); margin-top: 1.1mm; } .bar__tag { margin-left: auto; @@ -98,7 +115,7 @@ body { padding: 1.4mm 3mm; } -.bar__ref { font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.1em; color: #9a99d6; font-variant-numeric: tabular-nums; } +.bar__ref { font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.72); font-variant-numeric: tabular-nums; } .bar--p2 .bar__title { margin-left: auto; font-size: var(--t-fine); font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; } @@ -174,7 +191,19 @@ body { .hero figure { margin: 0; display: flex; flex-direction: column; } -.hero img { width: 100%; height: 44mm; object-fit: cover; display: block; } +/* The photo fills whatever height the text column sets, so the two hero columns + always end level. The image is taken out of flow so its intrinsic height + can't drive the grid row; the frame then stretches to whatever the text needs. */ +.hero__frame { flex: 1 1 auto; min-height: 0; position: relative; } + +.hero__frame img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: cover; + display: block; +} .hero figcaption { font-size: var(--t-micro); @@ -210,7 +239,7 @@ body { table { width: 100%; border-collapse: collapse; } th { - background: var(--navy); + background: var(--brand); color: #fff; font-size: var(--t-micro); font-weight: 600; @@ -279,6 +308,35 @@ tbody tr:last-child td { border-bottom: 0; } .faq p { margin: 0; font-size: var(--t-fine); line-height: 1.36; color: var(--ink-mid); } +/* ---------- pull quotes ---------- */ + +.quotes { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 7mm; } + +.quotes blockquote { + margin: 0; + border-left: 2px solid var(--red); + padding-left: 3.4mm; +} + +.quotes p { + margin: 0; + font-size: var(--t-body); + line-height: 1.34; + font-style: italic; + max-width: 155mm; +} + +/* Not uppercased: a name plus a long affiliation is hard to read in caps. */ +.quotes cite { + display: block; + margin-top: 1.6mm; + font-size: var(--t-fine); + font-style: normal; + color: var(--ink-faint); +} + +.quotes cite b { color: var(--ink); font-weight: 700; } + /* ---------- page 2 two-column band ---------- */ .band { display: grid; grid-template-columns: 1.05fr 1fr; gap: 8mm; } @@ -340,6 +398,13 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; } .disclaimer { margin-top: 1.8mm; font-size: var(--t-micro); line-height: 1.45; color: var(--ink-mid); max-width: 150mm; } +/* Optional call-to-action beside the institution list on page 1. */ +.contact { flex: none; border-left: 2px solid var(--rule-hard); padding-left: 5mm; align-self: stretch; } + +.contact__lines { margin-top: 1.8mm; font-size: var(--t-fine); line-height: 1.5; } +.contact__lines span { display: block; font-weight: 600; white-space: nowrap; } +.contact__lines span:first-child { font-weight: 700; color: var(--red); } + .pageno { flex: none; font-size: var(--t-h2); @@ -361,7 +426,7 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; } .deck { display: block; gap: 0; padding: 0; } .sheet { break-after: page; page-break-after: always; box-shadow: none; } .sheet:last-child { break-after: auto; page-break-after: auto; } - th, .bar, .bar__tag, .zebra tbody tr:nth-child(odd) td { + th, .bar, .bar::before, .bar__tag, .zebra tbody tr:nth-child(odd) td { -webkit-print-color-adjust: exact; print-color-adjust: exact; } @@ -388,12 +453,12 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
{{&hero.body}}
++ {{/items}} +{{&text}}
+ {{&name}}{{#affiliation}} · {{&affiliation}}{{/affiliation}} +