38 / 52 · 개념
Ready/valid와 1칸 탄력 버퍼
정지할 수 있는 데이터 경로에서 손실·중복 없는 전달 조건과 동시 입출력을 설계합니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
전송은 valid와 ready가 같은 에지에서 1일 때입니다
송신 측은 유효한 데이터를 내보낼 때 valid를 1로, 수신 측은 받을 수 있을 때 ready를 1로 둡니다. 전송 여부는 클록 에지에서 두 신호를 함께 샘플링해서 결정합니다.
송신 측은 valid=1, ready=0인 동안 valid와 데이터를 유지해야 합니다. ready가 올라올 때까지 valid를 아예 내지 않는 방식은 상대의 규칙에 따라 교착을 일으킬 수 있습니다. 여기서는 모든 신호가 같은 클록 도메인에 있다고 가정합니다. ready/valid 자체는 CDC를 해결하지 않습니다.
대기한 데이터는 한 번만 전송하기
아래 열은 순서대로 0~5번째 샘플링 사이클을 나타냅니다. 신호 값은 해당 상승 에지 직전의 값으로 읽으세요. A가 대기하는 1·2번째 사이클에는 valid=1, ready=0이므로 데이터와 valid를 유지합니다. 3번째 에지에서 A, 4번째 에지에서 B를 수락합니다. 클록·신호선의 정렬은 계약을 설명하는 도식이며 setup/hold 지연을 모델링하지 않습니다.
파형 데이터 보기
| 신호 | 파형 | 버스 값 |
|---|---|---|
| clk | p..... | |
| valid | 01...0 | |
| ready | 10.1.. | |
| transfer | 0..1.0 | |
| data | x3..4x | A → B |
valid가 여러 사이클 동안 1이라고 한 번만 전송되는 것은 아닙니다. ready도 1인 에지마다 별개의 전송이 일어납니다.
한 개를 보관하는 버퍼를 만듭니다
버퍼가 비어 있거나, 현재 데이터를 이번 에지에서 내보낼 수 있다면 새 데이터를 받을 공간이 있습니다.
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가 갱신됩니다. 조합 bypass는 없으므로 같은 에지에서 그 새 값을 출력 전송한 것으로 세지 않습니다. reset 동안에는 전송을 세지 않고, out_valid=0일 때 out_data의 값은 의미가 없습니다. 그래서 데이터 레지스터 자체를 반드시 리셋할 필요는 없습니다.
가득 찬 상태에서도 교체할 수 있습니다
| 에지 직전 상태 | out_ready | in_valid | 에지에서 일어나는 일 |
|---|---|---|---|
| 비어 있음 | 0 또는 1 | 1 | 입력을 저장하고 valid=1 |
| 가득 참 | 0 | 0 또는 1 | 현재 데이터와 valid 유지 |
| 가득 참 | 1 | 0 | 출력을 전달하고 비움 |
| 가득 참 | 1 | 1 | 기존 출력 전달과 새 입력 저장을 동시에 수행 |
마지막 행 때문에 한 번 채워진 뒤에는 매 사이클 하나씩 처리할 수 있습니다. 지연이 존재한다고 처리율까지 절반이 되는 것은 아닙니다.
데이터 순서를 검증하는 모델
참조 모델에는 길이가 최대 1인 큐를 사용합니다. 매 에지의 이전 값으로 출력 전송과 입력 수락을 판단하고, 출력이 있다면 큐의 앞 항목과 비교한 뒤 새 입력을 뒤에 넣습니다. 같은 에지에서 dequeue와 enqueue가 모두 가능하므로 순서를 명확히 하세요.
위 불변식은 리셋으로 기록을 새로 시작한 구간에서 성립합니다. 추가로 stall 동안 데이터가 안정적인지, 전달 순서가 보존되는지, 같은 데이터를 두 번 전달하지 않는지 검사합니다. 개수 불변식만으로 데이터 값의 정확성까지 검증되는 것은 아닙니다.
여러 버퍼의 ready를 조합으로 길게 연결하면 역방향 타이밍 경로가 길어질 수 있습니다. 구조를 연결할 때는 조합 루프가 없는지도 확인하세요.
직접 생각해 보기
버퍼가 데이터 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인 에지에서 일어납니다.