第 48 环 · 会话记忆归档(K/V 上下文落内存、下次接着聊)
第 46 环让一场对话在片内跑完,第 47 环把整场对话收进一条 npu.chat。可这记忆只活在 K/V 环里:会话一结束、环被写满、或者电源一断,上一场说过的话就没了。
手机不是每次打开都从陌生人开始。用户关掉窗口、过一会儿再打开,AI 该记得刚才聊到哪儿。本环给上下文加一条落内存 / 回片内的通路:
ok=1。于是 OS 只需要说「把上一场接上」,芯片自己把记忆装回来——这就是「下次接着聊」。
新增 rtl/kv_archive.sv(会话记忆归档引擎),并把它接进主路:
表头 8 字(base+0..7): [0] 魔术字 "SALT" = 0x53414C54 [1] 版本/层数/环深 [2] K 条数(层1|层0) [3] V 条数(层1|层0) [4] 载荷摘要 [5] 会话号 [6] 载荷字数 [7] 结束标记 0xA5A5C3C3 载荷(base+8 起):层0 K → 层0 V → 层1 K → 层1 V,按逻辑时间序
arc_clear 在 load 的第一拍清空 K/V —— 追加进一个非空的环只会留下最后 DEPTH 条,记忆会错位。conv_loop 新增 mode_mem——回合 0 不清上下文,而是等归档引擎恢复;整场结束自动归档。同一场里回合之间仍由 mode_ctx 管。min_bus 内 512 字 × 32bit 的会话记忆区(真芯片上就是 DRAM/Flash 的一个会话快照区),新页 0xA00。0xA00 ARC_CMD 0xA14 ARC_WORDS 0xA2C ARC_PEEK_DATA 0xA44 SCREEN24 0xA04 ARC_GO 0xA18 ARC_DIGEST 0xA30 ARC_ERR 0xA48 ARC_KVCNT 0xA08 ARC_BUSY 0xA1C ARC_MISMATCH 0xA34 ARC_NENT 0xA0C ARC_DONE 0xA20 ARC_MAGIC 0xA38 ARC_HDRSESS 0xA10 ARC_OK 0xA24 ARC_SESSION 0xA3C ARC_AUTO
协同仿真 tb_min_soc48 在既有全部观察点之后跑四段:
| 步骤 | 做什么 | 结果 |
|---|---|---|
| A | 两回合 [0,1],ctx=1 + mem=1,结束后自动归档 | ok=1 / 16 字 / 魔术字 SALT / 会话号 0x0048 |
| Ref | 用 A 留下的上下文跑一趟整网(不采样) | Y_ref = 0x05FF04F9 |
| B | 一回合 prompt=2,ctx=0 + mem=0(清空上下文) | Y_other = 0x0800FAFC ≠ Y_ref |
| L | 一条 ARC_CMD=2 + ARC_GO 从内存恢复 | ok=1 / mismatch=0 / 每层 4 条(ARC_KVCNT=0x2424) |
| Res | 恢复后同一趟整网 | Y_res = 0x05FF04F9 == Y_ref |
| C | 恢复后再开一场一回合(mem=1) | CONV_CTXCLR=0:回合 0 走恢复、没清上下文 |
单元仿真 tb_kv_archive:归档⇄恢复 12 条逐位一致;改坏一个载荷字 → mismatch=1、ok=0;空会话 0 字仍 ok;魔术字被抹 → err=1 且不污染环;换环深/两层独立都覆盖。
主通路未动:SCREEN=0xF905FD04、SCREEN2=0x02040404、SCREEN23=0x08020500 与第 25~47 圈逐位一致。
其一(读使能写成寄存器,读回的是上一轮残留)。内存与 K/V 环都在 posedge 采样:mem_ren 若在 S_xRD 用非阻塞置高,真正采样要到再下一拍,而 FSM 下一拍就去收数据——魔术字读回恒 0、表头全是残留。改成组合驱动读地址/读使能,S_xRD → S_xCP 才对齐。教训:「谁在哪一拍采样」要写下来,寄存一拍就是错一拍。
其二(归档只写了读口,没写存口)。save 完成时 ARC_MAGIC 探针读到 0——因为 save 路径从不填 hdr[] 数组,只有 load 才填。归档完成时把刚写进内存的魔术字/会话号同时报给探针,OS 才不用自己去窥视内存。
其三(恢复前必须清环)。第一版直接往现有环里追加 16 条:环深只有 4,追加完只剩最后 4 条(全是层 1 的 V),记忆完全错位。arc_clear 在 load 第一拍清空后才对。
其四(摘要不能省)。改坏内存里的一个字后,恢复出来的环与内存仍然「自洽」——逐条比对 0 条不一致、ok 却是假绿。只有把表头里的摘要与重算的摘要比一次,才抓得住。教训:逐条比对证明「搬得对」,摘要证明「搬的是原来那份」。
其五(s4 是收尾的最终残差流)。归档自检借了 s4 存 ARC_OK,把收尾要写屏幕的 0xF905FD04 覆盖成 1,SCREEN 变成 0x00000001。改用 t6 后恢复。另:mv s3, a0 后必须隔两拍再做分支(第 45 环已记,这次又踩了一次)。
到这一环,Salt OS 的「同一个对话窗口」有了场外记忆:窗口关掉再打开,AI 记得上一场说到哪儿;恢复出来的上下文与「一直没关」算出来的整网输出逐位相同——不是「有点像」,是同一份。
对一台手机的意义:记忆是关系的前提。没有记忆的 AI 每次都是陌生人,只能当工具;有记忆的 AI 才能「接着聊」,才谈得上总调度、谈得上为别人搭台时每个服务都接着同一份上下文。再往上,才是多会话、多用户、断电持久化。
现在会话区只有一个槽:归档第二场,第一场就被覆盖。可手机上不会只有一场对话——家人的、工作的、某个服务的,各自都该记得自己的上下文。下一环做多会话槽位:按会话号分槽归档与恢复,槽位可分配、可枚举、可淘汰。让「记得你」从一条记忆变成一本通讯录。