Altifigence Academy

61 / 63 · Khái niệm

Pipeline có thể dừng và backpressure

Tính ready theo từng tầng để tránh mất, trùng hoặc tính lại dữ liệu trong lúc dừng và di chuyển đồng thời.

Nếu bên nhận không phải lúc nào cũng sẵn sàng

Kiến thức cần có: bộ đệm ready/validBắt tay Quy ước xác nhận truyền khi valid phía phát và ready phía nhận cùng bằng 1 tại cùng cạnh, gồm cả quy tắc giữ dữ liệu lúc chờ. Tìm hiểu thêm một ô và căn chỉnh dữ liệu trong pipelinePipeline Chia tính toán thành các tầng ngăn bởi thanh ghi để xử lý nhiều đầu vào chồng lấp. Dữ liệu, valid và điều khiển phải thẳng hàng theo tầng. Tìm hiểu thêm.

Chỉ thêm out_ready để chặn đầu ra của pipeline tốc độ cố định là chưa đủ. Khi tầng cuối đầy và dừng, tầng trước cũng không được ghi đè. Cần thiết kế backpressureBackpressure Cách bên nhận thông báo tạm thời không nhận được để bên gửi dừng luồng dữ liệu. Dữ liệu chưa truyền phải được bảo toàn trong lúc dừng. Tìm hiểu thêm truyền yêu cầu dừng ngược về phía đầu vào.

Biểu diễn mỗi tầng bằng một phần tử dữ liệu và một bit valid. Tầng 2 có thể nhận giá trị mới khi rỗng hoặc có thể gửi đầu ra hiện tại. Áp dụng cùng quy tắc cho tầng 1.

r2=¬v2∨out_ready,r1=¬v1∨r2r_2=\neg v_2\lor\mathrm{out\_ready},\qquad r_1=\neg v_1\lor r_2

in_ready bên ngoài là r1. Dù r2=0, nếu tầng 1 rỗng thì vẫn nhận được một đầu vào mới. Cách này tận dụng chỗ lưu tốt hơn quy tắc “đầu ra dừng thì từ chối mọi đầu vào”.

Mỗi tầng chỉ cập nhật khi được phép di chuyển

Ví dụ dưới tính y=2(x+1) cho x unsignedunsigned Quy tắc diễn giải chuỗi bit là số nguyên không âm. Phạm vi n bit là 0 đến 2^n−1 và có thể khác diễn giải signed của cùng chuỗi bit. Tìm hiểu thêm 8 bit. Tầng 1 lưu x+1 trong 9 bit; tầng 2 mở rộng thành 10 bit và dịch trái một bit. Mạch biểu diễn chính xác cả kết quả 512 của đầu vào cực đại 255.

SystemVerilog
module stallable_pipeline (
    input  logic       clk, 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 [9:0] out_data
);
    logic v1, v2, r1, r2;
    logic [8:0] d1;
    logic [9:0] d2;
    assign r2 = !v2 || out_ready;
    assign r1 = !v1 || r2;
    assign in_ready  = r1;
    assign out_valid = v2;
    assign out_data  = d2;

    always_ff @(posedge clk) begin
        if (rst) begin
            v1 <= 1'b0;
            v2 <= 1'b0;
        end else begin
            if (r2) begin
                v2 <= v1;
                if (v1) d2 <= {d1, 1'b0};
            end
            if (r1) begin
                v1 <= in_valid;
                if (in_valid) d1 <= {1'b0, in_data} + 9'd1;
            end
        end
    end
endmodule

Do phép gán nonblockingNonblocking Phép gán <= trong RTL tuần tự. Đánh giá vế phải rồi lên lịch cập nhật, cho các thanh ghi cùng cạnh tính từ trạng thái cũ. Tìm hiểu thêm, tầng 2 nhận d1 cũ, không phải d1 vừa tính tại cùng cạnh. Khi r1=0, v1 và d1 giữ nguyên; khi r2=0, v2 và d2 giữ nguyên. Giữ valid nhưng vẫn liên tục cập nhật dữ liệu là triển khai sai.

Theo dõi khi cả hai tầng đều đầy

Giả sử ban đầu tầng v2 chứa kết quả của A, tầng v1 chứa giá trị trung gian của B và đầu vào C đang chờ.

out_readyin_readyHành động tại cạnh
00Giữ A và B, chưa nhận C
00Giữ A và B, chưa nhận C
11Truyền A, chuyển B sang tầng 2, nhận C

Bên gửi giữ C cùng in_valid đến khi C được nhận. Nếu tưởng đã gửi C ở cạnh dừng đầu tiên rồi đưa dữ liệu tiếp theo, C sẽ bị mất.

Mỗi cột là giá trị ngay trước cạnh lênCạnh lên Khoảnh khắc clock chuyển 0 sang 1, khác với mức cao chỉ cả khoảng CLK=1. Tìm hiểu thêm. Ban đầu tầng cuối chứa A, tầng đầu chứa B và C chờ ở đầu vào. Sau khi truyền A và nhận C tại E2, đầu ra ngay trước E3 đổi thành B.

Backpressure khi cả hai tầng đều đầy
Xem dữ liệu dạng sóng
Dữ liệu dạng sóng: mỗi ký tự là một khoảng; dấu chấm giữ trạng thái trước; p là một chu kỳ đồng hồ.
Tín hiệuDạng sóngGiá trị bus
edge2345E0 → E1 → E2 → E3
out_ready0.1.
out_valid1...
out_data2..3A → B
in_valid1...
in_ready0.1.
in_data2..3C → D

Định luật bảo toàn cần kiểm chứng

Gọi Nin là số đầu vào được nhận và Nout là số đầu ra được truyền kể từ reset; số phần tử đang lưu là biểu thức sau. Không đếm truyền tại cạnh reset.

Nin−Nout=v1+v2,0≤Nin−Nout≤2N_{\mathrm{in}}-N_{\mathrm{out}}=v_1+v_2,\qquad 0\le N_{\mathrm{in}}-N_{\mathrm{out}}\le2

Chỉ đúng số lượng vẫn có thể bỏ sót lỗi xuất A hai lần và bỏ B, nên hàng đợi tham chiếu cũng phải kiểm tra giá trị và thứ tự. Cho valid đầu vào và ready đầu ra thay đổi độc lập; bao gồm dừng dài, xử lý liên tiếp và làm rỗng khi reset.

Đường ready cũng là đường timing

Nối nhiều tầng làm dài cả đường tổ hợp ngược như r2→r1. Nếu dùng một thanh ghi trì hoãn ready, có thể cần chỗ bổ sung để lưu các đầu vào đã được cam kết trong khoảng trễ đó. Chỉ chèn flip-flop vào ready mà không xét dung lượng lưu và giao thức không phải là tối ưu timing an toàn.

Tự thử

v1=0, v2=1 và out_ready=0. Mạch có thể nhận đầu vào có in_valid=1 không? Nếu chu kỳ tiếp theo out_ready vẫn bằng 0, mạch có thể tiếp tục nhận thêm không?

Đọc giải thích

Ban đầu r2=0 nhưng r1=1 nên có thể nhận một phần tử và lấp đầy tầng 1. Sau cạnh, nếu v1=v2=1 thì r1=r2=0, nên không thể nhận thêm. Sự khác biệt này cho phép thực sự tận dụng cả hai ô lưu.

Lựa chọn áp dụng cho trình duyệt này. Có thể đổi ở chân trang bất cứ lúc nào.