STEP 1427 — Tang Nano 9K Ring oscillator PUF spike (Option A)
目的
藤本さん 3-task 順番処理 directive 中、 「Tang Nano 9K では代替 になりませんか?」 → Option A OSC drift (STEP 1415)、 続いて 発注 stance 探索 → wiring 能力 boundary 明示 (「私の能力では BME280 の 接続が 出来ません」) → feedback rule 2 追加 → 次 spike arc 3 選択肢 A/B/C 提示 → 藤本さん directive 「両方お願い致します」 → 私 (Claude) の 推奨 A (Ring PUF) で proceed → STEP claim 1427 → 5-step 実装 → 実測 verify。
本 spike の primary purpose = combinational feedback loop を 使う LUT-based ring oscillator が Gowin GW1NR-9C で 実現可能か の 検証。 副 goal = STEP 1350 verdict primitive の 「不確実性 → NEITHER」 原則が operational に働くか の 確認。
設計
27 MHz crystal (pin 52) ──┬── clk_27m domain 1-second gate (27M count)
└── ring_slow edge detect (2-FF sync + rise)
│
▼
edge counter (24-bit)
│
gate expires ──▶ latch slow_cnt / reset / sec_cnt++
│
▼
UART TX (115200 8N1) → USB VCP → PC COM9
"RPUF:REF=27000000,DIV=XXXXXX,SEC=YY\r\n"
51-stage LUT chain (combinational feedback, syn_keep = "true")
ring[0] = ~ring[50]
ring[i] = ~ring[i-1] for i > 0
↓
async ripple divider 16 stages (÷ 65536)
↓
ring_slow (~164 Hz @ ring 10.77 MHz)
↓
(sampled into clk_27m domain, safe << 13.5 MHz Nyquist)
実装
Files (6、 hardware/phase-c/11-tang-nano-9k-ring-puf-spike/)
| File | Lines | Purpose |
|---|---|---|
ring_puf_top.v | ~260 | 51-stage LUT chain feedback loop + 16-stage ripple divider + edge counter + UART emitter |
uart_tx.v | ~75 | 8N1 UART TX (STEP 1410/1411/1415 verbatim copy) |
tang_nano_9k.cst | ~28 | Pins: clk 52, LED[0-3] 10/11/13/14, uart_tx 17、 ring LUT LOC 制約なし |
build.tcl | ~15 | Gowin V1.9.12.02_SP2 build script |
pc_ring_puf_reader.py | ~230 | pyserial + rolling baseline (3 samples) + ring freq est + STEP 1350 verdict subset |
README.md | ~350 | design + honest scope + verify record |
実測結果 (2026-08-27)
Build (Gowin V1.9.12.02_SP2)
Build PASS + Gowin ACCEPTS combinational loop — 398 LUT/ALU (5%) + 180 FF (3%) + 222 CLS (6%)、 bitstream 2,070,608 bytes、
syn_keep = "true" attribute で combinational feedback loop を Gowin GowinSynthesis が accept、 errors 0、 warnings TA1132 x2 (clk_27m + ring[0] SDC 未 create、 cosmetic)。 STEP 1415 (339 LUT / 164 FF) と 近い resource footprint、 +59 LUT (ring chain) + +16 FF (divider chain) の 増加。
SRAM Program
初回 FTDI channel stuck — 0.0 sec cost + no User Code (STEP 1411 と同 pattern、 3 例目)。 COM9 が Windows WMI serial list に 未認識、 JTAG channel A は 認識 (0x1100481B) だが Program 実 write せず。
藤本さん USB 抜き差し 3-5 秒 hold 後 再試行 → Program PASS — User Code
0x0000A59D / Status 0x0003F020 (Ready) / Cost 3.51 sec、 Cable FT2CH cable-index 1。 FTDI channel A (JTAG) + Channel B (VCP COM) 双方 復帰。
PC 側実測 15 秒 (pc_ring_puf_reader.py --port COM9 --duration 15)
[ 1] sec=0x3F ref=27000000 div= 164 ring~=10.75 MHz collecting baseline drift= --- [ 2] sec=0x40 ref=27000000 div= 164 ring~=10.75 MHz collecting baseline drift= --- [ 3] sec=0x41 ref=27000000 div= 165 ring~=10.81 MHz base= 164.3 drift= --- [ 4] sec=0x42 ref=27000000 div= 164 ring~=10.75 MHz base= 164.3 drift= -2028.4 ppm [ 5] sec=0x43 ref=27000000 div= 164 ring~=10.75 MHz base= 164.3 drift= -2028.4 ppm ... [ 16] sec=0x4E ref=27000000 div= 164 ring~=10.75 MHz base= 164.3 drift= -2028.4 ppm total packets : 16 parsed packets : 16 malformed : 0 baseline (DIV) : 164.3 (3 samples) baseline ring freq: ~10.770 MHz (est. DIV × 65536) DIV min/max/mean : 164 / 165 / 164.2 drift ppm range : [-2028.4, +4056.8] span=6085.2 verdict : NEITHER reason : drift span 6085.2 ppm exceeds ±5000 ppm tolerance
解釈: Ring oscillator は 正常動作
- Baseline ring frequency = 10.77 MHz (10.766 - 10.827 MHz range)
- 51-stage × 平均 1.82 ns/LUT = 92.8 ns period = 10.77 MHz ← realistic FPGA fabric LUT delay
- Consistent operation over 15 sec (16 packets 全 parse)
★ 核心 finding: verdict NEITHER が 「不確実性」 を 正しく検出
Verdict NEITHER の 正しい 意味:
- DIV は 2 値 discrete (164 or 165)
- 1 count 差 = 1/164 ≈ 6098 ppm = single-count quantization noise
- Tolerance 5000 ppm より quantization noise の 方が大きい
- NEITHER は 「temperature drift 検出できない」 でなく 「measurement 分解能不足」 の accurate report
- STEP 1350 verdict primitive の 「不確実性 → NEITHER」 原則 の operational proof (STEP 1415 の verdict TRUE と 対称の 有意 NEITHER 実例)
改善 path (defer)
- Divider ratio 縮小 (2^16 → 2^10) → DIV ×64 増加 (~10500) → quantization ~95 ppm → tolerance 内 stable
- Gate window 拡大 (1s → 10s) → 10 倍 count → quantization ~610 ppm
- 別 board で 実測 → per-die variance 検証 (現状 1 board のみ)
5-step spike template mapping
| Step | 内容 | 状態 |
|---|---|---|
| 1 | STEP claim 1427 (claim-step.ts) + Ring oscillator 設計 (syn_keep verify) | ✅ |
| 2 | benchtop-mcp mock (defer — real hardware 直接動作で mock 不要、 STEP 1415 pattern 継承) | ⏸ defer |
| 3 | ring_puf_top.v + Gowin build PASS (398 LUT) | ✅ |
| 4 | SRAM Program (0x0000A59D、 USB 挿し直し 経由) + 実測 verify (16 packets、 verdict NEITHER = quantization detected) | ✅ |
| 5 | README + memory + Inbox pattern 経由 hook + site 反映 (本 page) | ✅ |
Honest scope (7 条)
1. Ring oscillator = Gowin accept 済 —
syn_keep = "true" attribute で combinational loop reject 回避 verify。 GW1NR-9C 上 LUT-based ring oscillator 実現可能性 evidence2. "PUF" 主張は controllable — 単一 ring は 1 dimension per-die signature、 challenge-response 型 cryptographic PUF ではない。 名前は 教育的/概念的、 crypto 用途 保証なし
3. 1 board のみ実測 — per-die variance の 実測は 別 board 必要、 現状 evidence は 「1 die 上の 10.77 MHz 実測」 のみ
4. Quantization noise > drift signal — 現 設計 で drift span 6085 ppm は 分解能不足の帰結、 temperature-induced drift detection には 改善 path 実装必要
5. Novelty ゼロ — FPGA ring oscillator は 電子工作/PUF 研究 の 定番 primitive、 「初」 主張なし
6. Placement uncontrolled — LUT chain の 物理位置 uncontrolled、 rebuild ごとに frequency 変動可能、 per-die identity 議論には 固定 LOC 制約必要
7. Ripple divider = non-standard clock use — Gowin warning TA1132 で
ring[0] を clock として 検出、 dedicated clock network 経由でない async design、 実動作 verify 済だが 商用設計 非推奨Rei stack alignment
- STEP 1415 OSCO drift pattern 95% reuse (UART emit + PC reader + build/program flow)
- STEP 1350 verdict 3 値 subset の 「不確実性 → NEITHER」 operational proof (TRUE と NEITHER 双方の 有意 実例が 揃った)
- Tang Nano 9K 物理 silicon 8 例目 (STEP 1028/1029/1039/1038/1399/1410/1411/1415 継承)
- feedback: hardware purchase stance rule 2 (wiring boundary) 遵守 evidence = 手元 hardware 完結 spike domain 拡張の operational instance
- 藤本さん directive Option A (Ring PUF) 明示 answer
Reproducing
# 1. Build cd C:/Users/user/rei-aios/hardware/phase-c/11-tang-nano-9k-ring-puf-spike "/c/Gowin/Gowin_V1.9.12.02_SP2_x64/IDE/bin/gw_sh.exe" build.tcl # 2. Program (SRAM, flash 保護、 FTDI stuck 時は USB 抜き差し) "/c/Gowin/Gowin_V1.9.12.02_SP2_x64/Programmer/bin/programmer_cli.exe" \ --cable "Gowin USB Cable(FT2CH)" --cable-index 1 \ --device GW1NR-9C --operation_index 2 \ --fsFile impl/pnr/ring_puf_top.fs # 3. PC verify (COM9 auto-bound VCP) python pc_ring_puf_reader.py --port COM9 --duration 15 --baseline-samples 3
Related
- STEP 1415 — OSCO drift spike (sibling pattern、 verdict TRUE 対称実例)
- STEP 1411 — BME280 Phase 2 prep (USB 挿し直し pattern origin)
- STEP 1410 — UART/I2C scaffold Phase 1 (uart_tx.v origin)
- STEP 1409 — 5-step spike template origin
- feedback: hardware purchase stance (rule 1 + rule 2)
- feedback: world-uniqueness-claim-controllable