🎯 圆心 · 目标(每环都从这里出发)
造一台 Salt OS 手机:基于 DeepSeek 的 AI 操作系统,iPhone 4S 外形(含底部圆形 Home 键),开机只有一个 AI(无桌面、无图标),软硬协同设计(OS + 芯片 + 主板一起做),为别人搭台、让别人在平台上赚钱。

🧭 完整框架(同心圆)

①文字闭环 · ②技术深入 · ③挂SRAM · ④权重INT4 · ⑤激活INT4 · ⑥NPU.STORE · ⑦KV Cache · ⑧注意力QK^T · ⑨Softmax · ⑩加权V · ⑪前馈FFN · ⑫残差·LayerNorm · ⑬多层堆叠 · ⑭QKV投影 · ⑮K/V分离 · ⑯自回归解码 · ⑰连续生成 · ⑱采样 · ⑲KV环形缓冲 · ⑳滑窗注意力 · ㉑多头注意力 · ㉒输出投影 W_o · ㉓多头块入残差流 · ㉔多头块进解码循环 · ㉕整层一块 · ㉖整网一块 · ㉗ISA契约 · ㉘权重内存化 · ㉙权重预取双缓冲 · ㉚权重分块 · ㉛矩阵行块 · ㉜行块自增 · ㉝起始块号可编程 · ㉞段表连扫 · ㉟段表流式取 · ㊱行块矩阵扫 ISA 化 · ㊲描述符链 · ㊳链槽直喂 · ㊴主路走链 · ㊵链预投下层 · ㊶跨趟预投 · ㊷权重池三 bank · ㊸权重池 ISA 化 · ㊹一步生成 ISA 化 · ㊺整段生成 ISA 化 · ㊻对话回路 · ㊼对话 ISA 化 · ㊽会话记忆归档 · ㊾多会话槽位 · ㊿会话槽位 ISA 化 · 51 开机续聊 · 52 会话清单 · 53 开机用上清单 · 54 问候接话 · 55 删掉一场 · 56 会话改名 · 57 名字进问候 · 58 问候念清单 · 59 按名字接话 · 60 叫错名字也回一句 · 61 反问给选项 · 62 按序号点选 · 63 序号用于删除 · 64 删除回执念名字 · 65 删除可撤回 · 66 撤回回执念名字 · 67 撤回即续聊 · 68 续聊先开口 · 69 开口带名字 · 70 开口不叫错人 · 71 开机问候也认人 · 72 单名问候也验归属 · 73 单名问候带余场 · 74 余场点名 · 75 余场翻页 · 76 翻页带序号 · 77 序号点选也叫名字 · 78 点完就接着聊

本环:点完不是终点,AI 接着说

① 目标(这一环要解决什么)

第 76/77 环把「第N个」点选做进了芯片:从余场序号表取出会话号、验过名字归属、念出「好,工作那场,接着聊。」、再换场恢复 K/V。可说完这句回执就安静了——目录对了、上下文也回来了,却没人开口,用户还得再补一句「然后呢」。

这一环让序号点选点完就接着聊:进场完成,硬件直接用恢复的上下文说下一句。回执是第一句,AI 的下一句是第二句——点选和续聊连成一句话。

② 实现(做了什么)

三段接力,各管一段。新增 rtl/pick_speak.sv:点选引擎管「点谁」、开关场引擎管「进场」、这一环管「开口」。它只认 npu.name 的 done 电平 + per/ord 标志,且必须 answered;删除路径(del)一律不开口——删完没有「下一句」可接。

等真进场,不抢跑。名字点选在 S_ENT 已经发过一条 enter,这一环不重发,只用「见 busy 起、再见 busy 落」两段式等它跑完,绝不把上一轮的 done 当本轮。只有 ok && mem_ok(真读回旧上下文)才开口;空场不假装记得。

话头从记忆里来。发一段整段生成(与 npu.generate 同一台引擎):话头取刚恢复那场的归档摘要低位、层数 2、采样种子固定 0xA5——与第 68 环「续聊先开口」完全同一套契约。核一个生成入口寄存器都不写。

只消费一次。pick_done 是电平,consumed 标志保证同一场只开口一次;pick_done 落下才清零。pending 补「认下了但 busy 还没进寄存器」那一拍,npu.wait 不会把半路看成空闲。

开关保守。新写口 0xB38 NP_PKSPK(默认 0 = 第 77 环老语义);新只读 0xB3C PKS_SPOKE / 0xB40 PKS_SID / 0xB44 PKS_SEQ / 0xB48 PKS_N / 0xB4C PKS_LAST / 0xB50 PKS_PROMPT / 0xB54 PKS_CORE / 0xB5C PKS_DONE / 0xB60 PKS_ERR / 0xB68 PKS_BUSY,0xB58 PKS_RST,0xB64 SCREEN54。前 77 圈地址映射一字不改、ISA 一位没动。

③ 验证(怎么证明它真的跑通)

单元 tb_pick_speak(替身开关场 + 替身生成引擎,五用例):

  • 序号点选 → 等进场 busy 起落 → 摘要低位当话头 → gen_start/seed_we 各一拍 → spoke=1、收下 n/seq/last;
  • 全名点选(per=0/ord=0)→ 不动作;
  • 空场(mem_ok=0)→ done=1 / spoke=0 / err=0,不发 gen_start;
  • 删除路径(ord=1、del=1)→ 不动作;
  • pick_done 还举着时 clear → 同一场不重复开口。

ISA 协同 tb_isa_greet78(真整颗 SoC,四场目录 + 活清单 0x1C0 + 余场序号表 0x2A0,slot1 = 0xA2 归档 4 条 K/V,摘要 0x76CA6F0E):

NP_PKSPK=1, NP_ORDNM=1
说「第二个」→ 一条 npu.name
   → 换场 0xA2,回执「好,工作那场,接着聊。」
   → 硬件接一句:话头=摘要低位 2、种子 0xA5、4 步
     seq=0x22([0,2,0,2])、末 token 2、PKS_CORE=0
   → npu.wait 等到这一句说完才返回
PKS_RST → 说「查资料」(全名点选)
   → 照旧换场 0xA3,spoke=0(全名路径留给下一圈)
SCREEN54 = 0x84A28022(spoke|4|0xA2|prompt2|core0|seq22)
SCREEN = 0x78

回归:name_pick77、rem_pick76、resume_speak70、isa_greet77、isa_resume68 全部 PASS;第 77 环的回执、第 68 环的先开口逐位不变。

✅ 仿真通过 · 本环闭环
单元 5 用例 + ISA 协同 + 5 项相邻回归;「第二个」之后 AI 真的接着说了下一句
④ 本环的钉子
  • 前缀撞车:第 54 环问候接话已经占用 pk_*(pk_rst_pulse / pk_corecnt),新引擎全部改用 pks_*;否则编译期就是重复声明;
  • 复位不能重新开口:PKS_RST 时若 pick_done 还举着,consumed 必须置 1(consumed <= pick_done),否则 clear 会把同一场点选当新的一次、再说一遍;
  • 目录项和活清单是两张表:目录项 0x190 的 w0 = {valid[31], …, sid[15:0]};活清单 0x1C0 = {cnt, {slot[2:0],13'b0,sid}, words, …}。把目录项写成清单格式会让 valid=0,整场恢复失败;
  • 摘要会重算:归档恢复时重算载荷摘要并与表头比对,载荷换一个数就对不上 → mismatch → ok=0 → mem_ok=0,表现为「静默不开口」;
  • 新来路要接全:gen_run 的 start/prompt/layers 与 sampler 的 seed 四处都要加 pks_* 来路,漏一处就是「有点像」的假绿;
  • 脉冲进每拍默认块:gen_start / seed_we / pks_rst_pulse 只写复位分支会常高——第 38/44/68 环同一颗钉子。