Files
BSI-901-fpga-software/docs/csi040_ctrl_datasheet.md
T

13 KiB
Raw Blame History

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.v
  • c64_pro.srcs/sources_1/rtl/csi040/csi040_spi_master.v
  • c64_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 == 1bram_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 payloadMAX_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 1Direct SPI 写;0Direct 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 0x0009F9h
[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 0x00020x10

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_clkbram_rst 当前未使用,BRAM 访问必须同步到 clk
  • 只支持整字写,软件侧需要保证 bram_we == 4'hF
  • busy = 1 时不要写命令寄存器,否则命令被丢弃并置位 error_busy
  • TRIGGER 寄存器是通过 SPI 写 ASIC trigger registerPIN_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 0x0200075A0x020008A5
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