🎯 圆心 · 目标(每环都从这里出发)
造一台 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 开口不叫错人

本环:开口第一句,先叫出这一场是谁

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

第 68 环让接回之后 AI 先开口,可第一句只看归档摘要——它不知道自己在跟谁说话。用户点名「跑步计划」找回一场没聊完的对话,屏幕上第一句却是没有称呼的罐头话,像换了个人。

这一环在「先开口」之前加一步「叫名字」:名字格在会话记忆里(第 56/57 环改名时落进去的),按当前槽自己读出来,拼成「<名字>,咱们接着聊。」落进对话窗口,再让整段生成接着说。

② 实现(做了什么)

名字从内存读,不让软件填。接回成功(resume_done && ok && mem_ok)后,resume_speak 先按会话开关场的 cur_slot 发 6 拍同步读,取名字格 0x200 + 槽×6(6 字 = 24 字节 UTF-8):

  • 同步 SRAM 三态读:发地址 → 空一拍 → 收数据,六个字全部进寄存器后才拼句;
  • 名字长度由硬件数:遇 0 截止、最多 24 字节;名字短就缩短,后缀紧接最后一个名字字节,不留 24 字节空洞;
  • 拼「名字 + ,咱们接着聊。」(后缀 7 个汉字 = 21 字节),定长 48 字节 / 12 字,连写 12 拍落 0x1E0(与开机问候同一个对话窗口,新的覆盖旧的);
  • 名字格为空(没改过名)不硬塞称呼:退回「咱们接着聊。」18 字节,named=0 如实报;
  • 这句话落屏之后,才发同一台整段生成引擎(与 npu.generate 完全同一条通路),先开口的下一句照旧从刚恢复的记忆里长出来;
  • 忙闲覆盖「读名字 → 拼句 → 落屏 → 整段生成」整段,pending 仍补接回落忙那一拍;每次接回只说一次。

接口。探针接在第 68 环页后:RS_NAMED(0xA8C)、RS_BYTES(0xA90)、RS_SLOT(0xA94)、RS_LINE0..RS_LINE11(0xA98~0xAC4),屏摘要 SCREEN44(0xAD0) / SCREEN45(0xAD4)。前 68 圈地址映射一字不改;ISA 一位没动(仍 npu.undo)。会话记忆区新增第七个写主,优先级 rsp > ud > np > rn > fs > gp > bg > ss > arc。

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

单元仿真 tb_resume_speak69(真同步 SRAM 行为模型):

  • 空场(mem_ok=0)→ 不读名字、不写窗口、不开口,但照样落 done;
  • 槽 2「跑步计划」→ named=1 / bytes=33 / slot=2,0x1E0 十二字与「跑步计划,咱们接着聊。」逐位相同;
  • 槽 1 空名字 → 退回「咱们接着聊。」bytes=18 / named=0;
  • 槽 0「工作」→ bytes=27,后缀紧接第 6 字节,不留空洞;
  • done 保持高不重复,下一次接回才说第二句;clear 归零。

ISA 协同仿真 tb_isa_resume69(真整颗 SoC):0x92 在槽 2(名字「跑步计划」,摘要 76CA6F0E),0x93 在槽 1(名字「工作」,摘要 85955090)。程序各走一遍 npu.forget → npu.undo → npu.wait:

  • 两场都 spoke=1,RS_CORE=0(核一个生成入口都没写);
  • SCREEN44=0x243:槽 2 / 33 字节 / named=1;SCREEN45=0x137:槽 1 / 27 字节 / named=1;
  • 第一次 spoke 时快照 0x1E0,十二字等于「跑步计划,咱们接着聊。」;最终 0x1E0 等于「工作,咱们接着聊。」;
  • 两场话头 A_PROMPT=2 / B_PROMPT=0,各自取自归档摘要低位;程序走到 SCREEN=0x69,两次 npu.wait 都没冻死。
RESULT=PASS
两场接回各自叫名字 · 33/27 字节逐字对上 · RS_CORE=0

回归:tb_isa_resume68、tb_isa_undo67、tb_min_soc64 复跑 RESULT=PASS,主通路 SCREEN=0xF905FD04 与第 25~68 环逐位一致(计算面一个字没动)。第 68 环的单元 tb_resume_speak 断言的是旧时序(接回后立刻 gen_start),已被本环「先读名字再落屏」取代,留作历史快照,不再随最新 RTL 复跑。

④ 回到目标(这一环让手机多了什么)

只有一个对话窗口的手机,不该让用户猜「它知不知道我是谁」。接回一场没聊完的对话,第一句先叫名字,是把记忆变成称呼——名字在清单里、记忆在环里,两者在同一句里收口。

更重要的是:这句话不是 OS 拼的固定问候。硬件按当前槽去名字格取字、数长度、拼后缀、落窗口,核一个 MMIO 都没写。名字是数据,找名字、叫名字是硬件的事。