모든 이야기

AXI 배선을 레지스터로 끊을 때 데이터를 잃지 않는 조건

길어진 AXI 배선을 레지스터로 끊으면 타이밍을 맞추기 쉬워진다. 그런데 payload 비트에 플립플롭만 붙이는 것으로는 전송을 보존할 수 없다. 입력은 새 값을 수락했는데 출력은 이전 값을 아직 내보내지 못하는 순간이 있기 때문이다. AXI register slice는 시간을 늦추는 회로와 함께, 수락한 정보를 보관하는 회로여야 한다.

한 채널의 정보는 payload, valid, ready로 움직인다. 출력 쪽이 멈추면 slice가 받은 값이 남아 있어야 하고, 저장할 수 없는 상태에서는 입력 쪽의 추가 수락을 막아야 한다. 여기에 ready의 긴 조합 경로까지 끊으려면 downstream의 순간적인 정지를 전달하기 전에 추가 수락할 수 있는 정보도 담을 공간이 필요하다.

PULP의 axi_cut은 다섯 채널에 각각 handshake 저장 블록을 두고 채널별 bypass를 선택할 수 있게 한다. 사용하는 spill register에서 flush와 clear를 사용하지 않는 동작을 읽어 보면 A와 B 두 저장 위치가 있으며, 입력 ready는 두 위치의 점유 상태에서 결정된다. 단순한 데이터 플립플롭 하나와 구별되는 부분이다. PULP, axi_cut, common_cells, cc_spill_register_flushable

이 구현의 핵심 상황을 작은 상태 추적으로 보자. reset과 flush는 없고, 출력 준비 신호가 내려가는 동안 입력은 값을 계속 보내려고 한다. A에는 X1이 있고 B는 비어 있는 상태에서 시작한다. B에 값이 있으면 그것을 먼저 출력하며, 양쪽이 가득 차면 입력 ready는 0이라고 하자.

정지 시작: A=X1, B=empty → 출력에는 X1
다음 수락: X1을 B로 보관하고 A에 X2 수락
정지 유지: A=X2, B=X1 → 출력은 X1, 추가 입력 수락 금지
출력 재개: X1 수락 → 남은 다음 값은 X2

두 저장 위치가 없는데 X1을 내보내지 못한 상태에서 X2를 수락하면 X1을 덮어쓰거나 X2를 잃는다. 받았다는 handshake는 이미 일어났으므로 송신자에게 나중에 다시 보내 달라고 암묵적으로 요청할 수 없다. slice가 자기 저장 용량에 맞추어 ready를 제어해야 하는 이유다.

저장 공간을 둔다고 해서 throughput이 반드시 떨어지는 것은 아니다. 출력이 계속 준비되어 있는 정상 구간에서 기존 값을 내보내는 경계와 새 값을 받는 경계를 겹칠 수 있으면 매 사이클 하나씩 전달할 수 있다. 빈 slice를 통과하는 최초 지연이 한 사이클 늘어나는 것과, 연속 전송의 간격이 두 사이클이 되는 것은 다른 현상이다. 실제 지연과 정지에서 회복하는 간격은 선택한 slice 구조와 상태에 맞추어 확인해야 한다.

채널마다 지연을 다르게 줄 수도 있다. 가상으로 AW에만 저장 단계를 하나 넣고 W는 바로 연결했다고 하자. 외부에서는 주소와 데이터를 같은 경계에 제시했어도 아래쪽에서는 W가 먼저 보일 수 있다. AXI는 쓰기 데이터가 주소보다 먼저 도착할 수 있도록 정의한다. 따라서 올바른 수신기는 이 상대 지연을 처리해야 한다. Arm IHI0022H, A3.3 Relationships between the channels

하지만 독립 채널이라는 이유로 순서를 바꾸어도 되는 것은 아니다. AW의 요청 순서와 대응하는 W burst 순서, 동일 ID의 응답 순서 등은 유지되어야 한다. 각 slice가 같은 채널의 입력 순서를 보존하더라도 주변 회로가 주소와 데이터를 현재 사이클의 조합으로만 짝짓는다면 문제가 드러난다. slice를 넣은 뒤 틀린 것이 아니라, 지연 차이를 처리하지 못한 전제가 드러난 경우일 수 있다.

또 하나의 경계는 slice를 넣는 위치다. PULP crossbar 문서는 채널별 저장을 지원하면서, 내부 demux와 mux 사이에 임의로 spill register를 추가하면 W 경로의 순환 대기를 만들 수 있다는 설계 이유를 설명한다. 외부 인터페이스에 허용된 저장 블록을 넣는 일과, 여러 중재기의 결정 순서를 내부에서 바꾸는 일은 같지 않다. 전송 규약을 지키는 부품 하나를 썼다는 사실만으로 새 네트워크의 교착 가능성이 사라지지는 않는다. PULP axi_xbar, Design Rationale for No Pipelining Inside Crossbar

검증에서는 고정된 사이클 번호보다 입력에서 수락한 정보와 출력에서 수락한 정보를 먼저 비교하면 좋다. 정지가 없을 때의 지연도 확인하되, 정지 중에는 손실·중복·payload 변경이 없는지 별도로 확인해야 한다. 주소와 데이터를 서로 다른 간격으로 보내고, 응답 채널만 멈추는 상황도 넣으면 채널 간 대응을 점검할 수 있다. reset이나 clear로 보관 중 거래를 버릴 때는 시스템이 어떤 복구를 약속하는지도 별도 조건이다.

AXI register slice가 회로에 추가하는 것은 지연과 보관 책임이다. 두 책임을 함께 설계하면 긴 조합 경로를 끊고도 같은 거래들을 전달할 수 있다. 데이터가 몇 사이클 늦어졌는지와, 그 사이 수락한 데이터를 어디에 담았는지를 함께 적는 것이 slice의 올바름을 판단하는 출발점이다.