13 KiB
13 KiB
CSI040 控制模块 Datasheet
1. 概述
csi040_ctrl 是用于控制 CSI040 ASIC 的 PL 侧控制模块。模块对上层软件暴露一组 32 bit BRAM 风格寄存器,并把软件写寄存器的动作转换为 CSI040 SPI 总线访问。
该模块主要完成:
- CSI040 ASIC 控制寄存器写入
- 16 通道 enable 配置
- 单通道参数寄存器写入
- DCS/Test 模式 key 序列写入
- Direct SPI 读写
- ASIC reset/trigger 引脚直接控制
- SPI busy/done/error 状态反馈
相关 RTL 文件:
c64_pro.srcs/sources_1/rtl/csi040/csi040_ctrl.vc64_pro.srcs/sources_1/rtl/csi040/csi040_spi_master.vc64_pro.srcs/sources_1/rtl/csi040/csi040_ctrl_tb.v
2. 模块框图
+------------------------------+
BRAM register | | SPI command
access -------->| csi040_ctrl |----------------+
| | |
| register map / shadow regs | v
| sequence engine | +--------------------+
| busy/done/error status | | csi040_spi_master |
+------------------------------+ +---------+----------+
| | |
| | direct pins | SPI pins
v v v
asic_rst_n asic_trig asic_csn/asic_sck/asic_si/asic_so
3. 主要特性
| 项目 | 规格 |
|---|---|
| 软件接口 | 32 bit BRAM 风格寄存器接口 |
| BRAM 地址宽度 | 13 bit |
| 支持写类型 | 仅支持 bram_we == 4'hF 的整字写 |
| 支持读类型 | bram_en == 1 且 bram_we == 4'h0 |
| ASIC 地址宽度 | 默认 16 bit |
| SPI 地址字节数 | 默认 2 byte |
| Direct SPI 最大 payload | 默认 4 byte,由 MAX_BURST_BYTES 决定 |
| SPI SCK 极性 | idle low |
| SPI CSN 极性 | active low |
| SPI 输出位序 | opcode/address/data 均 MSB first 按帧发送;payload byte0 来自低 8 bit |
| 忙保护 | 忙时写命令寄存器不会启动新命令,并置位 error_busy |
| 复位 | rst_n 异步低有效 |
4. 参数
4.1 csi040_ctrl 参数
| 参数 | 默认值 | 说明 |
|---|---|---|
VERSION |
32'h04040001 |
模块版本号,读 0x0000 返回 |
SPI_CLK_DIV |
50 |
SPI SCK 半周期分频,f_sck = f_clk / (2 * SPI_CLK_DIV) |
REG_ADDR_WIDTH |
16 |
ASIC 寄存器地址宽度 |
SPI_ADDR_BYTES |
2 |
SPI 帧中地址字段字节数 |
MAX_BURST_BYTES |
4 |
Direct SPI 最大 payload 字节数 |
SPI_OPCODE_WRITE |
8'h00 |
SPI 写 opcode |
SPI_OPCODE_READ |
8'h80 |
SPI 读 opcode |
CSI_REG_CONTROL |
16'h0002 |
CSI040 control register 地址 |
CSI_REG_CH_ENABLE1 |
16'h0007 |
channel 0-7 enable 地址 |
CSI_REG_CH_ENABLE2 |
16'h0008 |
channel 8-15 enable 地址 |
CSI_REG_TEST_DCS_KEY |
16'h0009 |
DCS/Test key register 地址 |
CSI_CH_BASE |
16'h0010 |
通道寄存器基地址 |
CSI_CH_STRIDE |
16'h0010 |
通道寄存器地址步进 |
CSI_REG_STIM_TRIGGER |
16'h0110 |
stimulation trigger register 地址 |
CSI_REG_PART_ID |
16'h011D |
part ID register 地址 |
CSI_REG_REVISION |
16'h011E |
revision register 地址 |
4.2 MAX_BURST_BYTES 说明
MAX_BURST_BYTES 同时影响以下信号宽度和行为:
| 位置 | 影响 |
|---|---|
spi_cmd_wdata |
宽度为 8 * MAX_BURST_BYTES |
spi_cmd_rdata |
宽度为 8 * MAX_BURST_BYTES |
| SPI master 内部 frame | 最大帧长为 8 * (1 + SPI_ADDR_BYTES + MAX_BURST_BYTES) |
| Direct SPI 长度 | SPI_CTRL[15:8] 超过 MAX_BURST_BYTES 时会被截断 |
高层命令序列目前都只发 1 byte payload;MAX_BURST_BYTES 主要服务于 Direct SPI burst 访问。
5. 端口说明
5.1 时钟复位
| 信号 | 方向 | 位宽 | 说明 |
|---|---|---|---|
clk |
input | 1 | 主时钟,模块内部逻辑均使用此时钟 |
rst_n |
input | 1 | 异步低有效复位 |
bram_clk |
input | 1 | 当前 RTL 未使用,保留接口 |
bram_rst |
input | 1 | 当前 RTL 未使用,保留接口 |
注意:当前实现中 bram_clk/bram_rst 未参与逻辑,BRAM 访问必须与 clk 同步。
5.2 BRAM 寄存器接口
| 信号 | 方向 | 位宽 | 说明 |
|---|---|---|---|
bram_addr |
input | 13 | BRAM 字节地址 |
bram_din |
input | 32 | 写数据 |
bram_dout |
output reg | 32 | 读数据 |
bram_en |
input | 1 | BRAM 访问使能 |
bram_we |
input | 4 | 写 strobe;仅 4'hF 识别为写,4'h0 识别为读 |
5.3 状态输出
| 信号 | 方向 | 位宽 | 说明 |
|---|---|---|---|
busy |
output | 1 | 模块忙。为 1 时不要写命令寄存器 |
spi_done |
output | 1 | SPI master 完成脉冲,持续 1 个 clk |
error_busy |
output reg | 1 | 忙时启动命令产生的粘滞错误标志 |
5.4 ASIC 引脚
| 信号 | 方向 | 位宽 | 说明 |
|---|---|---|---|
asic_rst_n |
output reg | 1 | ASIC reset 引脚,软件通过 PIN_CTRL[0] 控制 |
asic_trig |
output reg | 1 | ASIC trig 引脚,软件通过 PIN_CTRL[1] 控制 |
asic_csn |
output | 1 | SPI CSN,低有效 |
asic_sck |
output | 1 | SPI SCK,空闲低 |
asic_si |
output | 1 | SPI master 输出到 ASIC |
asic_so |
input | 1 | ASIC 输出到 SPI master |
6. BRAM 寄存器映射
| 地址 | 名称 | 访问 | 说明 |
|---|---|---|---|
13'h0000 |
VERSION |
R | 返回 VERSION |
13'h0004 |
STATUS |
R/W1C | 状态寄存器;写 bit0 清 done,写 bit1 清 error |
13'h0008 |
SPI_ADDR |
R/W | Direct SPI 目标 ASIC 地址 |
13'h000C |
SPI_WDATA |
R/W | Direct SPI 写数据 |
13'h0010 |
SPI_CTRL |
W | Direct SPI 启动控制 |
13'h0014 |
SPI_RDATA |
R | 最近一次 SPI 读回数据 |
13'h0018 |
PIN_CTRL |
R/W | 直接控制 asic_rst_n/asic_trig |
13'h001C |
LAST_ADDR |
R | 最近一次完成 SPI 操作的 ASIC 地址 |
13'h0020 |
CONTROL |
R/W | 写 CSI040 control register |
13'h0024 |
CH_ENABLE |
R/W | 写 channel enable1/2 |
13'h0028 |
TRIGGER |
W | 向 ASIC trigger register 写 8'hAA |
13'h002C |
SEQ_CMD |
W | 特殊序列命令 |
13'h0040 |
CH_INDEX |
R/W | 选择通道编号 |
13'h0044 |
CH_MISC |
W | 当前通道 offset 0x0 |
13'h0048 |
CH_CUR_A |
W | 当前通道 offset 0x1 |
13'h004C |
CH_CUR_B |
W | 当前通道 offset 0x2 |
13'h0050 |
CH_CUR_C |
W | 当前通道 offset 0x3 |
13'h0054 |
CH_CUR_D |
W | 当前通道 offset 0x4 |
13'h0058 |
CH_STIM_PW |
W | 当前通道 offset 0x5 |
13'h005C |
CH_DZ0 |
W | 当前通道 offset 0x6 |
13'h0060 |
CH_DZ1 |
W | 当前通道 offset 0x7 |
13'h0064 |
CH_SKIP_AB |
W | 当前通道 offset 0x8 |
13'h0068 |
CH_SKIP_CD |
W | 当前通道 offset 0x9 |
13'h006C |
CH_STIM_NUM |
W | 当前通道 offset 0xA |
13'h0070 |
CH_DZ2 |
W | 当前通道 offset 0xB |
13'h0074 |
CH_THERAPY_DELAY |
W | 当前通道 offset 0xC |
13'h0078 |
CH_THERAPY_NUM |
W | 当前通道 offset 0xD |
13'h007C |
CH_DZ3 |
W | 当前通道 offset 0xE |
13'h0080 |
CH_MASTER_NUM |
W | 当前通道 offset 0xF |
7. 寄存器位定义
7.1 STATUS 寄存器
STATUS 读回值由 RTL 拼接得到:
{16'd0, seq_id, seq_step, error_busy, done_latched, spi_cmd_ready, ctrl_busy}
赋值给 32 bit bram_dout 时左侧补 0。软件可按以下位使用:
| 位 | 名称 | 说明 |
|---|---|---|
[5] |
ctrl_busy |
当前模块忙 |
[6] |
spi_cmd_ready |
SPI master 空闲可接收命令 |
[7] |
done_latched |
至少完成过一次 SPI 操作 |
[8] |
error_busy |
忙时写命令错误 |
[11:9] |
seq_step |
当前序列步骤 |
[15:12] |
seq_id |
当前序列编号 |
写 STATUS 清除粘滞位:
| 写 bit | 行为 |
|---|---|
[0] = 1 |
清除 done_latched |
[1] = 1 |
清除 error_busy |
7.2 SPI_CTRL 寄存器
| 位 | 名称 | 说明 |
|---|---|---|
[0] |
direct_write |
1:Direct SPI 写;0:Direct SPI 读 |
[15:8] |
direct_len |
payload 字节数;0 会被转换为 1 |
| 其他 | 保留 | 当前未使用 |
direct_len 最终会在 SPI master 内限制到 1..MAX_BURST_BYTES。
7.3 PIN_CTRL 寄存器
| 位 | 名称 | 说明 |
|---|---|---|
[0] |
asic_rst_n |
直接驱动 ASIC reset_n |
[1] |
asic_trig |
直接驱动 ASIC trig |
| 其他 | 保留 | 当前读回为 0 |
7.4 SEQ_CMD 寄存器
| 位 | 命令 | SPI 行为 |
|---|---|---|
[0] |
DCS unlock | 向 0x0009 依次写 55h, B3h, 0Ah |
[1] |
Test unlock | 向 0x0009 依次写 AAh, 4Ch, F5h |
[2] |
Mode exit | 向 0x0009 写 F9h |
[3] |
Control quick write | 设置 control_shadow = 8'h10 并写 0x0002 |
[4] |
Control quick write | 设置 control_shadow = 8'h08 并写 0x0002 |
若多个 bit 同时为 1,优先级从 bit0 到 bit4。
8. 命令行为
8.1 CONTROL
写 BRAM_ADDR_CONTROL:
control_shadow <= bram_din[7:0]
SPI write addr 0x0002, data control_shadow, len 1
8.2 CH_ENABLE
写 BRAM_ADDR_CH_ENABLE:
ch_enable_shadow <= bram_din[15:0]
step0: SPI write addr 0x0007, data ch_enable_shadow[7:0]
step1: SPI write addr 0x0008, data ch_enable_shadow[15:8]
8.3 通道参数写
通道参数地址计算:
asic_addr = CSI_CH_BASE + CH_INDEX * CSI_CH_STRIDE + channel_offset
默认:
asic_addr = 0x0010 + CH_INDEX * 0x0010 + channel_offset
示例:
CH_INDEX = 3
写 CH_CUR_A = 0x7F
channel_offset = 0x1
asic_addr = 0x0041
8.4 Direct SPI
Direct SPI 使用 SPI_ADDR/SPI_WDATA/SPI_CTRL:
1. 写 SPI_ADDR 设置 ASIC 地址
2. 写 SPI_WDATA 设置写数据
3. 写 SPI_CTRL 启动 direct transfer
4. 读操作完成后,从 SPI_RDATA 取数据
9. SPI 时序规格
9.1 SCK 频率
f_sck = f_clk / (2 * SPI_CLK_DIV)
示例:
f_clk |
SPI_CLK_DIV |
f_sck |
|---|---|---|
| 100 MHz | 50 | 1 MHz |
| 100 MHz | 25 | 2 MHz |
| 100 MHz | 10 | 5 MHz |
| 100 MHz | 5 | 10 MHz |
9.2 SPI 帧格式
默认 SPI_ADDR_BYTES = 2:
byte0 opcode
byte1 address high byte
byte2 address low byte
byte3.. payload byte0..N
写 1 byte 示例:
opcode = 0x02
addr = 0x0002
data = 0x10
frame = 0x02_0002_10
9.3 SPI bit 数
frame_bits = 8 * (1 + SPI_ADDR_BYTES + payload_len)
默认地址 2 byte 时:
| payload_len | frame_bits |
|---|---|
| 1 | 32 |
| 2 | 40 |
| 3 | 48 |
| 4 | 56 |
9.4 传输时间估算
不计状态机少量额外周期时:
transfer_time ≈ frame_bits * 2 * SPI_CLK_DIV * clk_period
100 MHz、SPI_CLK_DIV = 50、1 byte payload:
frame_bits = 32
transfer_time ≈ 32 * 2 * 50 * 10 ns = 32 us
10. 软件推荐流程
10.1 写普通命令
1. 轮询 STATUS[5] == 0,确认不忙
2. 写目标命令寄存器
3. 轮询 STATUS[7] == 1,确认完成
4. 写 STATUS[0] = 1,清除 done_latched
5. 若 STATUS[8] == 1,记录错误并写 STATUS[1] = 1 清除
10.2 Direct read 示例
读取 CSI040 Part ID:
write SPI_ADDR = 0x0000011D
write SPI_CTRL = 0x00000100 // bit0=0 read, len=1
wait done
read SPI_RDATA[7:0]
testbench 中 ASIC 模型返回 8'h28。
10.3 Direct write 示例
向 ASIC 0x0002 写 0x10:
write SPI_ADDR = 0x00000002
write SPI_WDATA = 0x00000010
write SPI_CTRL = 0x00000101 // bit0=1 write, len=1
wait done
11. 复位默认值
| 项目 | 复位值 |
|---|---|
direct_addr |
0 |
direct_wdata |
0 |
direct_len |
1 |
direct_write |
1 |
control_shadow |
0 |
ch_enable_shadow |
0 |
ch_index |
0 |
seq_id |
SEQ_IDLE |
seq_step |
0 |
seq_active |
0 |
error_busy |
0 |
done_latched |
0 |
last_rdata |
0 |
last_addr |
0 |
asic_rst_n |
1 |
asic_trig |
0 |
asic_csn |
1 |
asic_sck |
0 |
asic_si |
0 |
12. 集成注意事项
bram_clk和bram_rst当前未使用,BRAM 访问必须同步到clk。- 只支持整字写,软件侧需要保证
bram_we == 4'hF。 busy = 1时不要写命令寄存器,否则命令被丢弃并置位error_busy。TRIGGER寄存器是通过 SPI 写 ASIC trigger register;PIN_CTRL[1]是直接驱动asic_trig引脚,两者不是同一个功能。SPI_OPCODE_WRITE/READ需要与最终 CSI040 SPI 协议匹配。当前 testbench 使用8'h02/8'h03。- 若系统时钟不是 100 MHz,需要重新计算
SPI_CLK_DIV,保证 CSI040 SPI 时序满足要求。 - Direct SPI 多字节读写最大长度由
MAX_BURST_BYTES控制,默认最多 4 byte。
13. 验证状态
当前 testbench 覆盖:
| 测试项 | 期望 |
|---|---|
| CONTROL 写 | SPI frame 0x02000210 |
| CH_ENABLE 写 | SPI frame 0x0200075A 和 0x020008A5 |
| CH3 CUR_A 写 | SPI frame 0x0200417F |
| DCS unlock | SPI frame 0x02000955/0x020009B3/0x0200090A |
| Direct read Part ID | SPI frame 0x03011D00,读回 0x28 |
已运行:
xvlog: pass
xelab: pass
xsim : $finish at 10940 ns