1. 握手协议基础:什么是握手协议?

做数字设计这么多年,我越来越觉得——握手协议就像芯片世界的“交通规则”。没有它,数据在模块之间乱窜,迟早要出事故。

说白了,握手协议就是一套通信双方约定好的信号交互规则。发送方说“我有数据了”,接收方说“我准备好了”,然后数据才真正传输。就这么简单。

1.1 为什么需要握手?

你想想看,在数字芯片里,不同模块的工作速度往往不一样。有的模块一拍就能处理完数据,有的模块要等好几拍。如果发送方不管不顾地往外扔数据,接收方根本接不住。

我在项目中遇到过这样一个场景:一个高速ADC采集模块,采样率是200MHz,但后端的图像处理模块只能跑到100MHz。如果不加握手,数据直接丢包,画面花得一塌糊涂。

握手协议要解决的核心问题就两个:

  • 什么时候可以发?——接收方有空了才能发
  • 什么时候可以收?——发送方有数据了才能收

1.2 valid-ready 握手机制详解

目前最主流的握手方式,就是 valid-ready 协议。它只有两根控制信号:

信号名 方向 含义
valid 发送方 → 接收方 “我这里有有效数据”
ready 接收方 → 发送方 “我可以接收数据”

数据传输只发生在 valid 和 ready 同时为高 的那个时钟周期。这就是所谓的“握手成功”。

核心规则:valid 信号一旦拉高,必须保持到握手成功为止,不能中途撤销。这是很多新手容易踩的坑。

1.3 三种握手场景

实际工作中,我总结出三种典型场景:

  1. 接收方一直 ready:比如 FIFO 非满时,ready 始终为高。这时候 valid 一拉高,数据立刻传输,一拍搞定。
  2. 发送方一直 valid:比如数据源源不断。这时候等 ready 拉高才能传,ready 没来就等着。
  3. 双方都不可预测:这是最常见的情况。valid 和 ready 各自独立,只有同时为高才传输。

我的习惯:设计接口时,我一般默认按第三种场景来做。因为这样最通用,后续改起来也方便。曾经有个项目,我偷懒假设接收方永远 ready,结果换了个后端模块就出问题了……从那以后我再也不敢偷这个懒。

1.4 握手协议的 Verilog 实现

来个最简单的例子。一个数据发送模块,用握手协议往外传数据:

module handshake_tx (
    input  clk,
    input  rst_n,
    input  [7:0] data_in,
    input  data_valid,      // 上游数据有效
    output data_ready,      // 本模块可以接收
    
    output reg [7:0] data_out,
    output reg       out_valid,
    input            out_ready
);

    // 内部 FIFO 非满时,可以接收上游数据
    assign data_ready = !fifo_full;
    
    // 输出握手:valid 和 ready 同时为高时,数据被接收方取走
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            out_valid <= 1'b0;
            data_out  <= 8'd0;
        end else begin
            if (out_valid && out_ready) begin
                // 握手成功,可以准备下一笔数据
                out_valid <= 1'b0;
            end else if (/* 有新数据准备好 */) begin
                out_valid <= 1'b1;
                data_out  <= new_data;
            end
        end
    end

endmodule

嗯,这里要注意:out_valid 一旦拉高,就不能随便拉低,必须等到 out_ready 也拉高,完成握手。这是 valid-ready 协议的铁律。

1.5 握手协议在数字设计中的重要性

我个人觉得,握手协议的重要性怎么强调都不过分。它几乎是所有数字接口的基础:

  • AXI 总线:五个通道全是 valid-ready 握手
  • FIFO 接口:读写侧本质上也是握手
  • 模块间通信:几乎都靠握手来协调
  • 跨时钟域处理:握手是同步的基础手段

我曾经踩过的坑:有次做视频处理芯片,一个模块的 valid 信号在握手成功后没有及时拉低,导致同一个数据被重复处理了两遍。查了三天才找到原因。所以我现在写代码,一定会检查 valid 的撤销逻辑。

1.6 知识体系总览

下面这张图,是我梳理的本章知识结构。你可以把它当作一个快速索引:

握手协议知识体系 握手协议 什么是握手协议 valid-ready 机制 设计中的重要性 通信双方约定规则 解决速度不匹配 valid 信号 ready 信号 同时为高才传输 AXI 总线基础 FIFO 接口 跨时钟域同步 核心:valid 不能撤,ready 看情况,同时为高才算数

这张图把本章的三个核心模块串起来了。从左到右,先理解“是什么”,再掌握“怎么用”,最后明白“为什么重要”。

一个小建议:刚开始学握手协议的时候,别急着看复杂的 AXI 总线。先把 valid-ready 这两根信号玩明白,后面所有接口协议都是它的变体。

好了,这一章就到这里。握手协议是数字设计的基石,理解透了,后面学状态机、学总线都会轻松很多。

可可精品资料库