Close

Build Log #11 : What Came Back

A project log for PTSG — Programmable Timing Sequence Generator

A tiny FPGA-resident programmable sequencer that controls time and space directly

tsuneoohnakaTsuneo.Ohnaka 07/11/2026 at 13:240 Comments

Build 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 to state_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_flag port, 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_branching example, 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.

次の項は、それを書き戻すことについてである。

Discussions