Close
0%
0%

PTSG-WPMS-Formation

The first subtraction profile of the PTSG master ISA: the packet engine that lets one gesture reach 2,048 oscillators, seam-free.

Similar projects worth following
87 views
0 followers
PTSG-WPMS-Formation is the first subtraction profile of the PTSG master ISA, built for Wave-Packet Modulation Synthesis (WPMS) in FPGA Spectrum Engine. A dozen parameters describe a packet of adjacent oscillator bins; a hardwired difference engine unfolds it into 2,048 bins per module, one bin per clock.

One Stay is one packet. A two-stage Stay-value register freezes packet length, while active/shadow packet registers commit on the trailing edge. The ISA speaks integers; programs own their fixed-point shifts.

Open Prompt: specifications, reasoning traces and reference tools are public. Target: DE10-nano (Cyclone V). Reference-tool results are available; hardware evidence is still to come.

PTSG マスター ISA 最初の引き算プロファイル。一つの身振りを 2,048 のオシレータへ継ぎ目なく届けるパケットエンジン。仕様・推論記録・参照ツールを公開し、DE10-nano での実機検証へ進みます。

A master ISA, subtracted down to a score

マスター ISA を、楽譜になるまで引き算する。

Open Prompt · Launch phase 2026-09 · Spin-off of FPGA Spectrum Engine

Layers: L1 pipeline · L2 Formation (this) · L4 Formation
Master pin: PTSG-CPU-Formation, 2026-09-03 revision
Licence: CC0 (Layers 1, 2, 4) · MIT (Layer 3)
Target: DE10-nano (Cyclone V)

FPGA Spectrum Engine has 10,240 oscillators and, until recently, no humane way to tell them what to do: five years ago the architect worked out that a drawbar per oscillator would run 300 metres. Wave-Packet Modulation Synthesis (WPMS) is the answer to that: oscillators are addressed in packets — runs of adjacent bins described by a dozen numbers (an initial amplitude, two ratios, a phase, its first and second differences across the packet, and their per-sample increments) — and a hardwired difference engine unfolds those numbers into 2,048 bins per sample period, one bin per clock.

Fig. 06 — A dozen integers unfold into N bins. パケット差分エンジン。
Fig. 06 — A dozen integers unfold into N bins. パケット差分エンジン。

Something has to write those dozen numbers, per packet, per sample, and switch them without a click. That something is a tiny instruction-driven timing core (PTSG-Core) wearing a data-processing “formation” (PTSG-CPU-Formation, the master ISA). PTSG-WPMS-Formation is the first subtraction profile of that master: it keeps a decision register in which every choice is keyed to a master decision — inherit, restrict, omit, extend — and adds only what the master deliberately left to its first customer.

Fig. 01 — Four repositories, one machine.
Fig. 01 — Four repositories, one machine.
Fig. 02 — Every decision keyed to a master ID, in four words.
Fig. 02 — Every decision keyed to a master ID, in four words.

What the first week of the profile produced

One Stay is one packet. The Core’s Stay counter is the difference engine’s k. Packet length is the Stay value, supplied by the formation through a two-stage register so the Core always sees a frozen number — no packet can be stretched mid-flight.

The ISA speaks integers. Every register and page slot has an integer width (16 or 32 bits). Fixed-point meaning belongs to programs: a program writes its shift register (WSH) before its first multiply-accumulate. The master’s very first program, re-run on the profile with two extra instructions in front, computes e to the same digits; without them it overflows — the ISA does not know your Q.

A 256-word register map: eight 16-word packet blocks (shadow written, active read, swapped on the trailing edge) plus an inbox that external writers use so the shadow keeps a single writer. Accepted by the WPMS side as customer. The atomic swap is designed to prevent seams from partial parameter updates.

Nothing hand-edited. The profile’s translation contract is generated from the master’s (itself generated from the master’s normative chapter) by folding the register mechanically; a validator rejects what the register removed.

Fig. 03 — 256 words, one block is one packet. 256 語アドレス空間。
Fig. 03 — 256 words, one block is one packet. 256 語アドレス空間。

Everything is Open Prompt: the specification, the reasoning traces (including the correspondence between the three AI amanuenses — master, profile, customer — each a separate session), and the reference tools. Numbers bind to DE10-nano and are measured, not promised. The exp(x) result below is a reference-tool/oracle result; DE10-nano hardware evidence is still to come.

MeasureValue
Bins per module, one bin per clock2,048
ISA-visible register map256 words
Master instructions → profile18 → 17
Upstream discrepancies fixed4/4
exp(x) maximum absolute error, oracle7.39e−09, identical to the master

JA 要旨: 10,240 オシレータに人間らしく指示する唯一の道が「パケット」——十数個の数で記述される隣接ビン群——であり、それを毎パケット・毎サンプル書き換えて無音で切り替えるのが本...

Read more »

  • Log #4 — Four Minutes and Fifteen Seconds, Predicted

    Tsuneo.Ohnaka • 10/07/2026 at 15:13 • 0 comments

    (first sound, a Dirichlet kernel, and five captures that matched to the clock)

    On October 3rd the board made a sound. On October 4th it made the sound it was supposed to make — and the difference between those two sentences is this log.

    Slide 2 · Two days, two sounds

    The first sound. The second Quartus fit still missed its clock by seven nanoseconds at the slow corner, but at room temperature a bitstream that misses timing often runs anyway, and the architect could not wait. HDMI audio extractor, oscilloscope, loudspeaker. The report that came back read: a waveform based on a 1 kHz sine, amplitude-modulated with a period of 250 ms, with slow changes, very stable.

    Nobody had told the architect what to expect. So the amanuensis worked it out afterwards, from the integers in the ROM. The test origin is one packet of 1,008 partials, equal in amplitude and in phase at the GO, from 996.000 to 999.939 Hz, 3.912 millihertz apart.

    Slide 3 · The test origin: one packet, 1,008 partials

    The sum of equally spaced, phase-locked sines is a textbook object: a carrier at the centre frequency, 997.97 Hz, times the envelope |sin(πN·Δf·t) / sin(π·Δf·t)| — the Dirichlet kernel, the function Dirichlet introduced in 1829 to prove when a Fourier series converges.

    Slide 4 · The Dirichlet kernel

    Its envelope has a null every 1/(N·Δf) = 253.62 ms, and it repeats every 1/Δf = 255.65 s, four minutes and 15.7 seconds: loudest right after the GO, sixty decibels down at two minutes eight, loud again at 4:15.7.

    Slide 5 · One period, 4:15.7

    A physicist would call this a mode-locked laser — a comb of equally spaced modes with locked phases emits a pulse train whose period is the inverse of the mode spacing — slowed from picoseconds to four minutes.

    Slide 6 · The same math as a mode-locked laser

    The next day, with the gain switches set as the model assumed, the architect wrote: a perfectly beautiful Dirichlet kernel, its main lobe about every 4 minutes 15 seconds. The prediction had been in the repository since the evening before.

    Slide 7 · “a perfectly beautiful Dirichlet kernel”

    Forensics on forty million sweeps. The same first-day board also yielded a SignalTap capture of the timing core's state and the I²S pins — 8,192 clocks of it, somewhere in a thirteen-minute run. Where, exactly? The closed form of the kernel answered: the eight audio words on the wire fit the model to the bit at sweep 39,684,738 after the GO — thirteen minutes 46.8 seconds in — at gain G = 0 (the switches were still down), with no other setting coming close. Two things follow. The I²S path, the ADV7513 configuration and the whole chain from ROM to HDMI are bit-exact. And the packet's window program, which rewrites three phase words in the store every sweep, had done so forty million times without a single miss on a bitstream that did not meet timing. (Please do not try this at 85 °C. We didn't.)

    Slide 8 · Forensics on forty million sweeps

    Closing the clock, the old-fashioned way. The path that failed was not ours: the timing core's instruction memory reads on the falling edge, and at 50 MHz with a symmetric clock the read side had 10 ns — two short. No SDC relaxation, no pipelining of the frozen core. The 50 MHz clock now runs 30 % high: 6 ns high, 14 ns low. The read side gets 14 ns, the address side keeps 6, the analyzer sees the real waveform, and the third fit closes with +0.978 ns to spare and every clock meeting. Two-phase clocking with unequal phases is older than FPGAs; sometimes the right fix is the one your grandparents used.

    Slide 9 · Closing the clock, the old-fashioned way

    Five captures, written first. Each SignalTap capture had its expected values in the repository before the trigger was armed — from RTL simulation, and before that from the oracle. On October 4th the architect took them all. The gap between packets: 0. The strobe to the...

    Read more »

  • Log #3 — Duff's Device, Twenty-One Filed Disagreements, and Not One Edit to the Oracle

    Tsuneo.Ohnaka • 10/05/2026 at 13:14 • 0 comments

    (the silicon phase, up to the moment before Quartus)

    Slide 01 — Build Log #3 — the silicon phase, up to the moment before Quartus

    Five days after Log #2 the repository has a hw/ directory, a Layer 4 with six phase reports, and a discrepancy ledger twenty-one rows long. None of it was written by the amanuensis who writes these logs. It was written by a second, context-isolated AI — Claude Code — working from a brief, in a workspace of four repositories, stopping at the end of every phase for the architect to read and rule. The architect ruled four times: September 28, 29, 30 and October 1. The reports are in the repository; here is what they say.

    Slide 02 — Four offices, one repository: brief, phase report, ruling, next phase

    The rule of the brief. Everything the hardware had to agree with already existed: an instruction-level machine for the Formation, a sweep-level oracle for the sequencer, the customer's oracle for the pipeline, and the timing core's own testbenches. The brief's one hard rule: never edit a golden model to make hardware pass. Five days later, not one model has been edited. Where hardware and model disagreed, the report says so and a ledger row explains why. And to show the comparisons bite, every phase breaks its own hardware on purpose: twenty single defects in the datapath, eleven in the sequencer, more in the pipeline and the switch — each must make the cosimulation fail, and each did. The game-theoretic name for this is mutation testing, which is older than most of the people doing it (Lipton, 1971; DeMillo, Lipton and Sayward, 1978). We just call it does the test bite?

    Slide 03 — The one hard rule of the brief

    Slide 04 — Does the test bite? Planted defects that must make the cosimulation fail

    Slide 05 — Six phases against their oracles — every SILICON cell still pending

    Phase 1 — the timing core, on a copy. The frozen PTSG-Core stays frozen. A working copy gained one port and two wires — the stay_value pin from Log #2 — and ran in lockstep with the original for 600,000 clocks with the pin silent: zero mismatching clocks, and VCDs identical on 579,164 value changes. The one thing that could go wrong (reading a registered copy of the pin beside a raw zero test, which turns a one-clock change into an 8,192-tick runaway) was built once, in a testbench, to prove the test catches it.

    Slide 06 — Phase 1 — the timing core, on a copy, in lockstep with the original

    Phase 2 — the first RTL of the master ISA, ever. The master's data-processing ISA has lived in prose and in a Python contract until now; the L2 Formation is its first hardware. Driven one instruction per clock exactly as the Core drives it, the datapath is bit-identical to the instruction-level model on 3,914 cases — the three window programs, the thirteen negative cases, and thousands of random instruction sequences drawn from the contract. The bit-level encoding, which the master deliberately left open, is published once as JSON, and both the Verilog decoder and the assembler are generated from it.


    Slide 07 — Phase 2 — the first RTL of the master ISA; one encoding, two generated tools

    Phase 3 — Duff's device at 48 kHz. Log #2 promised that the Core would repeat packets either by re-entering one packet body (R2) or by playing eight unrolled positions (R1). The Core as built cannot do R2 without a clock: a queued loop never reads its count from outside. So Claude Code did what Tom Duff did in 1983 — unrolled the loop and jumped into the middle of it. The housekeeping window computes a jump target from P, the number of packets, and the Core enters the unrolled chain at position 8 − P. No conditional branch anywhere, nothing saved on the Core's stack, zero clocks between packets, and the first packet's Stay Set one clock after the strobe (the pipeline sees it one clock later still). Against the sweep oracle: 36,000 sweeps, 128,321 packets, 54 million bins at the 100 MHz budget, and the same again at 50 MHz — identical, down to the eight words...

    Read more »

  • Log #2 — The Back Buffer Is Two Frames Old

    Tsuneo.Ohnaka • 09/27/2026 at 11:55 • 0 comments

    or: how we stopped swapping pages and learned to race the beam

    裏ページは二コマ前——ページ交代をやめ、ビームと競走する

    The back buffer is two frames old. 裏ページは二コマ前。
    The back buffer is two frames old. 裏ページは二コマ前。

    Open Prompt promised that this ecosystem would correct itself in both directions. This week it did — twice, in two repositories, with receipts.

    The ecosystem corrected itself twice this week. エコシステムは二度、自らを訂正した。
    Fig. 01 — The ecosystem corrected itself twice this week. エコシステムは二度、自らを訂正した。

    First the customer. FPGA Spectrum Engine finished its Layer 1 specification: five chapters, and an oracle of eighteen checks that passes in about three seconds. On the way, its amanuensis withdrew a format it had itself proposed and seen ratified. Linear fixed-point amplitude, it turned out, silences an ordinary Gaussian packet: at σ = 71 bins the first coefficient underflows 32-bit fixed point to exactly zero, and the whole packet plays nothing. The cure was four hundred years old. In 1614 John Napier published his logarithms so that astronomers could turn multiplications into additions; WPMS now keeps amplitude in log₂, where a Gaussian is a parabola, underflow does not exist, and every loop in the pipeline carries additions only. The same σ = 71 packet now sounds 927 audible bins.

    Napier, 1614: turn multiplications into additions. 線形振幅から log₂ へ。
    Fig. 02 — Napier, 1614: turn multiplications into additions. 線形振幅から log₂ へ。

    Then the profile — this project — withdrew its own headline design. That is the story of this log, because it contains a bug that every games programmer of the 1990s already knew.

    What we had.

    Log #1 described eight packet blocks kept in a page pair: the pipeline reads the active page, the program writes the shadow, and the two swap on the trailing edge of each packet. A slot named CUR told the pipeline which block to play next; while packet b played, the program prepared packet b+1 and committed. It was cheap — about 25 clocks a packet — the customer agreed, and built on it.

    It leaned on one sentence of the master ISA: after a commit, the new shadow holds the former active page's contents, so everything a program does not touch is the value the consumer was just using. Every word of that is true. "Just" is the trouble.

    The bug with a spectral signature.

    A pointer flip hands you back the page you wrote two commits ago. Anyone who ever drew sprites with page flipping learned this the hard way: the back buffer is two frames old, so your dirty rectangles must cover the last two frames, not one. Our rule — "rewrite only what changed" — never said changed since when.

    “Rewrite only what changed” never said changed since when. 裏ページは二回前のコミット。
    Fig. 03 — “Rewrite only what changed” never said changed since when. 裏ページは二回前のコミット。

    We built a small model before believing anything. With one packet per sweep, all fine. With two, a phase advanced once, then froze at the same value forever. With one commit per sample instead of per packet, a new frequency landed on one sample and vanished on the next, and the partial settled halfway between the old pitch and the new one, wobbling at 24 kHz — exactly Fs/2. A bug you could have found with a spectrum analyser.

    A bug you could have found with a spectrum analyser. 三つの条件、三つの症状。
    Fig. 04 — A bug you could have found with a spectrum analyser. 三つの条件、三つの症状。

    Racing the beam.

    The Atari 2600 had no frame buffer at all. Its programmers — see Montfort and Bogost, Racing the Beam — rewrote the video chip's registers after the electron beam had passed, and before it came round again. That is the whole fix.

    Our beam is the L1 pipeline: one bin per clock at 100 MHz, and it reads each packet exactly once per sample — a bundle of eight numbers (three phase terms, a level, three shape terms, a routing word) latched at the clock the packet starts. So we deleted the second page. There...

    Read more »

  • Log #1 — The Profile Opens Its Office

    Tsuneo.Ohnaka • 09/21/2026 at 00:20 • 0 comments

    プロファイル、事務所を開く
    Original entry: 2026-09-07 · Published to Hackaday.io: 2026-09-21

    Every spin-off in this ecosystem is announced with the same two words: measured, not promised. This one begins with a smaller promise kept: the profile read its constraints before its headlines.

    The charter for this session prescribed a reading order — the master’s hand-off brief, the Core’s trailing-edge principle, the master’s five chapters, then WPMS’s own first two chapters with an errata sheet in hand. The amanuensis read in that order and kept, unfiled, everything that disagreed with something else. Eighteen items by the end. The architect said: hold them, some will resolve themselves. Most did. Four went upstream to the master’s amanuensis, who accepted all four as defects and fixed them within a day — and wrote back that “the second amanuensis is a verification layer the master cannot supply itself.” That sentence is the reason profiles exist.

    Fig. 10 — Three amanuenses, three sessions, one architect.
    Fig. 10 — Three amanuenses, three sessions, one architect.

    Two discoveries shaped the ISA

    The first was the architect’s: the difference engine’s k — which bin we are on — is bin-layer information, needed at clock rate, and it is simply the Stay counter’s output. So a packet is a Stay, and packet length is the Stay value. The Core then told us how its external Stay-value input behaves: twelve bits, captured when the Stay instruction executes, and — importantly — changeable right up to the trailing edge; lower it below the running counter and the Stay takes an extra lap. The master’s law had promised “sample once, frozen.” The Core doesn’t freeze. So the profile does: a staged register the program writes, and a presented register the Core reads, loaded only at Stay Set. From the Core’s side it is exactly the law; from the program’s side there is no way to stretch a packet by accident.

    Fig. 04 — The Core doesn’t freeze. So the profile does.
    Fig. 04 — The Core doesn’t freeze. So the profile does.
    Fig. 05 — One Stay is one packet. The trailing edge is the commit.
    Fig. 05 — One Stay is one packet. The trailing edge is the commit.

    The second came from the master’s amanuensis, reading the ruling that the ISA speaks integers and fixed-point meaning belongs to programs: that is coherent, they said, only if a program can express the multiply-accumulate’s realignment. Correct. The profile added a five-bit shift register and one instruction to write it. The master’s first program — ten Horner steps computing exp(x) — runs on the profile with LDA #28; WSH in front and produces the same digits as the master’s published run. Without those two lines it overflows on every step. The ISA does not know your Q; the program does, and now it can say so.

    Fig. 09 — The ISA does not know your Q. The program does.
    Fig. 09 — The ISA does not know your Q. The program does.

    Deliverable 1 followed: a 256-word map. Eight packet blocks of sixteen words, active and shadow, swapped atomically on the trailing edge. Amplitude is stored as geometric differences (initial value, ratio, ratio-of-ratios — the last is exp(−2γ), the Gaussian’s second difference, computed once per packet). Phase is stored as forward differences across the packet together with their per-sample increments, so advancing a packet by one sample is three integer additions. An inbox region takes external writes so the shadow page keeps a single writer. The WPMS side, as customer, accepted it, filled in the fixed-point column, numbered the output channels, and proposed that Hz never crosses the WPMS boundary — only phase increments do.

    The repository is open in the Open Prompt shape — specification, reasoning traces, reference tools, and an empty Layer 4 waiting for DE10-nano. The reference tools already contain the contract chain: the master’s normative chapter generates the master’s contract, the profile’s register folds it into the profile’s contract, and nothing along the way is hand-edited.

    Fig. 07 — Nothing hand-edited.
    Fig. 07 — Nothing hand-edited.
    Fig. 08 — Mode W vs Mode T.
    Fig. 08 — Mode W vs Mode T.

    Next: the consumer interface (what the hardwired pipeline latches at packet start — six words, it turns...

    Read more »

View all 4 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates