fpga系列 HDL:跨时钟域同步 shift register同步 + SPI中的同步方式

发布于:2025-02-11 ⋅ 阅读:(31) ⋅ 点赞:(0)

SPI 通信时序图

           ______________                      ______________ 
          |              |--------SCK-------->|              |
          |              |--------CS--------->|              |
          | MASTER       |                    | SLAVE        |
          |              |--------MOSI------->|              |
          |              |<-------MISO--------|              |
          |______________|                    |______________|
  • 基本组件

    • MOSI (Master Out Slave In):主机发送数据到从机。
    • MISO (Master In Slave Out):从机发送数据到主机。
    • SCK (Serial Clock):由主机生成的时钟信号。
    • SS/CS (Slave Select/Chip Select):用于选择从设备,低电平有效。
    • 注:在3-line spi中用SDA引脚代替MOSI和MISO发送数据
  • 多设备链接方式:常规SPI模式、菊花链模式

    ______________                      
   |           CS3|------------------->-----------+----------------------------------------------------------------
   |           CS2|------------------->-----------|---------------------------+------------------------------------
   |           CS1|------------------->---------- |---------------------------|---------------------------+--------
   | MASTER       |                               |                           |                           |
   |          SCLK|------------+------>-----------|---------+-----------------|---------+-----------------|--------
   |          MOSI|------------|--+--->-----------|---------|--+--------------|---------|--+--------------|--------
   |          MISO|<-----------|--|--+------------|---------|--|--+-----------|---------|--|--+-----------|--------
   |______________|            |  |  |            |         |  |  |           |         |  |  |           |
                               |  |  |            |         |  |  |           |         |  |  |           |
                               |  |  |            |         |  |  |           |         |  |  |           |
                               |  |  |            |         |  |  |           |         |  |  |           |
                               |  |  |            |         |  |  |           |         |  |  |           |
                               |  |  |      ______|______   |  |  |     ______|______   |  |  |     ______|______
                               |  |  |     |      CS     |  |  |  |    |      CS     |  |  |  |    |      CS     |
                               +--|--|---->|CLK          |  +--|--|--->|CLK          |  +--|--|--->|CLK          |
                                  +--|---->|SDI          |     +--|--->|SDI          |     +--|--->|SDI          |
                                     |     |    SLAVE    |        |    |    SLAVE    |        |    |    SLAVE    |
                                     +----<|SDO          |        +---<|SDO          |        +---<|SDO          |
                                           |_____________|             |_____________|             |_____________|
    ______________                      
   |            CS|------------------->---------- +---------------------------+---------------------------+
   | MASTER       |                               |                           |                           |
   |          SCLK|------------+------>-----------|---------+-----------------|---------+                 |
   |          MOSI|------------|--+               |         |                 |         |                 |
   |          MISO|<-----------|--|---------------|---------|-----------------|---------|-----------------|------------+
   |______________|            |  |               |         |                 |         |                 |            |
                               |  |               |         |                 |         |                 |            |
                               |  |               |         |                 |         |                 |            |
                               |  |               |         |                 |         |                 |            |
                               |  |               |         |                 |         |                 |            |
                               |  |         ______|______   |           ______|______   |           ______|______      |
                               |  |        |      CS     |  |          |      CS     |  |          |      CS     |     |
                               +--|------->|CLK          |  +--------->|CLK          |  +--------->|CLK          |     |
                                  +------->|SDI          |     +------>|SDI          |     +------>|SDI          |     |
                                           |    SLAVE    |     |       |    SLAVE    |     |       |    SLAVE    |     |
                                           |          SDO|>----+       |          SDO|>----+       |          SDO|>----+
                                           |_____________|             |_____________|             |_____________|
解释
  1. SS/CS 信号

    • SS/CS 为低电平时,表示从设备被选中并开始通信。
    • SS/CS 变高时,通信结束,从设备停止响应。
  2. SCK 信号

    • 主机生成时钟信号 SCK,用于同步数据传输。
    • 每个时钟周期可以传输一位数据。
    • 数据在时钟的上升沿或下降沿采样,具体取决于 SPI 模式(Mode 0, 1, 2, 3)。
  3. MOSI 和 MISO 信号

    • 在每个时钟周期内,MOSIMISO 线上会传输一位数据。
    • 数据通常以 MSB(最高有效位)先的方式传输。
    • MOSI 用于主机发送数据到从机。
    • MISO 用于从机发送数据到主机。
示例:8 位数据传输

假设我们传输一个字节(8 位),数据从高位到低位依次为 D7, D6, D5, D4, D3, D2, D1, D0

  1. 初始状态SS/CS 高电平,SCK 低电平,MOSIMISO 空闲。
  2. 激活从设备SS/CS 下降到低电平,从设备被选中。
  3. 数据传输
    • 第一个时钟周期(上升沿或下降沿,取决于模式):传输 D7
    • 第二个时钟周期:传输 D6
    • 第八个时钟周期:传输 D0
  4. 完成传输SS/CS 上升到高电平,通信结束。

SPI中的同步方式(shift register同步)

// https://www.fpga4fun.com/SPI2.html
// sync SCK to the FPGA clock using a 3-bit shift register
reg [2:0] SCKr;  
always @(posedge clk) 
    SCKr <= {SCKr[1:0], SCK};  // Shift in new SCK value on each clk posedge

wire SCK_risingedge = (SCKr[2:1]==2'b01);  // Detect SCK rising edges
wire SCK_fallingedge = (SCKr[2:1]==2'b10); // Detect SCK falling edges

always @(posedge clk)
begin
  if (~SSEL_active)  // Check if chip select is active
    bitcnt <= 3'b000;
  else if (SCK_risingedge)  // Only proceed if SCK has a rising edge
  begin
    bitcnt <= bitcnt + 3'b001;  // Increment bit counter

    // Implement a shift-left register (since we receive the data MSB first)
    byte_data_received <= {byte_data_received[6:0], MOSI_data};
  end
end
  • 代码使用移位寄存器(如 SCKr)可以方便地检测 SCK 的上升沿和下降沿(一般要求clk需要比 SPI 总线上的SCK更快):

    • SCKr[2:0] 是一个3位寄存器,每次在 clk 的上升沿更新。
    • SCKr[2:1] == 2'b01 表示 SCK 从低电平变为高电平(上升沿)。
    • SCKr[2:1] == 2'b10 表示 SCK 从高电平变为低电平(下降沿)。
  • 为什么使用3-bit shift register来同步SPI,而不直接使用always @(posedge SCK ) begin … end

    • 通过使用移位寄存器同步 SCK 到 FPGA 的本地时钟域,不仅可以解决跨时钟域问题,还能可靠地检测边沿变化,提高系统的稳定性和可靠性。这种方法还简化了设计,使所有逻辑都能在一个统一的时钟域内工作。
    • 直接在 SCK 上升沿触发写入数据,而在本地时钟读取数据,无法保证数据满足建立和保持时间的约束,导致次稳态发生,因此不推荐使用。
    • shift register方法不仅能够可靠地检测边沿变化,还能过滤掉毛刺(glitches),因为需要连续两个周期保持一致的变化才能被识别为有效的边沿。