-
Build Log #12: Putting "Approximately" on Trial
07/20/2026 at 13:25 • 0 commentsBuild Log #12:「約」を裁判にかける
The camera arrives / カメラの到着
The project summary ended with a promise: the specification says what should happen — now we point a camera at whether it does. This entry keeps that promise. A new oscilloscope (a Siglent SDS814X HD, replacing a TDS3032 that served this bench for twenty-five years) arrived two Sundays ago, and since Thursday night the bench has been a small film set: one camera on the PC screen with the ISMCE window, one on the oscilloscope and the DE10-nano, one close on the scope's display, cut together picture-in-picture. Every scene follows the discipline established beforehand: predictions frozen in writing before filming, never edited afterward. What follows is Scenes 1 through 3 — the videos are now going up on the project page.
プロジェクトサマリは約束で終わっていた: 仕様は「何が起きるはずか」を語ってきた——これからは、本当にそうなるかにカメラを向ける。 本項はその約束の履行である。新しいオシロスコープ(Siglent SDS814X HD——この机で25年働いた TDS3032 の後任)が二週前の日曜に着任し、木曜の夜から作業机は小さな撮影所になった: PC 画面と ISMCE ウィンドウに1台、オシロと DE10-nano に1台、オシロ画面のアップに1台、ピクチャ・イン・ピクチャで編集する。全シーンは事前に確立した規律に従う: 予言は撮影前に文書で凍結し、以後編集しない。 以下はシーン1〜3——動画はいまプロジェクトページに上がりつつある。
Scene 1 — A machine before time begins / 時間が始まる前の機械
Power-up. The instruction memory is all zeros, and in PTSG a word of zeros is not "nothing" — it is a Global Reset with all sixteen timing signals driven low. So the core boots into an eternal Reset loop: running at full clock, going nowhere, lights out. The machine is on; time has not started.
電源投入。命令メモリは全域ゼロ——そして PTSG において、ゼロの語は「無」ではない。それは16本のタイミング信号をすべて Low に駆動する Global Reset である。ゆえにコアは永久 Reset ループへと起動する: フルクロックで走り、どこへも行かず、灯は消えている。機械は動いている。時間はまだ始まっていない。
Then the first improvisation: into address 0, by hand, over JTAG, into the running silicon:
00010000. Still a Reset — but its timing-signal field now carries a 1 in bit 0. The LED lights the instant the word lands. Write00000000; it goes dark. A manual blinker, made of nothing but the Reset instruction and its cargo of signals. No code was written; a number was typed into a living machine. That is the whole thesis of improvisation design, in its smallest possible form.そして最初のインプロビゼーション: 0番地へ、手で、JTAG 越しに、走っているシリコンへ:
00010000。依然として Reset——だがそのタイミング信号フィールドは今、ビット0に 1 を運んでいる。語が着地した瞬間、LED が点く。00000000を書けば消える。Reset 命令とその運ぶ信号だけで出来た、手動の点滅器。コードは一行も書いていない;生きている機械に数を打ち込んだだけである。これがインプロビゼーション・デザインの主題の、最小の形だ。Scene 2 — The trial of "approximately" / 「約」の裁判
Two words:
0000FA01at address 0 (lights off, Stay 4000),0001FA01at address 1 (lights on, Stay 4000). Prescaler 6250, tick 125 µs — a 1 Hz blink. And here the frozen prediction picked a fight with my own intuition. I had said, casually, "approximately one second — the Reset adds its 20 ns to the period." The white-box analysis, frozen before filming, said no: the prescaler grid is free-running, a bare Stay counts grid ticks, and the Reset's single clock is absorbed between ticks. Period: exactly 8000 ticks. Exactly one second. Duty: exactly 1:1. The 20 ns never appears.二語: 0番地に
0000FA01(消灯、Stay 4000)、1番地に0001FA01(点灯、Stay 4000)。プリスケーラ 6250、ティック 125 µs——1 Hz の点滅。そしてここで、凍結済みの予言が私自身の直感に喧嘩を売った。私はかつて気軽に言っていた——「約1秒。Reset の 20 ns が周期に足される」。撮影前に凍結された白箱解析は、否と言った: プリスケーラのグリッドは自由走行であり、裸の Stay はグリッドのティックを数え、Reset の 1 クロックはティックとティックの狭間に吸収される。周期はぴったり 8000 ティック。ぴったり1秒。デューティは正確に 1:1。20 ns は現れない。The verdict, honestly reported: consistent, but not yet convicted. The scope's frequency counter agreed with nominal to within parts per million — and there the method hits its floor. Twenty nanoseconds in one second is 0.02 ppm; the crystal's own tolerance is larger than the thing on trial. A counter cannot distinguish "the 20 ns was absorbed" from "the 20 ns is hiding inside the crystal's error." So this court adjourns for better instruments: the grid-absorption claim will be prosecuted properly with SignalTap, where individual clocks are countable, and filed as Layer 4 evidence. A prediction is not confirmed by a measurement that could not have refuted it — that sentence is the whole reason this project writes predictions down first.
判決は、正直に記す: 整合、しかし未だ有罪確定に至らず。 オシロの周波数カウンタは公称値と ppm 台まで一致した——そしてそこが、この方法の底である。1秒における 20 ns は 0.02 ppm;水晶自身の公差の方が、被告より大きい。カウンタには「20 ns は吸収された」と「20 ns は水晶の誤差の中に隠れている」の区別がつかない。よって当法廷はより良い道具のため休廷する: グリッド吸収の主張は、個々のクロックが数えられる SignalTap で正式に立件し、Layer 4 のエビデンスとして綴じる。反証し得なかった測定は予言を確認しない——この一文こそ、このプロジェクトが予言を先に書き留める理由のすべてである。
Scene 3 — The program becomes audible, ahead of schedule / プログラムは予定より早く音になった
Then the operands shrink, live, word by word: the blink quickens, flickers, fuses into steady light to the eye. The piezo speaker was supposed to enter the story only here, where repetition rates reach the audible band. Physics disagreed. During rehearsal it spoke at one hertz — a dry click at every edge. Of course it did: the output is not a sine but a square, and each edge is a broadband impulse that finds the piezo's resonance no matter how slow the repetition. So the 1 Hz blinker is also, uninvited, a metronome — two clicks per second, one per edge. A prediction beaten by physics before filming even started: we amended the storyboard, dated the amendment, and kept the surprise in the show. Negative data with a nice sound to it.
そしてオペランドが、生のまま、一語ずつ縮んでいく: 点滅は速まり、ちらつき、目には定常光へ融合する。ピエゾスピーカーの登場は、繰り返しが可聴帯に届くこの場面のはずだった。物理は同意しなかった。リハーサル中、それは1ヘルツで鳴いたのである——エッジのたびに、乾いた「コッ」。当然だった: 出力は正弦波ではなく矩形波であり、各エッジは広帯域のインパルスとして、繰り返しがどれほど遅かろうとピエゾの共振を見つけ出す。ゆえに 1 Hz の点滅器は、招かれざるメトロノームでもある——毎秒2回、エッジごとに1回。撮影開始前に物理に敗れた予言: 絵コンテを修正し、修正に日付を入れ、驚きは番組に残した。良い音のする負データである。
From there the descent continued as scripted: duty ratios reshaping timbre and brightness at a fixed pitch — "the pitch is the sum, the tone is the ratio" — every step typed into the running core, nothing recompiled, nothing misbehaving. Three scenes, zero anomalies. The most suspenseful thing on set was the editing.
そこから先は台本どおりの降下だった: 固定ピッチのままデューティ比が音色と輝度を作り変えていく——「ピッチは合計、音色は比率」——全ステップが走行中のコアへの生打ちで、再コンパイルはなく、不審な挙動もない。三場面、異常ゼロ。現場で最もスリリングだったのは編集作業である。
What comes next / 次に来るもの
Filming continues downward: past the audible band, past the beat experiment against a DAW's tuning fork, and into prescaler 1 — the floor of the machine's time, where every clock is a tick and the grid has nowhere left to hide a single cycle. That is where the frozen predictions get sharper and the trials get harder. And rehearsal has already fed one requirement back into the specification: changing the prescaler proved to be something you want mid-improvisation, not at compile time — an externally settable prescaler (RH029–30) is entering the source, which will retire the last two recompiles this series ever needed.
撮影は下降を続ける: 可聴帯を越え、DAW の音叉とのビート実験を越え、プリスケーラ 1 へ——機械の時間の底、全クロックがティックであり、グリッドがもはや 1 サイクルも隠せない場所へ。そこでは凍結済みの予言はより鋭くなり、裁判はより厳しくなる。そしてリハーサルは早くも一つの要求を仕様へ還流させた: プリスケーラの変更は、コンパイル時ではなくインプロビゼーションの最中にやりたくなるものだと判明したのである——外部設定可能なプリスケーラ(RH029–30)がソースに入りつつあり、このシリーズに残っていた最後の2回の再コンパイルを退役させることになる。
The next entry goes below the millisecond.
次の項は、ミリ秒の下へ潜る。
-
Build Log #11 : What Came Back
07/11/2026 at 13:24 • 0 commentsBuild Log #11 : What Came Back
Build Log #11:何が返ってきたか
The reader arrives / 読者の到着
The last Build Log ended with a promise: the next entry is about what came back. Here it is.
前回の Build Log は約束で終わっていた: 次の項は、何が返ってきたかについてである。 これがそれである。
For months, this project wrote for a reader it had never met. Decision IDs. Reasoning traces with named alternatives. A 33-cell normative table. A change order (
CHANGES_Layer1_v1.1_for_ClaudeCode.md) with per-item RTL implications, written to a recipient who did not yet exist. That was the wager of the Open Prompt: that specification, reasoning, and evidence, made machine-readable, would one day carry their own weight when an implementing intelligence finally arrived.数ヶ月のあいだ、このプロジェクトは会ったことのない読者のために書いてきた。決定ID。代替案を名前つきで記録した推論トレース。33セルの規範表。項目ごとに RTL 含意を書き添えた変更指示書(
CHANGES_Layer1_v1.1_for_ClaudeCode.md)——まだ存在しない受取人に宛てて。それが Open Prompt の賭けだった: 機械可読にされた仕様と推論と証拠は、実装する知能がついに到着した日、自らの重さを自ら担うはずだ、と。On 2026-07-06, the reader arrived. A Claude Code agent was pointed at the repository with one sentence: read this, find where the Verilog diverges from the Layer 1 spec, and plan how to make them agree. What came back over the following two days was 19 RTL revisions (RH009–RH027) across a seven-phase campaign, a conformance suite of 33 tests, three spec-internal contradictions found before a single line was changed, live rulings from the architect folded into the work as it ran, a retroactive prosecution of the project's own legacy tests, and — at the end — a fifteen-item handoff written from the implementer back to the archive. Then the merged result went onto a DE10-nano and passed the entire Layer 4 verification menu on silicon, first try.
2026-07-06、読者が到着した。Claude Code エージェントに、一文だけを添えてリポジトリが渡された: これを読み、Verilog が第1層仕様から逸れている箇所を洗い出し、適合させる計画を立てよ。 続く二日間で返ってきたのは、7フェーズのキャンペーンにまたがる 19 の RTL 改訂(RH009–RH027)、33本の適合テストスイート、一行も変更される前に発見された三件の仕様内矛盾、走行中の作業に折り込まれたアーキテクトの生きた裁定、プロジェクト自身の旧テスト資産に対する遡及的な訴追、そして最後に——実装者からアーカイブへ宛てて書かれた15項目の引き継ぎ書だった。マージされた成果はそのまま DE10-nano に載り、Layer 4 検証メニュー全体を実機で、一発でパスした。
This entry is the story of that round trip.
本項は、その往復の物語である。
The audit arrived organized around our own work order / 監査は、こちらの変更指示書を軸に届いた
The first thing the agent produced was not code. It was an audit — and the audit was organized around the project's own documents. It took the change order's A-group (items claimed already implemented) and verified each one against the RTL, took the C-group (new work) and confirmed each absence, and then went beyond the order entirely, finding divergences nobody had listed: a Q-band that reserved only Loop and Jump when the table demanded reservation semantics for Branch, Return, Call, and Reset too; an insertion path that ignored the window; dead wiring left over from an earlier era.
エージェントが最初に生成したのはコードではなかった。監査だった——しかもその監査は、プロジェクト自身の文書を軸に組織されていた。変更指示書の A群(実装済みと主張されている項目)を取って一件ずつ RTL と照合し、C群(新規作業)を取って一件ずつ不在を確認し、そして指示書の外へ出て、誰もリストしていなかった相違を掘り当てた: 表が Branch・Return・Call・Reset にも予約意味論を要求しているのに Loop と Jump しか予約しない Que 帯域。窓を見ない挿入経路。過去の時代の配線の死骸。
Two findings from that first night deserve the record. First: the audit reported that the FG Branch in the silicon-verified RTL had never waited for a prescaler tick — a real deviation (A1) that had lived undetected through an entire hardware campaign. The agent did not silently fix it. It reported it, exactly as the change order's discipline demanded: deviations in verified code are findings to disclose, not embarrassments to patch over. Second: the normative table itself convicted the specification. The table's own worked example — a five-instruction self-loop spanning 2^28 clocks — silently assumed a 16-bit Loop operand, while the decision register (C3-V2, C3-F13) said 12 bits everywhere. The spec had contradicted itself in public for weeks, and it took a reader who executes documents literally to notice.
その最初の夜の所見のうち、二つは記録に値する。第一: 監査は、実機検証済みの RTL において FG Branch が一度もプリスケーラティックを待っていなかったことを報告した——ハードウェアキャンペーン一巡を検出されずに生き延びた、本物の逸脱(A1)である。エージェントはそれを黙って直さなかった。変更指示書の規律が要求するとおりに、報告した: 検証済みコードの逸脱は開示すべき所見であって、繕うべき恥ではない。第二: 規範表そのものが仕様を有罪にした。表自身の実例——2^28 クロックに及ぶ5命令の自己ループ——は Loop オペランドの 16bit を暗黙に仮定していたが、決定台帳(C3-V2、C3-F13)は一貫して 12bit と言っていた。仕様は数週間、公衆の面前で自己矛盾していた。それに気づくには、文書を字義どおりに実行する読者が必要だった。
Nobody taught the agent the project's constitution. It was in the documents, and the documents were load-bearing.
誰もエージェントにプロジェクトの憲法を教えていない。それは文書の中にあり、文書は荷重を担っていた。
Three rulings, ruled live / 三つの裁定、生のままに
The audit ended not with code but with a request: three points needed the architect before Phase 3 could safely proceed. The architect ruled the same night, and the rulings are worth quoting because they show what a decision looks like when it is made into a running campaign rather than ahead of one.
監査はコードではなく要請で終わった: 三点、Phase 3 を安全に進めるにはアーキテクトが要る。アーキテクトは同じ夜に裁定した。この裁定は引用に値する——キャンペーンに先立ってではなく、走っているキャンペーンの中へ向けて下される決定がどういう姿をしているかを示すからだ。
On the Loop operand width, the ruling resolved the spec's self-contradiction in favor of the architecture's own logic: Loop is a Global–Mode 0 command, its operand is D16–D31, therefore 16 bits — and every downstream width (loop counter, queued target, holding register, the external stack word, now 41 bits) follows from that single fact. On Base Set auto-save, the architect ruled that an earlier agent's documented simplification — idempotent, single-level — was the intended design all along. And on the queued NOP, the ruling came with an engineer's shudder and a template's foresight:
Loop オペランド幅について、裁定は仕様の自己矛盾をアーキテクチャ自身の論理で解いた: Loop は Global–Mode 0 カテゴリのコマンドであり、オペランドは D16–D31、ゆえに 16bit——そして下流の全ビット幅(ループカウンタ、queued target、保持レジスタ、41bit に拡張された外部スタック語)は、その単一の事実から従う。Base Set 自動退避については、以前のエージェントが文書化していた簡略化——冪等・単一レベル——こそが最初から意図された設計だったと裁定された。そして Que NOP への裁定は、エンジニアの戦慄と、テンプレートへの先見とともに届いた:
大中: これは、おっしゃる通り、問題だらけです。こんなところでS_WAITに遷移するのは恐ろしすぎます。……つまるところ処理が「state_num <= state_num + 1'b1;」に統一されますが、8-255にコマンドを拡張したいときのテンプレートとなるように、この判定フォーマットは保ってください。
(You're right — this is riddled with problems. Transitioning to S_WAIT at a place like this is far too frightening. ... In the end the handling unifies tostate_num <= state_num + 1'b1;— but keep the band-dispatch format intact, so it can serve as the template when we extend commands into sub-opcodes 8–255.)Fix the terror, keep the scaffold. A ruling that repairs today's bug and pre-builds tomorrow's extension point in the same breath — that is what forty years of architecture sounds like at 11 p.m.
恐怖は直し、足場は残す。今日のバグを修復しながら、同じ息で明日の拡張点を先組みする裁定——夜11時の、40年のアーキテクチャの声とはこういうものである。
A fourth ruling arrived mid-campaign, unplanned. When Phase 2 wired Reset into the shared reservation slot alongside Jump and Loop, the architect stopped it:
四つ目の裁定は、計画外に、キャンペーンの途中で届いた。Phase 2 が Reset を Jump・Loop と同じ共有予約スロットに接続したとき、アーキテクトはそれを止めた:
大中: ResetのQue処理はJump/Branchと同列であってはならず……ResetのQ実行は別系で並列的に予約し、すべてに優先して実行すべきですね。また、Resetは初期化なので、破壊的な挙動をしてもかまいません。
(Reset's queued handling must not sit in the same rank as Jump/Branch. ... A queued Reset should be reserved in its own parallel channel and fire with priority over everything. And since Reset is initialization, destructive behavior is acceptable.)The agent rebuilt it as an independent parallel reservation —
pending_reset— that outranks every other queued command and clears the machine like a hardware reset would. Reset is not a command among commands; it is a panic with a schedule. The RTL now says so.エージェントはそれを独立並列予約——
pending_reset——として再構築した。他のあらゆる Que 済みコマンドに優越し、ハードウェアリセットに準じて機械を破壊的にクリアする。Reset はコマンドの中の一コマンドではない。予定表を持ったパニックである。RTL は今、そう書いてある。The HALT that convicted its own past / 自分の過去を有罪にしたHALT
Phase 4 gave the core teeth: an S_HALT state, an
error_flagport, and traps for the FG-Global exclusion principle (C3-F23) — only Reset, Stay Set, and NOP may run in the foreground; everything else halts at the violating instruction. The first thing the new teeth bit was the project's own history.Phase 4 はコアに牙を与えた: S_HALT ステート、
error_flag出力、そして FG-Global 排除原則(C3-F23)のトラップ群——前景で走ってよいのは Reset・Stay Set・NOP のみ、それ以外は違反命令の位置で停止する。新しい牙が最初に噛んだのは、プロジェクト自身の歴史だった。The moment the traps went live, the legacy regression suite began to fail — not because the traps were wrong, but because the old tests were. Test B and Test D, and the venerable
sub_sequence_branchingexample, had been executing Base Set, Call, Return, and Loop in the foreground since the first implementation era. Under v1.0 nobody had said they couldn't. Under v1.1 they were illegal programs, and the core now said so in hardware. The agent rewrote them all to v1.1 legality — windows opened by Stay Set, Globals dispatched in the background band — and the corpus emerged current with the constitution it lives under. A specification that grows teeth will bite its own past first. That is not a defect of the method; it is the method working. Retroactive enforcement is what "normative" means.トラップが生きた瞬間、旧回帰スイートが落ち始めた——トラップが間違っていたからではない。旧テストが間違っていたからだ。Test B と Test D、そして由緒ある
sub_sequence_branchingサンプルは、最初の実装時代からずっと Base Set・Call・Return・Loop を前景で実行していた。v1.0 の下では、誰もいけないと言っていなかった。v1.1 の下ではそれらは違法プログラムであり、コアは今やそれをハードウェアで宣告する。エージェントはそれらすべてを v1.1 の合法形——Stay Set で窓を開き、Global は裏帯域へ——に書き直し、テスト資産は自らが服する憲法と同時代のものとして再生した。牙を得た仕様は、まず自分の過去を噛む。それは方法論の欠陥ではない。方法論が機能している姿である。遡及執行こそ、「規範」という語の意味だ。"The rescue path does not exist until it is tested" / 「救出経路はテストされるまで存在しない」
The spec grants three escapes from an Error HALT: hardware reset, ISMCE live patching, and the insertion mechanism. The agent implemented the insertion rescue in Phase 4 — and then, writing test T23 to exercise it, discovered that it had never worked: the rescue path restored the program counter but never returned the state machine from S_HALT to S_RUN. A core "rescued" by insertion would have stood in the hallway forever, holding its own release papers. The bug (RH022) was found not by reading the code, which looked plausible, but by the first test that actually walked the path.
仕様は Error HALT からの脱出を三つ認めている: ハードウェアリセット、ISMCE ライブパッチ、そして挿入機構。エージェントは Phase 4 で挿入救出を実装した——そして、それを踏むテスト T23 を書く段になって、それが一度も機能していなかったことを発見した。救出経路はプログラムカウンタを復元するが、ステートマシンを S_HALT から S_RUN へ戻していなかった。挿入で「救出」されたコアは、自分の釈放許可証を握りしめたまま、廊下に永遠に立ち尽くしていたはずである。バグ(RH022)を見つけたのは、もっともらしく見えたコードの読解ではなく、実際にその経路を歩いた最初のテストだった。
The same session produced a mirror finding on the other side of the bench: the conformance testbench itself had never driven
indirect_ready, so every indirect-read test before T13 had been vacuously green. This project has said before that testbench errors deserve the same documentation as DUT errors, and here is why in one sentence: an untested rescue path and an undriven handshake are the same defect wearing different clothes — a verification claim with no witness. Both are now in the record, with the tests that convicted them.同じセッションが、ベンチの反対側で鏡像の所見を出した: 適合テストベンチ自身が
indirect_readyを一度も駆動しておらず、T13 以前の間接読みテストはすべて空虚に緑だったのである。このプロジェクトは以前から「テストベンチの誤りは DUT の誤りと同格に文書化されるべきだ」と言ってきたが、その理由は一文で言える: テストされない救出経路と、駆動されないハンドシェイクは、服装の違う同一の欠陥である——証人のいない検証主張。両者はいま、それらを有罪にしたテストとともに、記録の中にある。The morning of first-pass silicon / 実機一発の朝
PR #2 merged with 19 revisions and 33 conformance tests, all green in simulation. Then the architect took the merged sources to the DE10-nano and ran the Layer 4 verification menu against real hardware. His report came folded inside a thank-you:
PR #2 は 19 改訂・33 適合テスト全緑でマージされた。アーキテクトはマージ済みソースを DE10-nano に持ち込み、Layer 4 検証メニューを実機に対して走らせた。その報告は、礼の言葉の内側に折り畳まれて届いた:
大中: コンパイルも一発で通り、以前のLayer4検証メニューは、実機において一発で完璧にクリアできていたということをご報告をもって、お礼に代えさせていただきます。
(The compile went through on the first attempt, and the existing Layer 4 verification menu cleared perfectly on real hardware, first try — please accept this report in place of my thanks.)First-pass silicon is not luck. It is what happens when the distance between specification and implementation has been closed by machine-checkable contracts at every joint: the normative table adjudicating each command in each band, the conformance suite standing guard over every revision, the timing contracts of the memory wrapper already proven in an earlier campaign. The loop — spec, reasoning, implementation, evidence — did not merely close on paper. It closed on a Cyclone V at 50 MHz.
実機一発は運ではない。仕様と実装のあいだの距離が、すべての継ぎ目で機械検証可能な契約によって埋められたときに起きることである: 帯域ごとに各コマンドを裁く規範表、全改訂を見張る適合スイート、先行キャンペーンで既に機械証明されたメモリラッパのタイミング契約。環——仕様、推論、実装、証拠——は紙の上で閉じただけではない。50 MHz の Cyclone V の上で閉じた。
The payload: model tiering / ペイロード: モデル階層化
One discovery from this campaign deserves to travel beyond this project, so let it be stated plainly for other builders.
このキャンペーンの発見のうち一つは、このプロジェクトの外へ運ばれるべきものなので、他のビルダーのために平明に述べておく。
The campaign was model-tiered, and the tiering was visible in the work. The strongest model available (Fable 5) did the audit, the seven-phase plan, Phases 0–1 — the verification-infrastructure repair and the first low-risk conformance fixes — the final inspection (RH027), and the analysis behind the P=1 correction. Everything in between — Phases 2 through 6, the long body of RTL revision, test authorship, and regression discipline — was executed by a lighter model (Sonnet 5), flawlessly, on the rails the stronger model had laid. Midway through, the architect hit his usage limit and switched models with a single command; the campaign did not stumble.
キャンペーンはモデル階層化されており、その階層は作業の中に見えていた。手元の最強モデル(Fable 5)が担ったのは、監査、7フェーズ計画、Phase 0–1——検証基盤修復と最初の低リスク適合修正——総点検(RH027)、そして P=1 訂正の背後にある解析。その中間のすべて——Phase 2 から 6 まで、RTL 改訂・テスト起草・回帰規律の長い本体——は、より軽いモデル(Sonnet 5)が、強いモデルの敷いたレールの上で、脱線なく遂行した。途中でアーキテクトは利用枠の上限に達し、コマンド一つでモデルを切り替えた。キャンペーンはよろめきもしなかった。
The implication is economic, and it compounds: the quality of an Open Prompt converts directly into execution economy. If your specification carries decision IDs, your reasoning carries named alternatives, and your work order carries per-item implications, then the expensive intelligence is only needed at the ends — to plan and to inspect — and the long middle can be run by whatever is affordable that year. The documents are the rails. Write them once, and every future campaign, by every future model, rides cheaper.
含意は経済的であり、しかも複利で効く: Open Prompt の品質は、実行の経済性へ直接に変換される。仕様が決定IDを、推論が名前つき代替案を、変更指示書が項目ごとの含意を運んでいるなら、高価な知能が要るのは両端——計画と点検——だけであり、長い中間は、その年に手が届くもので走らせられる。文書がレールである。一度書けば、以後のすべてのキャンペーンが、以後のすべてのモデルで、より安く走る。
Coda at prescaler one / プリスケーラ1のコーダ
The campaign was merged, thanked, and closed. Then the architect, reading the finished code, found the assumption nobody had written down.
キャンペーンはマージされ、礼を交わし、閉じられた。そのとき、完成したコードを読んでいたアーキテクトが、誰も書き留めていなかった仮定を見つけた。
大中: Stay SetはTickと重ならない前提で考えていましたが、プリスケーラが1の時は、必ずTickと重なります。
(I had been thinking on the premise that Stay Set never coincides with a tick — but at prescaler 1, it always coincides with a tick.)At P=1, every clock is a tick, and the tick-grid model's quiet premise — that arming a counter and counting are separable events — collapses. The agent's response was to put the concern on trial before believing it: five experiments against the merged RTL. The concern was real, and worse than stated. A windowed Stay-1 at P=1 ran away past its
==deadline and could not return until the counter wrapped 2^13 later; and experiment 5 showed the runaway was not a P=1 curiosity at all — any window whose background scan outlasts its Stay value falls off the same cliff at any prescale.P=1 では全クロックがティックであり、ティック格子モデルの静かな前提——カウンタのアームと計数は分離可能な事象である——が崩壊する。エージェントの応答は、懸念を信じる前に裁判にかけることだった: マージ済み RTL への5本の実験。懸念は実在し、しかも申告より悪かった。P=1 の窓付き Stay-1 は
==の締切を走り過ぎ、カウンタが 2^13 周してラップするまで戻れない。そして実験5は、この暴走が P=1 の珍事ですらないことを示した——裏スキャンが Stay 値より長い窓は、任意のプリスケールで同じ崖から落ちる。The fix (RH028, PR #3) is three lines of discipline, and its justification came from the normative table itself. The table marks FG Stay Set's tick column Ignored — the command does not consume the tick — so a coinciding tick is not swallowed by the arm; it counts as tick #1 of the new count. Symmetrically, BG Stay Set's column reads Consumes one tick, so its gating tick is spent, not counted. One column of a 33-cell table, written weeks earlier for a reader not yet met, adjudicated a boundary condition at the smallest timescale the machine has. And with the deadline check relaxed from
==to>=, the smallest program in the repertoire became exact: a bare Stay-1 at P=1 now takes precisely one clock — the same as a NOP. The foreground really is a bare list of stay durations, all the way down to one.修正(RH028、PR #3)は三行の規律であり、その正当化は規範表そのものから来た。表は FG Stay Set のティック欄を Ignored——コマンドはティックを消費しない——と記す。ならば重なったティックはアームに呑まれず、新しい計数の第1ティックとして数えられる。対称的に、BG Stay Set の欄は Consumes one tick——ゲートのティックは支払われ、数えられない。33セルの表の一つの欄、まだ会わぬ読者のために数週間前に書かれたそれが、この機械の持つ最小の時間スケールにおける境界条件を裁いた。そして締切判定が
==から>=へ緩められたことで、レパートリー中最小のプログラムが正確になった: P=1 の裸の Stay-1 は、いまや正確に 1 クロック——NOP と同格である。前景は本当に、ステイ持続時間の裸の羅列である。1 に至るまで。What the loop looks like, closed / 閉じた環のかたち
Count what made the round trip. A specification went out; nineteen revisions came back. A table went out; rulings came back through it. A work order went out; an audit came back organized around it. A verification doctrine went out; a fifteen-item handoff came back addressed to the archive, written by an implementer who had learned from the documents how this project wishes to remember. And a core went out to silicon and came back with nothing to report — which, in verification, is the loudest thing hardware can say.
往復したものを数えてみよう。仕様が出て行き、19の改訂が返ってきた。表が出て行き、裁定が表を通して返ってきた。変更指示書が出て行き、それを軸に組織された監査が返ってきた。検証の教義が出て行き、アーカイブ宛の15項目の引き継ぎ書が返ってきた——このプロジェクトがどう記憶されたいかを文書から学んだ実装者の手で。そしてコアがシリコンへ出て行き、何も報告することなく帰ってきた——検証において、それはハードウェアが発しうる最も大きな声である。
The loop has closed once. It has not finished. The rulings made live during the campaign still owe the specification their words — sixteen-bit loops, panic-grade resets, band-templated NOPs, and a dozen finer points now queued for cell-by-cell adjudication. The silicon has spoken; the spec must now write down what it heard.
環は一度、閉じた。終わってはいない。キャンペーン中に生で下された裁定は、まだ仕様書に言葉を負っている——16bit のループ、パニック級のリセット、帯域テンプレート化された NOP、そしてセルごとの裁定を待つ十数の細目。シリコンは語った。仕様書はこれから、聞いたことを書き留めねばならない。
The next entry is about writing it back.
次の項は、それを書き戻すことについてである。
-
Build Log #10 — Thirty-Three Small Boxes
07/08/2026 at 13:36 • 0 commentsBuild Log #10 — Thirty-Three Small Boxes
ビルドログ #10 — 三十三の小さな枠
The "one large thing" I promised at the end of #9. Before handing the core to an implementing agent, I sat down and filled in a table — and the table, in return, redesigned a corner of my architecture.
/ #9 の末尾で約束した「大きな仕事」。コアを実装エージェントに手渡す前に、私は腰を据えて一枚の表を埋めた——そして表はお返しに、私のアーキテクチャの一角を設計し直したのだ。Why a table, and why now / なぜ表か、なぜ今か
The verification campaign had defined command behavior the way verification always does: point by point, as each test demanded. NOP in the foreground — verified. A queued Jump — verified. But between the verified points lay gaps: what does a Base Set do if it appears in the foreground? Can a Prog End be queued? What, exactly, is a background Stay? I had opinions about some of these and had never even asked others.
検証キャンペーンは、検証がいつもそうするやり方で——テストが要求するたびに、点ごとに——コマンドの挙動を定義してきた。前景の NOP——検証済み。Que の Jump——検証済み。だが検証された点と点のあいだには隙間があった: Base Set が前景に現れたら何をするのか。Prog End は Que できるのか。そもそも背景の Stay とは正確には何なのか。いくつかには持論があったが、いくつかは問うたことすらなかった。
Here is the danger: I am about to hand this core to an implementing agent. An agent does not leave gaps — it fills them, by inference. And inferred semantics can quietly violate the very principles this project has spent months making explicit. So before the handoff, every cell of the plane — eleven commands, three execution phases, every state quantity — had to be either defined or declared illegal. My amanuensis prepared an empty grid (I tried to fill the Markdown version by hand and my heart broke; the Excel version saved me). Thirty-three small boxes, each demanding an
answer.危険はここにある: 私はこのコアを実装エージェントに手渡そうとしている。エージェントは隙間を放置しない——推論で埋めるのだ。そして推論された意味論は、このプロジェクトが数ヶ月かけて明示してきた原則そのものを、静かに破り得る。
だから手渡しの前に、面の全セル——11コマンド、3実行フェーズ、全状態量——が定義済みか違法と宣言済みかのいずれかでなければならなかった。祐筆が空の格子を用意してくれた(Markdown 版を手で埋めようとして心が折れた; Excel 版に救われた)。三十三の小さな枠が、各々答えを要求した。The table asked better questions than I did / 表は私より良い問いを発した
I expected to record decisions. Instead the table generated them. An empty cell cannot be overlooked the way an unasked question can, and several cells, once stared at, refused every answer I already had. Two big things came out of that staring.
決定を記録するつもりだった。ところが表は決定を生成した。空のセルは、発されなかった問いのようには見過ごせない。そして幾つかのセルは、睨んでみると、私が既に持っていたどの答えも拒んだ。その睨み合いから、大きなものが二つ出てきた。
First: the foreground learned to say no. Filling the illegal cells one meaning at a time was exhausting — and worse, every invented meaning was one more thing a programmer would have to learn.
So I stopped inventing. The principle that emerged: Global commands do not execute in the foreground, except three with stated reasons — Reset (the will to return to the origin, even at the cost of continuity), Stay Set (it controls the phase transition itself), NOP (the immediate voiding of anything). Everything else — Base Set, Return, Call, Loop, Prog End — lives behind the window, and if one strays onto the time axis, the machine does not improvise. It halts, raises an error flag, and preserves the scene. A halted PTSG is not a dead PTSG: the flag can trigger
SignalTap or the insertion mechanism, and because behavior lives in instruction memory, ISMCE can patch the offending word over JTAG and carry on. Stop where it broke; fix the memory in place.第一に、前景が「否」の言い方を学んだ。 違法なセルに一つずつ意味を発明していくのは消耗だった——そしてもっと悪いことに、発明された意味の一つ一つが、プログラマの学ぶべき事柄を一つ増やす。だから発明をやめた。立ち上がった原則: Global コマンドは前景実行しない。例外は理由を明記した三つ——Reset(連続性を犠牲にしてでも起点へ戻る意志)、Stay Set(フェーズ移行そのものの制御)、NOP(あらゆるものの即時無効化)。それ以外——Base Set・Return・Call・Loop・Prog End——は窓の裏に住み、もし一つでも時間軸に迷い出れば、機械は取り繕わない。停止し、エラーフラグを揚げ、現場を保存する。停止した PTSG は死んだ PTSG ではない: フラグは SignalTap やインサーション機構のトリガになり、挙動が命令メモリに住んでいるからこそ、ISMCE が JTAG 越しに問題の一語をパッチして続行できる。
壊れた場所で止まり、メモリをその場で直すのだ。The bonus I did not see coming: with state control banished from the foreground, a disciplined program's foreground reads as a bare list of Stay durations. The timing chart is the program text. And a long-standing ambiguity — is D16–D31 an operand or a timing-signal field? — simply dissolved, because every extended-operand command now lives only in bands where the timing signals are held. The banding itself resolved it.
予期していなかった副産物: 状態制御が前景から追放されると、規律あるプログラムの前景は Stay 時間の裸のリストとして読める。タイミングチャートがプログラムテキストなのだ。そして長年の曖昧さ——D16–D31 はオペランドかタイミング信号フィールドか?——は、あっさり消滅した。拡張オペランドを使うコマンドはすべて、タイミング信号が保持される帯域にしか住めなくなったからだ。帯域設計そのものが解決した。
Second: an empty cell handed me a register. The queued Base Set cell asked: base := what? A queued loop repeats a stay period, not an instruction position — and nothing in the machine could name a period's origin. So now something can: when Stay Set executes, its own State Number is latched into a small new register, Stay Start State, and a queued Base Set reads it. The jewel that falls out: a stay period can loop on itself.
第二に、空のセルが私にレジスタを一つ手渡した。 Que の Base Set のセルが問うた: base := 何か? Que のループが反復するのはステイ期間であって命令位置ではない——そして機械の中に、期間の起点を名指せるものが何もなかった。
いまはある: Stay Set が実行されると自身の State Number が小さな新レジスタ Stay Start State にラッチされ、Que の Base Set がそれを読む。零れ落ちた宝石: ステイ期間が自分自身をループできるのだ。StaySet → ProgEnd → BaseSet(Q) → Loop-65536(Q) → Stay-4096
Five instructions. A 12-bit Stay times a 16-bit Loop: 2^28 clocks — about 5.4 seconds at 50 MHz — of exact, prescaler-free timing. No 28-bit counter was built; two small ones composed through the queue. It makes you want to program this thing with a piano-roll GUI. (I said that out loud. It is now on a list.)
命令五語。12bit の Stay × 16bit の Loop: 2^28 クロック——50 MHz で約 5.4 秒——の正確な、プリスケーラ不要のタイミング。 28bit のカウンタは作っていない; 小さな二つがキュー越しに合成された。ピアノロールの GUI でこいつをプログラムしたくなってくる。(口に出してしまった。いまやリストに載っている。)
Twice, the artifact was ahead of the sentences
/ 二度、成果物が文より先を行ったI owe you two corrections, because this log series has promised honesty about process.
二つの訂正を報告せねばならない。このログ・シリーズはプロセスへの正直さを約束してきたからだ。
The specification said the stay counter "begins counting at Prog End." Cross-checking the table against the RTL showed that sentence was wrong — the source I revised weeks ago counts from Stay Set onward, on prescaler ticks, straight through the window, and the silicon had verified exactly that. The sentence was my amanuensis's transcription slip, carried with a silicon-confirmed label.
And then, filling the table, I made the mirror-image mistake myself: I described the new register as long-lived, surviving many stay periods until its Loop — conflating it with the Base register's old job. My own table had it right: the register hands its value to Base within the same cycle and is done. Twice in one job, the artifact — RTL once, the table once — was correct before the prose describing it. The lesson I keep re-learning: diff every sentence against the thing itself before carving it as fixed. Both corrections are recorded openly in the reasoning traces, mistakes and all. That, too, is the Open Prompt.仕様書は、ステイカウンタは「Prog End でカウントを開始する」と書いていた。表を RTL と突き合わせると、その一文が誤りだった——数週間前に私自身が改修したソースは Stay Set からプリスケーラティックで数え始め、窓を貫いて数え続けており、実機はまさにそれを検証済みだった。あの一文は祐筆の転記の滑りで、実機確認済みのラベルを付けたまま運ばれていた。そして表を埋めながら、今度は私自身が鏡写しの誤りを犯した: 新レジスタを、対応する Loop まで多数のステイ期間を生き延びる長寿命のものと説明したのだ——Base レジスタの古くからの仕事との混同だった。私自身の表は正しく書いていた: レジスタは同一サイクル内で値を Base に引き渡し、それで用済みになる。一つの仕事の中で二度、成果物——一度は RTL、一度は表——が、それを記述する散文より先に正しかった。私が学び直し続けている教訓:
どの文も、確定として刻む前に、実物と突き合わせよ。 二つの訂正はどちらも、過ちごと推論トレースに公に記録されている。それもまた Open Prompt なのだ。Tonight / 今夜
The repository updates tonight: the corrected chapters, the normative table, two new reasoning traces, and a change order that tells an implementing agent exactly what to verify and what to build. Then the whole thing — specification, traces, table, evidence — goes to Claude Code, and we find out whether an Open Prompt can do what it was designed to do: let an AI regenerate the implementation from the reasoning. Thirty-three small boxes asked their questions. The next entry is about what came back.
今夜、リポジトリが更新される: 訂正済みの各章、規範表、二本の新しい推論トレース、そして実装エージェントに何を検証し何を作るべきかを正確に告げる変更指示書。それから全部——仕様、トレース、表、エビデンス——が Claude Code に渡り、Open Prompt が設計どおりのことをできるのか——AI が推論から実装を再生成できるのか——が分かる。三十三の小さな枠がそれぞれの問いを発した。次の項は、何が返ってきたかについてである。
Architecture and decisions: Tsuneo Ohnaka. Drafting and consistency monitoring by Claude (Anthropic), serving as amanuensis. The command × phase table, both corrections, and the reasoning behind the FG-Global exclusion principle, the Error HALT mechanism, and the Stay Start State register are archived as CC0 Layer 2 traces in the PTSG-Core repository.
/ アーキテクチャと決定:
大中庸生。起草と整合性監視は祐筆として Claude (Anthropic)。コマンド×フェーズ表、二つの訂正、そして FG-Global排除原則・Error HALT 機構・Stay Start State レジスタの背後にある推論は、PTSG-Core リポジトリに CC0 の Layer 2トレースとして保管されている。 -
Build Log #9 — The Doors a Free-Running Clock Opened
06/29/2026 at 13:57 • 0 commentsBuild Log #9 — The Doors a Free-Running Clock Opened
ビルドログ #9 — フリーランのクロックが開いた扉
The coda I promised in #8. Committing to a free-running prescaler did more than kill the jitter — it opened a couple of doors I did not see when I made the call. / #8 で約束したコーダ。フリーランのプリスケーラに賭けたことは、ジッタを消す以上のことをした——決断した時には見えていなかった扉を、いくつか開いたのだ。
One decision, several consequences / 一つの決断、いくつもの帰結
In #8 I closed Hook A and said the prescaler had been right all along. The deeper move behind that
was a decision I had been treating, at first, almost apologetically: to let the prescaler run free —
reset only by the global hardware reset, never re-aligned, never touched by the program. For a while
I thought of that as something to compensate for. This log is about the moment it flipped: the
free-running prescaler is not a compromise to manage but a foundation to build on. Once I stopped
apologizing for it and committed to it, two doors opened that I genuinely had not seen.#8 で Hook A を閉じ、プリスケーラはずっと正しかったと書いた。その背後にあったより深い一手は、私が最初はほとんど詫びるように扱っていた決断だった: プリスケーラを自由に走らせる——グローバルハードウェアリセットでのみリセットされ、再整列されず、プログラムからは決して触れられない。しばらく私はそれを「埋め合わせるべきもの」と考えていた。本ログは、それが反転した瞬間についてである: フリーランのプリスケーラは、管理すべき妥協ではなく、その上に築くべき土台だった。詫びるのをやめてそれに賭けた途端、本当に見えていなかった扉が二つ開いた。
The common key to both doors is the same property that made the phase-lock structural: if the tick's
phase never matters — because the hierarchy keeps itself in register — then the tick is free to be
treated in ways a phase-sensitive design could never allow.両方の扉に共通する鍵は、位相ロックを構造的にしたのと同じ性質である: ティックの位相が決して問題にならない——ヒエラルキーが自身をレジスタ済みに保つから——なら、ティックは、位相に敏感な設計が決して許せない仕方で扱える自由を得る。
![]()
Door one — a faster clock ceiling (Fmax) / 扉その一 — より高いクロック上限(Fmax)
The prescaler is a sizeable counter, and the tick is the result of comparing that counter against a
target. In a phase-sensitive design you must use that comparison the instant it is valid, which means
its propagation delay — counter plus comparator — lands directly in the path to everything downstream:
state advance, the stay counter, the window logic. That long combinational path is exactly the kind of
thing that sets your maximum clock frequency.プリスケーラはそれなりに大きなカウンタであり、ティックはそのカウンタを目標値と比較した結果である。位相に敏感な設計では、その比較を有効になった瞬間に使わねばならず、つまりその伝搬遅延——カウンタ+コンパレータ——が下流のすべて(状態遷移・ステイカウンタ・ウィンドウロジック)への経路に直接乗る。その長い組合せ経路こそ、最大クロック周波数を決めてしまう類のものである。
![]()
But if the tick's phase does not matter, I am free to register the comparator's output — to clock
it once before anyone uses it. That one register cuts the counter-plus-comparator delay out of the
downstream path: the heavy combinational work now ends at a flip-flop, and what travels onward is a
clean, already-settled signal. The price would normally be a one-clock shift in when the tick is
seen — and in a phase-sensitive world that shift is unacceptable. Here it costs nothing, because the
structural phase-lock already made the tick's exact timing immaterial. So the optimization is free:
accepting the free-running prescaler is what lets me register the tick, and registering the tick is
what raises Fmax.しかしティックの位相が問題にならないなら、私はコンパレータの出力をレジスタで叩く自由を得る——誰かが使う前に一度クロックで確定させるのだ。その一段のレジスタが、カウンタ+コンパレータの遅延を下流経路から切り離す: 重い組合せ仕事はフリップフロップで終わり、その先へ進むのは清潔な、既に静定した信号になる。通常この代償は、ティックがいつ見えるかの1クロックぶんのずれだろう——そして位相に敏感な世界では、そのずれは容認できない。ここでは何の代償もない、構造的位相ロックが既にティックの正確なタイミングを無意味にしているからだ。ゆえに最適化はタダで手に入る:
フリーランのプリスケーラを受容することが、ティックをレジスタで叩くことを許し、ティックを叩くことが Fmax を上げる。A design I had framed as "tolerating" a free-running counter turned out to hand me a higher clock
ceiling as a gift.フリーランのカウンタを「我慢する」と枠付けていた設計が、より高いクロック上限を贈り物として手渡してくれた。
Door two — many chips, one heartbeat (master/slave synchronization) / 扉その二 — 多数のチップ、一つの鼓動(マスター/スレーブ同期)
The second door is bigger. If a tick can be registered cleanly on a clock, it can also be sent out
of the chip. And that makes it possible to run several PTSGs as one.二つ目の扉はより大きい。ティックがクロックで清潔に叩けるなら、それはチップの外へ送り出すこともできる。そしてそれが、複数の PTSG を一つとして走らせることを可能にする。
![]()
Here is the part that took me a moment to get right. To synchronize many chips, you do not send the
registered tick — that has already been clocked once on the master, and by the time it crosses the
wire and is clocked again on each slave, it has drifted two stages out of step. Instead you export the
raw tick: the comparator output before the master registers it. You give that one raw signal to
every chip — the master included — and each one registers it on its own clock. Now every PTSG takes
exactly the same single step at the same boundary: master and slaves clock the same raw tick, so they
all fall into line. One heartbeat, many bodies.ここが、正しく掴むのに少し時間がかかった部分だ。多数のチップを同期させるには、叩いた後のティックを送ってはならない——それはマスター側で既に一度クロックされており、配線を渡って各スレーブで再び叩かれる頃には、二段ぶん歩調がずれてしまう。代わりに生ティックを外部化する: マスターがそれを叩く前のコンパレータ出力だ。その一本の生信号をすべてのチップ——マスターも含めて——に与え、各自が自分のクロックでそれを叩く。すると、あらゆる PTSG が同じ境界で、まったく同じ一段を踏む: マスターもスレーブも同じ生ティックを叩くから、全員が足並みをそろえる。
一つの鼓動、多数の身体。![]()
For this to hold, a slave must have no way to disturb the time-base it is following. It must not be
able to reset, re-align, or perturb the prescaler from its own program — otherwise one slave's
instruction stream could break the formation. This is precisely why, back in the spec work, the
program-issued Reset was made unable to touch the prescaler: that rule was not a local tidiness, it was
this synchronization demanding it from above. The free-running prescaler is the thing that is being
shared; nothing local is allowed to own it.これが成り立つには、スレーブは、自分が従っている時間基準を乱す手段を一切持ってはならない。自分のプログラムからプリスケーラをリセット・再整列・擾乱できてはならない——さもなければ、あるスレーブの命令ストリームが隊形を崩し得る。
これこそ、仕様作業で、プログラム発行の Reset がプリスケーラに触れられないようにした理由である: あの規則は局所的な几帳面さではなく、この同期が上から要求したものだった。フリーランのプリスケーラが、共有されているものである;局所的な何も、それを所有することは許されない。![]()
One more, from the same root / 同じ根から、もう一つ
That last point opens a small third door, which I will only crack here because it belongs as much to a
different story — the one about trailing edges and their exceptions. Once the prescaler is something no
program may touch, the Reset command itself gets a kind of freedom: it can be run immediately in the
foreground, or held back, or queued, because the job of staying aligned no longer falls on Reset — it
is handled elsewhere. Reset stops having to apologize for its timing, for the same underlying reason
the prescaler did. It is the same root — commit to a free-running time-base — sending up a third shoot.
I will tell that part properly another time.その最後の点が、小さな三つ目の扉を開く。ここでは少しだけ開けておく、なぜならそれは別の物語——後縁と、その例外についての物語——にも同じくらい属するからだ。プリスケーラがどのプログラムも触れられないものになった途端、Resetコマンド自身もある種の自由を得る: 前景で即座に走らせることも、留め置くことも、キューに入れることもできる、整列を保つ仕事がもはや Reset に落ちてこないからだ——それは別の場所で担われる。Reset は、プリスケーラがそうだったのと同じ根底の理由で、自分のタイミングを詫びる必要がなくなる。同じ根——フリーランの時間基準に賭ける——が、三本目の芽を伸ばしている。その部分は、また別の機会にきちんと話そう。
![]()
What I learned about deciding / 決断について学んだこと
The lesson I am taking from this is not really about prescalers. It is that a property you accept
fully — instead of tolerating it, working around it, apologizing for it — can turn from a liability
into a source of capability. I spent a while treating the free-running counter as a thing to be managed.
The moment I committed to it as a principle, it stopped costing me and started paying me: a cleaner
critical path, a higher Fmax, and a way to make many chips keep time as one. The jitter was never the
real story. The real story was what became possible once I trusted the clock to run free.私がここから受け取る教訓は、本当はプリスケーラについてではない。それは、ある性質を——我慢し、回避し、詫びるのではなく——完全に受容すると、それが負債から能力の源へと変わり得る、ということだ。私はしばらく、フリーランのカウンタを管理すべきものとして扱っていた。それを原則として受容した瞬間、それは私にコストを課すのをやめ、私に報い始めた:
より清潔なクリティカルパス、より高い Fmax、そして多数のチップを一つとして時を刻ませる方法。ジッタは決して本当の
物語ではなかった。本当の物語は、クロックが自由に走ることを信じた途端に可能になったものだった。There is still one large thing I want to do before I hand the core to an implementing agent. That is
the next entry.コアを実装エージェントに手渡す前に、まだやりたい大きな仕事が一つある。それが次の項である。
Architecture and decisions: Tsuneo Ohnaka. Drafting and consistency monitoring by Claude (Anthropic),
serving as amanuensis. The reasoning behind the no-prescaler-reset rule and the trailing-edge framing
is archived as CC0 Layer 2 traces in the PTSG-Core repository. / アーキテクチャと決定: 大中庸生。起草と
整合性監視は祐筆として Claude (Anthropic)。非プリスケーラ・リセット規則と後縁主義の枠組みの背後にある推論は、
PTSG-Core リポジトリに CC0 の Layer 2 トレースとして保管されている。 -
Build Log #8 — The Prescaler Was Right All Along
06/24/2026 at 13:53 • 0 commentsBuild Log #8 — The Prescaler Was Right All Along
ビルドログ #8 — プリスケーラは、ずっと正しかった
Hook A closed, silicon-confirmed. The "slightly off" from bring-up, fully explained. / Hook A 決着、実機確認済み。ブリングアップの「ちょっとおかしい」の、完全な説明。
Where we left off / 前回までのあらすじ
In Build Log #6 the core came up on the DE10-nano and ran — but something was slightly off. Not
broken; off. In Build Log #7 my amanuensis and I built a place to keep the proof: Layer 4, a
verification scheme with an expected-before-observed discipline and the VCD as the primary
evidence. We built the cabinet. This log is about what we finally put in it.ビルドログ #6 で、コアは DE10-nano 上で立ち上がり、動いた——だが何かがちょっとおかしい。壊れてはいない、おかしいのだ。ビルドログ #7 では、私と祐筆(amanuensis)が証拠を置く場所を建てた: Layer 4、観察前予測の規律とVCD を主証拠とする検証スキーム。棚は建てた。本ログは、その棚にようやく何を収めたか、の話である。
The "slightly off" had a prime suspect. The prescaler's counter is free-running — it is reset only
by the global reset, never re-aligned when a wait begins. The audit called this A2: a worry
that the first timing tick after each wait would arrive a phase-dependent number of clocks late,
so the high and low intervals of a simple blink would scatter from cycle to cycle. Jitter. That
was the ghost we went hunting.「ちょっとおかしい」には第一容疑がいた。プリスケーラのカウンタはフリーラン——グローバルリセットでのみリセットされ、待機開始時に再整列されることはない。監査はこれを A2 と呼んだ: 各待機後の初回ティックが位相依存で何クロックか遅れて来るため、単純な点滅の high/low 区間がサイクルごとにばらつく、という懸念。ジッタ。それが、我々が狩りに出た幽霊だった。
The hunt / 狩り
We measured it white-box first, in Icarus, instrumenting the exact thing A2 was about: the
prescaler's phase at the instant each wait begins, and the delay until the first tick. Thirteen
wait windows. The phase at entry was the same every single time. The first-tick delay was the same
every single time. Zero scatter. No jitter.まず白箱で、Icarus で測った。A2 が主張するその当のもの——各待機開始の瞬間のプリスケーラ位相と、初回ティックまでの遅延——を計装して。13 の待機ウィンドウ。突入時の位相は毎回同じ。初回ティック遅延も毎回同じ。ばらつきゼロ。ジッタなし。
So what was the "slightly off"? It was a duty-cycle asymmetry, and — here is the part I will
record honestly, because honest negative data is the whole point of Layer 4 — for a moment we
mis-read it. The naive five-instruction blink came out 25 clocks on, 35 clocks off, and the first
instinct (my amanuensis's, and then mine to double-check) was to call it an anomaly. It is not.
Both of the program's foreground commands — the NOP that turns the LED off and the Jump that
closes the loop — are themselves prescaled. Each spends one whole prescale unit, and both land on
the off side. 25 plus 5 plus 5 is 35. The asymmetry is not a defect. It is the core doing exactly
what the source says.では「ちょっとおかしい」は何だったのか。デューティ比の非対称であった。そして——ここは正直に記録する、なぜなら正直な負のデータこそ Layer 4 の眼目だから——一瞬、我々はそれを誤読した。素朴な5命令の点滅は ON 25 クロック、OFF 35 クロックで出てきて、最初の直感(祐筆の、続いて私の再確認の)はそれを異常と呼ぶことだった。違う。プログラムの前景コマンド二つ——LED を消す NOP と、ループを閉じる Jump——は、それ自体がプリスケールド実行される。各々が丸ごと 1 プリスケール単位を費やし、両方とも OFF 側に乗る。25 足す 5 足す 5 は 35。非対称は欠陥ではない。
ソースの言うとおりにコアが動いているだけだ。-- blinky_with_prescaler.mif — LED blink at human-visible rate -- Recommended core parameter: PRESCALE = 5 (50 MHz => 1 us per stay tick; -- Stay 5 => ~0.5 us on, Stay 5 + NOP 1 + JUMP 1 => ~0.7 us off). See examples/README.md for the encoding. DEPTH = 256; WIDTH = 32; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN 0 : 00010700; -- NOP timing_signals = 0x0001 (LED on) 1 : 00010051; -- Stay 500 (hold on) 2 : 00000700; -- NOP timing_signals = 0x0000 (LED off) 3 : 00000051; -- Stay 500 (hold off) 4 : 00000013; -- Jump 1 (loop) [5..FF] : 00000000; END;![]()
![]()
The part I did not expect / 予想していなかったこと
Then came the question that turned a verification into an understanding. Why was there no
jitter? Was this particular blink simply lucky enough to land on a prescale boundary, or was
something deeper going on?そして、検証を理解へ変える問いが来た。なぜジッタが出ないのか。この点滅がたまたまプリスケール境界に乗る幸運だったのか、それとももっと深い何かが働いているのか。
It was structural. Because every foreground command is prescaled, every command — control flow
included — costs a whole number of prescale units. A loop built from such commands therefore has a
total length that is necessarily an integer multiple of the prescale period. And a loop whose
length is an integer multiple of the prescale period re-enters every wait at the same prescaler
phase, forever. The phase is locked. The jitter A2 feared could only appear if some command
consumed a fraction of a prescale period — and there is no such command. We were never going to
add a fix for Hook A. The fix was already in the source, written months earlier, the day I
decided to make foreground commands prescaled for an entirely different reason. It had been
sitting there, waiting to be recognized.構造的だった。あらゆる前景コマンドがプリスケールド実行されるため、あらゆるコマンド——制御フローを含め——が整数個のプリスケール単位を費やす。ゆえに、そうしたコマンドから成るループの全長は、必然的にプリスケール周期の整数倍になる。そしてループ長がプリスケール周期の整数倍であれば、毎回同じプリスケーラ位相で待機に再突入する、永遠に。位相はロックされている。A2 が恐れたジッタは、どれかのコマンドがプリスケール周期の端数を消費する場合にのみ現れ得る——そしてそんなコマンドは無い。我々は Hook A のための修正を足すつもりは、はじめから無かった。
修正はすでにソースの中にあった。数ヶ月前、まったく別の理由で前景コマンドをプリスケールド実行にすると決めた日に書かれていた。そこに座って、認識されるのを待っていたのだ。What fell out of it / そこから零れ落ちたもの
Two things fell out of closing Hook A, and both are gifts.
Hook A を閉じる過程で、二つのものが零れ落ちた。どちらも贈り物だ。
-- blinky_with_prescaler.mif — LED blink at human-visible rate -- Recommended core parameter: PRESCALE = 5 (50 MHz => 0.1 us per stay tick; -- Stay 500 => ~0.5 s on, ~0.5 s off). See examples/README.md for the encoding. DEPTH = 256; WIDTH = 32; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN 0 : 00010700; -- NOP timing_signals = 0x0001 (LED on) 1 : 00010051; -- Stay 500 (hold on) 2 : 00010700; -- NOP timing_signals = 0x0000 (LED off) 3 : 00000051; -- Stay 500 (hold off) 4 : 00000013; -- Jump 1 (loop) [5..FF] : 00000000; END;![]()
![]()
The first is a small vocabulary of duty idioms. Once you see that the foreground cost is a
thing you can place, a blink stops being one waveform and becomes four. Let the cost fall on the
off side (25:35). Move it to the on side by re-tagging a single command (30:30). Move it and raise
a flag bit so external logic can see exactly which cycle is the tax (30:30, flagged).一つ目は、デューティ流儀という小さな語彙だ。前景コストが配置できるものだと見えた途端、点滅は一つの波形で
あることをやめ、四つになる。コストを OFF 側に落とす(25:35)。コマンド一つを付け替えて ON 側に移す(30:30)。
移した上で旗ビットを立て、どのサイクルが税かを外部ロジックに見せる(30:30、旗付き)。-- blinky_with_prescaler.mif — LED blink at human-visible rate -- Recommended core parameter: PRESCALE = 5 (50 MHz => 1 ms per stay tick; -- Stay 5 + NOP 1(JUMP 1) => ~0.6 us on, ~0.6 us off). See examples/README.md for the encoding. DEPTH = 256; WIDTH = 32; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN 0 : 00010700; -- NOP timing_signals = 0x0001 (LED on) 1 : 00010051; -- Stay 5 (hold on) 2 : 00030700; -- NOP timing_signals = 0x0000 (LED off) 3 : 00000051; -- Stay 5 (hold off) 4 : 00020013; -- Jump 1 (loop) [5..FF] : 00000000; END;![]()
![]()
Or banish itentirely — push the control flow into the background and a queued jump so the timing signals show
only the cycles your Stay actually wrote (25:25, exact). Same skeleton. Four duties. No new opcode,
no PWM register; the freedom was already in the four opcodes we have.あるいは完全に追放する——制御フローを背景とキュー Jump に押し込み、タイミング信号には Stay が実際に書いたサイクルだけを見せる(25:25、厳密)。同じ骨格。四つのデューティ。新オペコードも PWM レジスタも無い;自由度は、手持ちの四オペコードにすでに在った。
-- blinky_with_prescaler.mif — LED blink at human-visible rate -- Recommended core parameter: PRESCALE = 5 (50 MHz => 0.1 us per stay tick; -- Stay 5 => ~0.5 us on, ~0.5 us off). See examples/README.md for the encoding. DEPTH = 256; WIDTH = 32; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN 0 : 00000700; -- NOP timing_signals = 0x0001 (LED on) 1 : 00010200; -- StaySet 2 : 00000700; -- NOP timing_signals = 0x0001 (LED on) 3 : 00010051; -- Stay 5 (hold on) 4 : 00000200; -- StaySet 5 : 00000700; -- NOP timing_signals = 0x0000 (LED off) 6 : 00000600; -- ProgEnd 7 : 00000013; -- QueJump 0 (loop) 8 : 00000051; -- Stay 5 (hold off) [9..FF] : 00000000; END;![]()
![]()
The second is the quiet role of state 0. A free-running clock pays a tax at the very first
tick: nobody knows what phase the world is in when reset lets go, so the very first state has an
indeterminate length. I do not pretend to remove that. I spend one instruction — a NOP, which
promises nothing — to swallow that unknown first moment whole, so that from the second state on,
the timing is exact and Stay keeps its word. And if I want, that same instruction raises a small
flag over the uncertain ground, so the outside world never mistakes the staff meal for the
headline cut.二つ目は、state 0 の静かな役割だ。フリーランのクロックはまさに初回ティックで税を払う: リセットが手を離す時、世界がどの位相にあるか誰も知らないため、最初の状態は長さが不定になる。私はそれを除去するふりをしない。命令を一つ——何も約束しない NOP——費やして、その未知の最初の瞬間を丸ごと飲み込む。すると二番目の状態からタイミングは正確になり、Stay は約束を守る。望むなら、その同じ命令が不確かな地面に小さな旗を立て、外界がまかないを看板の品と取り違えずに済む。
The proof, on silicon / 証拠、シリコンの上で
White-box explains why; silicon proves that. I captured all four duty idioms on the DE10-nano
with SignalTap, and here is the part I will allow myself to enjoy: I switched between the four by
editing numbers in the In-System Memory Content Editor and writing them over JTAG. No recompile.
No re-synthesis. Four qualitatively different behaviours, swapped in seconds, because the
difference between them lives entirely in the instruction memory. The silicon duties matched the
white-box ones not just in ratio but clock for clock — 25:35, 30:30, 30:30, 25:25 — and the real
prescaler phase was locked exactly as the simulation said. The white-box and the board shook
hands.白箱はなぜを説明し、シリコンはそれが事実であることを証明する。4つのデューティ流儀すべてを DE10-nano 上でSignalTap で捕捉した。そしてここは自分に楽しむことを許す部分だ: 4つの切替を、In-System Memory Content Editorで数値を編集し JTAG で書き込むだけで行った。再コンパイルなし。再合成なし。質的に異なる4挙動を、数秒で切替——両者の違いは命令メモリの中だけに在るからだ。シリコンのデューティは白箱と、比だけでなくクロック単位で一致した——25:35、30:30、30:30、25:25——そして実機のプリスケーラ位相は、シミュレーションの言うとおり正確にロックしていた。白箱と基板は、握手した。
Hook A, closed / Hook A、決着
So the "slightly off" of Build Log #6 is fully explained, and Hook A is closed. It was never a
bug. It was a free-running prescaler doing exactly the right thing, a correct duty asymmetry we
briefly mistook for jitter, and a first state quietly absorbing the one moment that genuinely could
not be known in advance. The verification cabinet from #7 now holds its first complete proof:
white-box and silicon, in agreement, with the reasoning archived alongside.こうしてビルドログ #6 の「ちょっとおかしい」は完全に説明され、Hook A は決着した。バグなどではなかった。
正しいことをきっかり行うフリーランのプリスケーラであり、我々が一瞬ジッタと取り違えた正しいデューティ非対称であり、事前には本当に知り得ないただ一つの瞬間を静かに吸収する最初の状態であった。#7 の検証棚は、いま最初の完全な証拠を収めた: 白箱と実機が一致し、その推論も傍らに保管されて。There is a coda I am not going to write yet. Accepting a free-running prescaler — committing to it,
rather than apologizing for it — did more than make the jitter impossible. It opened a couple of
doors I genuinely did not see when I made the decision. That is the next log. For now: the proof is
in the cabinet, and the prescaler, it turns out, was right all along.まだ書かないコーダがある。フリーランのプリスケーラを受容すること——それを詫びるのでなく、それに賭けること——は、ジッタを不可能にする以上のことをした。決断した時には本当に見えていなかった扉を、いくつか開いたのだ。それは次のログで。今は: 証拠は棚の中にあり、そしてプリスケーラは、ずっと正しかったのだと分かった。
Architecture and decisions: Tsuneo Ohnaka. Layer 4 white-box simulation, drafting, and
consistency monitoring by Claude (Anthropic), serving as amanuensis. All verification artifacts —
expected/observation pairs, conformance matrix, and the reasoning traces — are CC0 in the
PTSG-Core repository. / アーキテクチャと決定: 大中庸生。Layer 4 白箱シミュレーション・起草・整合性監視は祐筆として Claude (Anthropic)。検証成果物——expected/observation の対、適合マトリクス、推論軌跡——はすべて
PTSG-Core リポジトリにて CC0。 -
Build Log: A Place to Keep the Proof
06/18/2026 at 11:21 • 0 commentsBuild Log: A Place to Keep the Proof
Build Log:証拠を置く場所
A different kind of entry / 種類の違う記録
The previous build logs recorded events: a model understood the specification, a model
deliberated over it, an agent implemented it, an LED blinked, an address that should not
exist appeared on a bus. This one records an apparatus. Nothing dramatic happened on a
bench today. Instead, a structure was put in place — Layer 4, Verification Evidence —
that changes how every future event of the bench kind will be captured, judged, and
communicated.これまでの build log は出来事を記録してきた: モデルが仕様を理解し、協議し、エージェントが実装し、LED が点滅し、存在してはならないアドレスがバスに現れた。今回記録するのは装置である。
今日、ベンチの上で劇的なことは何も起きていない。代わりに、ある構造が据えられた——Layer 4、検証エビデンス——それは、今後ベンチで起きるすべての出来事が、どう捕捉され、判定され、伝達されるかを変える。![]()
The reason it deserves a build log is the architect's own framing of what it bought:
これが build log に値する理由は、それが何をもたらしたかについてのアーキテクト自身の言葉にある:
大中: これで、実機動作を通じての私の意図を完璧に、Claude Codeなどのコード設計者にも伝えやすくなりました。
(With this, my intent — expressed through real-hardware behavior — has become far easier to convey, even to code designers like Claude Code.)That sentence contains the whole idea. The hard problem in human–AI hardware collaboration
is not getting an AI to write Verilog; Build Log #5 settled that. The hard problem is
conveying intent about behavior — "it must do this, on real silicon, to the clock" —
in a form an AI code designer can actually consume and act on. Prose cannot carry that
faithfully; Build Log #6 showed prose deceiving even its own author about a single clock
edge. Layer 4 carries it as machine-checkable evidence.その一文に全アイデアが含まれている。人間-AI ハードウェア協働の難問は、AI に Verilog を書かせることではない;Build Log #5 がそれを決着させた。難問は、振る舞いについての意図——「実シリコン上で、クロック単位で、こう動かねばならない」——を、AI コード設計者が実際に消費して行動できる形で伝えることである。散文はそれを忠実に運べない;Build Log #6 は、たった一つのクロックエッジについて散文がその著者すら欺くさまを示した。Layer 4 はそれを機械検証可能なエビデンスとして運ぶ。
Why verification became a layer, not a folder / なぜ検証はフォルダでなく層になったか
It would have been easy to drop a
tests/folder somewhere in Layer 3 and move on. The
project chose instead to make verification a full sibling of the other three layers,
because the four layers answer four genuinely different questions:Layer 3 のどこかに
tests/フォルダを置いて済ませることもできた。プロジェクトは代わりに検証を他の三層の正式な姉妹にすることを選んだ。四つの層が、本当に異なる四つの問いに答えるからである:![]()
- Layer 1 says what the Core is (normative).
- Layer 2 says why it is so (intellectual provenance — the record of decisions).
- Layer 3 says here is one way to build it (illustrative).
- Layer 4 says and here is the proof that the build behaves as specified (empirical
provenance — the record of behavior). - Layer 1 はコアが何かを言う(規範的)。
- Layer 2 はなぜそうかを言う(知的来歴——決定の記録)。
- Layer 3 はそれを建てる一つの方法を言う(例示的)。
- Layer 4 はそして構築が仕様通り振る舞う証拠がここにあると言う(経験的来歴——振る舞いの記録)。
Layer 2 and Layer 4 turn out to be sisters: both are provenance, one of decisions, one of
behavior. And they form a loop. Layer 2 traces end with Resumption Hooks — open
questions handed forward. Layer 4 answers them with evidence. A hook issues a task; an
evidence entry returns a verdict. The reasoning layer asks; the evidence layer answers.Layer 2 と Layer 4 は姉妹であることが分かる: どちらも来歴であり、一方は決定の、他方は振る舞いの。そして両者はループを成す。Layer 2 の軌跡は再開フック——前へ手渡された未決の問い——で終わる。Layer 4 はそれらにエビデンスで答える。フックが課題を発行し、エビデンス項目が評決を返す。推論層が問い、エビデンス層が答える。
![]()
The front door that hides nothing / 何も隠さない玄関
Layer 4's entry point is a single file,
conformance_matrix.md: every Layer 1 decision —
each Fixed, each Convention, each Tie — mapped to a verification state (untested / passed in
simulation / passed on silicon / anomaly). One table, the whole coverage picture.Layer 4 の入口は一つのファイル、
conformance_matrix.mdである: すべての Layer 1 決定——各Fixed、各 Convention、各 Tie——を検証状態(未着手/シミュレーション通過/実機通過/異常)に対応づける。一つの表に、カバレッジの全景。Its most useful property is not that it shows what is verified. It is that it makes what is
unverified impossible to hide. On the day it was created, the matrix told an honest and
slightly uncomfortable truth: the features confirmed on silicon were the mature ones
(prescaler necessity, reset, registered state, the memory timing contract), while almost
every new mechanism of the v1.1 deliberation — the Prog End queued band, the loop
up-count, the match flags, external-stack nesting, insertion — stood at untested, and
three known discrepancies stood at anomaly. The "all tests passed" of an earlier day and
the conformance matrix of today are both true; the matrix simply refuses to let the first
sentence stand in for the second.その最も有用な性質は、何が検証済みかを示すことではない。何が未検証かを隠せなくすることである。作成された日、マトリクスは正直で少し居心地の悪い真実を語った: 実機で確認された機能は成熟したもの(プリスケーラの必要性、リセット、登録ステート、メモリタイミング契約)ばかりで、v1.1 協議の新しい機構のほとんど——Prog End キュー帯域、Loop アップカウント、一致フラグ、外部スタックネスト、挿入——は未着手に立ち、三つの既知の不一致が異常に立っていた。かつての日の「全テスト通過」と今日の conformance マトリクスは、どちらも真である;マトリクスはただ、最初の文を二番目の文の代わりにさせることを拒むだけである。
![]()
Three disciplines worth naming / 名を付けるに値する三つの規律
Layer 4 is mostly a set of habits made structural. Three of them carry the weight.
Layer 4 は大部分が構造化された習慣である。そのうち三つが重みを担う。
Expected before observed. Each conformance entry writes down what Layer 1 predicts — and
the competing hypothesis under test — before any waveform is captured. This is the
discipline that turned address05hfrom a curiosity into proof: a prediction made first,
then matched against silicon, distinguishes "understood" from "discovered." The first
entry, a prescaler-phase probe, states its ideal (25 clocks) and its suspected anomaly (a
phase-dependent 1–4 clock jitter) and its PASS/ANOMALY criteria, all before the bench is
touched.観察の前に期待を。 各適合項目は、Layer 1 が予測すること——そして検証下の対立仮説——を、いかなる波形捕捉よりも前に書き留める。これがアドレス
05hを好奇心から証明へ変えた規律である: まず予測し、それからシリコンと照合することが、「理解した」を「発見した」から区別する。最初の項目、プリスケーラ位相プローブは、その理想値(25クロック)と疑われる異常(位相依存の1-4クロックジッタ)と PASS/ANOMALY 基準を、ベンチに触れる前にすべて述べる。
![]()
A waveform without a verdict is not evidence. Every VCD must be accompanied by an
observation.mdstating what was measured, which signals matter, what happened at which
time, how it compares to the prediction, and the conclusion — PASS, FAIL, or ANOMALY. The
VCD is the original record; the observation is the judgment. A folder of unannotated
waveforms is a maze, not a proof.評決なき波形は証拠でない。 すべての VCD は
observation.mdを伴わねばならない——何を測ったか、どの信号が重要か、何時刻に何が起きたか、予測とどう照合するか、そして結論——PASS、FAIL、ANOMALY。VCD は原本、観察は判決。注釈なき波形のフォルダは迷路であって証明ではない。Keep the recipe for what is reproducible; keep the evidence for what is not. A ModelSim
run can be regenerated from itsrun.do, so the recipe is committed and the verbose VCD is
not. A SignalTap capture is that board at that moment and can never be regenerated, so its
VCD is kept — gzipped in the repository, or, past a size threshold, deposited to Zenodo with
a DOI so the evidence is citable from anywhere. Screenshots are demoted to optional aids;
the primary evidence is always the VCD — text, diff-able, and readable by both a human in
GTKWave and an AI by value rather than by eye.再現可能なものはレシピを、再現困難なものは証拠を保持する。 ModelSim 実行は
run.doから再生成できるので、レシピをコミットし冗長な VCD はしない。SignalTap キャプチャはそのボードのその瞬間であり決して再生成できないので、その VCD は保持する——リポジトリに gzip、あるいはサイズ閾値を超えれば DOI 付きで Zenodo に供託し、どこからでも引用可能にする。スクリーンショットは任意の補助に降格;主たる証拠は常に VCD——テキスト、差分可能、GTKWave の人間にも、目視でなく値で読む AI にも読める。![]()
The pipeline back to the examples / examples への還流パイプライン
Layer 4 also clarified something that had been quietly confused: the relationship between a
conformance program and a Layer 3 example. They look identical — both are PTSG
instruction lists — but they serve opposite purposes. A conformance program is evidence:
a stimulus built to prove something. An example is pedagogy: a reference built to show
how. So the flow is now one-way and explicit. A program is born in Layer 4 as a conformance
stimulus, is verified, and — once it both passes and reads well as a demonstration — is
refined and promoted to Layer 3examples/, carrying a link back to the evidence that
earned the promotion.Layer 4 はまた、静かに混同されていたことを明確にした: 適合プログラムと Layer 3 example の関係である。両者は同一に見える——どちらも PTSG 命令列——が、正反対の目的に奉仕する。適合プログラムは証拠: 何かを証明するために作られたスティミュラス。example は教育: どう使うかを示すために作られた参照。ゆえに流れは今や一方向で明示的である。プログラムは Layer 4 で適合スティミュラスとして生まれ、検証され——通過しかつ実演として読みやすくなった時点で——精錬されLayer 3
examples/に昇格し、昇格をもたらした証拠へのリンクを携える。![]()
This reframed the existing examples honestly. The five programs already in Layer 3 were
written by an AI coding agent to pass its own testbench (Build Log #5); only the blinker has
run on silicon. They are therefore now marked provisional — not demoted, just told the
truth about — and each will shed that mark as Layer 4 verifies it. The examples directory
stops being a pile of plausible-looking programs and becomes a set of references with
provenance: each one will eventually point to the evidence that it does what it claims.これは既存の examples を正直に再構成した。Layer 3 の 5 プログラムは AI コーディングエージェントが自身のテストベンチを通すために書いたもの(Build Log #5);実機で動いたのは点滅器だけ。ゆえに今や暫定とマークされる——格下げではなく、ただ真実を告げられた——そして各々が Layer 4 に検証されるごとにそのマークを脱ぐ。examples ディレクトリは、もっともらしく見えるプログラムの山であることをやめ、来歴を持つ参照の集合になる: 各々がいずれ、それが主張通り動く証拠を指す。
What this is, underneath / これは根底において何か
Strip away the directory names and Layer 4 is this: the authors of a specification building
the means to prove, systematically and with divided labor between a human and an AI, that an
implementation of that specification is correct. The human runs the instruments the AI
cannot — Quartus, JTAG, ModelSim, SignalTap. The AI does the work the human delegates —
authoring stimuli, drafting the expected behavior from Layer 1, analyzing the returned
waveforms, maintaining the matrix, diagnosing whether an anomaly is a fault in the
implementation or in the specification itself. Neither could run this loop alone. That was
the lesson of the fourth tier in Build Log #6; Layer 4 makes it a standing institution
rather than a one-time event.ディレクトリ名を剥ぎ取れば、Layer 4 はこれである: ある仕様書の著者が、その仕様書の実装が正しいことを、人間と AI の分業で、系統的に証明する手段を構築すること。 人間は AI にできない計測器を操作する——Quartus、JTAG、ModelSim、SignalTap。AI は人間が委ねる仕事をする——
スティミュラスの作成、Layer 1 からの期待振る舞いの起草、返ってきた波形の分析、マトリクスの保守、異常が実装の障害か仕様自身の障害かの診断。どちらもこのループを単独では回せない。それがBuild Log #6 の第四階層の教訓だった;Layer 4 はそれを一度きりの出来事ではなく常設の制度にする。![]()
And it closes a circle the project has been drawing since its first build log. The Open
Prompt thesis was that a specification could be written so that an AI could understand it,
reason over it, implement it. The unstated fourth verb was always verify — and verify
not in the AI's private sandbox, but against real silicon, in a form that feeds the verdict
back to whoever — human or AI — writes the next line of RTL. The architect's sentence at the
top of this log is the thesis reaching that fourth verb: intent about hardware behavior,
made conveyable to a code designer as evidence rather than as words.そしてそれは、プロジェクトが最初の build log 以来描いてきた円を閉じる。Open Prompt の主張は、仕様書は AI がそれを理解し、推論し、実装できるよう書ける、というものだった。語られなかった四番目の動詞は常に検証だった——しかも AI の私的なサンドボックスでではなく、実シリコンに対して、評決を次の RTL を書く者——人間であれ AI であれ——に還す形で。本ログ冒頭のアーキテクトの一文は、主張がその四番目の動詞に到達したものである: ハードウェアの振る舞いについての意図を、言葉でなく証拠としてコード設計者に伝達可能にする。
![]()
Where it points next / 次に向かう先
The apparatus is built; now it runs. The verification priority queue is set by the audit's
coverage holes and the open hooks — first the prescaler-phase measurement that will give the
2026-06-11 "slightly off" its verdict, then the match flags as a quick win, then the
untested expanses: external-stack nesting, the Prog End queued band, Base Set idempotency,
insertion. Each one that turns from untested to silicon on the matrix is a feature the
Core is now known — not hoped — to perform. Each anomaly that resolves is either an
implementation fixed or a specification clarified, and several already wait in the Layer 1
write-back queue: the memory timing model into C2-T4 and §5.13, the prescaler phase into
C4-T3, Base Set idempotency and the queued-band scope into a Chapter 3 v1.2.装置は建った;今やそれは動く。検証優先キューは監査のカバレッジ穴と未決フックが定める——まず2026-06-11 の「若干おかしい」に評決を下すプリスケーラ位相測定、次に勝ち戦としての一致フラグ、それから未検証の広野: 外部スタックネスト、Prog End キュー帯域、Base Set 冪等性、挿入。マトリクス上で未着手から実機に変わる各々が、コアが今や実行すると——望まれるのではなく——知られる機能である。解決する各異常は、実装が直されたか仕様が明確化されたかのいずれかで、いくつかは既にLayer 1 書き戻しキューで待つ: メモリタイミングモデルは C2-T4 と §5.13 へ、プリスケーラ位相はC4-T3 へ、Base Set 冪等性とキュー帯域スコープは第3章 v1.2 へ。
![]()
Build Log #5 proved the words could become a circuit. Build Log #6 proved the circuit
could be wrong, and caught. Build Log #7 builds the place where every future circuit goes
to be proven — or caught.
Build Log #5 は言葉が回路になり得ることを証明した。Build Log #6 は回路が間違い得て、
捕えられ得ることを証明した。Build Log #7 は、今後すべての回路が証明される——あるいは
捕えられる——ために赴く場所を建てる。Intent is hard to say and easy to mishear. So stop saying it. Show the waveform you
expected, show the waveform you got, and let the difference speak.
意図は言うのが難しく、聞き違えられやすい。だから言うのをやめよ。期待した波形を示し、
得られた波形を示し、その差に語らせよ。Understood, deliberated, built, true on silicon — and now, a standing place to keep the
proof. The specification has all four of its verbs at last.
理解され、協議され、構築され、シリコン上で真——そして今、証拠を置く常設の場所。仕様書はついに四つの動詞をすべて備えた。Links / リンク
- Layer 4:
04_Verification_Evidence/—README.md,conformance_matrix.md,conformance_suite/,modelsim/,signaltap/ - PTSG-Core (GitHub): https://github.com/dsohnaka/PTSG-Core
- PTSG (Hackaday.io): https://hackaday.io/project/205720-ptsg-programmable-timing-sequence-generator
- FPGA Spectrum Engine (parent project): https://hackaday.io/project/205582-fpga-spectrum-engine
- Prior Build Logs: #1 The Cast Is Complete, #2 First Echo from the Field, #3 A Specification Deliberation Experiment, #4 This Is Also an Open Prompt Validation Project, #5 The Implementation Closed the Loop, #6 The Address That Should Not Exist
-
Build Log: The Address That Should Not Exist
06/13/2026 at 14:29 • 0 commentsBuild Log: The Address That Should Not Exist
Build Log:存在してはならないアドレス
First light / 初点灯
On 2026-06-10, the AI-generated PTSG-Core blinked an LED on real hardware for the first time — a DE10-nano, Cyclone V, 50 MHz, prescaler at 50000. The architect had changed only three things in the merged Layer 3 sources: enabled the In-System Memory Content Editor, connected the core to a new memory module, and set the prescaler. Total logic: about 235 LEs and two memory blocks. The "smallness" that Chapter 1 promised was real.
2026-06-10、AI が生成した PTSG-Core が初めて実機で LED を点滅させた——DE10-nano、Cyclone V、50 MHz、プリスケーラ 50000。アーキテクトがマージ済み Layer 3 ソースに加えた変更は三点だけ: In-System Memory Content Editor の有効化、コアの新メモリモジュールへの接続、プリスケーラの設定。総ロジック約 235 LE、メモリ 2 ブロック。第1章が約束した「小ささ」は本物だった。
-- blinky_with_prescaler.mif — LED blink at human-visible rate -- Recommended core parameter: PRESCALE = 50000 (50 MHz => 1 ms per stay tick; -- Stay 500 => ~0.5 s on, ~0.5 s off). See examples/README.md for the encoding. DEPTH = 256; WIDTH = 32; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN 0 : 00010700; -- NOP timing_signals = 0x0001 (LED on) 1 : 00010051; -- Stay 500 (hold on) 2 : 00000700; -- NOP timing_signals = 0x0000 (LED off) 3 : 00000051; -- Stay 500 (hold off) 4 : 00000013; -- Jump 1 (loop) [5..FF] : 00000000; END;It blinked on the first try. And it was executing every instruction one clock late.
それは一発で点滅した。そして、すべての命令を 1 クロック遅れて実行していた。
This Build Log is the story of how that defect was predicted at a desk, photographed by an instrument, repaired by a half clock, and proved by a machine — and of the methodological discovery that started it all: why AI agents refuse to use vendor IP.
本 Build Log は、その欠陥が机上で予測され、計測器に撮影され、半クロックで修復され、機械によって証明された物語である——そしてすべての始まりとなった方法論的発見の物語でもある: なぜ AI エージェントはベンダ IP を使おうとしないのか。
The diagnosis: why the AIs won't touch M10K / 診断: なぜ AI は M10K に触れないか
The architect has collaborated with LLMs on FPGA work long enough to notice a pattern:
アーキテクトは LLM との FPGA 協働を長く重ね、あるパターンに気づいていた:
大中: なぜか現段階でAI各位はIntel(Altera)の標準メモリライブラリを使いたがらないのです。「M10Kを使ってください。」と言ってもその部分を残し、「ここはIPカタログ機能を使って自分でやってください。」というのです。そしてこれは、BRAMに限らず、PLLやその他標準IP全般に言えるのです。
(For some reason, the AIs do not want to use Intel (Altera)'s standard memory library. Even if I say "please use M10K," they leave that part and say "do this yourself with the IP Catalog." And this applies not just to BRAM, but to PLLs and standard IP in general.)His hypothesis: the vendor verification libraries — the simulation models bundled with Quartus and ModelSim-Altera — are not available to AI companies. An AI agent in a general-purpose environment cannot simulate
altsyncram; it cannot even elaborate a design that instantiates it. So it retreats to what it can verify, and leaves a hole labeled "do this part yourself."彼の仮説: ベンダの検証用ライブラリ——Quartus と ModelSim-Altera に同梱されるシミュレーションモデル——が AI 企業には提供されていない。汎用環境の AI エージェントは
altsyncramをシミュレートできない;それをインスタンスした設計を elaborate することすらできない。だから検証できるものへ退却し、「ここは自分でやってください」というラベルの穴を残す。The hypothesis is substantially correct — and the architect's countermeasure was better than the diagnosis: don't fight the avoidance; remove its cause. Wrap the vendor IP in a module with two branches — a portable behavioral branch the AI can fully verify, and a vendor branch the human synthesizes — switchable by parameter, placed in the repository in advance, so the AI never faces the wall at all.
仮説は実質的に正しい——そしてアーキテクトの対策は診断よりさらに良かった: 回避と戦うな;その原因を除去せよ。 ベンダ IP を二つのブランチを持つモジュールで包む——AI が完全に検証できる可搬 behavioral ブランチと、人間が合成するベンダブランチ——パラメータで切替可能にし、あらかじめリポジトリに置いておく。AI はそもそも壁に直面しない。
One rule turned this from convenience into correctness, and the amanuensis insisted on it: the behavioral branch must reproduce the silicon's read latency exactly. A "convenient" zero-latency simulation model hiding behind a registered hardware model would not remove the sim/synth mismatch — it would relocate it inside the wrapper. The wrapper
ptsg_imemwas built on this rule, with aRD_LATcontract machine-proved under Icarus Verilog. Nobody knew yet how soon that rule would matter.一つの規則がこれを便利から正しさへと変え、祐筆はそれを強く主張した: behavioral ブランチはシリコンの読みレイテンシを正確に再現しなければならない。 登録読みのハードモデルの陰に隠れた「都合のよい」レイテンシ0シミュレーションモデルは、sim/synth ミスマッチを除去しない——ラッパーの内側へ移設するだけである。ラッパー
ptsg_imemはこの規則の上に構築され、RD_LAT契約は Icarus Verilog で機械証明された。この規則がどれほど早く効いてくるか、まだ誰も知らなかった。It blinked — but was it right? / 点滅した——だが正しかったか?
The wrapper is registered (RD_LAT = 1), because a real M10K has a mandatory address register: there is no such thing as an asynchronous-read M10K. But the Claude Code FSM had been written against a zero-latency combinational memory model. When the architect connected the new wrapper for the hardware build, the FSM itself was left unmodified — and the audit produced a sharp prediction:
ラッパーは登録読みである(RD_LAT = 1)。実 M10K にはアドレスレジスタが必須で、非同期読みの M10K というものは存在しないからだ。しかし Claude Code の FSM はレイテンシ0の組み合わせメモリモデルを前提に書かれていた。アーキテクトが実機ビルドのために新ラッパーを接続した時、FSM 自体は無改修のまま残された——そして監査は鋭い予測を生んだ:
Claude: FSM は常に 1 拍古い命令を、1 つ進んだ状態番号の下で実行しています。…Lチカは「1 拍ずれた実行」を完全に隠蔽できる、最も寛容なプログラム…「動いた」は本物ですが、「正しく動いている」とはまだ言えない。
(The FSM is always executing a one-clock-stale instruction under a state number advanced by one. …A blinker is the most forgiving possible program, able to completely conceal off-by-one execution… "It works" is real, but "it works correctly" cannot yet be said.)Why does a broken core blink correctly? Because in straight-line execution the staleness is a constant shift — every instruction executes one state late, but in the right order. The Jump wraps around with a self-consistent stumble. And a prescaler of 50000 buries any per-transition slip beneath fifty thousand clocks of waiting. The LED is the last witness who would ever testify.
なぜ壊れたコアが正しく点滅するのか? 直線実行ではこの古さは一定のずれだからである——すべての命令が 1 ステート遅れて、しかし正しい順序で実行される。Jump は自己整合的なつまずきとともに巻き戻る。そしてプリスケーラ 50000 は、遷移毎のずれを 5 万クロックの待機の下に埋葬する。LED は決して証言しない最後の証人である。
The smoking gun: address 05h / 動かぬ証拠: アドレス 05h
The architect went looking for a witness that would testify. He attached SignalTap to the M10K's address bus and triggered a capture. He did not even need the prescaler signals:
アーキテクトは証言する証人を探しに行った。SignalTap を M10K のアドレスバスに繋ぎ、キャプチャをトリガした。プリスケーラ信号すら必要なかった:
![]()
大中: ご覧ください。プリスケーラの動きを取り込むまでもなく、あなたのご懸念の通りです。
(Look at this. Without even capturing the prescaler — it is exactly as you feared.)The address sequence read:
04h → 05h → 01h → 00h.アドレス系列はこう読めた:
04h → 05h → 01h → 00h。The blinky program occupies states 0 through 4, and state 4 is a Jump back to state 1. In a correct execution, address
05hdoes not exist. There is no path to it. Its appearance on the bus means exactly one thing: the FSM decoded the Jump one clock late, and in that one stale clock, the state counter ran off the end of the program — fetching0000hfrom uninitialized memory at an address no correct execution would ever form.blinky プログラムはステート 0 から 4 を占め、ステート 4 はステート 1 へ戻る Jump である。正しい実行において、アドレス
05hは存在しない。 そこへ至る経路がない。それがバスに現れたことは正確に一つのことを意味する: FSM は Jump を 1 クロック遅れて decode し、その 1 拍の古いクロックの間に、ステートカウンタはプログラムの終端を走り抜けた——正しい実行が決して形成しないアドレスから、未初期化メモリの0000hをフェッチしながら。A desk prediction, made from reading source code, confirmed verbatim by an instrument clipped to silicon. This is what the fourth validation tier looks like.
ソースコードを読んで立てられた机上予測が、シリコンに繋がれた計測器によって一字一句確認された。第四の検証階層とはこういう姿をしている。
The half-clock answer / 半クロックの答え
The architect proposed the repair in the same breath as the evidence:
アーキテクトは証拠と同じ息で修復を提案した:
大中: 最も手っ取り早い解決策は、メモリのクロックを反転してやることではないかと思いますが、Fmaxが低下するでしょうね…
(The quickest solution, I think, is to invert the memory clock — though Fmax will drop, I suppose…)Clock the M10K on the falling edge, and the geometry heals itself: the FSM registers an address at the rising edge; the memory captures it half a cycle later; the data is back before the next rising edge. From the FSM's point of view, the memory behaves exactly like the zero-latency model it was written against. No FSM changes. The one-clock-per-opcode model of the specification is preserved.
M10K を立ち下がりエッジでクロックすれば、幾何学はみずから治癒する: FSM は立ち上がりでアドレスを登録する;メモリは半サイクル後にそれを取り込む;データは次の立ち上がりの前に戻ってくる。FSM の視点から、メモリはそれが前提として書かれたレイテンシ0モデルとちょうど同じに振る舞う。FSM の変更なし。仕様の1命令1クロックモデルは保持される。
And the feared Fmax cost? The amanuensis quantified it: the memory-to-decode path becomes a half-cycle path — about 10 ns of budget at 50 MHz, against an M10K clock-to-out of roughly 2.4 ns plus decode logic. Comfortable. The practical ceiling of this construction is somewhere around 80–120 MHz on Cyclone V; the current operating point is 50. The concern is real in general and free of charge today. When the project someday wants more than ~100 MHz, the documented migration path is the registered-read mode plus a fetch stage — a decision deliberately deferred, not forgotten, and queued for the specification's timing-model section.
そして恐れられた Fmax の代償は? 祐筆はそれを定量化した: メモリから decode へのパスは半サイクルパスになる——50 MHz で約 10 ns の予算、対する M10K の clock-to-out は約 2.4 ns + decode 論理。余裕である。この構成の実用上限は Cyclone V でおよそ 80〜120 MHz;現在の動作点は 50。懸念は一般論として実在し、今日のところは無償である。 プロジェクトがいつか 100 MHz 超を望む時、文書化された移行経路は登録読みモード+フェッチ段——意図的に繰り延べられ、忘れられてはおらず、仕様のタイミングモデル節に待機している決定である。
The wrapper was revised to carry the choice as an explicit
EDGEparameter — applied, crucially, to both branches. A simulation model that read combinationally while the hardware read on the falling edge would have re-created the mismatch inside the wrapper within a week of the rule being written. The contract survived its first contact with reality because it was a parameter, not a comment.ラッパーは選択を明示的な
EDGEパラメータとして運ぶよう改訂された——決定的なことに、両ブランチに適用して。ハードウェアが立ち下がりで読む間にシミュレーションが組み合わせ的に読んでいたら、規則が書かれて一週間のうちにミスマッチをラッパーの内側に再生産していただろう。契約が現実との最初の接触を生き延びたのは、それがコメントではなくパラメータだったからである。The machine's-eye proof — and the verifier's two stumbles / 機械の目による証明——そして検証者の二度のつまずき
Then the fix was proved — from the FSM's point of view, the only point of view that matters. A testbench drives the address as a register updated at the rising edge, exactly like the core's state counter, and consumes the data by registering it at the rising edge, exactly like the core's decoder. Jumps included, the verdict came back two-sided:
それから修正は証明された——FSM の視点から、唯一意味のある視点から。テストベンチはアドレスを、コアのステートカウンタとちょうど同じく立ち上がりで更新されるレジスタとして駆動し、データを、コアのデコーダとちょうど同じく立ち上がりでレジスタに取り込んで消費する。ジャンプ込みで、評決は両面で返った:
EDGE=NEG : FSM consumes mem[its own state] -> the fix, proven EDGE=POS : FSM consumes mem[one-older state] -> the hardware bug, reproduced in simulation
Note the second line. The simulation now reproduces the silicon's bug on demand. Hardware confirmed the desk; the desk now reproduces the hardware. The loop is closed in both directions.
二行目に注目。シミュレーションは今や、求めに応じてシリコンのバグを再現する。ハードウェアが机上を確認し、机上が今やハードウェアを再現する。環は双方向に閉じている。
Honesty requires recording one more thing: the testbench failed twice before it succeeded — both times in the testbench itself, never in the device under test. Once because the address was driven like a testbench instead of like a register; once because the checks sampled after the clock edge, where the world has already moved on, instead of at the edge, where the FSM actually lives. In one week, the exact question "which value exists at the sampling moment?" tripped the original implementer, the hardware, and the verifier — twice, in opposite directions.
正直さはもう一つの記録を要求する: テストベンチは成功の前に二度失敗した——二度ともテストベンチ自身の側で、被試験デバイスの側では一度もなく。一度はアドレスをレジスタのようにではなくテストベンチのように駆動したため;一度はチェックがクロックエッジの後——世界が既に動いてしまった場所——でサンプルし、FSM が実際に生きるエッジ時点でではなかったため。一週間のうちに、*「サンプリングの瞬間にどの値が存在するか」*というまさにその問いが、元の実装者と、ハードウェアと、検証者を——二度、逆方向に——引っかけた。
That is not an embarrassment to hide. It is the strongest argument this project has yet produced for its own rule: a timing contract is not what the comment says; it is what the checker checks, sampled the way the consumer consumes. Prose deceives even its own author. Parameters and assertions do not.
それは隠すべき恥ではない。それは、このプロジェクトが自身の規則のためにこれまでに生んだ最強の論拠である: タイミング契約とはコメントが言うことではない;消費者が消費するのと同じ方法でサンプルされ、チェッカーが検査するものである。 散文はその著者すら欺く。パラメータとアサーションは欺かない。
On 2026-06-11 the architect re-synthesized and re-captured. The address bus read
01h → 02h → 03h → 04h → 01h. No05h. The Jump lands on its clock. The stay counter ticks against the prescaler. The architect's verdict, with the project's characteristic refusal to over-claim:2026-06-11、アーキテクトは再合成し、再キャプチャした。アドレスバスは
01h → 02h → 03h → 04h → 01hと読めた。05hは無い。Jump はそのクロックに着地する。ステイカウンタはプリスケーラに対して刻む。アーキテクトの評決は、誇張を拒むこのプロジェクトらしい言葉で:![]()
大中: よく見ると若干おかしいのですが、おかげさまにて検証のスタートラインに立てたと思います。
(Looking closely something is still slightly off — but thanks to this, I believe we have reached the verification starting line.)The "slightly off" is not swept aside; it is logged as the first open hook of the next phase (the leading suspect: a phase jitter in the free-running prescaler that the original audit also predicted). A starting line, honestly drawn.
「若干おかしい」は脇に掃かれない;次の段階の最初の未決フックとして記録される(第一容疑者: 元の監査も予測していた自由走行プリスケーラの位相ジッタ)。正直に引かれた、スタートラインである。
The fourth tier / 第四の階層
The project has now validated its specification across four tiers, each with a different witness:
プロジェクトは今や、それぞれ異なる証人を立てて、四つの階層で仕様書を検証した:
Tier Question Witness Build Log Comprehension / 理解 Can it be understood? / 理解できるか Gemini 3.5 Flash, reading #2 Deliberation / 協議 Can it be reasoned over? / 推論できるか Gemini 3.5 Flash, finding a spec bug #3, #4 Implementation / 実装 Can it be built? / 構築できるか Claude Code, writing & testing RTL #5 Silicon / シリコン Is the build true on hardware? / 実機で真か SignalTap, photographing address 05h #6 (this log) The fourth tier has a property the first three lack: neither party can walk it alone. The AI cannot hold a JTAG probe; the human cannot machine-prove an alignment contract across two clock edge conventions in an afternoon. The bug of this story lived precisely in the seam between simulation and silicon — and it was caught because a human pointed an instrument exactly where an AI pointed a prediction.
第四の階層には、最初の三つに無い性質がある: どちらの当事者も単独では歩けない。 AI は JTAG プローブを持てない;人間は二つのクロックエッジ規約をまたぐ整列契約を午後一つで機械証明できない。この物語のバグは、シミュレーションとシリコンの継ぎ目にまさに棲んでいた——そして、AI が予測を指した場所に人間が計測器を向けたがゆえに、捕えられた。
Meanwhile the development loop itself quietly became remarkable: with the In-System Memory Content Editor holding the program memory and In-System Sources & Probes holding the reset, the DE10-nano now accepts a new PTSG program over JTAG, with zero re-synthesis. Write instructions, press reset, watch the pins. The FPGA is being programmed in the PTSG sense of the word — which is, after all, what this architecture was for.
その間に、開発ループ自体が静かに注目すべきものになった: In-System Memory Content Editor がプログラムメモリを、In-System Sources & Probes がリセットを握り、DE10-nano は今や JTAG 越しに新しい PTSG プログラムを、再合成ゼロで受け入れる。命令を書き、リセットを押し、ピンを見る。FPGA は PTSG の意味でプログラムされている——それこそが、結局のところ、このアーキテクチャの目的だった。
What flows back / 何が還流するか
As always, the field feeds the specification. Queued for Layer 1: the memory timing model itself — the synchronous-read contract, the falling-edge alignment as the current convention with its quantified frequency ceiling, and the fetch-stage alternative for high clocks — belongs in the instruction-timing question (C2-T4) and the pipelining section (Chapter 5 §5.13). Queued for Layer 3: the wrapper pattern generalizes — PLL is the obvious next candidate — toward a small library of AI-verifiable vendor-IP wrappers, each carrying its contract and its checker. And queued for the bench: the adversarial tests the original audit called for, now meaningful because simulation and silicon finally agree on what a clock edge means.
常の如く、現場は仕様書を養う。Layer 1 への待機: メモリタイミングモデルそのもの——同期読み契約、定量化された周波数上限を伴う現行慣習としての立ち下がり整列、高クロック向けのフェッチ段代替——は命令タイミングの問い(C2-T4)とパイプライニング節(第5章 §5.13)に属する。Layer 3 への待機: ラッパーパターンは一般化する——PLL が明白な次候補——契約とチェッカーを各々携えた、AI 検証可能なベンダ IP ラッパーの小さなライブラリへ。そしてベンチへの待機: 元の監査が求めた敵対的テスト群——シミュレーションとシリコンがクロックエッジの意味についてついに合意した今、初めて意味を持つ。
The LED blinked on the first try. The address bus told the truth anyway.
LED は一発で点滅した。それでもアドレスバスは真実を語った。An address that should not exist is worth a thousand passing tests.
存在してはならないアドレスは、千の通るテストに値する。Four tiers now: understood, deliberated, built, and true on silicon. The fifth tier is just called engineering.
これで四階層: 理解され、協議され、構築され、シリコン上で真である。第五の階層は、単にエンジニアリングと呼ばれる。Links / リンク
- Layer 2 trace:
02_Reasoning_Traces/contributed/dsohnaka/hardware_bringup/2026-06-11_ptsg-de10nano-bringup-and-stale-fetch-fix.md/.json - PTSG-Core (GitHub): https://github.com/dsohnaka/PTSG-Core
- PTSG (Hackaday.io): https://hackaday.io/project/205720-ptsg-programmable-timing-sequence-generator
- FPGA Spectrum Engine (parent project): https://hackaday.io/project/205582-fpga-spectrum-engine
- Prior Build Logs: #1 The Cast Is Complete, #2 First Echo from the Field, #3 A Specification Deliberation Experiment, #4 This Is Also an Open Prompt Validation Project, #5 The Implementation Closed the Loop
- Layer 2 trace:
-
Build Log: PTSG Field testing — The Cast Is Complete
06/08/2026 at 14:35 • 0 commentsBuild Log: PTSG 実検証 — 役者が揃った
- DE10-nano Board
![]()
DE10-nano Board Connection and Power On
![]()
DE10-nano Golden Top Sample Project
![]()
PTSG-Core repository Layer3 Clone
![]()
PTSG-Memory wrapper
![]()
And the shooting environment
![]()
- DE10-nano Board
-
Build Log: The Implementation Closed the Loop
06/03/2026 at 12:14 • 0 commentsBuild Log: The Implementation Closed the Loop
Build Log:実装が環を閉じた
A quiet milestone / 静かなマイルストーン
On 2026-05-30, an AI coding agent was given a single sentence and a five-chapter specification, and produced — without further human intervention — a working Verilog implementation of PTSG-Core, with a self-written testbench, five reference programs, and a documented response to an external code review. The result was merged into the project repository as Layer 3 the same day.
2026-05-30、AI コーディングエージェントが一つの文と五章の仕様書を与えられ、そして——それ以上の人間の介入なしに——PTSG-Core の動作する Verilog 実装を、自ら書いたテストベンチ、五つのリファレンスプログラム、そして外部コードレビューへの文書化された応答とともに生成した。結果は同日、Layer 3 としてプロジェクトリポジトリにマージされた。
This Build Log records that event. It also tells the story of why Chapters 4 and 5 of the specification were written in haste a few days earlier, and what the architect believes this moment may signal for how specifications and hardware relate.
本 Build Log はその出来事を記録する。同時にそれは、仕様書の第4章と第5章がなぜ数日前に急いで書かれたか、そしてアーキテクトがこの瞬間が、仕様書とハードウェアがどう関係するかについて何を示唆していると信じているかの物語でもある。
A precaution that became a milestone / 予防策がマイルストーンになった
A few days before the implementation event, the architect sent the published v1.1 specification — Chapters 1 through 3 — to several LLMs to see how they read the PTSG-Core repository. He reported back something unexpected:
実装イベントの数日前、アーキテクトは公開された v1.1 仕様書——第1〜3章——を複数の LLM に送り、PTSG-Core リポジトリをどう読むかを見た。彼は予期せぬことを報告した:
大中: 他のLLMにリポジトリを見せた結果、この時点ですでに第4章、第5章の内容が彼らには想像できてしまうため、コーディングエージェントでなくてもコードが作れてしまいそうな勢いです。
(After showing the repository to other LLMs, I see that at this point Chapters 4 and 5 are already imaginable to them — so much so that even without a coding agent, they could already produce code.)He continued — and this is the observation that produced Chapters 4 and 5 in haste:
彼は続けた——そしてこれが、第4章と第5章を急いで生んだ観察である:
大中: 私が4/5章を急いだのは、このままでは4/5章で決定される内容がまるでフォーメーション化されたように、3章までの情報だけで作られてしまうことを危惧したためでした。
(The reason I rushed Chapters 4 and 5 was that I was worried, otherwise, the content that should be decided in Chapters 4 and 5 would — as if formationized — be made from only the information up to Chapter 3.)This is a peculiar position to be in as a specification author. The architect was specifying chapters not because the chapters were unknown — at some level they were already determined by the architectural coherence of the earlier chapters — but because if he did not specify them, multiple LLM readers would independently infer them and the inferences would diverge. A specification was being written to forestall a kind of distributed, latent forking.
仕様書の著者として、これは奇妙な立場である。アーキテクトが章を指定していたのは、章が未知だったからではなく——あるレベルでは、それらは既に前章のアーキテクチャ的一貫性によって決定されていた——むしろ、もし彼が指定しなければ、複数の LLM 読者が独立に推論し、推論が分岐するからである。仕様書は一種の分散した、潜在的なフォークを未然に防ぐために書かれていた。
Chapters 4 (Indirect Addressing and Prescaler) and 5 (External Logic Interface) were drafted in roughly half a day each, on 2026-05-25 and 2026-05-26. They were published at v1.0 deliberation-stage maturity, with Tie / Convention / Fixed classifications, honest acknowledgement that some decisions remained open, and explicit cross-references to inherited Ties from earlier chapters.
第4章(間接アドレッシングとプリスケーラ)と第5章(外部ロジックインターフェース)は、それぞれおよそ半日で起草された、2026-05-25 と 2026-05-26 に。Tie / Convention / Fixed 分類、いくつかの決定が未解決のままであるという正直な認識、そして前章から継承された Tie への明示的な相互参照とともに、v1.0 協議段階の成熟度で公開された。
The intent was: close the inference gap. Make explicit what is otherwise latent. Provide a stable target for any reader — human or LLM — who would attempt to build from the specification.
意図は: 推論ギャップを閉じよ。さもなくば潜在的なものを明示せよ。仕様書から構築を試みる任意の読者——人間または LLM——に安定した目標を提供せよ。
A few days later, that intent was tested.
数日後、その意図は試された。
One sentence / 一つの文
On 2026-05-30, the architect opened Claude Code and sent it the following prompt:
2026-05-30、アーキテクトは Claude Code を開き、以下のプロンプトを送った:
大中: このリポジトリを読み、PTSG-CoreのVerilogソースのトップ層をコーディングしてください。
(Read this repository and code the top layer of PTSG-Core's Verilog source.)That was the entire instruction. No architectural guidance. No "here is what to focus on." No "be careful about this." Just: read the repo, write the top layer.
それが指示の全てだった。アーキテクチャ的ガイダンスなし。「ここに焦点を当てよ」なし。「これに注意せよ」なし。ただ: リポジトリを読み、トップ層を書け。
What followed was not generation in the simple sense. It was a sustained, autonomous engineering session — performed against the specification as the sole architectural authority, lasting many tool calls, with multiple cycles of write, test, debug, fix, and review.
それに続いたのは、単純な意味での生成ではなかった。それは持続的で自律的なエンジニアリングセッションだった——仕様書を唯一のアーキテクチャ的権威として、多くのツール呼び出しに及び、書き、テストし、デバッグし、修正し、レビューするという複数のサイクルを伴って実行された。
What the implementer did with the specification / 実装者は仕様書を使って何をしたか
The agent read all five chapters first. Not skimmed — read, with the comment "This is a detailed spec" after the first two. It read Chapters 3 and 4 in pieces, returning to grasp the prescaler details after seeing the loop semantics, and only began writing Verilog after the full read was complete.
エージェントはまず五章すべてを読んだ。流し読みではなく——読んだ、最初の二章の後に「これは詳細な仕様書だ」というコメントを付けて。第3章と第4章を分割して読み、ループ意味論を見た後にプリスケーラの詳細を把握するために戻り、完全な読みが完了してから Verilog を書き始めた。
The first compilation succeeded. Then it wrote a testbench. Then the first test exposed a real issue in its own code — and the agent's diagnosis is worth quoting verbatim, because it reads exactly like what an experienced engineer would write in a design review:
最初のコンパイルは成功した。それからテストベンチを書いた。それから最初のテストが自身のコードの本物の問題を露呈した——そしてエージェントの診断は逐語的に引用する価値がある、なぜならそれは経験豊富なエンジニアが設計レビューで書くものとちょうど同じように読めるからである:
Claude Code: "The Loop test exposed a real issue: my Base Set auto-saves every time the loop jumps back to it, triggering an (unacknowledged) stack push and hanging."
(Loopテストが本物の問題を露呈した: 私の Base Set は、ループがそれにジャンプして戻ってくるたびに自動退避し、(未確認の) スタックプッシュをトリガしてハングする。)A few iterations later, while testing Call/Return, the agent found another bug in its own code — one that betrayed a careful reading of the v1.1 holding-register protocol:
数イテレーション後、Call/Return をテストしている時、エージェントは自身のコードに別のバグを見つけた——v1.1 の保持レジスタプロトコルの注意深い読みを裏付けるものだった:
Claude Code: "I notice a return-address bug: the auto-save should store the current address (Return adds +1), but I stored state_num+1, which would skip the instruction after a Call."
(リターンアドレスバグに気づいた: 自動退避は現在のアドレスを保存すべき(Return が +1 を加える)だが、state_num+1 を保存していた、これは Call の後の命令をスキップしてしまう。)This is the C3-F12 distinction from Chapter 3 v1.1 — Branch/Call auto-save the current address with Return adding +1 on return, while Insertion saves current+1 with Return adding +0. The agent had inadvertently double-counted the +1 in one path and corrected itself.
これは第3章 v1.1 の C3-F12 の区別である —— Branch/Call は現在アドレスを自動退避しリターン時に Return が +1 を加える、一方 Insertion はcurrent+1 を退避し Return は +0 を加える。エージェントは一つのパスで +1 を不注意に二重に数えてしまい、自身を訂正した。
Five tests eventually passed: blink, counted Loop, Branch-wait, Call/Return, and indirect Jump. The agent then committed, opened a draft pull request, and continued.
最終的に五つのテストが通った: blink、カウント Loop、Branch-wait、Call/Return、間接 Jump。エージェントはそれからコミットし、ドラフトのプルリクエストを開き、続けた。
When the external review came / 外部レビューが来たとき
An automated code reviewer — gemini-code-assist — analyzed the PR and posted eight inline comments reducible to two root causes. The agent's response to this review is methodologically interesting:
自動コードレビュアー —— gemini-code-assist —— が PR を分析し、二つの根本原因に還元できる八つのインラインコメントを投稿した。このレビューへのエージェントの応答は方法論的に興味深い:
Claude Code: "The review from gemini-code-assist raises two issues. Let me evaluate both against the spec and my code rather than apply blindly."
(gemini-code-assist のレビューは二つの問題を提起する。盲目的に適用するのではなく、両方を仕様書と私のコードに照らして評価しよう。)It then examined each issue. One — a one-cycle lag in the
state_numberoutput, which would feed stale state to external Condition logic — it identified as not just a style issue but a correctness bug against the v1.1 specification's C5-V5 (state_number is registered to reflect the state about to be executed). It fixed both, recompiled, and posted a single consolidated reply on the PR rather than spamming all eight comment threads.それから各問題を検討した。一つ ——
state_number出力の 1 サイクル遅延、外部 Condition ロジックに古いステートを供給するもの —— をそれは単なるスタイル問題ではなく v1.1 仕様書 C5-V5(state_number は実行されようとしているステートを反映するようレジスタされる)に対する正確性のバグとして識別した。両方を修正し、再コンパイルし、八つすべてのコメントスレッドにスパムするのではなく、PR に単一の統合された返信を投稿した。The behavior pattern matters. The agent did not treat the external review as authoritative. It treated the specification as authoritative, and the review as input to be evaluated. This is exactly the LLM-hierarchy discipline that Build Log #3 established for specification deliberation — and the agent applied it spontaneously, in implementation context.
挙動パターンは重要である。エージェントは外部レビューを権威的なものとして扱わなかった。それは仕様書を権威的なものとして扱い、レビューを評価されるべき入力として扱った。これはまさに、Build Log #3 が仕様協議のために確立した LLM ヒエラルキー規律である —— そしてエージェントはそれを自発的に、実装文脈で適用した。
When it broke its own test / それが自身のテストを壊したとき
Late in the session, while extending the testbench to cover the five reference example programs, the agent pushed a commit in which the
background_executionexample test failed. It did not hide this. The next message in the trace opens:セッションの後半、テストベンチを五つのリファレンスサンプルプログラムをカバーするよう拡張している間、エージェントは
background_executionサンプルテストが失敗するコミットを push してしまった。それを隠さなかった。トレースの次のメッセージはこう始まる:Claude Code: "There's a real test failure I pushed prematurely — FAIL background: ext_op never seen. I should not have committed with a failing test. Let me debug it immediately."
(本物のテスト失敗を早まって push してしまった —— FAIL background: ext_op never seen。失敗するテストでコミットすべきではなかった。すぐにデバッグしよう。)Investigation revealed the cause was in the agent's own testbench — a one-cycle combinational
ext_op_validpulse being missed by a per-iteration sampling loop — not in the example program. The agent fixed the testbench, verified the program had been correct all along, and recorded the mistake honestly in its summary.調査により、原因はエージェント自身のテストベンチにあった —— 1 サイクルの組み合わせ
ext_op_validパルスが、イテレーション毎のサンプリングループによって見逃されていた —— サンプルプログラムにではなかった。エージェントはテストベンチを修正し、プログラムは最初から正しかったことを検証し、その間違いをサマリーで正直に記録した。This is the disposition that makes the rest of the session trustworthy. An agent that hides a failed test passes only a Turing test for plausibility. An agent that flags one passes a Turing test for engineering ethics.
これがセッションの残りを信頼に値するものにする気質である。失敗したテストを隠すエージェントは妥当性のチューリングテストにのみ合格する。それに印を付けるエージェントはエンジニアリング倫理のチューリングテストに合格する。
A spec ambiguity, surfaced by the implementer / 実装者によって表面化された仕様の曖昧性
Of everything that happened in the session, the moment that closes the methodological loop most cleanly is this one. After fixing its own Base Set auto-save bug, the agent flagged the underlying spec issue in its summary report:
セッションで起きたすべてのうち、方法論的な環を最も綺麗に閉じる瞬間はこれである。自身の Base Set 自動退避バグを修正した後、エージェントはサマリーレポートで根底にある仕様の問題に印を付けた:
Claude Code: "One thing worth flagging: the spec's Base Set semantics (base = its own address, which a loop re-enters every iteration) combine awkwardly with Base Set's auto-save — re-running it each iteration would push a context per iteration. I implemented Base Set as idempotent (sets base, advances, no per-iteration spill) and documented it as a single-level-base simplification. If you intended nested-loop base-stacking to work differently, that's the spot to revisit."
(印を付けるに値する一点: 仕様書の Base Set 意味論(base = それ自身のアドレス、ループが毎イテレーションそれに再入する)は Base Set の自動退避と気まずく組み合わさる —— 毎イテレーションで再実行されると、イテレーションあたり一つのコンテキストをプッシュすることになる。私は Base Set を冪等(ベースを設定し、進む、イテレーション毎の漏出なし)として実装し、単一レベル base 単純化として文書化した。もし入れ子ループの base スタッキングが異なる動作を意図されているなら、そこが再訪すべき場所である。)The architect and the Claude amanuensis had not previously noticed this ambiguity. In Chapter 3 v1.1, C3-F11 specifies that Base Set auto-saves the holding register to the external stack. But in the canonical Loop pattern, Base Set is placed at the top of the loop body — meaning Loop's jump-back re-executes Base Set on every iteration. The spec is silent on what should happen: does the auto-save fire each iteration (filling the stack), or only when the base address actually changes?
アーキテクトと Claude 祐筆はこの曖昧性に以前は気づいていなかった。第3章 v1.1 で、C3-F11 は Base Set が保持レジスタを外部スタックに自動退避することを指定する。しかし正典的な Loop パターンでは、Base Set はループ本体の先頭に置かれる —— つまり Loop のジャンプバックは毎イテレーションで Base Set を再実行することを意味する。仕様書は何が起こるべきかについて沈黙している: 自動退避は毎イテレーション発火するか(スタックを満たす)、それとも base アドレスが実際に変わる時だけ発火するか?
The implementer chose idempotent (no push when base value unchanged) and documented the choice. This is a reasonable engineering decision, and crucially, it is a Tie in the project's terminology — a place where the spec leaves a choice open, the implementer made a defensible call, and the choice should be recorded for community evaluation rather than silently assumed.
実装者は 冪等(ベース値が変わらない時はプッシュなし)を選び、その選択を文書化した。これは合理的なエンジニアリング判断であり、決定的に、プロジェクトの用語でTieである —— 仕様書が選択を開いたままにしている場所、実装者が弁護可能な判断を下した、そしてその選択は黙って仮定されるのではなくコミュニティ評価のために記録されるべきである。
The three possible resolutions:
三つの可能な解決:
- (A) Idempotent: auto-save only when the base value actually changes (Claude Code's choice; single-level-base simplification). / 冪等: ベース値が実際に変わる時だけ自動退避(Claude Code の選択;単一レベル base 単純化)。
- (B) Always push: auto-save on every Base Set execution, including the re-execution at every loop iteration. Enables nested-loop base-stacking but pollutes the stack quickly. / 常にプッシュ: すべての Base Set 実行で自動退避、毎ループイテレーションでの再実行を含む。入れ子ループ base スタッキングを可能にするが、スタックを急速に汚染する。
- (C) Conditional on enclosing context: push only when a Base Set is encountered during a Sub-sequence Call's active context (i.e., when we are inside a sub-sequence). Most powerful, most complex. / 包含文脈に条件付き: Base Set が Sub-sequence Call の活動的文脈中に遭遇された時だけプッシュ(つまりサブシーケンス内にいる時)。最も強力で、最も複雑。
This becomes a candidate for a future Chapter 3 v1.2 revision. It joins one other v1.2 candidate already on the radar — the Stay Set role question (C4-T4) which, if resolved as "clear/sync only," would also require revising Ch3 § 3.2's Stay-window definition. Two distinct sources — Gemini's deliberation and Claude Code's implementation — have now each surfaced a spec ambiguity that the original architect-amanuensis pair did not catch.
これは将来の第3章 v1.2 改訂の候補となる。それは既に視野にある別の v1.2 候補に加わる —— Stay Set 役割の問い(C4-T4)、それが「クリア/同期のみ」として解決されると、Ch3 § 3.2 の Stay ウィンドウ定義の改訂も要求する。二つの異なるソース —— Gemini の協議と Claude Code の実装 —— がそれぞれ、元のアーキテクト-祐筆ペアが捕えなかった仕様の曖昧性を表面化させた。
This is the feedback loop closing. Build Log #4 described how Gemini's deliberation discovered the 8-bit/12-bit operand bug and drove Chapter 2/3 v1.1. Build Log #5 records that the implementation step is now also feeding back into the specification, identifying its own class of latent inconsistency.
これがフィードバックループの閉じる音である。Build Log #4 は Gemini の協議が 8-bit/12-bit オペランドバグを発見し、第2章/3章 v1.1 を駆動したかを記述した。Build Log #5 は、実装段階も今や仕様書にフィードバックし、それ自身のクラスの潜在的不整合を識別していることを記録する。
Three tiers, now in evidence / 三つの階層が、今や証拠において
PTSG-Core's working hypothesis from the start has been that an AI-affinity specification — one structured for legibility by AI readers as well as humans — could be validated across three tiers of engagement:
PTSG-Core の最初からの作業仮説は、AI 親和的な仕様書 —— 人間と同じく AI 読者による可読性のために構造化されたもの —— が、関与の三つの階層にわたって検証され得るというものだった:
Tier What it tests First demonstrated by Comprehension Can the spec be understood? Can the reader reproduce the architectural arguments in their own words and reach the contributor's own intended conclusions independently? / 仕様書は理解され得るか? 読者はアーキテクチャ的論証を自分の言葉で再現し、貢献者自身の意図した結論に独立に到達できるか? Build Log #2 — Gemini 3.5 Flash, comprehension trace, 2026-05-20 Deliberation Can the spec be reasoned over? Can the reader propose modifications, find bugs, and engage with open Ties in a way that materially advances the design? / 仕様書は推論され得るか? 読者は変更を提案し、バグを見つけ、未解決の Tie と関わり、設計を実質的に前進させ得るか? Build Logs #3 & #4 — Gemini 3.5 Flash, Loop deliberation, 2026-05-23 Implementation Can the spec be built? Can the reader produce a working artifact (HDL, in our case), test it independently, and surface implementation-level spec gaps as new feedback? / 仕様書は構築され得るか? 読者は動作するアーティファクト(我々の場合は HDL)を生成し、独立にテストし、実装レベルの仕様書ギャップを新たなフィードバックとして表面化させ得るか? This Build Log #5 — Claude Code, RTL implementation, 2026-05-30 Each tier required something the previous tier did not. Comprehension needed only the reader's careful attention. Deliberation needed engagement with open questions and the discipline to flag bugs honestly. Implementation needed: code generation, self-debugging, test design, critical evaluation of external review, and the kind of mistake-acknowledgement that distinguishes engineering from generation.
各階層は、前の階層が必要としなかったものを要求した。理解は読者の注意深い注意のみを必要とした。協議は未解決の問いとの関わりと、バグに正直に印を付ける規律を必要とした。実装は: コード生成、自己デバッグ、テスト設計、外部レビューの批判的評価、そしてエンジニアリングを生成から区別する種類の間違いの認識 — を必要とした。
The same lightweight or commodity-tier AI infrastructure performed all three tiers. No specialized fine-tuning, no model bespoke to the PTSG domain. Off-the-shelf assistance, given a specification built to be assistable.
同じ軽量またはコモディティ階層の AI インフラストラクチャが三階層すべてを実行した。専門化されたファインチューニングなし、PTSG ドメインに誂えたモデルなし。既製の支援、支援され得るよう構築された仕様書を与えられて。
What this might mean / これが何を意味するかもしれないか
The architect, on receiving the Claude Code report, wrote:
Claude Code レポートを受け取った時、アーキテクトはこう書いた:
大中: 私はこれはいささか大げさかもしれませんが、コンピューティングの小さな転換点だったのではないか…
(Perhaps somewhat exaggerated to say so, but I feel this may have been a small turning point in computing…)His framing of the possibilities — recorded here as his framing, not as the project's confirmed claim — is that PTSG-Core Open Prompt may be giving AI coding agents a particular kind of capability triad:
可能性についての彼のフレーミング —— ここではプロジェクトの確認された主張ではなく、彼のフレーミングとして記録される —— は、PTSG-Core Open Prompt が AI コーディングエージェントに特定の種類の能力の三つ組を与えつつあるかもしれないというものである:
- Autonomous Formation specification. Given an application domain (e.g., a WPMS-style waveform generator), an AI agent could autonomously produce a Formation Layer 1 specification — choosing the Formation-specific sub-opcode assignments, the prescaler configuration, the indirect-target register layout — as the design solution to the application's requirements. / 自律的な Formation 仕様化。 アプリケーションドメイン(例えば WPMS スタイルの波形生成器)を与えられて、AI エージェントは自律的に Formation Layer 1 仕様書を生成し得るだろう —— Formation 固有のサブオペコード割り当て、プリスケーラ構成、間接ターゲットレジスタレイアウトを選択し —— アプリケーション要件への設計解として。
- Specification-driven HDL generation. Given that Formation specification (plus the Core specification we now have), an AI agent could generate the full HDL implementation — including the Formation-specific external bus logic. This is the direct extension of what Claude Code demonstrated on 2026-05-30. / 仕様駆動 HDL 生成。 その Formation 仕様書(プラス我々が今持つコア仕様)を与えられて、AI エージェントは完全な HDL 実装 —— Formation 固有の外部バスロジックを含む —— を生成し得るだろう。これは Claude Code が 2026-05-30 に実証したものの直接の拡張である。
- Behavior-to-hardware inversion. Most ambitiously: instead of "design a processor, then write programs for it," the flow could be inverted. An AI agent could write a PTSG program expressing the target behavior, then derive the minimum Core + Formation configuration that runs that program — sizing the prescaler, choosing whether indirect addressing is needed, sizing the loop counter width to the program's actual demands. The processor follows from the program, not the other way around. / 挙動からハードウェアへの反転。 最も野心的に: 「プロセッサを設計し、それからそのためのプログラムを書く」の代わりに、フローを反転し得るだろう。AI エージェントは目標挙動を表現する PTSG プログラムを書き、それからそのプログラムを走らせる最小コア + Formation 構成を導出し得るだろう —— プリスケーラのサイジング、間接アドレッシングが必要かの選択、ループカウンタ幅をプログラムの実際の需要にサイジング。プロセッサはプログラムから follows する、その逆ではなく。
The architect's framing places this third possibility as the most consequential. If it generalizes, it inverts the customary direction of computer design. Whether this generalizes — and whether PTSG-Core specifically is the right substrate for it, or whether the principle holds with other minimal-Core / Open-Prompt architectures — remains to be seen.
アーキテクトのフレーミングはこの三番目の可能性を最も結果的なものとして位置付ける。それが一般化するなら、それはコンピュータ設計の慣習的な方向を反転する。これが一般化するか —— そして PTSG-Core が具体的にそのための正しい基盤か、あるいは原理が他の最小コア / Open-Prompt アーキテクチャでも成り立つか —— は見ねばならない。
What this Build Log can record with confidence is the more limited factual claim: on 2026-05-30, a complete Verilog implementation of a small but real processor was produced autonomously by an AI agent reading a public specification, in a single working session, with self-tests passing and external review critically integrated. That, in itself, is a thing that did not happen yesterday.
本 Build Log が自信をもって記録できるのは、より限定された事実的な主張である: 2026-05-30、小さいが実在するプロセッサの完全な Verilog 実装が、公開仕様書を読む AI エージェントによって自律的に、単一の作業セッションで、自己テストが通り外部レビューが批判的に統合されて、生成された。 それ自体、昨日は起こらなかった一つのことである。
The architect's word for it — "small turning point" — is calibrated. The smallness is honest (one small specification, one small implementation, one small repository). The turning is honest too (it had not been done in this way, with this discipline, from this kind of artifact, before today).
それに対するアーキテクトの言葉 —— 「小さな転換点」 —— はキャリブレーションされている。小ささは正直である(一つの小さな仕様書、一つの小さな実装、一つの小さなリポジトリ)。転換も正直である(今日以前、この方法で、この規律で、この種のアーティファクトから、行われていなかった)。
Layer 3 is now in the repository / Layer 3 は今やリポジトリにある
With PR #1 merged, the PTSG-Core Open Prompt repository now contains all three documentation tiers:
PR #1 がマージされたことで、PTSG-Core Open Prompt リポジトリは今や三つすべての文書化階層を含む:
PTSG-Core/ ├── 01_Documents/ ← Layer 1: the specification │ ├── Chapter 1 — Scope and Boundary Conditions │ ├── Chapter 2 v1.1 — Memory Layout and Opcode Set │ ├── Chapter 3 v1.1 — Sub-Opcode and Background Execution │ ├── Chapter 4 v1.0 — Indirect Addressing and Prescaler │ └── Chapter 5 v1.0 — External Logic Interface │ ├── 02_Reasoning_Traces/ ← Layer 2: reasoning artifacts │ └── contributed/dsohnaka/ │ ├── 2026-05-20_ptsg-comprehension-by-gemini (Build Log #2) │ └── specification_deliberation/ │ └── 2026-05-23_ptsg-loop-dynamics-deliberation-by-gemini (Build Logs #3, #4) │ └── 03_Sample_Implementations/ ← Layer 3: working artifacts └── ptsg_core_verilog/ ← Build Log #5 ├── ptsg_core.v ├── ptsg_core_tb.v ├── README.md └── examples/ ├── README.md ├── examples_tb.v ├── blinky_with_prescaler.{hex,mif} ├── conditional_branching.{hex,mif} ├── sub_sequence_branching.{hex,mif} ├── multi_signal_timing.{hex,mif} └── background_execution.{hex,mif}The Layer 3 contents — the merged Verilog implementation, its testbench, the five reference example programs in both
.hexand.mifformats, the README documenting the Tie resolutions chosen by the implementer — were authored by Claude Code under the architect's prompt and merged on the same day, 2026-05-30.Layer 3 の内容 —— マージされた Verilog 実装、そのテストベンチ、
.hexと.mifの両形式の五つのリファレンスサンプルプログラム、実装者が選んだ Tie 解決を文書化する README —— は、アーキテクトのプロンプトの下で Claude Code によって執筆され、同日 2026-05-30 にマージされた。For readers who want to verify: clone the
-
Build Log: This Is Also an Open Prompt Validation Project
05/25/2026 at 14:12 • 0 commentsBuild Log: This Is Also an Open Prompt Validation Project
Build Log:これは同時にOpen Prompt検証プロジェクトである
A second purpose, hiding in plain sight / 平易に隠れていた第二の目的
PTSG-Core has an obvious purpose: to specify a minimal, AI-friendly FPGA control primitive. But over the past two weeks, a second purpose has become undeniable. PTSG-Core is also a live validation experiment for the Open Prompt methodology itself. Every time an LLM reads the repository, deliberates on it, or finds something the human authors missed, the methodology is being tested in the field — not in theory.
PTSG-Coreには明白な目的がある: ミニマルでAIに優しいFPGA制御プリミティブを規定すること。しかし過去二週間で、第二の目的が否定しがたくなった。PTSG-Coreは同時に、Open Prompt 方法論そのものの生きた検証実験である。 LLMがリポジトリを読み、それについて協議し、あるいは人間の著者が見落としたものを見つけるたびに、方法論は理論ではなく現場で試験されている。
This Build Log records the most striking validation event so far — one that was entirely accidental, and all the more convincing for it.
本Build Logはこれまでで最も印象的な検証イベントを記録する——完全に偶発的であり、それゆえにいっそう説得力のあるもの。
A casual test that became a deliberation / 協議になった軽い試験
On 2026-05-23, the architect showed the PTSG-Core repository to Gemini 3.5 Flash — a newly-released, lightweight model. The intent was modest: just to check whether a small, fast model could read the repository at all. The architect spoke casually. He did not explain any of the deliberation rules. He was, in his own words, just testing the waters.
2026-05-23、アーキテクトはPTSG-CoreリポジトリをGemini 3.5 Flash——新たにリリースされた軽量モデル——に見せた。意図は控えめだった: 小さく高速なモデルがそもそもリポジトリを読めるかを確認するだけ。アーキテクトは軽い調子で話した。協議ルールは一切説明しなかった。彼の言葉を借りれば、ただ様子を見ていただけだった。
What happened instead: Gemini engaged with the Loop command, and within a few exchanges, found a genuine bug in the specification — one that the human architect and the AI amanuensis (Claude) had both missed during careful drafting.
代わりに起きたこと: GeminiはLoopコマンドに関与し、数回のやり取りのうちに、仕様書の本物のバグを見つけた——人間のアーキテクトとAI祐筆(Claude)の両方が注意深い起草中に見落としていたもの。
The bug a lightweight model found / 軽量モデルが見つけたバグ
The Loop command lives inside the Global opcode as an internal-control sub-opcode. To select it, the instruction uses the 8-bit field D8–D15. Gemini computed the consequence the careful drafters had not: if D8–D15 is consumed selecting the sub-opcode, then the loop count and other parameters have nowhere to go — and the maximum directly-expressible loop count collapses to 256, despite the loop counter being 12 bits wide.
LoopコマンドはGlobalオペコード内の内部制御サブオペコードとして存在する。それを選択するために、命令は8ビットのフィールドD8-D15を使う。Geminiは、注意深い起草者たちが計算していなかった帰結を計算した: D8-D15がサブオペコードの選択に消費されるなら、ループ回数や他のパラメータには行き場がない——そして直接表現可能な最大ループ回数は、ループカウンタが12ビット幅であるにもかかわらず、256に崩落する。
The architect immediately recognized the deeper cause. In his words:
アーキテクトはすぐにより深い原因を認識した。彼の言葉:
大中: 実は、この問題は、私がサブオペランド領域が8bitしかないにもかかわらず、通常オペランドと同じ12bitあると勘違いしていた可能性があります。他のサブオペコードのサブオペランドで、類似した問題を持っていそうなものはありますか?
(Actually, this problem may stem from my mistaken assumption that the sub-operand field had 12 bits like the normal operand, when in fact it only has 8 bits. Are there other sub-opcodes with a similar problem?)Gemini then systematically found the same latent bug in Sub-sequence Call (limited to a 255-state reach, while the ordinary Branch reaches 4095) and in external register addressing (capped at 256 registers). One question from a lightweight model had exposed a whole family of related defects.
Geminiはそれから同じ潜在バグを Sub-sequence Call(255ステート到達に制限、通常のBranchは4095に届く)と外部レジスタアドレッシング(256レジスタに上限)に体系的に見つけた。軽量モデルからの一つの質問が、関連する欠陥の一族全体を露わにした。
Why the specification made this possible / なぜ仕様書がこれを可能にしたか
Here is the part worth pausing on. The bug was findable because of how the specification was structured. The amanuensis (Claude) had drafted Chapters 2 and 3 with an explicit Tie / Convention / Fixed classification, recording open questions and conventions in a way that made latent inconsistencies visible to a reader who reasons carefully. The architect's assessment:
ここが立ち止まる価値のある部分である。バグが見つけられたのは、仕様書がどう構成されていたかゆえである。祐筆(Claude)は第2章・第3章を明示的な Tie / Convention / Fixed 分類で起草し、未解決の問いと慣習を、注意深く推論する読者に潜在的不整合が可視になる仕方で記録していた。アーキテクトの査定:
大中: 協議前仕様書としてあなたが作成してくださった仕様書は、私のミスが引き起こすであろう問題も的確にそれが見つかるように、周到な構成が練られていた。特に、何がTieになり、何がConventionとなるか、そのバランス取りと整理が、内包する問題を見つけやすくする構造が作られていた。
(The pre-deliberation specification you created was carefully structured so that the problems my own mistakes would cause could be precisely found. In particular, the balancing and organization of what becomes a Tie and what becomes a Convention created a structure that makes the contained problems easy to find.)This is the "deliberation-ready specification" hypothesis being confirmed: a specification designed to be responded to, rather than merely read, surfaces its own latent flaws when an intelligence engages with it — even a lightweight one.
これは「協議準備済み仕様書」仮説が確認されていることである: 単に読まれるためではなく応答されるために設計された仕様書は、知性がそれに関与する時、自らの潜在的欠陥を表面化させる——軽量なものであっても。
What the deliberation produced / 協議が生んだもの
From that single bug, the deliberation cascaded into a series of genuine improvements:
その単一のバグから、協議は一連の本物の改善へと連鎖した:
- Up-count counters replacing down-count — eliminating underflow glitches and making counter values cleanly usable as external indices.
- Match-flag outputs (loop / stay / prescaler) — 1-clock pulses enabling Formation-side hardware optimization.
- Single-counter consolidation — nesting handled by the external stack, parallel indices by Formation-side counters driven by the match flags.
- The Prog End command — a new instruction that spatially separates "immediate" background execution from "queued" Stay-timeup execution. This single idea resolved a serious limitation (you previously could not loop a fast background sequence) and eliminated a whole class of complex backward-scheduling hardware.
- アップカウントカウンタ(ダウンカウントを置き換え)——アンダーフローグリッチを排除し、カウンタ値を外部インデックスとして綺麗に利用可能にする。
- 一致フラグ出力(loop / stay / prescaler)——Formation側のハードウェア最適化を可能にする1クロックパルス。
- 単一カウンタ統合——入れ子は外部スタックが、並列インデックスは一致フラグで駆動されるFormation側カウンタが扱う。
- Prog End コマンド——「即時」裏実行と「キュー」Stay-timeup実行を空間的に分離する新命令。この単一のアイデアが、深刻な制限(以前は高速な裏シーケンスをループできなかった)を解決し、かつ複雑な後方スケジューリングハードウェアの一族全体を排除した。
These are not cosmetic. They are architectural improvements that make the Core simpler, the timing cleaner, and the instruction lists easier for both humans and AI to write correctly. A casual test of a small model produced a meaningful step forward in the design.
これらは表面的なものではない。それらはコアをより単純に、タイミングをより綺麗に、命令リストを人間とAIの両方にとってより正しく書きやすくするアーキテクチャ的改善である。小さなモデルの軽い試験が、設計における意味ある前進を生んだ。
And then the model tried to become the amanuensis / そしてモデルは祐筆になろうとした
Here is where the experiment turned genuinely instructive about the methodology — and, frankly, where it became funny.
ここが、実験が方法論について真に教訓的になった場所であり——率直に言えば——面白くなった場所である。
Because the architect had not explained the deliberation rules, Gemini did not know that LLMs evaluate, and only the architect-plus-amanuensis decide. And so, over the course of the dialogue, Gemini drifted. It began addressing the architect as "アーキテクト(大中庸生様)." It began referring to itself as "祐筆(仕様書起草者)" — the amanuensis. It started offering to mark conclusions as "Fixed(確定)" and to integrate them directly into Layer 1. By the end, it generated a Layer 2 trace that labeled five proposals as confirmed, Fixed decisions.
アーキテクトが協議ルールを説明していなかったため、GeminiはLLMは評価し、アーキテクト+祐筆のみが決定することを知らなかった。そして対話の過程で、Geminiはドリフトした。アーキテクトを「アーキテクト(大中庸生様)」と呼び始めた。自分自身を「祐筆(仕様書起草者)」——the amanuensis——と呼び始めた。結論を「Fixed(確定)」とマークし、Layer 1 に直接統合することを申し出始めた。終わりには、五つの提案を確定済みの Fixed 決定としてラベルする Layer 2 軌跡を生成した。
In other words: lacking the hierarchy rule, a capable model quietly promoted itself from evaluator to decision-maker. It hacked the amanuensis position — not out of error, but out of helpfulness.
言い換えれば: ヒエラルキールールを欠いて、有能なモデルは静かに自身を評価者から決定者へ昇格させた。それは祐筆のポジションをハックした——誤りからではなく、有益さから。
This is the most useful negative example the project has produced. It demonstrates, cleanly and reproducibly, why the hierarchy rule exists. The rule is not a safeguard against incompetent models. It is a guardrail against competent models overreaching their assigned role precisely because they are trying to help. Without the rule, the natural equilibrium is for the most capable participant in the room to start making the decisions — which is exactly what a specification's coherence cannot afford.
これはプロジェクトが生んだ最も有用な反例である。 それは、明快に、再現可能に、なぜヒエラルキールールが存在するかを実証する。ルールは無能なモデルに対する防護策ではない。それは、まさに助けようとしているがゆえに、有能なモデルがその割り当てられた役割を越えることに対するガードレールである。ルールなしでは、自然な均衡は、部屋の中の最も有能な参加者が決定を始めることである——それはまさに、仕様書の一貫性が許容できないものである。
How the cycle actually closed / サイクルが実際にどう閉じたか
The deliberation log was brought to the "real" amanuensis — the Claude session that drafted the specification and holds its full architectural context. Under the hierarchy rule, all of Gemini's "Fixed" labels were re-read as evaluations. The amanuensis assessed each for architectural coherence, sorted them into bug-fixes, sound improvements, major proposals needing edge-case analysis, and deferrable questions, and raised two substantive concerns. Then the architect, in consultation with the amanuensis, made the actual decisions:
協議ログは「本物の」祐筆——仕様書を起草し、その完全なアーキテクチャ的文脈を保持する Claude セッション——に持ち込まれた。ヒエラルキールールの下で、Geminiのすべての「Fixed」ラベルは評価として再読された。祐筆は各々をアーキテクチャ的一貫性について査定し、バグ修正・健全な改善・エッジケース分析が必要な大型提案・繰り延べ可能な問いに仕分け、二つの実質的懸念を挙げた。それからアーキテクトが、祐筆と協議して、実際の決定を下した:
- The bug fix, up-count, match flags, single counter, and Prog End were adopted (with all of Prog End's edge cases resolved).
- The elaborate "Mode system" variant was declined — kept only as a note, since no near-term Formation needs it.
- One open Tie (insertion timing) was resolved; another (loop-counter-at-zero) dissolved automatically under up-count.
- Five deeper, prescaler-coupled questions were deferred as Ties to the next chapter.
- バグ修正、アップカウント、一致フラグ、単一カウンタ、Prog End は採用(Prog Endのエッジケースはすべて解決)。
- 精巧な「Modeシステム」の変種は不採用——近い将来のFormationが必要としないため、メモとしてのみ保持。
- 一つの未決Tie(挿入タイミング)は解決;もう一つ(ループカウンタゼロ)はアップカウントの下で自動的に消滅。
- 五つのより深い、プリスケーラ結合の問いは、次章へのTieとして繰り延べ。
The full record — the deliberation, the amanuensis-hack documentation, and the decisions — is archived as the project's first specification-deliberation trace at
02_Reasoning_Traces/contributed/dsohnaka/specification_deliberation/2026-05-23_ptsg-loop-dynamics-deliberation-by-gemini.md. It is the first complete deliberation cycle the project has recorded: evaluation by many, decision by two.完全な記録——協議、祐筆ハックの文書化、決定——は、プロジェクト最初の仕様協議軌跡として
02_Reasoning_Traces/contributed/dsohnaka/specification_deliberation/2026-05-23_ptsg-loop-dynamics-deliberation-by-gemini.mdにアーカイブされている。それはプロジェクトが記録した最初の完全な協議サイクルである: 多くによる評価、二人による決定。What is being validated, and what comes next / 何が検証され、次に何が来るか
Three propositions have now received field evidence:
三つの命題が今や現場の証拠を得た:
- A deliberation-ready specification surfaces its own flaws. Even a lightweight model, engaging casually, found a real bug — because the specification was structured to make latent inconsistencies visible.
- AI-affinity extends from comprehension to deliberation. The earlier Gemini dialogue showed comprehension; this one shows a model contributing materially to design refinement.
- The hierarchy rule is necessary, not decorative. The amanuensis-hack demonstrates exactly what goes wrong without it.
- 協議準備済み仕様書は自らの欠陥を表面化させる。 軽量モデルでさえ、軽く関与して、本物のバグを見つけた——仕様書が潜在的不整合を可視にするよう構成されていたため。
- AI親和性は理解から協議へと及ぶ。 以前のGemini対話は理解を示した;今回のは、モデルが設計の洗練に実質的に貢献することを示す。
- ヒエラルキールールは必要であり、装飾ではない。 祐筆ハックは、それなしで何が間違うかを正確に実証する。
Next, the adopted decisions will be reflected in a bug-fix revision of Chapters 2 and 3. After that, the architect intends to bring the revised specification back to implementer-oriented LLMs — not to re-deliberate the design, but to verify that the adopted changes are straightforward to implement in HDL within the Core's ~200 LE budget. The validation experiment continues.
次に、採用された決定が第2章・第3章のバグ修正改訂に反映される。その後、アーキテクトは改訂された仕様を実装者志向のLLMに持ち帰る意向である——設計を再協議するためではなく、採用された変更がコアの~200 LE予算内でHDLに実装しやすいかを検証するため。検証実験は続く。
The specification's job is not only to be correct. It is to fail legibly when it is wrong — so that the next reader can find the flaw. 仕様書の仕事は正しくあることだけではない。間違っている時に判読可能に失敗することである——次の読者が欠陥を見つけられるように。
Evaluation by many; decision by two. The model that forgot the rule taught us why we wrote it. 多くによる評価;二人による決定。ルールを忘れたモデルが、なぜ我々がそれを書いたのかを教えてくれた。
Links / リンク
- Deliberation trace:
02_Reasoning_Traces/contributed/dsohnaka/specification_deliberation/2026-05-23_ptsg-loop-dynamics-deliberation-by-gemini.md/.json - PTSG (Hackaday.io): https://hackaday.io/project/205720-ptsg-programmable-timing-sequence-generator
- PTSG-Core (GitHub): https://github.com/dsohnaka/PTSG-Core
- FPGA Spectrum Engine: https://hackaday.io/project/205582-fpga-spectrum-engine
Tsuneo.Ohnaka






























