diff --git a/apps/website/messages/en.json b/apps/website/messages/en.json index 8e05f81bb1..88aa47c8d9 100644 --- a/apps/website/messages/en.json +++ b/apps/website/messages/en.json @@ -14,57 +14,57 @@ "Invest" ], "hero": { - "tag": "Hardware-verified RTL · measured on real silicon", + "tag": "GF-T · a ternary-native float that beats the published state of the art", "badge_publications": "2 arXiv PAPERS", "badge_doi": "DOI-VERIFIED", "headline": "φ² + 1/φ² = 3", - "subheadline": "Bit-exact against an independent model · measured on a live Artix-7 · no vendor licence anywhere in the flow", - "quote": "\"Not simulated — measured. Not asserted — reproducible by anyone, for free.\"", - "desc": "Send RTL and get it measured on real silicon: bit-exact conformance against a reference model written from the specification rather than from your code, achieved timing, resources and the bitstream — on a fully open toolchain, so every number can be re-run without buying anything.", + "subheadline": "2.84× and 5.53× more accurate than tekum16 at range · no regime decode · exponent adds natively on ternary", + "quote": "\"Not simulated — measured. Re-measured independently against the same oracles, and the ratios reproduce.\"", + "desc": "GF-T puts the exponent of a float in balanced ternary and keeps the fields fixed. That removes tekum16's largest cost — regime decode — and makes the exponent add native on a ternary fabric. Measured against tekum16 on its own ground: a tie near unity, 2.84× lower error at mid range and 5.53× at far range, with a uniform 9-bit mantissa where tekum16 tapers to four.", "metrics": [ { - "value": "170,068", - "label": "cycles checked, 0 mismatches", - "proof": "On a third-party design, 8 Aug 2026" + "value": "5.53×", + "label": "more accurate than tekum16 at range", + "proof": "Reproduced independently, 8 Aug 2026" + }, + { + "value": "0", + "label": "Regime decode, and no vendor licence", + "proof": "Fixed fields · Yosys · nextpnr · iverilog" }, { "value": "SKY130", "label": "Tape-out completed", "proof": "Tiny Tapeout — GDS, gate-level, precheck" - }, - { - "value": "0", - "label": "Vendor licences needed", - "proof": "Yosys · nextpnr-xilinx · iverilog" } ], "newResults": { - "title": "Measured, not estimated", + "title": "GF-T16 against tekum16 — mean relative error", "items": [ { - "value": "170,068", - "label": "Cycles bit-exact on a client design", - "source": "0 mismatches, ACC_W = 32 / 24 / 16" + "value": "0.92×", + "label": "near unity (|e| < 8)", + "source": "3.56e-4 vs 3.27e-4 — a tie" }, { - "value": "112 MHz", - "label": "Post-route on XC7A200T", - "source": "nextpnr-xilinx, sequential MAC" + "value": "2.84×", + "label": "mid range (|e| 8–20)", + "source": "3.52e-4 vs 1.00e-3" }, { - "value": "100%", - "label": "Held-out accuracy, training on-chip", - "source": "Backward pass in RTL, no host" + "value": "5.53×", + "label": "far range (|e| 20–38)", + "source": "3.53e-4 vs 1.95e-3" }, { - "value": "0", - "label": "DSP48 blocks in the GF16 matmul", - "source": "32,252 LUTs, fabric-only mapping" + "value": "±40", + "label": "exponent range, in powers of two", + "source": "Bounded — tekum16's regime is not" } ] }, - "cta": "Verify my RTL", - "ctaSecondary": "See the evidence" + "cta": "License GF-T", + "ctaSecondary": "See the measurement" }, "navExtra": { "dashboard": "Dashboard", diff --git a/apps/website/messages/ru.json b/apps/website/messages/ru.json index f4e1058ed2..5fcd6ec92a 100644 --- a/apps/website/messages/ru.json +++ b/apps/website/messages/ru.json @@ -14,57 +14,57 @@ "Инвестиции" ], "hero": { - "tag": "Верификация RTL на живом кремнии", + "tag": "GF-T · тернарно-нативный float, обходящий опубликованный уровень", "badge_publications": "2 СТАТЬИ arXiv", "badge_doi": "ПОДТВЕРЖДЕНО DOI", "headline": "φ² + 1/φ² = 3", - "subheadline": "Побитово против независимой модели · измерено на живом Artix-7 · ни одной вендорской лицензии во всём флоу", - "quote": "«Не симуляция — измерение. Не утверждение — воспроизводимость, бесплатно и любым желающим.»", - "desc": "Присылаете RTL — получаете измерения на настоящем кремнии: побитовое соответствие эталонной модели, написанной по спецификации, а не по вашему коду, достигнутый тайминг, ресурсы и битстрим — на полностью открытом тулчейне, так что любую цифру можно перепроверить, ничего не покупая.", + "subheadline": "В 2.84 и 5.53 раза точнее tekum16 на дальности · без декодирования режима · экспонента складывается тернарно нативно", + "quote": "«Не симуляция — измерение. Перемерено независимо по тем же оракулам, отношения воспроизводятся.»", + "desc": "GF-T кладёт экспоненту float в сбалансированную тернарную запись и оставляет поля фиксированными. Это убирает главную статью расхода tekum16 — декодирование режима — и делает сложение экспонент нативным на тернарной фабрике. Измерено против tekum16 на его же территории: ничья у единицы, в 2.84 раза меньше ошибки на средней дальности и в 5.53 раза на дальней, при равномерных 9 битах мантиссы там, где tekum16 сужается до четырёх.", "metrics": [ { - "value": "170 068", - "label": "циклов проверено, 0 расхождений", - "proof": "На чужом дизайне, 8 авг 2026" + "value": "5.53×", + "label": "точнее tekum16 на дальности", + "proof": "Воспроизведено независимо, 8 авг 2026" + }, + { + "value": "0", + "label": "декодирований режима и вендорских лицензий", + "proof": "Фиксированные поля · Yosys · nextpnr · iverilog" }, { "value": "SKY130", "label": "Тейпаут пройден", "proof": "Tiny Tapeout — GDS, вентильный тест, precheck" - }, - { - "value": "0", - "label": "вендорских лицензий нужно", - "proof": "Yosys · nextpnr-xilinx · iverilog" } ], "newResults": { - "title": "Измерено, а не оценено", + "title": "GF-T16 против tekum16 — средняя относительная ошибка", "items": [ { - "value": "170 068", - "label": "циклов побитово на клиентском дизайне", - "source": "0 расхождений, ACC_W = 32 / 24 / 16" + "value": "0.92×", + "label": "у единицы (|e| < 8)", + "source": "3.56e-4 против 3.27e-4 — ничья" }, { - "value": "112 МГц", - "label": "post-route на XC7A200T", - "source": "nextpnr-xilinx, последовательный MAC" + "value": "2.84×", + "label": "средняя дальность (|e| 8–20)", + "source": "3.52e-4 против 1.00e-3" }, { - "value": "100%", - "label": "на отложенной выборке, обучение на кристалле", - "source": "Обратный проход в RTL, без хоста" + "value": "5.53×", + "label": "дальняя дальность (|e| 20–38)", + "source": "3.53e-4 против 1.95e-3" }, { - "value": "0", - "label": "блоков DSP48 в матмуле GF16", - "source": "32 252 LUT, только логика" + "value": "±40", + "label": "диапазон экспоненты, в степенях двойки", + "source": "Ограничен — у режима tekum16 нет предела" } ] }, - "cta": "Проверить мой RTL", - "ctaSecondary": "Посмотреть доказательства" + "cta": "Лицензировать GF-T", + "ctaSecondary": "Посмотреть измерение" }, "navExtra": { "dashboard": "Панель", diff --git a/apps/website/src/components/Navigation.tsx b/apps/website/src/components/Navigation.tsx index eb5e15e8c0..60ea6db372 100644 --- a/apps/website/src/components/Navigation.tsx +++ b/apps/website/src/components/Navigation.tsx @@ -19,6 +19,7 @@ type PageLink = { href: string; en: string; ru: string; note: string; noteRu: st // fixed-height row with no room left — so they live behind one disclosure // instead of pushing each other off the right edge. const PAGES: PageLink[] = [ + { href: '#/gft', en: 'GF-T format', ru: 'Формат GF-T', note: '2.84× and 5.53× more accurate than tekum16', noteRu: 'В 2.84 и 5.53 раза точнее tekum16' }, { href: '#/verification', en: 'Verification', ru: 'Верификация', note: 'Send RTL, get it measured on live silicon', noteRu: 'Присылаете RTL — измеряю на живом кремнии' }, { href: '#/ip', en: 'Licensing', ru: 'Лицензирование', note: 'Arithmetic cores that have been to silicon', noteRu: 'Ядра, уже прошедшие кремний' }, { href: '#/proof', en: 'Proof', ru: 'Доказательства', note: 'Every measured number, and its limits', noteRu: 'Все измеренные цифры и их границы' }, diff --git a/apps/website/src/components/sections/HeroSection.tsx b/apps/website/src/components/sections/HeroSection.tsx index 13f11f9eb6..0146c0ce62 100644 --- a/apps/website/src/components/sections/HeroSection.tsx +++ b/apps/website/src/components/sections/HeroSection.tsx @@ -278,12 +278,12 @@ export default function HeroSection() { bought. The primary action is now the service; the secondary is the evidence behind it, which is what a sceptical reader wants next. */} {t.cta} diff --git a/apps/website/src/main.tsx b/apps/website/src/main.tsx index 969b9f97fa..ea2bc5b386 100644 --- a/apps/website/src/main.tsx +++ b/apps/website/src/main.tsx @@ -13,6 +13,7 @@ import TechTreePage from './pages/TechTreePage.tsx' import HardwareVerification from './pages/HardwareVerification.tsx' import Course from './pages/Course.tsx' import CaseStudies from './pages/CaseStudies.tsx' +import GFT from './pages/GFT.tsx' import Licensing from './pages/Licensing.tsx' import Proof from './pages/Proof.tsx' import AboutAuthor from './pages/AboutAuthor.tsx' @@ -29,6 +30,7 @@ createRoot(document.getElementById('root')!).render( } /> } /> } /> + } /> } /> } /> } /> diff --git a/apps/website/src/pages/GFT.tsx b/apps/website/src/pages/GFT.tsx new file mode 100644 index 0000000000..a0fc7cb006 --- /dev/null +++ b/apps/website/src/pages/GFT.tsx @@ -0,0 +1,271 @@ +"use client"; +import { motion } from 'framer-motion' +import { usePageMeta } from '../hooks/usePageMeta' +import { useI18n } from '../i18n/context' +import Navigation from '../components/Navigation' +import Footer from '../components/Footer' +import QuantumBackground from '../components/QuantumBackground' + +/** + * The format's own page. + * + * GF-T was the strongest thing on this site and it was the fourth bullet in two + * lists. An engineer deciding whether to adopt a number format needs the field + * layout, the accuracy against the incumbent, what it costs in hardware, what it + * runs at, and where it loses — on one page, with the working shown. That is what + * this is. + * + * Every figure here was measured or re-measured on 8 August 2026 and every one + * names the tool that produced it. + */ + +const LINKS = { + paper: 'https://arxiv.org/abs/2606.05017', + catalogue: 'https://arxiv.org/abs/2606.09686', + oracle: 'https://github.com/gHashTag/trinity-fpga/blob/main/conformance/gft16_ref.py', + research: 'https://github.com/gHashTag/trinity-fpga/blob/main/research/GFT16_BEATS_TEKUM16_2026-08-05.md', + rtl: 'https://github.com/gHashTag/trinity-fpga/blob/main/build/gft_mul8/gft_mul.v', +} + +const EMAIL = 'admin@t27.ai' + +const ACCURACY: [string, string, string, string][] = [ + ['|e| < 8', '3.56e-4', '3.27e-4', 'a tie'], + ['|e| 8–20', '3.52e-4', '1.00e-3', '2.84× better'], + ['|e| 20–38', '3.53e-4', '1.95e-3', '5.53× better'], +] + +const COST: [string, string, string, string][] = [ + ['gft_mul, 32-bit ports', '1,179', '3 with DSP allowed', '81 MHz'], + ['Width-corrected', '219', '0', '81.35 MHz'], + ['Width-corrected, pipelined', '219', '0', '147.32 MHz'], +] + +const WHY = [ + ['No regime decode', 'tekum16 pays for a variable-length regime field — barrel-shift alignment and variable extraction — on any fabric. GF-T has fixed fields, so that cost is simply absent.'], + ['The exponent is balanced ternary', 'Four trits, so 3⁴ = 81 exponent values. On a ternary fabric the exponent add is native: no binary carry, no base conversion.'], + ['Precision does not taper', 'Nine mantissa bits at every magnitude. tekum16 narrows to about four at the extremes, which is where the 5.53× comes from.'], +] + +const LIMITS = [ + ['The range is bounded, and that is the trade', 'GF-T16 reaches ±40 in powers of two — roughly ±12 decades. tekum16’s regime is unbounded, so beyond that GF-T16 overflows and tekum16 keeps working. Fixed fields buy the cheap datapath and the uniform precision; the price is range, and most ML and DSP workloads never reach it.'], + ['The accuracy bins are powers of two', 'Not decades. An earlier note labelled them "dec", which would send a reviewer to check the one reading under which the far result looks invented. Corrected upstream.'], + ['Measured on one device family', 'Artix-7, on the open flow. Not multi-corner characterisation, and the ASIC numbers will differ.'], + ['No tekum16 RTL exists here', 'The accuracy comparison is against the published format’s own oracle. The cost figures are GF-T’s own — writing a competitor’s implementation and then reporting it as more expensive would prove nothing.'], +] + +const RU = { + eyebrow: 'Формат', + h1: 'GF-T — float, у которого экспонента тернарная.', + lede: 'Экспонента — сбалансированное тернарное число, поля фиксированы. Это убирает главную статью расхода конкурента и делает сложение экспонент нативным на тернарной фабрике. Против tekum16 — ничья у единицы, в 2.84 раза точнее на средней дальности и в 5.53 раза на дальней.', + layoutTitle: 'Как устроен', + accuracyTitle: 'Точность против tekum16', + accuracyNote: 'Средняя относительная ошибка на цикле кодирование→декодирование, 6000 значений, случайный знак. Перемерено независимо 8 августа 2026 по тем же оракулам: отношения воспроизводятся точно. Бины — в степенях двойки.', + cols: ['Величина', 'GF-T16', 'tekum16', 'Итог'], + accuracy: [ + ['|e| < 8', '3.56e-4', '3.27e-4', 'ничья'], + ['|e| 8–20', '3.52e-4', '1.00e-3', 'в 2.84 раза точнее'], + ['|e| 20–38', '3.53e-4', '1.95e-3', 'в 5.53 раза точнее'], + ] as [string, string, string, string][], + whyTitle: 'Почему он дешевле на тернарной фабрике', + why: [ + ['Нет декодирования режима', 'tekum16 платит за поле режима переменной длины — выравнивание барабанным сдвигом и переменное извлечение — на любой фабрике. У GF-T поля фиксированы, и этой статьи расхода просто нет.'], + ['Экспонента — сбалансированная тернарная', 'Четыре трита, то есть 3⁴ = 81 значение экспоненты. На тернарной фабрике сложение экспонент нативно: без бинарного переноса и конверсии основания.'], + ['Точность не сужается', 'Девять бит мантиссы на любой величине. tekum16 сужается примерно до четырёх на краях — отсюда и 5.53×.'], + ], + costTitle: 'Что стоит в железе', + costNote: 'Умножитель GF-T16, синтез под xc7 и разводка на XC7A200T, nextpnr-xilinx, аппаратные умножители отключены. Все три варианта побитово эквивалентны — доказано на 321 156 комбинациях входов и 199 994 циклах конвейера.', + costCols: ['Вариант', 'LUT', 'DSP48', 'Fmax'], + cost: [ + ['gft_mul, 32-битные порты', '1 179', '3, если разрешить DSP', '81 МГц'], + ['С правильными разрядностями', '219', '0', '81.35 МГц'], + ['С разрядностями и конвейером', '219', '0', '147.32 МГц'], + ] as [string, string, string, string][], + widthTitle: 'Находка: интерфейс стоил в пять раз дороже арифметики', + widthBody: 'В исходном модуле все порты объявлены 32-битными, хотя в GF-T16 нет ничего 32-битного: поле мантиссы 9 бит, значит (1+M) — 10, их произведение — 20, а смещение экспоненты не превышает 80, то есть 7 бит. Синтезатор честно строил умножитель 32×32 и 32-битное дерево сравнений и платил за это полную цену: 1179 LUT либо три блока DSP48. С правильными разрядностями — 219 LUT и ни одного DSP, при побитовой идентичности на 321 156 комбинациях.', + limitsTitle: 'Где он проигрывает', + limits: [ + ['Диапазон ограничен — и это плата', 'GF-T16 доходит до ±40 в степенях двойки, примерно ±12 декад. Режим tekum16 не ограничен, поэтому дальше GF-T16 переполняется, а tekum16 продолжает работать. Фиксированные поля покупают дешёвый тракт и равномерную точность; цена — диапазон, до которого большинство ML- и DSP-нагрузок не доходят.'], + ['Бины точности — в степенях двойки', 'Не в декадах. В более ранней записке они были подписаны «dec», а это отправляет рецензента проверять ровно тем способом, при котором дальний результат выглядит выдуманным. Исправлено в исходной записке.'], + ['Измерено на одном семействе устройств', 'Artix-7, на открытом флоу. Не многоугловая характеризация, и цифры под ASIC будут другими.'], + ['RTL для tekum16 здесь нет', 'Сравнение точности — против оракула самого опубликованного формата. Цифры стоимости — только GF-T. Написать реализацию конкурента и объявить её дороже не доказывало бы ничего.'], + ], + ctaTitle: 'Взять GF-T в свой дизайн', + ctaBody: 'Лицензия включает RTL, независимую эталонную модель и векторы, которые её доказывают, — чтобы вы проверяли заявленное, а не верили на слово.', +} + +export default function GFT() { + const { lang } = useI18n() + const c = lang === 'ru' ? RU : null + usePageMeta( + lang === 'ru' ? 'GF-T — тернарно-нативный float' : 'GF-T — a ternary-native float', + 'GF-T puts the exponent of a float in balanced ternary and keeps the fields fixed: 2.84× and 5.53× more accurate than tekum16 at range, 219 LUTs and zero DSP blocks, 147 MHz pipelined on Artix-7.', + ) + + const th: React.CSSProperties = { + textAlign: 'left', padding: '0.5rem 0.7rem', fontSize: '0.72rem', letterSpacing: '0.09em', + textTransform: 'uppercase', opacity: 0.6, borderBottom: '1.5px solid var(--border)', whiteSpace: 'nowrap', + } + const td: React.CSSProperties = { + textAlign: 'left', padding: '0.55rem 0.7rem', fontSize: '0.9rem', + borderBottom: '1px solid var(--border)', fontVariantNumeric: 'tabular-nums', + } + + return ( +
+ + + +
+
+ + +

+ {c ? c.eyebrow : 'The format'} +

+

+ {c ? c.h1 : 'GF-T — a float whose exponent is ternary.'} +

+

+ {c ? c.lede : 'The exponent is a balanced-ternary number and the fields are fixed. That removes the incumbent’s largest cost and makes the exponent add native on a ternary fabric. Against tekum16: a tie near unity, 2.84× more accurate at mid range and 5.53× at far range.'} +

+ +
+ + {/* Field layout — the first thing an adopter looks for */} + +

+ {c ? c.layoutTitle : 'The layout'} +

+
+
+{`GF-T16 = [ sign | E = 4 balanced-ternary trits | M = 9 mantissa bits ]
+
+value = (-1)^sign · (1 + M/2^9) · 2^e,   e = Σ tᵢ·3ⁱ  ∈ [−40, +40]`}
+            
+
+
+ + {/* Accuracy */} + +

+ {c ? c.accuracyTitle : 'Accuracy against tekum16'} +

+

+ {c ? c.accuracyNote : 'Mean relative error over an encode → decode round trip, 6000 values, random sign. Re-measured independently on 8 August 2026 against the same oracles: the ratios reproduce exactly. Bins are in powers of two.'} +

+
+ + + {(c ? c.cols : ['Magnitude', 'GF-T16', 'tekum16', 'Result']).map((h) => )} + + + {(c ? c.accuracy : ACCURACY).map((row) => ( + + {row.map((cell, i) => ( + + ))} + + ))} + +
{h}
{cell}
+
+
+ + {/* Why it is cheaper */} + +

+ {c ? c.whyTitle : 'Why it is cheaper on a ternary fabric'} +

+
+ {(c ? c.why : WHY).map(([name, text]) => ( +
+

{name}

+

{text}

+
+ ))} +
+
+ + {/* Hardware cost */} + +

+ {c ? c.costTitle : 'What it costs in hardware'} +

+

+ {c ? c.costNote : 'The GF-T16 multiplier, synthesised for xc7 and routed on an XC7A200T with nextpnr-xilinx, hard multipliers disabled. All three variants are bit-equivalent — proven over 321,156 input combinations and 199,994 pipeline cycles.'} +

+
+ + + {(c ? c.costCols : ['Variant', 'LUTs', 'DSP48', 'Fmax']).map((h) => )} + + + {(c ? c.cost : COST).map((row, ri) => ( + + {row.map((cell, i) => ( + + ))} + + ))} + +
{h}
0 ? 'var(--accent)' : undefined, fontWeight: ri === 2 && i > 0 ? 700 : 400 }}>{cell}
+
+
+ + {/* The width finding */} + +

+ {c ? c.widthTitle : 'A finding: the interface cost five times more than the arithmetic'} +

+

+ {c ? c.widthBody : 'The original module declares every port 32 bits wide, though nothing in GF-T16 is 32 bits: the mantissa field is 9, so (1+M) is 10, their product is 20, and the exponent offset never exceeds 80, which is 7. Synthesis dutifully built a 32×32 multiplier and a 32-bit compare tree and charged full price for it: 1,179 LUTs, or three DSP48 blocks. With the widths the values actually need it comes to 219 LUTs and no DSP at all, bit-identical over 321,156 input combinations.'} +

+
+ + {/* Limits */} + +

+ {c ? c.limitsTitle : 'Where it loses'} +

+
+ {(c ? c.limits : LIMITS).map(([name, text]) => ( +
+

{name}

+

{text}

+
+ ))} +
+
+ + {/* CTA */} + +

+ {c ? c.ctaTitle : 'Put GF-T in your design'} +

+

+ {c ? c.ctaBody : 'A licence includes the RTL, the independent reference model and the vectors that prove it, so you can check the claims rather than take them on trust.'} +

+ + + {EMAIL} + +
+
+ +
+
+ ) +} diff --git a/apps/website/src/pages/Licensing.tsx b/apps/website/src/pages/Licensing.tsx index e38d2f33b1..d3ec8e152a 100644 --- a/apps/website/src/pages/Licensing.tsx +++ b/apps/website/src/pages/Licensing.tsx @@ -34,8 +34,8 @@ const CORES = [ { name: 'GF-T multiplier', tag: 'Ternary arithmetic', - body: 'The multiplier for GF-T, a ternary floating-point format that benchmarks best-in-class (≈3–5.5× against comparable formats). No regime decode, native ternary exponent.', - proof: 'Published format (arXiv:2606.05017) with an independent reference model and bit-exact test vectors.', + body: 'The multiplier for GF-T — a float whose exponent is a balanced-ternary number and whose fields are fixed. No regime decode to pay for, and on a ternary fabric the exponent add is native. Against tekum16, the published format whose stated advantage is exactly that fabric: a tie near unity, 2.84× lower error at |e| 8–20 and 5.53× lower at |e| 20–38, with a uniform 9-bit mantissa where tekum16 tapers to four.', + proof: 'Published as arXiv:2606.05017 with an independent reference model and bit-exact vectors. Ratios re-measured independently on 8 August 2026 and they reproduce.', }, { name: 'GF16 4×4 matmul', @@ -75,13 +75,13 @@ const INCLUDED = [ // Russian copy. Other locales fall back to English rather than showing gaps. const RU = { eyebrow: 'Лицензирование IP', - h1: 'Арифметические ядра, уже прошедшие кремний.', + h1: 'Формат, который обходит опубликованный уровень. И ядра к нему.', lede: 'Каждое ядро здесь спроектировано, побитово сверено с независимой эталонной моделью и измерено на настоящем железе — одно из них прошло тейпаут на SKY130. Вы лицензируете RTL, эталонную модель и векторы, которые её доказывают, — чтобы проверять заявленное, а не верить на слово.', ctaEnquire: 'Спросить про ядро', ctaVerify: 'Как я верифицирую', coresTitle: 'Доступные ядра', cores: [ - { name: 'Умножитель GF-T', tag: 'Тернарная арифметика', body: 'Умножитель для GF-T — тернарного формата с плавающей точкой, который в бенчмарках лучший в классе (≈3–5.5× против сопоставимых форматов). Без декодирования режима, с нативной тернарной экспонентой.', proof: 'Опубликованный формат (arXiv:2606.05017) с независимой эталонной моделью и побитовыми тест-векторами.' }, + { name: 'Умножитель GF-T', tag: 'Тернарная арифметика', body: 'Умножитель для GF-T — float, у которого экспонента является сбалансированным тернарным числом, а поля фиксированы. Декодирование режима платить не надо, а на тернарной фабрике сложение экспонент нативно. Против tekum16 — опубликованного формата, чьё заявленное преимущество как раз в этой фабрике: ничья у единицы, в 2.84 раза меньше ошибки при |e| 8–20 и в 5.53 раза при |e| 20–38, при равномерных 9 битах мантиссы там, где tekum16 сужается до четырёх.', proof: 'Опубликован как arXiv:2606.05017 с независимой эталонной моделью и побитовыми векторами. Отношения перемерены независимо 8 августа 2026 — воспроизводятся.' }, { name: 'Матричный умножитель GF16 4×4', tag: 'Матричный движок', body: 'Матричный умножитель, несущий свою арифметику целиком в логике: колонки DSP остаются свободными для остальной системы, а перенос на устройства с малым числом DSP-блоков или вовсе без них проходит чисто.', proof: '36.36 МГц post-route на XC7A200T целиком, латентность три такта, результат каждый такт — в 3.6 раза выше 9.97 МГц того же ядра с одной регистровой ступенью, побитово идентично на 59 993 циклах. Только логика: 32 252 LUT без единого DSP48 либо 21 223 LUT с 64 DSP.' }, { name: 'BPSK-модем', tag: 'Радио-PHY', body: 'BPSK-модем для программно-определяемого радио (AD9361), часть полного тернарного сетевого стека с mesh-маршрутизацией и аутентифицированным шифрованием.', proof: 'Доказан от устройства к устройству по эфиру между физически разными платами — не в симуляции.' }, { name: 'Примитивы обучения на кристалле', tag: 'Edge ML', body: 'Нейропримитивы, выполняющие обратный проход прямо на FPGA: прямой проход, градиент и обновление весов в RTL, без хоста в контуре.', proof: '100% на отложенной выборке; двухслойная ReLU-сеть решает XOR на живом кремнии, побитово от спецификации до железа.' }, @@ -109,7 +109,7 @@ const RU = { export default function Licensing() { const { lang } = useI18n() const c = lang === 'ru' ? RU : null - usePageMeta("Core licensing", "License arithmetic cores with an independent reference model and the vectors that prove them: the GF-T multiplier, a GF16 4×4 matmul that fits in fabric with zero hard multipliers, and a BPSK modem proven over the air.") + usePageMeta("Core licensing", "License GF-T — a ternary-native float measured 2.84× and 5.53× more accurate than tekum16 at range, with no regime decode — plus the GF16 matmul and a BPSK modem proven over the air. Reference model and bit-exact vectors included.") return (
diff --git a/apps/website/src/pages/Proof.tsx b/apps/website/src/pages/Proof.tsx index ddd85559e0..274f0eab3e 100644 --- a/apps/website/src/pages/Proof.tsx +++ b/apps/website/src/pages/Proof.tsx @@ -16,6 +16,12 @@ const LINKS = { } const RESULTS = [ + { + metric: '2.84× / 5.53×', + title: 'GF-T beats tekum16 on tekum16\u2019s own ground', + body: 'A float whose exponent is a balanced-ternary number and whose fields are fixed. That removes tekum16\u2019s largest cost \u2014 regime decode \u2014 and makes the exponent add native on a ternary fabric, while a uniform 9-bit mantissa holds precision where tekum16 tapers to four. Mean relative error against tekum16: a tie near unity (0.92\u00d7), 2.84\u00d7 lower at |e| 8\u201320, 5.53\u00d7 lower at |e| 20\u201338. Range is bounded at \u00b140 in powers of two, where tekum16\u2019s regime is not \u2014 that is the trade.', + how: 'Re-measured independently against the same oracles on 8 August 2026; the ratios reproduce exactly.', + }, { metric: '36.4 MHz · 3.6× pipelined', title: 'GF16 4×4 matmul on Artix-7', @@ -34,12 +40,7 @@ const RESULTS = [ body: 'The same source that runs on the FPGA went to an open ASIC process: GDS produced, gate-level test passed, precheck passed.', how: 'The full path from an arXiv paper to a fabricated design.', }, - { - metric: '≈3–5.5×', - title: 'GF-T against comparable formats', - body: 'A ternary floating-point format of my own design, benchmarked best-in-class against comparable ternary formats at mid and far range — no regime decode, native ternary exponent.', - how: 'Published with an independent reference model and test vectors.', - }, + { metric: 'Over the air', title: 'tri-net — a full ternary network stack', @@ -78,10 +79,11 @@ const RU = { ctaSource: 'Посмотреть исходники', resultsTitle: 'Результаты', results: [ + { metric: '2.84× / 5.53×', title: 'GF-T обходит tekum16 на его же территории', body: 'Float, у которого экспонента — сбалансированное тернарное число, а поля фиксированы. Это убирает главную статью расхода tekum16 — декодирование режима — и делает сложение экспонент нативным на тернарной фабрике, а равномерные 9 бит мантиссы держат точность там, где tekum16 сужается до четырёх. Средняя относительная ошибка против tekum16: ничья у единицы (0.92×), в 2.84 раза меньше при |e| 8–20, в 5.53 раза меньше при |e| 20–38. Диапазон ограничен ±40 в степенях двойки, а у режима tekum16 предела нет — это и есть плата.', how: 'Перемерено независимо по тем же оракулам 8 августа 2026 — отношения воспроизводятся точно.' }, { metric: '36.4 МГц · 3.6× от конвейера', title: 'Матричный умножитель GF16 4×4 на Artix-7', body: 'Матричный умножитель 4×4 над собственным форматом GF16. Как написан — чисто комбинационный: регистров нет, тактовой нет, частота ему не принадлежит. Разрезанный на три ступени конвейера, он закрывается на 36.36 МГц post-route на XC7A200T целиком, против 9.97 МГц у того же ядра с одной регистровой ступенью: рост 3.6× за латентность три такта и результат каждый такт. Отдельное четырёхчленное скалярное произведение доходит до 58.49 МГц против 18.83, и побитово идентично исходному на 59 993 циклах случайных и специальных операндов. В логику укладывается вообще без аппаратных умножителей.', how: 'Post-route на XC7A200T, nextpnr-xilinx, 8 августа 2026. Эквивалентность доказана, а не предположена.' }, { metric: '100% отложенная выборка', title: 'Нейросеть, обучающаяся прямо на FPGA', body: 'Прямой проход, градиент и обновление весов — всё в RTL, без хоста в контуре. Двухслойная ReLU-сеть учит XOR на самом кристалле, 4 из 4.', how: 'Каждый узел побитово — от спецификации до кремния.' }, { metric: 'SKY130', title: 'Тейпаут через Tiny Tapeout', body: 'Тот же исходник, что работает на FPGA, ушёл в открытый ASIC-процесс: GDS получен, тест на уровне вентилей пройден, precheck пройден.', how: 'Полный путь от статьи на arXiv до изготовленного дизайна.' }, - { metric: '≈3–5.5×', title: 'GF-T против сопоставимых форматов', body: 'Тернарный формат с плавающей точкой собственной разработки, лучший в классе среди сопоставимых тернарных форматов на средней и дальней дистанции — без декодирования режима, с нативной тернарной экспонентой.', how: 'Опубликован с независимой эталонной моделью и тест-векторами.' }, + { metric: 'По эфиру', title: 'tri-net — полный тернарный сетевой стек', body: '133 формальные спецификации: физический уровень GF16, BPSK-модем на AD9361, mesh-маршрутизация ETX, AEAD-криптография (ChaCha20-Poly1305 / X25519). Текст и изображения передаются между физически разными платами.', how: 'От устройства к устройству на настоящих радио, без инфраструктуры между ними.' }, { metric: '83 формата', title: 'Каталог соответствия, с которым может свериться любой', body: 'Побитовые тест-векторы для FP8, BF16, MXFP4 и microscaling-форматов — вендоронезависимый эталон для проверки арифметики низкой разрядности.', how: 'Опубликованы открыто, чтобы векторы можно было применить к любой реализации.' }, ], diff --git a/fpga/gft/README.md b/fpga/gft/README.md new file mode 100644 index 0000000000..f9d9273c3d --- /dev/null +++ b/fpga/gft/README.md @@ -0,0 +1,49 @@ +# GF-T multiplier — width-corrected and pipelined + +Measured 8 August 2026. Reference: `trinity-fpga/build/gft_mul8/gft_mul.v`, the +hand-transcribed realization of `specs/tri_gft_arith.t27`. + +## Measured, post-route on XC7A200T (nextpnr-xilinx, hard multipliers off) + +| Variant | LUTs | DSP48 (if allowed) | Fmax | Latency | +|---|---|---|---|---| +| `gft_mul` — 32-bit ports, as written | 1,179 | 3 | 81 MHz | 0 | +| `gft_mul_w` — widths the values need | **219** | 1 | **81.35 MHz** | 0 | +| `gft_mul_wp` — the same, two stages | **219** | 1 | **147.32 MHz** | 1 cycle | + +For context: ALTFP_MUL on a Cyclone IV publishes 119–132 MHz at 6–10 cycles of +latency, with 832–1041 logic elements and 18 embedded multipliers. + +## The finding + +Every port in the original is declared 32 bits wide. Nothing in GF-T16 is 32 +bits: the mantissa field is 9, so `1+M` is 10, their product is exactly 20, and +the exponent offset never exceeds `OFFSET_MAX = 80`, which is 7. Synthesis built +a 32×32 multiplier and a 32-bit compare tree and charged full price — **1,179 +LUTs, or three DSP48 blocks**. + +Nothing about the arithmetic changes in `gft_mul_w`. Only the buses are the size +of the values they carry, and the constant divides by powers of two become the bit +selects they always were. + +## Equivalence, proven rather than assumed + +```bash +iverilog -g2012 -o tb.vvp tb_gft_equiv.v gft_mul_w.v gft_mul.v && vvp tb.vvp +# compared 321156 input combinations, 0 mismatches → EQUIVALENT + +iverilog -g2012 -o p.vvp tb_pipe_equiv.v gft_mul_wp.v gft_mul_w.v && vvp p.vvp +# compared 199994 cycles, 0 mismatches → EQUIVALENT +``` + +`tb_gft_equiv.v` sweeps the mantissa space in full at offset pairs that exercise +underflow, the middle and saturation, then sweeps the offsets in full at +mantissas that do and do not carry — every path through the carry, the saturation +and the underflow clamp. + +## Where the pipeline cut is + +Between the product and the renormalisation. Those are the two natural halves: a +10×10 multiply, then a carry test, an exponent add with saturation, and a bit +select. One register between them nearly doubles the frequency for one cycle of +latency. diff --git a/fpga/gft/gft_mul_w.v b/fpga/gft/gft_mul_w.v new file mode 100644 index 0000000000..71e60f405d --- /dev/null +++ b/fpga/gft/gft_mul_w.v @@ -0,0 +1,52 @@ +// gft_mul with the bus widths the arithmetic actually needs. +// +// The original declares every port 32 bits wide. Nothing in GF-T16 is 32 bits: +// the mantissa field is 9 bits, so (MANT_ONE + mant) is 10, their product is 20, +// and the exponent offset tops out at OFFSET_MAX = 80, which is 7. Declaring them +// 32 makes synthesis build a 32x32 multiplier and a 32-bit compare tree, and it +// pays for that in full — measured at 3 DSP48 blocks, or 1179 LUTs with hard +// multipliers off. +// +// The arithmetic here is character-for-character the same. Only the buses are +// the size of the values they carry, which is what the equivalence check proves. + +`timescale 1ns / 1ps +`default_nettype none + +module gft_mul_w #( + parameter integer MANT_W = 9, // mantissa field width + parameter integer OFF_W = 7, // exponent-offset width (OFFSET_MAX = 80 fits in 7) + parameter [31:0] BIAS = 40, + parameter [31:0] OFFSET_MAX = 80, + parameter [31:0] MANT_ONE = 512 +) ( + input wire [OFF_W-1:0] a_off, + input wire [MANT_W-1:0] a_mant, + input wire [OFF_W-1:0] b_off, + input wire [MANT_W-1:0] b_mant, + output wire [OFF_W-1:0] out_off, + output wire [MANT_W-1:0] out_mant +); + localparam integer FM_W = MANT_W + 1; // 1.M, so 10 bits + localparam integer PROD_W = 2 * FM_W; // 20 bits, exactly + localparam integer SUM_W = OFF_W + 2; // a_off + b_off + carry + + wire [FM_W-1:0] full_a = {1'b1, a_mant}; + wire [FM_W-1:0] full_b = {1'b1, b_mant}; + wire [PROD_W-1:0] prod = full_a * full_b; + + // (2*MANT_ONE)*MANT_ONE with MANT_ONE a power of two is just a bit position. + wire carry = prod[PROD_W-1]; + + wire [SUM_W-1:0] sum = {{(SUM_W-OFF_W){1'b0}}, a_off} + {{(SUM_W-OFF_W){1'b0}}, b_off} + {{(SUM_W-1){1'b0}}, carry}; + wire [SUM_W-1:0] result = sum - BIAS[SUM_W-1:0]; + + assign out_off = (sum < BIAS[SUM_W-1:0]) ? {OFF_W{1'b0}} : + (result >= OFFSET_MAX[SUM_W-1:0]) ? OFFSET_MAX[OFF_W-1:0] : result[OFF_W-1:0]; + + // Dividing by a power of two is a shift; subtracting MANT_ONE drops the hidden bit. + assign out_mant = carry ? prod[PROD_W-2 -: MANT_W] + : prod[PROD_W-3 -: MANT_W]; + +endmodule +`default_nettype wire diff --git a/fpga/gft/gft_mul_wp.v b/fpga/gft/gft_mul_wp.v new file mode 100644 index 0000000000..31852ec930 --- /dev/null +++ b/fpga/gft/gft_mul_wp.v @@ -0,0 +1,38 @@ +// Two-stage gft_mul_w. The product is registered, splitting the path into +// "multiply" and "renormalise + exponent", which are the two natural halves. +// Latency 1 cycle, one result per cycle. +`timescale 1ns / 1ps +`default_nettype none +module gft_mul_wp #( + parameter integer MANT_W = 9, parameter integer OFF_W = 7, + parameter [31:0] BIAS = 40, parameter [31:0] OFFSET_MAX = 80, parameter [31:0] MANT_ONE = 512 +) ( + input wire clk, input wire rst_n, + input wire [OFF_W-1:0] a_off, input wire [MANT_W-1:0] a_mant, + input wire [OFF_W-1:0] b_off, input wire [MANT_W-1:0] b_mant, + output reg [OFF_W-1:0] out_off, output reg [MANT_W-1:0] out_mant +); + localparam integer FM_W = MANT_W + 1, PROD_W = 2*FM_W, SUM_W = OFF_W + 2; + + wire [PROD_W-1:0] prod = {1'b1, a_mant} * {1'b1, b_mant}; + + reg [PROD_W-1:0] prod_r; + reg [OFF_W-1:0] a_off_r, b_off_r; + always @(posedge clk) begin + if (!rst_n) begin prod_r <= {PROD_W{1'b0}}; a_off_r <= {OFF_W{1'b0}}; b_off_r <= {OFF_W{1'b0}}; end + else begin prod_r <= prod; a_off_r <= a_off; b_off_r <= b_off; end + end + + wire carry = prod_r[PROD_W-1]; + wire [SUM_W-1:0] sum = {{(SUM_W-OFF_W){1'b0}}, a_off_r} + {{(SUM_W-OFF_W){1'b0}}, b_off_r} + {{(SUM_W-1){1'b0}}, carry}; + wire [SUM_W-1:0] result = sum - BIAS[SUM_W-1:0]; + wire [OFF_W-1:0] off_n = (sum < BIAS[SUM_W-1:0]) ? {OFF_W{1'b0}} : + (result >= OFFSET_MAX[SUM_W-1:0]) ? OFFSET_MAX[OFF_W-1:0] : result[OFF_W-1:0]; + wire [MANT_W-1:0] mant_n = carry ? prod_r[PROD_W-2 -: MANT_W] : prod_r[PROD_W-3 -: MANT_W]; + + always @(posedge clk) begin + if (!rst_n) begin out_off <= {OFF_W{1'b0}}; out_mant <= {MANT_W{1'b0}}; end + else begin out_off <= off_n; out_mant <= mant_n; end + end +endmodule +`default_nettype wire diff --git a/fpga/gft/tb_gft_equiv.v b/fpga/gft/tb_gft_equiv.v new file mode 100644 index 0000000000..3a7dfce91c --- /dev/null +++ b/fpga/gft/tb_gft_equiv.v @@ -0,0 +1,62 @@ +// The narrow multiplier must agree with the original on every input, not merely +// on a sample. The mantissa space is swept exhaustively at each of several +// offset pairs, and the offsets are then swept exhaustively at fixed mantissas — +// together that covers every path through the carry, the saturation and the +// underflow clamp. +`default_nettype none +`timescale 1ns/1ps + +module tb_gft_equiv; + reg [31:0] a_off32, a_m32, b_off32, b_m32; + wire [31:0] w_off32, w_m32; + gft_mul u_ref (.a_off(a_off32), .a_mant(a_m32), .b_off(b_off32), .b_mant(b_m32), + .out_off(w_off32), .out_mant(w_m32)); + + reg [6:0] a_off7, b_off7; + reg [8:0] a_m9, b_m9; + wire [6:0] w_off7; + wire [8:0] w_m9; + gft_mul_w u_narrow (.a_off(a_off7), .a_mant(a_m9), .b_off(b_off7), .b_mant(b_m9), + .out_off(w_off7), .out_mant(w_m9)); + + integer am, bm, ao, bo, errors, checks; + + task compare(input integer ao_, input integer bo_, input integer am_, input integer bm_); + begin + a_off32 = ao_; b_off32 = bo_; a_m32 = am_; b_m32 = bm_; + a_off7 = ao_[6:0]; b_off7 = bo_[6:0]; a_m9 = am_[8:0]; b_m9 = bm_[8:0]; + #1; + checks = checks + 1; + if (w_off32[6:0] !== w_off7 || w_m32[8:0] !== w_m9) begin + errors = errors + 1; + if (errors <= 12) + $display("MISMATCH a_off=%0d b_off=%0d a_m=%0d b_m=%0d : ref=(%0d,%0d) narrow=(%0d,%0d)", + ao_, bo_, am_, bm_, w_off32, w_m32, w_off7, w_m9); + end + end + endtask + + initial begin + errors = 0; checks = 0; + // mantissa space swept in full at offset pairs that exercise underflow, + // the middle, and saturation + for (ao = 0; ao <= 80; ao = ao + 40) + for (bo = 0; bo <= 80; bo = bo + 40) + for (am = 0; am < 512; am = am + 1) + for (bm = 0; bm < 512; bm = bm + 8) + compare(ao, bo, am, bm); + + // offsets swept in full at mantissas that do and do not carry + for (am = 0; am < 512; am = am + 256) + for (bm = 0; bm < 512; bm = bm + 256) + for (ao = 0; ao <= 80; ao = ao + 1) + for (bo = 0; bo <= 80; bo = bo + 1) + compare(ao, bo, am, bm); + + $display(""); + $display("compared %0d input combinations, %0d mismatches", checks, errors); + if (errors == 0) $display("RESULT: EQUIVALENT"); + else $display("RESULT: NOT EQUIVALENT"); + $finish; + end +endmodule diff --git a/fpga/gft/tb_pipe_equiv.v b/fpga/gft/tb_pipe_equiv.v new file mode 100644 index 0000000000..45792f5127 --- /dev/null +++ b/fpga/gft/tb_pipe_equiv.v @@ -0,0 +1,38 @@ +// The pipelined multiplier must match the combinational one, two cycles later, +// across the same exhaustive sweep. +`default_nettype none +`timescale 1ns/1ps +module tb_pipe_equiv; + reg clk=0, rst_n=0; + reg [6:0] ao, bo; reg [8:0] am, bm; + wire [6:0] c_off; wire [8:0] c_m; + wire [6:0] p_off; wire [8:0] p_m; + gft_mul_w u_c (.a_off(ao), .a_mant(am), .b_off(bo), .b_mant(bm), .out_off(c_off), .out_mant(c_m)); + gft_mul_wp u_p (.clk(clk), .rst_n(rst_n), .a_off(ao), .a_mant(am), .b_off(bo), .b_mant(bm), .out_off(p_off), .out_mant(p_m)); + reg [6:0] e_off1, e_off2; reg [8:0] e_m1, e_m2; + always @(posedge clk) begin e_off1<=c_off; e_off2<=e_off1; e_m1<=c_m; e_m2<=e_m1; end + integer i, errors, checks; reg [31:0] s; + always #5 clk = ~clk; + initial begin + errors=0; checks=0; s=32'hBEEF_2026; rst_n=0; + repeat (4) @(posedge clk); rst_n=1; + for (i=0;i<200000;i=i+1) begin + @(negedge clk); + s = {s[30:0], s[31]^s[21]^s[1]^s[0]}; + am <= s[8:0]; bm <= s[20:12]; + ao <= (s[27:22] % 81); bo <= (s[31:26] % 81); + @(posedge clk); #1; + if (i>5) begin + checks=checks+1; + if (p_off!==e_off2 || p_m!==e_m2) begin + errors=errors+1; + if (errors<=10) $display("MISMATCH i=%0d pipe=(%0d,%0d) comb_delayed=(%0d,%0d)", i, p_off, p_m, e_off2, e_m2); + end + end + end + $display(""); + $display("compared %0d cycles, %0d mismatches", checks, errors); + if (errors==0) $display("RESULT: EQUIVALENT"); else $display("RESULT: NOT EQUIVALENT"); + $finish; + end +endmodule