阶段六: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 答案。

先写预测,再留下自己的解释

本讲包含 2 课。展开对应课程,保存个人状态和笔记。

23:先冻结可以验证的规格记录
阅读本课 →

输入后自动保存在此浏览器。能独立解释并完成课程验收,再标记“已验收”。

24:用证据完成设计评审记录
阅读本课 →

输入后自动保存在此浏览器。能独立解释并完成课程验收,再标记“已验收”。