第 54 环 · 问候接话(用户点一场就切过去)
第 53 环让开机第一句话由硬件排好:「你有三场没聊完。」可这句话只是说,还没有接。用户在唯一的对话窗口里点第 2 场,软件得自己回清单表里查第 2 条、取出会话号、再发一条 npu.sess 切过去——点一下 = 查表 + 取值 + 换场,三件事又落回软件。
Salt OS 的对话窗口里没有「列表控件」:用户点的是那句话里的「第二场」,AI 要立刻接住、立刻进那一场、开口就能接着聊。本环把「接话」也收进芯片:一条 npu.pick 序号,剩下的全由硬件自己走完。
新增 rtl/greet_pick.sv 问候接话引擎。一条 start 之后,它按顺序做四件事:
0x1C0 读表头(人数),再读第 idx 条 {槽号[31:29], 13'b0, sid[15:0]} 和它的字数(下一字低半字);0x1F0;enter 脉冲,把刚解出来的会话号直接送进开关场引擎(与一条 npu.sess enter 走同一扇门)。点第 1 场 → 好,接着第一场。 点第 2 场 → 好,接着第二场。 … 点第 6 场 → 好,接着第六场。 点不到 → ok=0 / err=1(不换场、不写问候)
ISA 化。核升 v18,custom-1 新增 funct3=111:npu.pick rs1(rs1 = 第几场,1 起)。npu.rd 选源放宽到 6bit,新增 sel=31/32/33:解出的会话号 / {槽号, ok, err} / 字数。核不查表、不取号、不拼字、不发第二条指令。
软硬接口。接话页挂在 0xF00(PK_IDX / GO / BUSY / DONE / OK / ERR / SID / SLOT / WORDS / BYTES / CNT / W0..W5 / RST / SCREEN30 / PK_CORE)。接话引擎是会话记忆区的第四个写主(gp > bg > ss > arc),但读表、写问候、换场严格串行——写问候在换场之前完成,绝不抢同一个内存写口。
单元仿真 tb_greet_pick:点 1/2/3 分别解出 0x91/0x92/0x93,槽号 0/1/2、字数 12/16/9,问候语 24 字节逐位对上、0x1F0 读回同一行,enter 脉冲带出的正是解出来的号;点 0 / 点 4(人数 3)/ 点到 sid=0 的空条目,一律 ok=0/err=1,不换场、不写问候;人数由清单表头说了算(改成 1 后点 2 就点不到);重复点同一场结果逐位一致。
协同仿真 tb_min_soc54:造三场 0x91/0x92/0x93(各跑一场不同 prompt 的对话再 leave 归档)→ 一条 npu.boot 恢复到 0x93、清单 3 场、问候 3 场 → 在 0x93 的上下文里跑整网得 Y93。
npu.pick 1:PK_SID=0x91 / PK_SLOT=0 / PK_WORDS>0 / PK_OK=1、SX_CUR=0x91 / SX_MEMOK=1,问候语换成「好,接着第一场。」;跑整网得 Y91 ≠ Y93——点的真是另一场;npu.pick 3:SX_CUR=0x93、问候换成「好,接着第三场。」、Y == Y93(换回来上下文一模一样);npu.pick 7(人数 3):PK_ERR=1 / PK_OK=0、SX_CUR 不动、SX_ENTER 不涨、不写问候——点不到不是崩溃;PK_CORE=0、SX_CORE 没涨:点一场,核一个入口寄存器都没写。主通路 SCREEN=0xF905FD04、SCREEN2~29 与第 25~53 环逐位一致——这一环只加了一条「接话」通路,计算面一个字没动。
开机第一句话不再只是「报出名单」,而是能接住用户的选择。对话窗口里说「先聊第二场」,硬件就查清单、取会话号、把那一场的上下文恢复回来,AI 开口就能接着上次的话题——这正是「开机只有一个 AI、一切服务从同一个窗口进出」里最日常的一步。
到这里,会话这条线已经闭环:存在(槽位)→ 记得(开机续聊)→ 说得清(清单)→ 说得出话(问候)→ 点得进去(接话)。
删掉一场。接话已经能进任何一场,可聊完的那场还占着槽位、还留在清单里。下一圈让「这场不用留了」也变成一条指令:释放槽位 → 清单少一条 → 开机问候跟着改口 → 再点原来那一号,落到下一场。