# 02 模块详解

下面按“输入先经过什么、结果再交给什么”的顺序讲模块。括号中的文件名是源码入口，方便对照，但读者不需要一次读懂全部 SystemVerilog。

## A. 输入与模型准备

| 模块 | 输入 | 输出 | 作用 |
|---|---|---|---|
| Camera bridge | DVP 的 D[7:0]、PCLK、HREF、VSYNC | RGB888 或 A8 stream | 接摄像头、解码 YUV/RGB565、缩放到 512、加 letterbox，并把不可 backpressure 的 DVP 变成可控的 FIFO 流。 |
| ONNX inspector | 固定 ONNX 文件 | model contract | 检查输入是 `[1,3,512,512]`、输出是 `[1,300,6]`，并校验 SHA-256。 |
| Graph manifest | ONNX 图 | nodes/tensors/partition | 记录 384 个节点、629 个 tensor，以及 M0-M23 到 D0-D3 的逻辑归属。 |
| Calibration compiler | 代表性图像 | scale、mult、shift、LUT | 统计 activation 范围并生成 W8A8 的缩放参数。当前烟雾校准样本不足以签核部署精度。 |

## B. SRAM、DMA 与窗口

| 模块 | 作用 | 为什么重要 |
|---|---|---|
| `banked_tensor_sram.sv` | 把 HWC16 数据分到 16 个 bank，检查一周期访问是否冲突。 | 同一块 SRAM 不能在一个周期无限读；bank 设计决定计算阵列能否持续供数。 |
| `tensor_sram_dma_writer.sv` | 把经过 descriptor 和范围检查的 packet payload 写入本地 SRAM。 | 防止越界、未对齐地址或已经 abort 的 frame 继续写入。 |
| line buffer / window | 保存卷积所需的相邻行和滑动窗口。 | 3x3 卷积只需要附近几行，不必把整张 feature map 复制成 im2col。 |
| descriptor bank | 保存 tensor 的 shape、地址、scale、owner 和 lifetime。 | packet 只有 tensor_id 和 offset，还需要 descriptor 才能知道它该落在哪里。 |

## C. D2D 传输模块

| 模块 | 功能 | 初学者类比 |
|---|---|---|
| `d2d_header_codec.sv` | 打包/解包 128-bit header，计算 CRC8。 | 快递单的地址栏和校验码。 |
| `d2d_trailer_codec.sv` | 标记 packet 结束，计算 CRC16。 | 快递封条。 |
| `d2d_crc32c_stream/wide.sv` | 检查 payload 是否在传输中被改动；stream 每周期 1 byte，wide 每周期 16 byte。 | 对包裹内容做指纹。 |
| `d2d_header_router.sv` | 本地复制或转发，减少 hop，执行 VC1 dateline 规则。 | 交换机决定包走哪条线。 |
| `d2d_credit_manager.sv` | 统计接收端还有多少 packet slot。 | 传送带下游满了，上游就暂停。 |
| `d2d_vc_slot_allocator.sv` | 为 VC、slot、frame、epoch 分配和回收所有权。 | 给每个货箱一个不会重复的编号。 |
| `d2d_async_fifo.sv` | 用 Gray pointer 跨异步时钟域传数据。 | 两个不同步的工位之间的缓冲区。 |
| `d2d_rx_endpoint.sv` | 收包、做 descriptor/范围/序号/CRC 检查，验证通过后才 commit。 | 质检通过后才入库。 |
| `d2d_recovery_watchdog.sv` | frame 超时后发出 abort、清理和有限 retrain 请求。 | 发现流水线卡死时重启当前工单。 |

## D. 调度与帧生命周期

| 模块 | 功能 |
|---|---|
| `frame_context_manager.sv` | 最多接纳四个 frame context，记录 producer/consumer、active、completed、aborted 和 release。 |
| `local_micro_op_scheduler.sv` | 从不可变的 UOP RAM 中读取操作，等待 tensor/band 依赖、compute token、DMA token 和 D2D token 都满足后发射。 |
| `frame_event_arbiter.sv` | 合并计算完成、D2D 到达、释放、abort 等事件，避免多个来源同时修改状态。 |
| `tensor_descriptor_bank.sv` | active/shadow 双 bank；运行中使用 active，配置只写 shadow，在 quiescent 边界交换。 |

一个简单的 frame 生命周期是：`ADMIT -> LOAD/RECEIVE -> ISSUE -> COMPUTE/DMA/D2D -> COMPLETE -> RELEASE`。如果 CRC、超时或范围失败，则走 `ABORT -> CLEANUP -> RELEASE`，不应把坏 frame 留在 active 状态。

## E. 计算核心

| 模块 | 功能 |
|---|---|
| `conv_w8a8_banked_engine.sv` | 从 16-bank activation SRAM 取 HWC16 数据，每周期组织权重和输入，执行 W8×A8 累加，再做 bias/requant。 |
| `depthwise_conv_w8a8_pixel.sv` | 每个输入通道独立卷积，复用窗口但不做跨通道求和。 |
| `per_channel_requant.sv` | 把 INT32 accumulator 按 scale 乘法和右移变回 A8，并饱和到 int8 范围。 |
| `psa_tile_scheduler.sv` | 按 query/key/value tile 推进 PSA，处理 backpressure、依赖和 frame-local abort。 |
| `psa_qkvo_sram_adapter.sv` | 将 Q/K/V/O 的 workspace 绑定到 banked SRAM 的固定 bank 角色。 |
| `d3_e2e_tail_stream.sv` | D3 逐行接收候选，解码 box/class，并把通过筛选的候选写入 replay store。 |
| `e2e_two_stage_topk.sv` | 先做局部候选，再合并成 Top-300，避免保存完整 5376x80 score matrix。 |

## F. 验证环境

每个模块通常有三类文件：可综合 RTL、`tb_*.sv` 测试平台、`run_*_regression.ps1` 回归脚本。Python 工具负责模型检查、向量生成、量化和容量审计；Vivado XSim 负责时钟级 RTL 行为。

“XSim passed”只表示该模块在列出的测试条件下通过，不表示它已经连接上所有算子、真实 PHY 或板级 DDR/无 DDR 系统。
