Altifigence Academy

30 / 37 · 概念

Ready/valid 与单槽弹性缓冲区

设计可暂停数据通路中无丢失、无重复的传输条件与同时输入输出。

valid 与 ready 在同一边沿均为 1 才传输

发送端提供有效数据时令 valid=1,接收端能够接收时令 ready=1。是否传输,由时钟边沿同时采样两个信号来决定。

transferk=validk∧readyk\mathrm{transfer}_k=\mathrm{valid}_k\land\mathrm{ready}_k

valid=1、ready=0 期间,发送端必须保持 valid 与数据。若等 ready 上升后才给 valid,可能因对方的规则而死锁。这里假定所有信号位于同一时钟域,ready/valid握手 发送端 valid 与接收端 ready 在同一边沿均为 1 时,确认传输的约定,也包括等待期间的数据保持规则。 本身不解决 CDC。

等待中的数据只传输一次

下方各列依次表示第 0~5 个采样周期,信号值按对应上升沿上升沿 时钟从 0 变为 1 的瞬间。它不同于表示整个 CLK=1 区间的电平。了解更多之前读取。A 在第 1、2 周期等待,valid=1、ready=0,因此必须保持数据与 valid。第 3 个边沿接受 A,第 4 个边沿接受 B。时钟与信号线的对齐是用于说明约定的示意图,不模拟 setupsetup 捕获时钟边沿之前,输入数据必须保持稳定的最短时间。违反建立时间就无法保证存储结果。了解更多/hold 延迟。

Ready/valid · 等待与连续传输
查看波形数据
波形数据:每个字符表示一个区间,点表示保持前一状态,p 表示一个时钟周期。
信号波形总线值
clkp.....
valid01...0
ready10.1..
transfer0..1.0
datax3..4xA → B

valid 连续多个周期为 1,并不代表只传输一次。每个 ready 也为 1 的边沿,都会发生一次独立传输。

构造能保存一个数据的缓冲区

缓冲区为空,或本边沿能够送出当前数据时,就有空间接收新数据。

in_ready=¬out_valid∨out_ready\mathrm{in\_ready}=\neg\mathrm{out\_valid}\lor\mathrm{out\_ready}
SystemVerilog
module elastic_buffer (
    input  logic       clk,
    input  logic       rst,
    input  logic       in_valid,
    output logic       in_ready,
    input  logic [7:0] in_data,
    output logic       out_valid,
    input  logic       out_ready,
    output logic [7:0] out_data
);
    assign in_ready = !out_valid || out_ready;

    always_ff @(posedge clk) begin
        if (rst) begin
            out_valid <= 1'b0;
        end else if (in_ready) begin
            out_valid <= in_valid;
            if (in_valid) out_data <= in_data;
        end
    end
endmodule

空状态接收输入后,out_valid 与 out_data 在边沿之后更新。没有组合旁路,因此不能把新值算作在同一边沿已经完成输出传输。reset 期间不计传输,out_valid=0 时 out_data 没有有效含义,所以不一定要复位复位 将状态恢复为规定初值的控制。必须同时规定其同步或异步性质,以及相对于其他控制的优先级。了解更多数据寄存器寄存器 存储多位状态的电路。本课程中的同步寄存器在时钟边沿存储指定输入。了解更多本身。

满状态也能替换数据

边沿前状态out_readyin_valid边沿上的行为
空0 或 11存储输入并令 valid=1
满00 或 1保持当前数据与 valid
满10传出数据并清空
满11同时传出旧数据并存入新输入

最后一行使缓冲区填充后可以每周期处理一个数据。有延迟并不意味着吞吐率吞吐率 单位时间内接受或完成的工作数量。流水线即使不缩短单个任务的延迟,也可以提高吞吐率。了解更多减半。

验证数据顺序的模型

参考模型使用长度至多为 1 的队列。依据每个边沿的旧值判断输出传输与输入接受;若有输出,先与队首比较,再将新输入加入队尾。同一边沿可以同时 dequeue 与 enqueue,因此必须明确顺序。

0≤Naccepted−Ndelivered≤10\le N_{\mathrm{accepted}}-N_{\mathrm{delivered}}\le1

上述不变式在复位后重新开始记录的区间成立。还应检查暂停期间数据是否稳定、传输顺序是否保留,以及是否重复传输同一数据。数量不变式本身不能证明数据值正确。

若将多个缓冲区的 ready 长链组合连接,反向时序路径可能变长。连接结构时,也应检查是否存在组合环路。

延伸阅读:AMD UG934 — READY/VALID Handshake

自己试试

缓冲区已被数据 A 填满,新输入 B 的 in_valid=1。假设第一边沿 out_ready=0,下一边沿 out_ready=1,各边沿如何处理 A、B?发送端必须保持 B 到什么时候?

阅读解释

第一边沿 in_ready=0,因此保留 A,B 未被接受;发送端必须保持 B 与 in_valid=1。下一边沿 in_ready=1,传出 A 的同时存入 B。该边沿后缓冲区输出为 B,但不表示 B 已传出。B 的输出传输发生在之后 out_valid 与 out_ready 同时为 1 的边沿。

你的选择适用于此浏览器,可随时在页脚更改。