阶段六:SPI 模拟配置控制器(23–24)
这是待实现的结课项目规格,不是现有 Master 的功能,也不是已运行的参考设计。目标:通过 SPI 写入 12 位模拟码字和使能位,在指定安全窗口原子生效,并可读回状态。
23:先冻结可以验证的规格
架构与输入假设
首版选择过采样 Slave:系统 clk=50 MHz,全部功能寄存器由 clk 驱动。外部 SCLK、CS、MOSI 经同步、事件检测与稳定窗口分析,形成串行前端;寄存器层和更新控制层位于同一 clk 域。SCLK 域 + mailbox 是进阶替代实验,不混用两套约束。
外部接口 Mode 0、MSB first、一个从设备,每帧 24 个 SCLK 周期,最大 1 MHz。高、低电平各至少 500 ns;CS 拉低到首个上升沿、末个下降沿到 CS 释放各至少 200 ns;两帧 CS 高间隔至少 200 ns。MOSI 在每个外部上升沿前后至少 100 ns 稳定。safe_update 来自 clk 域。
这些窗口是本实验明确提出的源端约束,需要主机遵守,不宣称适用于任意 SPI 器件。典型两级同步加检测可能用数个 clk 周期;实现者必须推导 RTL 的最大检测/更新延迟,确认在 100 ns 教学预算内,并证明 MOSI 相对检测沿稳定。若实际结构超出预算,调整架构或规格并重新验证。
MISO 的本位必须在主机采样上升沿前至少 100 ns 有效,并在之后至少 100 ns 保持。下一位在检测到外部下降沿后准备,输出传播延迟也计入预算。CS 高时单从设备 MISO 返回 0,允许去选中检测与输出传播时间,不使用它驱动多从设备共用总线;多从设备的三态/OE 交接需要另写规格。
复位 rst_n 同步低有效,低覆盖至少一个 clk 上升沿。复位中止串行帧和 pending 更新,active_code=0、active_enable=0,所有状态清零,不产生应用完成脉冲。
串行帧格式
| 字节 | MOSI | MISO |
|---|---|---|
| 0 | bit7=W,bit6:0=地址;W=1 写,W=0 读 | 固定 00 |
| 1 | 写数据[15:8];读操作为 00 | 读快照[15:8];写为 00 |
| 2 | 写数据[7:0];读操作为 00 | 读快照[7:0];写为 00 |
读快照在内部确认第八个采样事件并解析读命令时一次性获取,之后这一帧不受 active/status 变化影响。第一个响应数据位必须在第九个外部上升沿之前满足预算。不要等到第九个上升沿才开始准备。
解析命令时仅保存快照,MISO 保持命令字节的末位 0;检测到第八个下降事件后才驱动快照 bit15,后续数据位也在下降事件后更新,保证命令最后一个采样沿的 hold。非法地址读返回 0000,并在帧结束时报告错误;读帧的两个 MOSI 占位字节必须为 00,否则也视为错误帧。
同一个 clk 边沿若刚好发生 active 更新,读快照按边沿之前的寄存器值获取。读数据的“新鲜度”因此有精确定义。
写操作只在检测 CS 释放后且该帧恰好为 24 个有效采样沿、地址和数据合法时接受。移位期间没有寄存器写副作用。短帧、长帧、非法地址/访问、保留位非零设 frame_error,原配置保持。长帧不能让计数器回绕成合法长度;使用饱和计数或额外 overflow 标志。
读数据会在帧未结束时发送,接收方只将正确长度和边界的帧作为有效结果。读没有清状态等副作用。复位中止帧不额外置 frame_error。
地址与访问语义
所有数据 16 位,高位未定义部分写入必须为 0,读取为 0。
| 地址 | 名称 | 属性 | 有效位/含义 | 复位 |
|---|---|---|---|---|
| 00 | SHADOW_CODE | RW | [11:0] 码字 | 0 |
| 01 | SHADOW_ENABLE | RW | [0] 使能 | 0 |
| 02 | COMMIT | W1P,读 0 | [0]=1 提交当前影子快照;0 无操作 | 0 |
| 03 | ACTIVE_CODE | RO | [11:0] 当前有效码字 | 0 |
| 04 | ACTIVE_ENABLE | RO | [0] 当前有效使能 | 0 |
| 05 | STATUS | RO | [0] pending,[1] busy_reject,[2] frame_error | 0 |
| 06 | CLEAR_STATUS | W1C,读 0 | [1] 清 busy_reject,[2] 清 frame_error | 0 |
写 RO 或不存在的地址视为 frame_error。CLEAR_STATUS 的 bit0 和其他位保留;STATUS 的 pending 不可软件清除。新错误与清除同周期时新错误优先。
提交与应用
pending=0 时 COMMIT=1 被接受,将 shadow_code 和 shadow_enable 同时复制到 pending 快照。pending=1 时再次 commit 被拒绝,置 busy_reject;原 pending 快照保持。shadow 仍可读写,为下一次提交准备。
safe_update=1 且边沿之前 pending=1 时,active 字段一次性更新,pending 清零,applied 脉冲高一个 clk 周期。刚接受 commit 的同一个边沿不立即应用,即使 safe_update=1,也从下一 clk 边沿开始判断。若旧 pending 同周期应用而又收到 commit,仍按旧 pending=1 拒绝新提交,行为确定但不追求最满吞吐。
applied 表示数字 active 更新,模拟电路的最终稳定还要满足自身 settling 要求。没有 safe_update 时允许一直 pending,由上层决定超时策略,不在本模块隐式放行。
示例交易
MOSI 80 0A BC:shadow_code = 0xABC
MOSI 81 00 01:shadow_enable = 1
MOSI 82 00 01:提交,pending = 1
safe_update 的有效 clk 边沿:active = {enable=1, code=0xABC}
MOSI 03 00 00:读 ACTIVE_CODE,MISO = 00 0A BC
先提交 0xABC,再把 shadow 改成 0x123,最后允许 safe_update:这次 active 仍应是 0xABC,不能引用已经改变的 shadow。
练习与验收
分模块实现 spi_frontend、register_bank、config_apply,在独立后续实验目录保存 RTL、testbench、约束和运行脚本。先写模块接口和接受条件,再写代码。保持原 Master 工程和验证契约。
验收测试至少包括:合法读写;所有合法地址;RO/非法/保留位访问;0、1、23、24、25 个采样沿的帧;CS setup/hold 和时钟最小宽度;MOSI/CS/SCLK 相位扫动;pending 中 commit;pending 中 shadow 改写;safe_update 缺失/持续高;commit 与应用同周期;读取快照期间 active 变化;所有阶段复位及恢复;单周期 applied;sticky 清除与新事件并发。
参考模型根据完整 SPI 事务和规格更新寄存器,不复制 DUT 的移位/计数实现。逻辑验证通过后,给出同步输入、输出 MISO、内部寄存器和复位的约束依据;不会因为所有功能寄存器共用 clk 就略去异步接口分析。
24:用证据完成设计评审
目标和讲解
交付需要能让另一个工程师独立判断功能、时序和接口边界,而不是只有一张 PASS 截图。评审顺序:规格是否完整;实现是否符合规格;验证是否覆盖风险;约束是否有来源;报告是否确实分析了目标场景。
证据包包括:版本化规格和地址表、时钟/复位架构图、RTL 和运行脚本、覆盖矩阵、失败和修复记录、实际仿真结果、映射网表和结构检查、时序约束假设、关键路径解释、未完成项。生成报告与波形放在 Git 忽略的 results 中,提交可复现的源文件和摘要。
先将当前 Master testbench 的独立 slave 验证思路迁移到此项目。随后可做 Master→Slave 集成,但不能用两个 DUT 互相通过作为唯一证明;双方若共享相同位序或时序错误,集成测试可能掩盖问题。
自评每项 0–2 分:0=无法解释/无证据,1=能解释但证据不全,2=解释和证据相符。
| 项目 | 达到 2 分的要求 |
|---|---|
| RTL 电路对应 | 能说明存储、选择、计数和输出结构 |
| 接口规格 | 接受、拒绝、有效窗口与异常行为明确 |
| 验证 | 独立参考、边界覆盖、故障能被发现 |
| 时序约束 | max/min 与物理来源一致,无任意放宽 |
| 配置一致性 | pending 快照和 active 更新可证明 |
| 复位/恢复 | 无假完成、假事务和残留 busy |
| 数模交界 | 定义瞬态、稳定窗口和模拟生效范围 |
| 可复现性 | 源文件、版本、命令与结果可对应 |
满分 16。建议达到 13 分且接口、验证、时序、配置一致性没有 0 分,再增加新功能。这个评分用于学习,不代替工程签核。
练习与验收
做一次自我设计评审:挑一条最可能出错的序列,说明规格、RTL、testbench 和时序假设如何共同覆盖它。若具备物理数据,再附布线后 setup/hold、多角和相应物理检查;否则明确“仅到 RTL/逻辑综合”。参考见 23–24 答案。