Altifigence Academy

61 / 63 · 개념

멈출 수 있는 파이프라인과 backpressure

단계별 ready를 계산해 정지와 동시 이동 중에도 데이터의 손실·중복·재계산을 방지합니다.

수신 측이 매번 받을 수 없다면

선수 지식: 1칸 ready/valid핸드셰이크 송신 측의 valid와 수신 측의 ready가 같은 에지에서 모두 1일 때 데이터를 전달하는 규칙입니다. 기다리는 동안 데이터를 유지하는 규칙도 포함합니다. 자세히 보기 버퍼와 파이프라인파이프라인 레지스터를 사이에 두고 계산을 여러 단계로 나누어, 여러 입력을 겹쳐 처리하는 구조입니다. 데이터와 valid, 제어 신호를 같은 단계에 맞춰 전달해야 합니다. 자세히 보기의 데이터 정렬.

고정 속도 파이프라인에 out_ready만 추가해서 출력을 막아서는 부족합니다. 마지막 단계가 가득 차서 멈추면 앞 단계에 남아 있는 데이터도 덮어쓰지 않아야 합니다. 정지 요청이 입력 방향으로 전달되는 backpressurebackpressure 수신 측이 잠시 데이터를 받을 수 없음을 송신 측에 알려 데이터 흐름을 멈추는 방식입니다. 멈춘 동안 아직 전달하지 않은 데이터를 유지해야 합니다. 자세히 보기를 설계해야 합니다.

두 단계를 각각 데이터 한 개와 valid 한 비트로 표현하겠습니다. 2단계는 비어 있거나 현재 출력을 내보낼 수 있을 때 새 값을 받을 수 있습니다. 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는 r1입니다. r2=0이라도 1단계가 비어 있다면 새 입력 한 개를 받을 수 있습니다. ‘출력이 멈추면 모든 입력을 무조건 거부’하는 것보다 저장 공간을 잘 활용합니다.

각 단계는 이동 허가가 있을 때만 갱신합니다

아래 예제는 unsignedunsigned 비트열을 음수가 없는 정수로 해석하는 규칙입니다. n비트의 범위는 0부터 2^n−1이며, 같은 비트열의 signed 해석과 다를 수 있습니다. 자세히 보기 8비트 x에 대해 y=2(x+1)을 계산합니다. 1단계는 x+1을 9비트로 저장하고, 2단계는 10비트로 한 비트 왼쪽 이동합니다. 최대 입력 255의 결과 512까지 정확하게 표현합니다.

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

nonblockingnonblocking 순차 RTL에서 <=로 표현하는 대입입니다. 우변을 평가한 뒤 갱신을 예약하므로 같은 에지의 레지스터들이 이전 상태를 기준으로 계산할 수 있습니다. 자세히 보기 대입이므로 2단계는 같은 에지에 새로 계산한 d1이 아니라 이전 d1을 받습니다. r1=0이면 v1·d1이 유지되고, r2=0이면 v2·d2가 유지됩니다. valid만 유지하고 데이터는 계속 갱신하는 구현은 잘못입니다.

두 단계가 모두 찼을 때의 동작

처음에 2단계에는 A의 결과가, 1단계에는 B의 중간값이 저장되어 있고 입력 C가 대기한다고 합시다.

out_readyin_ready에지에서의 동작
00A·B 유지, C 미수락
00A·B 유지, C 미수락
11A 전달, B가 2단계로 이동, C 수락

송신 측은 수신 측이 C를 받을 때까지 C와 in_valid를 유지합니다. 첫 정지 에지에서 C를 보냈다고 생각하고 다음 데이터를 내면 C가 사라집니다.

각 열은 상승 에지상승 에지 클록이 0에서 1로 바뀌는 순간입니다. CLK=1인 구간 전체를 뜻하는 레벨과 구별합니다. 자세히 보기 직전 값입니다. 시작할 때 마지막 단계에 A, 첫 단계에 B가 있으며 C가 입력에서 대기합니다. E2에서 A를 전달하고 C를 수락한 뒤, E3 직전 출력은 B로 바뀝니다.

두 단계가 모두 찬 상태의 backpressure
파형 데이터 보기
파형 데이터: 각 문자는 한 구간, 점은 이전 상태 유지, p는 클록 한 주기입니다.
신호파형버스 값
edge2345E0 → E1 → E2 → E3
out_ready0.1.
out_valid1...
out_data2..3A → B
in_valid1...
in_ready0.1.
in_data2..3C → D

검증할 보존 법칙

리셋 이후 입력 수락 수를 Nin, 출력 전달 수를 Nout이라고 하면 저장량은 다음과 같습니다. 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

개수가 맞더라도 A를 두 번 내보내고 B를 버리는 오류가 있을 수 있으므로, 참조 큐로 값과 순서도 검사합니다. 입력 valid와 출력 ready를 독립적으로 변하게 하고, 오랫동안 멈추는 경우, 연속으로 처리하는 경우, 리셋으로 저장된 데이터를 비우는 경우를 포함하세요.

ready 경로도 타이밍 경로입니다

단계를 길게 연결하면 r2→r1 같은 역방향 조합 경로도 길어집니다. 레지스터 하나로 ready를 지연시키면 그 지연 동안 받을 수 있다고 알린 입력을 보관할 추가 공간이 필요할 수 있습니다. 저장 공간과 프로토콜을 고려하지 않고 ready에 플립플롭만 넣는 것은 안전한 타이밍 최적화가 아닙니다.

직접 생각해 보기

v1=0, v2=1이고 out_ready=0입니다. in_valid=1인 입력을 받을 수 있습니까? 그 다음 사이클에도 out_ready=0이면 추가 입력을 계속 받을 수 있습니까?

해설 보기

처음 r2=0이지만 r1=1이므로 한 개를 받아 1단계를 채울 수 있습니다. 에지 이후 v1=v2=1이면 r1=r2=0이므로 더 이상 받지 못합니다. 이처럼 빈 단계가 있는지에 따라 수락 여부를 정해야 두 칸의 저장 공간을 모두 활용할 수 있습니다.

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.