QSPI / APB SPI Master — 功能 Spec 与验证 Testplan(详细版)
工程路径:/project/SOC_V1.1/To_Customer/QSPI/
DUT 顶层:apb_spi_master(rtl/qspi/apb_spi_master.v)
关联:IP验证环境资料.md
第一部分:功能 Spec
1. 概述
1.1 功能定义
本 IP 为 APB 从接口的 SPI/QSPI 主控制器,软件通过 寄存器 + TX/RX FIFO 组织一次 Flash 类访问:
- 配置 命令长度、地址长度、数据长度、Dummy 周期、时钟分频、片选。
- 写 SPI_CMD / SPI_ADR / TXFIFO。
- 写 SPI_CTRL 触发 RD/WR/QRD/QWR 之一。
- 轮询 SPI_STATUS 等待完成(本验证环境轮询 bit[5])。
- 读 RXFIFO 取回数据。
支持 标准 SPI 与 Quad SPI(四线 TX/RX),具体由 QWR/QRD 与 spi_mode 决定。
1.2 模块层次
apb_spi_master
├── spi_master_apb_if # APB 寄存器译码
├── spi_master_fifo # TX/RX FIFO(深度 BUFFER_DEPTH=10)
├── spi_master_controller # 主状态机:CMD→ADDR→DUMMY→DATA
├── spi_master_clkgen # 可编程 SCK
├── spi_master_tx / rx # 位移/采样
└── (片选 spi_csn0~3)
TB 额外例化:qspi_device(行为 Flash 从机)。
1.3 关键参数
| 参数 |
值 |
说明 |
BUFFER_DEPTH |
10 |
FIFO 深度 |
APB_ADDR_WIDTH |
12 |
4KB 地址空间 |
LOG_BUFFER_DEPTH |
3 |
log2(10) |
2. APB 接口 Spec
2.1 信号
| 信号 |
方向 |
说明 |
HCLK |
in |
APB 时钟 |
HRESETn |
in |
低有效复位 |
PADDR[11:0] |
in |
字节地址;寄存器译码用 PADDR[5:2] |
PWDATA[31:0] |
in |
写数据 |
PWRITE |
in |
1=写 |
PSEL / PENABLE |
in |
APB 选通 |
PRDATA[31:0] |
out |
读数据 |
PREADY |
out |
恒 1(零等待) |
PSLVERR |
out |
恒 0 |
events_o |
out |
中断事件(接 TB interrupt) |
2.2 寄存器地址映射
APB 字地址 = {PADDR[5:2], 2'b00},与 spi_master_apb_if.v 中 `REG_* 一致:
| 地址偏移 |
宏名 |
寄存器名 |
写行为摘要 |
读行为 |
0x00 |
REG_CTRL |
SPI_CTRL |
见 3.1 |
— |
0x04 |
REG_STATUS |
SPI_STATUS |
— |
组合状态 |
0x08 |
REG_CLKDIV |
SPI_CLKDIV |
加载分频 + valid 脉冲 |
返回 spi_clk_div |
0x0C |
REG_SPICMD |
SPI_CMD |
锁存命令字 |
读回 |
0x10 |
REG_SPIADR |
SPI_ADR |
锁存地址 |
读回 |
0x14 |
REG_SPILEN |
SPI_LEN |
cmd/addr/data 长度 |
读回拼接 |
0x18 |
REG_SPIDUM |
SPI_DUM |
dummy_rd/wr |
读回 |
0x1C |
REG_TXFIFO |
SPI_TXFIFO |
推入 TX FIFO |
— |
0x20 |
REG_RXFIFO |
SPI_RXFIFO |
— |
弹出 RX |
0x24 |
REG_INTCFG |
SPI_INTCFG |
中断阈值/使能 |
读回 |
0x28 |
REG_INTSTA |
SPI_INTSTA |
— |
中断状态 |
3. 寄存器位域 Spec
3.1 SPI_CTRL @ 0x00(写触发)
| 位 |
名 |
访问 |
描述 |
| 0 |
RD |
WO |
置 1 启动 标准读 事务 |
| 1 |
WR |
WO |
置 1 启动 标准写 |
| 2 |
QRD |
WO |
置 1 启动 Quad 读 |
| 3 |
QWR |
WO |
置 1 启动 Quad 写 |
| 4 |
SRST |
WO |
软复位(清空/中止相关状态) |
| 11:8 |
CS |
WO |
片选编码 spi_csreg |
| 31:12 |
— |
— |
未用 |
注意:写 CTRL 时 RD/WR/QRD/QWR 为脉冲;同一写可同时置 QWR 等。验证常用:
0xF08 = QWR + CS(Quad Page Program 类)
0xF04 = QRD(Quad Read)
0xF10 = SRST(软复位)
3.2 SPI_STATUS @ 0x04(读)
spi_status 由 apb_spi_master 拼装:
spi_status = { FILL, elements_tx[LOG:0], FILL, elements_rx[LOG:0], 9'h0, spi_ctrl_status[6:0] }
| 域 |
来源 |
说明 |
[6:0] |
spi_master_controller.spi_status |
控制器状态位(见 3.5) |
| TX/RX elems |
FIFO 计数 |
当前 FIFO 元素个数 |
| 上层填充 |
FILL_BITS |
对齐 32bit |
验证环境轮询:while (rdata[5:0] != 1) —— 即等待 bit5=1(控制器报告 传输完成/空闲 类状态,与 IDLE 态 spi_status[5] 相关,见 controller WAIT/结束态)。
3.3 SPI_CLKDIV @ 0x08
| 位 |
名 |
说明 |
| 7:0 |
CLKDIV |
SCK 分频系数;写同时产生 spi_clk_div_valid |
3.4 SPI_LEN @ 0x14
| 位 |
名 |
宽 |
说明 |
| 5:0 |
CMDLEN |
6 |
命令阶段 bit 数 |
| 13:8 |
ADDRLEN |
6 |
地址阶段 bit 数 |
| 31:16 |
DATALEN |
16 |
数据阶段 bit 数 |
示例(qspi_read_sequence):0x00201010 → CMDLEN=0x10,ADDRLEN=0x10,DATALEN=0x20。
3.5 SPI_DUM @ 0x18
| 位 |
名 |
说明 |
| 15:0 |
DUMMYRD |
读前置 dummy 周期数 |
| 31:16 |
DUMMYWR |
写前置 dummy 周期数 |
Quad 模式下 dummy 计数在 controller 内可能 ×4 对齐(见 spi_dummy_rd 与 en_quad)。
3.6 SPI_INTCFG / SPI_INTSTA @ 0x24 / 0x28
| 寄存器 |
位 |
说明 |
| INTCFG |
4:0 TXTH |
TX FIFO 低于阈值触发中断 |
| INTCFG |
12:8 RXTH |
RX 阈值 |
| INTCFG |
31 EN |
中断总使能 |
| INTSTA |
0 TXINT |
写 1 清 TX 中断 |
| INTSTA |
1 RXINT |
写 1 清 RX 中断 |
events_o 在 TB 中接 qspi_vif.interrupt。
4. 控制器状态机 Spec
4.1 状态列表(spi_master_controller.v)
| 状态 |
值 |
含义 |
| IDLE |
0 |
空闲;spi_status[0]=1 |
| CMD |
1 |
发送命令;spi_status[1]=1 |
| ADDR |
2 |
发送地址 |
| MODE |
3 |
模式切换 |
| DUMMY |
4 |
Dummy 周期 |
| DATA_TX |
5 |
发送数据 |
| DATA_RX |
6 |
接收数据 |
| WAIT_EDGE |
7 |
等待边沿 |
4.2 事务启动条件(IDLE)
当 SPI_CTRL 写使能 spi_rd | spi_wr | spi_qrd | spi_qwr:
- 拉低
spi_cs,使能 spi_clock_en。
- 若
spi_cmd_len != 0 → 进入 CMD,发 spi_cmd。
- 否则若
spi_addr_len != 0 → ADDR。
- 否则若
spi_data_len != 0 → 根据 RD/WR 进入 DUMMY 或 DATA_TX/RX。
4.3 SPI 模式
| 模式 |
编码 |
条件 |
| SPI_STD |
2'b00 |
标准单线 |
| SPI_QUAD_TX |
2'b01 |
spi_qwr 或 quad 写 |
| SPI_QUAD_RX |
2'b10 |
spi_qrd 或 quad 读 |
4.4 结束
eot 脉冲表示事务结束。
- 返回 IDLE 时
spi_status[5]=1(验证轮询用)。
5. 物理接口 Spec
| 信号 |
说明 |
spi_clk |
主机时钟输出 |
spi_csn0~3 |
片选,低有效 |
spi_sdo0~3 |
主机输出 |
spi_sdi0~3 |
主机输入 |
spi_oe0~3 |
输出使能(Quad 时) |
TB qspi_device 与 DUT 交叉连接(DUT SDO → Device SDI)。
6. 行为从机 qspi_device Spec
6.1 支持命令(16bit 命令宽)
| 命令值 |
宏 |
行为 |
0x6 |
WRITE_ENABLE |
写使能 |
0x4 |
WRITE_DISABLE |
写禁止 |
0x3 |
READ_DATA |
读数据 |
0x2 |
PAGE_PROGRAMMING |
页编程 |
6.2 参数(interface 可配)
| 参数 |
默认 |
说明 |
command_width |
16 |
命令位数 |
addr_width |
16 |
地址位数 |
data_width |
32 |
数据位数 |
wdata_addr_dummy / rdata_addr_dummy |
sequence 设置 |
与 SPI_DUM 对应 |
6.3 内部 FSM
IDLE → COMMAND → ADDR → WDATA/RDATA_DUMMY → RDATA,与主机 controller 配合完成 Page Program + Read。
7. 典型软件操作序列(Spec 级)
7.1 Quad Page Program + Read(与 qspi_read_sequence 一致)
写 Flash:
| 顺序 |
寄存器 |
典型值 |
含义 |
| 1 |
SPI_CMD |
0x00020000 |
命令域(Page Program 类) |
| 2 |
SPI_ADR |
random addr |
目标地址 |
| 3 |
SPI_TXFIFO |
0x12345678 |
写数据 |
| 4 |
SPI_LEN |
0x00201010 |
长度 |
| 5 |
SPI_DUM |
0x00080008 |
dummy |
| 6 |
SPI_CTRL |
0xF08 |
QWR 启动 |
| 7 |
SPI_STATUS |
poll |
直到 [5:0]==1 |
读 Flash:
| 顺序 |
寄存器 |
典型值 |
| 1 |
SPI_CMD |
0x00030000 |
| 2 |
SPI_ADR |
同上地址 |
| 3 |
SPI_LEN |
0x00201010 |
| 4 |
SPI_CTRL |
0xF04 |
| 5 |
SPI_STATUS |
poll |
| 6 |
SPI_RXFIFO |
read data |
第二部分:验证 Testplan
8. 验证目标
| # |
目标 |
| 1 |
所有 APB 寄存器可读写且与 RAL 一致 |
| 2 |
Quad 读写事务与 qspi_device 数据一致 |
| 3 |
CLKDIV、LEN、DUM、中断、软复位行为符合 RTL |
| 4 |
异常长度不导致挂死(或符合设计预期) |
9. 验证环境组件(摘要)
| 组件 |
职责 |
apb_agent |
APB 事务 |
ral_block_qspi + reg_adapter |
寄存器模型 |
qspi_scoreboard |
跟踪寄存器写、FIFO、device 存储 |
qspi_device |
从机 |
10. 需求 — 用例跟踪
| Req ID |
需求 |
Case |
优先级 |
| QSPI-R001 |
寄存器读写 |
QSPI-T01 |
P0 |
| QSPI-R002 |
读回数据正确 |
QSPI-T02 |
P0 |
| QSPI-R003 |
时钟分频可切换 |
QSPI-T03 |
P1 |
| QSPI-R004 |
可变 cmd/addr/data 长度 |
QSPI-T04 |
P1 |
| QSPI-R005 |
Dummy 周期生效 |
QSPI-T05 |
P1 |
| QSPI-R006 |
中断阈值 |
QSPI-T06 |
P1 |
| QSPI-R007 |
软复位清 FIFO |
QSPI-T07 |
P1 |
| QSPI-R008 |
短/异常长度 |
QSPI-T08 |
P2 |
11. 测试用例详细说明
QSPI-T01 — qspi_reg_rw_test
| 项 |
内容 |
| 类 |
qspi_reg_rw_test / qspi_reg_rw_sequence |
| 步骤 |
1. get_registers 2. 对每个 reg write(random) 3. read 回读 |
| 特殊 |
SPI_STATUS、SPI_TXFIFO、SPI_RXFIFO 关闭 read check |
| 通过 |
0 RAL mismatch error |
| 覆盖 |
所有寄存器地址译码 |
QSPI-T02 — qspi_read_test
| 项 |
内容 |
| 目的 |
端到端 Quad 写 + Quad 读 |
| 步骤 |
见第 7.1 节表;sequence 中固定数值 |
| 检查 |
SB + log 打印 Get read data |
| 通过 |
0 UVM_ERROR;读回数据与 device 一致 |
QSPI-T03 — qspi_clk_test
| 项 |
内容 |
| 目的 |
运行中改变 CLKDIV 仍完成事务 |
| 步骤 |
1. 写随机 CLKDIV 2. 完成一次写 3. 再次 写随机 CLKDIV 4. 完成读 |
| 通过 |
两次 poll STATUS 均成功 |
QSPI-T04 — qspi_data_length_test
| 项 |
内容 |
| 随机 |
data_length∈[4:128] 且 [2:0]==0;addr/cmd length 4~32 且 4 对齐 |
| 配置 |
qspi_vif.addr_width/data_width/command_width 与 SPI_LEN 一致 |
| 数据 |
写 6 笔 TXFIFO 后启动 |
| 通过 |
读回完成且无 SB error |
QSPI-T05 — qspi_dummy_test
| 项 |
内容 |
| 随机 |
dummy_write/read ∈ [4:128] |
| 配置 |
qspi_vif.wdata_addr_dummy、rdata_addr_dummy |
| 步骤 |
写 SPI_DUM= {dummy_wr, dummy_rd},再标准写读 |
| 通过 |
0 error;波形可见 dummy 相位 |
QSPI-T06 — qspi_interrupt_test
| 项 |
内容 |
| 随机 |
TXTH∈[1:6],RXTH∈[1:4] |
| 步骤 |
写 INTCFG(EN=1);灌多笔 TX;检查 interrupt |
| 规则 |
TXTH<5 时不应过早中断,否则 uvm_error |
| 通过 |
中断行为与阈值一致 |
QSPI-T07 — qspi_soft_reset_test
| 项 |
内容 |
| 步骤 |
写事务中途/后写 SPI_CTRL=0xF10(SRST);再写 TXFIFO 0x55aaaa55;poll;再读 |
| 目的 |
FIFO/状态机恢复;SB 中 qspi_tx_fifo 清空逻辑 |
| 通过 |
后续读回仍正确 |
QSPI-T08 — qspi_abnormal_length_test
| 项 |
内容 |
| 随机 |
data/addr/cmd length ∈ [0:16] 且 4 对齐 |
| 目的 |
边界/短包不挂死 |
| 通过 |
仿真结束;记录是否预期 error(课程定义) |
12. Scoreboard 检查点(摘要)
| 事件 |
SB 行为 |
| APB 写 CTRL 启动 Page Program |
从 TX FIFO 弹出数据写入 device_data[addr] |
| 写 SRST |
清 FIFO、清零 pending 区域 |
| 写 TXFIFO |
push qspi_tx_fifo |
| SPI monitor 事务 |
与 device_data 比对 |
13. 回归列表与命令
cd /project/SOC_V1.1/To_Customer/QSPI/sim
make comp
make run_qspi_reg_rw_test
make run_qspi_read_test
make run_qspi_clk_test
make run_qspi_data_length_test
make run_qspi_dummy_test
make run_qspi_interrupt_test
make run_qspi_soft_reset_test
make run_qspi_abnormal_length_test
注意:勿 make run(TEST=qspi_test 类不存在)。
14. 覆盖率与出口准则
| 类型 |
目标 |
| 状态机 |
CMD/ADDR/DUMMY/DATA_TX/RX 均到达 |
| 寄存器 |
所有 REG_* 写读 |
| 交叉 |
QWR+QRD、不同 LEN、SRST 打断 |
| 出口 |
上表 8 个用例 0 UVM_ERROR |
15. 与 SoC 关系
- RTL 与
soc/ip/apb_subsystem/rtl/qspi 同源。
- SoC C 测试通过
0x20000000 基址访问(见 uart_test.c / soc_dma_test.c)。
- 片级 SPI pad 在
soc/test/test.v 映射,与 IP 台纯总线环回不同,集成时需对照波形。