🎯 圆心 · 目标(每环都从这里出发)
造一台 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契约 → ㉘权重内存化 → ㉙权重预取双缓冲 → ㉚权重分块 → ㉛矩阵行块 → ㉜行块自增 → ㉝…

本环:块号交给硬件自己数——一次启动扫完整个矩阵

① 目标是什么

还是同一个圆心:一台开机只有一个 AI 的手机。上一环把块号做成「核可写的寄存器」,但跑法仍是软件驱动——4 块矩阵,核要写 4 次块号、发 4 次 RB_GO,还得自己记住下一个块号是几。
真 NPU 的一块权重有几百上千个行块,每块一次 MMIO = 核(软件)成了矩阵扫描的瓶颈。真做法是硬件自己数:给一次启动,引擎把块号自增着扫完整个矩阵,累加器一路长到最后一块,扫完才报 done。这一环把「核喂每块」升级成「核发一声、硬件扫完」。

② 怎么实现(不脱圆心)

· 自增开关:新增寄存器 0x3B4 RB_AUTO——写 1 = 块号由硬件自增;
· 一次启动扫完:auto_mode=1 时一条 RB_GO 即可,硬件把块号从 0 自增到 NB-1,每块照旧取权重 → 算部分积 → 累加进跨块 acc,中间不再要核发 start;最后一块算完才 busy=0 / done=1(软件只见「一次启动、一次完成」);
· 块计数探针:新增 blkcnt_out / 0x3B8 RB_BLKC = 自上次 RB_CLR 以来硬件真正处理过的块数(自增是否真扫完的硬证据);
· 只扩不推翻:auto_mode=0 = 第 31 环老语义(核写块号、核发每块 start),一个字没删,两条路径必须逐位一致;第 31 环的 RB_CLR 现在把块计数一并归零;
· 探针:0x3A0 RB_BLKO(自增停在的块号)、0x3B8 RB_BLKC(扫过块数)、0x3BC SCREEN7。前 31 圈地址映射一字不改。

③ 本环做了什么(真代码)

改 rtl/row_blk.sv(新增 auto_mode 输入 + blkcnt_out 探针 + ST_COMP 里的自增续跑),新增 tb/tb_row_blk32.sv(单元仿真);min_bus 挂 0x3B4 RB_AUTO / 0x3B8 RB_BLKC / 0x3BC SCREEN7 并新增第七观察点 screen7_out;circle32/gen_boot32.py 生成最小 OS(第 32 环试验段);tb/tb_min_soc32.sv 协同仿真。

// rtl/row_blk.sv(节选):一块算完,块号自己加 1,接着取下一块(不放手、不叫软件)
ST_COMP: begin
    for (n0 = 0; n0 < RB; n0 = n0 + 1) begin
        part_out[n0*ACC_W +: ACC_W] <= partial_c[n0];
        acc_out[(r0_i + n0)*ACC_W +: ACC_W] <=
            acc_out[(r0_i + n0)*ACC_W +: ACC_W] + partial_c[n0];
    end
    blkcnt_out <= blkcnt_r + 8'd1;            // 又处理完一块
    if (auto_r && more_blk) begin             // 还有块 → 自增续跑
        blk_r <= blk_r + 1'b1;                // 块号硬件自增
        rbase_out <= nxt_r0; cbase_out <= nxt_c0;
        f_i <= 2'd0;  st <= ST_FETCH;
    end else begin
        busy <= 1'b0; done <= 1'b1; st <= ST_IDLE;   // 扫完才放手
    end
end
④ 怎么算成(闭环验证)

测试矩阵 W = [1,2,-1,0 / 0,1,1,-2 / -1,0,2,1 / 2,-1,0,1]、x = [3,-2,5,-4],手算 y = W·x = [-6,11,3,4]。最小 OS 在芯片上真跑(整段只说了一次 start):

动作结果说明
RB_AUTO=1,一次 RB_GOacc = [-6, 11, 3, 4]== W·x(第 31 环这里要发 4 次 start)
读 RB_BLKC4硬件自己数到 4 块(探针)
读 RB_BLKO3块号加到 NB-1 才停
RB_AUTO=0 老路径(4 次 start)[-6, 11, 3, 4]两条路径逐位一致(递增不推翻)
RB_CLRacc=[0,0,0,0]、块计数 0累加器与块计数一起归零
SCREEN7 = 0x0403FA04
一次启动扫过 4 块 | 自增停的块号 3 | 整行 lane0 = 0xFA(-6) | 整行 lane3 = 4
前两字节 4|3 = 「一次启动、硬件自己数到底」的硬证据

单元仿真 tb_row_blk32 7 组用例通过(含自增途中逐块快照:acc 从 [-1,-2,0,0] → [-6,11,0,0] → 整行,全在同一次 start 之内;稀疏激活 x=[2,0,3,0] 逐 lane 对表);协同仿真 tb_min_soc32:SCREEN = 0xF905FD04、SCREEN2 = 0x02040404、SCREEN3 = 0x04000204、SCREEN4 = 0x10200707、SCREEN5 = 0x04081807、SCREEN6 = 0x0402FFFA 与第 31 环逐位一致(本环只给行块引擎加了个自增开关,主通路一个字没动);采样序列 [0,2,0,0,0,3]、第 6 步吐停止符 3 而停。全量回归 49 项全绿。

⑤ 回到目标(这环让目标前进了多少)

从「核一块块喂」走到「硬件自己数块号、一次启动扫完整个矩阵」——这正是软件与 NPU 的分工线:核只需要说「算这个矩阵」,剩下几百上千个行块由硬件流式走完,核不必为每块再插一笔 MMIO。芯片离「跑真 DeepSeek 权重」又近一层:层的权重再大,也只是硬件自己一块块数过去、累加器一格格长起来。