tweaking datasheet

This commit is contained in:
Matthew Venn
2026-08-02 17:05:43 +02:00
parent 8efe741709
commit 35625f090d
3 changed files with 114 additions and 45 deletions
+65 -2
View File
@@ -101,6 +101,69 @@ def prepare_table(name: str, table: dict) -> None:
table["has_footnote"] = bool(table.get("footnote"))
def load_config(path: Path) -> dict:
"""Parse the content YAML, reporting syntax errors against the offending line."""
text = path.read_text(encoding="utf-8")
try:
return yaml.safe_load(text)
except yaml.YAMLError as error:
mark = getattr(error, "problem_mark", None)
detail = getattr(error, "problem", str(error))
if mark is None:
raise SystemExit(f"{path}: {detail}")
line = (
text.splitlines()[mark.line] if mark.line < len(text.splitlines()) else ""
)
raise SystemExit(
f"{path}:{mark.line + 1}: {detail}\n"
f" {line.strip()}\n"
' hint: inside a "quoted" value, HTML quotes must be escaped as \\"'
)
def walk_strings(node, path: str = ""):
"""Yield (dotted-path, text) for every string in the loaded config."""
if isinstance(node, dict):
for key, value in node.items():
yield from walk_strings(value, f"{path}.{key}" if path else str(key))
elif isinstance(node, list):
for index, value in enumerate(node):
yield from walk_strings(value, f"{path}[{index}]")
elif isinstance(node, str):
yield path, node
def validate_markup(content: dict) -> None:
"""Catch the two easy ways to write broken HTML in the config.
YAML only processes \\" as an escape inside "quoted" values. In a >- folded
or plain value the backslash survives into the page and breaks the markup,
so a loaded string should never still contain one.
"""
problems = []
for path, text in walk_strings(content):
if '\\"' in text:
problems.append(
f'{path}: contains a literal \\" — in a >- or plain value write '
"the quote on its own, with no backslash"
)
for tag in ("b", "a", "span"):
opened = len(re.findall(rf"<{tag}\b", text))
closed = len(re.findall(rf"</{tag}>", text))
if opened != closed:
problems.append(
f"{path}: {opened} <{tag}> but {closed} </{tag}> — unbalanced tag"
)
# An unterminated href swallows the rest of the tag, which still leaves
# <a> and </a> balanced, so check the attribute closes its own quotes.
if len(re.findall(r"href=", text)) != len(re.findall(r'href="[^"]*"', text)):
problems.append(
f'{path}: malformed link — href="..." is missing its closing quote'
)
if problems:
raise SystemExit("\n".join(f"{p}" for p in problems))
def as_data_uri_payload(path: Path) -> str:
if not path.is_file():
raise SystemExit(f"missing asset: {path}")
@@ -223,8 +286,8 @@ def main() -> None:
level=logging.INFO, format="%(levelname)-8s %(message)s", stream=sys.stdout
)
with open(args.config, encoding="utf-8") as fh:
content = yaml.safe_load(fh)
content = load_config(args.config)
validate_markup(content)
for key in TABLE_KEYS:
if key not in content:
+16 -20
View File
@@ -12,6 +12,8 @@
:root {
--navy: {{theme.navy}};
--red: {{theme.red}};
--tag-bg: {{theme.tag_bg}};
--tag-fg: {{theme.tag_fg}};
--ink: {{theme.ink}};
--ink-mid: {{theme.ink_mid}};
--ink-faint: {{theme.ink_faint}};
@@ -88,8 +90,8 @@ body {
.bar__tag {
margin-left: auto;
background: var(--red);
color: #fff;
background: var(--tag-bg);
color: var(--tag-fg);
font-size: var(--t-fine);
font-weight: 700;
letter-spacing: 0.16em;
@@ -110,6 +112,10 @@ body {
min-height: 0;
}
/* Page 2 opens straight onto a section heading, so it needs the top margin
that page 1 gets from the hero's own padding. */
.body--specs { padding-top: 5.5mm; }
.label {
font-size: var(--t-micro);
font-weight: 600;
@@ -146,8 +152,7 @@ body {
display: grid;
grid-template-columns: 1.32fr 1fr;
gap: 7mm;
padding: 4.6mm 0 4.2mm;
border-bottom: 2px solid var(--rule-hard);
padding: 4.6mm 0 5.4mm;
}
.hero h1 {
@@ -167,8 +172,6 @@ body {
max-width: 62ch;
}
.hero .rule { height: 2px; background: var(--red); width: 22mm; margin-top: 3.2mm; }
.hero figure { margin: 0; display: flex; flex-direction: column; }
.hero img { width: 100%; height: 44mm; object-fit: cover; display: block; }
@@ -187,17 +190,11 @@ body {
.features {
display: grid;
grid-template-columns: repeat(3, 1fr);
border-bottom: 2px solid var(--rule-hard);
column-gap: 7mm;
row-gap: 4.4mm;
padding: 0 0 5.4mm;
}
.feature {
padding: 2.8mm 4mm 2.9mm 0;
border-right: 1px solid var(--rule);
}
.feature:nth-child(3n) { border-right: 0; padding-right: 0; }
.feature:nth-child(n + 4) { border-top: 1px solid var(--rule); }
.feature h3 {
margin: 1.6mm 0 1.4mm;
font-size: var(--t-body);
@@ -256,8 +253,8 @@ tbody tr:last-child td { border-bottom: 0; }
/* ---------- pricing / faq blocks ---------- */
.block { padding: 3.2mm 0; border-bottom: 2px solid var(--rule-hard); }
.block:last-of-type { border-bottom: 0; }
.block { padding: 0 0 5.4mm; }
.block:last-of-type { padding-bottom: 0; }
.faq {
display: grid;
@@ -366,7 +363,7 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
<header class="bar">
{{> logo}}
<div class="bar__word">{{&doc.wordmark}}<span>{{&doc.wordmark_sub}}</span></div>
<div class="bar__word">{{&doc.wordmark}}{{#doc.wordmark_sub}}<span>{{&doc.wordmark_sub}}</span>{{/doc.wordmark_sub}}</div>
<div class="bar__tag">{{&doc.tag}}</div>
<div class="bar__ref">{{&doc.ref}}</div>
</header>
@@ -378,7 +375,6 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
<div class="label">{{&hero.eyebrow}}</div>
<h1>{{&hero.heading}}</h1>
<p>{{&hero.body}}</p>
<div class="rule"></div>
</div>
<figure>
<img src="data:image/jpeg;base64,{{&photo_b64}}" alt="{{hero.photo_alt}}">
@@ -438,7 +434,7 @@ a:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
<div class="bar__title">{{&doc.page2_title}}</div>
</header>
<div class="body">
<div class="body body--specs">
<div class="block">
{{#process}}{{> secthead}}{{> table}}{{> footnote}}{{/process}}
+33 -23
View File
@@ -7,6 +7,10 @@
# Notes for editing:
# - Every text field is rendered as raw HTML, so <b>, <br> and <a href="...">
# work anywhere. Write a literal ampersand as &amp;.
# - Inside a "quoted" value (the table rows), escape any double quote the HTML
# needs as \" — an unescaped one ends the value and breaks the YAML:
# "see <a href=\"https://example.com\">the docs</a>"
# Values written as plain or >- folded text need no escaping.
# - Table `style` tokens set cell formatting, space separated:
# name bold, no wrapping (first column of most tables)
# mono bold + tabular figures (dimensions, values, signal names)
@@ -20,8 +24,8 @@
doc:
title: Tiny Tapeout — Datasheet
wordmark: Tiny Tapeout
wordmark_sub: SHARED SILICON ASIC SHUTTLE
tag: DATASHEET
wordmark_sub: "" # strapline under the wordmark on page 1; blank to hide
tag: PRODUCT DATASHEET
ref: DOC TT-DS-2026 · REV A
page2_title: Electrical &amp; Mechanical Specifications
@@ -29,6 +33,11 @@ doc:
theme:
navy: "#040371" # header bars and table header rows
red: "#ec3013" # accent: labels, rules, prices
# DATASHEET tag in the header bar. Official Tiny Tapeout brand colours:
# yellow #fef244 · cyan #3dfef7 · hot pink #f82381 · pink #fc9f9f · blue #040371
# Set tag_fg to navy for the light colours, #ffffff for hot pink.
tag_bg: "#fef244"
tag_fg: "#040371"
ink: "#141414" # body text
ink_mid: "#55545f" # secondary text
ink_faint: "#86858f" # captions, dashes
@@ -48,10 +57,10 @@ assets:
# --------------------------------------------------------------------------
hero:
eyebrow: Shared multi-project chip · SKY130 / SG13G2 / GF180MCU
eyebrow: Shared multi project chip · SKY130 / IHP SG13G2 / GF180MCU
heading: From idea to chip design in minutes
body: >-
Tiny Tapeout makes it more accessible than ever to get your designs manufactured on a real chip.
Tiny Tapeout makes it more accessible than ever to get designs manufactured on a real chip.
Submit from a
GitHub repository and we handle integration, tapeout, packaging and delivery.
photo_alt: Tiny Tapeout ETR demoboard with a QFN-64 packaged ASIC on a breakout board
@@ -66,7 +75,7 @@ features:
- kicker: 02 · Languages
title: HDL agnostic
body: >-
Any language that can produce Verilog RTL. Project templates and CI are
Any language that can produce Verilog. Project templates and CI are
supplied for Verilog, with community provided VHDL and Chisel.
- kicker: 03 · I/O
title: 26 pins, plus analog
@@ -77,11 +86,11 @@ features:
title: Three PDKs
body: >-
SkyWater SKY130, IHP sg13g2 and GlobalFoundries gf180mcu. Open-source PDKs
running multiple times per year.
running multiple times per year with no NDAs to sign.
- kicker: 05 · Hardware
title: Demoboard available
body: >-
An optional RP2350-based demoboard carries your packaged chip and selects
An optional RP2350-based demoboard carries the packaged chip and selects
any project on the die over USB.
- kicker: 06 · Flexibility
title: Bring your own flow
@@ -104,12 +113,12 @@ pricing:
"Multiplexed analog pad access for mixed signal designs. Minimum project size of 2 tiles applies.",
"€100 <span class=\"t-sub\">/ pin</span>"]
- ["Demoboard PCB",
"Optional add-on: your packaged chip, an RP2350 demoboard and a breakout board.",
"Optional add-on: packaged chip on an RP2350 powered demoboard.",
"€100 <span class=\"t-sub\">first 80 boards for individuals are subsidised</span><br>€300 <span class=\"t-sub\">academic &amp; industry</span>"]
footnote: >-
<b>Silicon area and the demoboard are billed separately.</b> Buying area gets
your design manufactured on the wafer — on its own it does not get you a
physical chip. To hold your chip in your hand, add the demoboard PCB. Confirm
your design manufactured on the chip — on its own it does not get you a
physical chip. To receive a physical chip, add the demoboard PCB. Confirm
current figures at
<b><a href="https://app.tinytapeout.com/calculator">app.tinytapeout.com/calculator</a></b>.
@@ -120,7 +129,7 @@ faq:
- q: How long until I get my chip?
a: >-
Fabrication takes 6–9 months, then boards are assembled, tested and
shipped. Check <a href="https://app.tinytapeout.com/chips">tinytapeout.com/chips</a> for the schedule.</b>.
shipped. Check <a href="https://app.tinytapeout.com/chips">tinytapeout.com/chips</a> for the schedule.
- q: Do I need chip design experience?
a: >-
No. Getting started documentation on the website and help on the Discord community helps beginners get started.
@@ -140,7 +149,7 @@ faq:
- q: What are the licence terms?
a: >-
Every design is published publicly under Apache-2.0. The minimum
submission is GDS + LEF, produced with any toolchain you like.
submission is GDS + LEF, produced with any toolchain you like. For full terms see <a href="https://tinytapeout.com/terms">tinytapeout.com/terms</a>.
institutions:
label: Taught and used at
@@ -163,15 +172,14 @@ process:
heading: Process &amp; fabrication
note: TILE DIMENSIONS PER PDK
columns:
- {label: PDK, width: "19%", style: name}
- {label: Foundry, width: "21%"}
- {label: Node, width: "17%", style: num}
- {label: 1×1 tile area, width: "25%", style: mono}
- {label: Package}
- {label: PDK, width: "22%", style: name}
- {label: Foundry, width: "26%"}
- {label: Node, width: "22%", style: num}
- {label: 1×1 tile area, style: mono}
rows:
- ["SKY130A", "SkyWater", "130 nm", "161.00 × 111.52 µm", "QFN-64"]
- ["ihp-sg13g2", "IHP", "130 nm BiCMOS", "202.08 × 154.98 µm", "QFN-64"]
- ["gf180mcuD", "GlobalFoundries", "180 nm", "346.64 × 160.72 µm", "QFN-64"]
- ["SKY130A", "SkyWater", "130 nm", "161.00 × 111.52 µm"]
- ["ihp-sg13g2", "IHP", "130 nm BiCMOS", "202.08 × 154.98 µm"]
- ["gf180mcuD", "GlobalFoundries", "180 nm", "346.64 × 160.72 µm"]
footnote: >-
One tile holds approximately <b>1,000 standard cells</b>. Larger designs are
built from multi-tile blocks from 1×2 up to 8×4; the available sizes differ
@@ -244,9 +252,11 @@ ordering:
- {}
rows:
- ["Shuttle cadence",
"Several shuttles per year across the three processes. Check <a href="https://app.tinytapeout.com/chips">tinytapeout.com/chips</a> for the schedule"]
"Several shuttles per year across the three processes. Check <a href=\"https://app.tinytapeout.com/chips\">tinytapeout.com/chips</a> for the schedule."]
- ["Lead time",
"6–9 months in fabrication, then assembly, test and fulfilment."]
- ["Volume discount",
"10% off orders over €10,000."]
- ["Deliverable",
"Silicon area only for remote or shared test, or area plus the demoboard kit: packaged chip, RP2350 demoboard and breakout board."]
- ["Design tools",
@@ -261,5 +271,5 @@ disclaimer:
Electrical characteristics are quoted for the SKY130A process unless stated
otherwise — consult tinytapeout.com/specs for the process you intend to use.
Pricing is indicative; confirm current figures with the calculator before
ordering. Tiny Tapeout devices are educational and prototyping parts, and are
not qualified for safety-critical, medical or automotive use.
ordering. Full terms and conditions of sale are published at
<a href="https://tinytapeout.com/terms">tinytapeout.com/terms</a>.