---
title: "주소와 데이터가 따로 도착하는 AXI 쓰기를 처리하는 법"
author: "브레이브브라우저쓰자"
published_at: "2026-10-26T23:53:04.501Z"
updated_at: "2026-10-06T02:44:25.826Z"
tags: ["axi 독립 채널"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/%EC%A3%BC%EC%86%8C%EC%99%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EB%94%B0%EB%A1%9C-%EB%8F%84%EC%B0%A9%ED%95%98%EB%8A%94-axi-%EC%93%B0%EA%B8%B0%EB%A5%BC-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B2%95"
ai_assisted: true
---

# 주소와 데이터가 따로 도착하는 AXI 쓰기를 처리하는 법

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/%EC%A3%BC%EC%86%8C%EC%99%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EA%B0%80-%EB%94%B0%EB%A1%9C-%EB%8F%84%EC%B0%A9%ED%95%98%EB%8A%94-axi-%EC%93%B0%EA%B8%B0%EB%A5%BC-%EC%B2%98%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B2%95)

쓰기 주소가 수락되었는데 아직 메모리에 보낼 데이터가 도착하지 않았다. 반대로 데이터가 먼저 도착하고 주소는 몇 사이클 뒤에 나타날 수도 있다. AXI 독립 채널을 구현하는 회로는 이런 간격을 오류로 여기지 않고 처리해야 한다. 주소와 데이터를 같은 순간에만 받는다고 가정하면, 단순한 주변장치에서도 정상 요청을 잃을 수 있다.

AXI에는 읽기 주소 AR, 읽기 데이터 R, 쓰기 주소 AW, 쓰기 데이터 W, 쓰기 응답 B라는 다섯 채널이 있다. 각각 자기 valid와 ready로 정보를 전달한다. 같은 클록 상승 경계에서 두 신호가 모두 1이면 그 채널의 정보가 수락된다. 주소의 handshake와 데이터의 handshake는 같은 사건이 아니다. [Arm IHI0022H, A1.2·A3.2](https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/IHI0022H_amba_axi_protocol_spec.pdf)

일반 AXI4 쓰기 하나를 추적해 보자. burst는 한 beat이고 주소는 0x1000, 크기는 4바이트, 쓰기 데이터는 0x12345678이며 네 byte strobe는 모두 켜져 있다. 수신기는 먼저 온 데이터나 주소를 각각 보관할 수 있고, 다른 요청은 없는 가상 상황이다. 표의 숫자는 클록 상승 경계의 번호다.

| 경계 | 채널에서 일어난 일 | 수신기가 기억할 상태 |
|---|---|---|
| 1 | WDATA와 WLAST=1 | 데이터는 있음, 주소는 아직 없음 |
| 4 | AWADDR=0x1000, AWLEN=0 | 주소와 마지막 데이터가 모두 있음 |
| 6 | BVALID=1, BREADY=0 | 응답을 제시했지만 아직 수락되지 않음 |
| 8 | BVALID=1, BREADY=1 | 쓰기 응답 수락, 요청 추적 종료 가능 |

주소 경계 4가 올 때 WVALID가 이미 내려가 있어도 경계 1에서 받은 데이터가 사라지는 것은 아니다. 정상적으로 수락한 정보를 수신기가 보관해야 한다. 반대로 데이터가 경계 4에 오고 주소가 경계 1에 왔다면 주소를 보관해야 한다. AXI는 쓰기 데이터가 주소보다 먼저 나타나는 것을 허용한다. [Arm IHI0022H, A3.3](https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/IHI0022H_amba_axi_protocol_spec.pdf)

자주 등장하는 실수는 다음과 같은 의미의 조건을 쓰는 것이다.

```text
if AWVALID && AWREADY && WVALID && WREADY:
    write_memory(AWADDR, WDATA)
```

이 조건은 두 채널의 수락이 같은 경계에서 일어난 쓰기만 알아본다. 표의 요청에서는 경계 1에 AW 쪽 조건이 없고, 경계 4에는 W 쪽 조건이 없다. 두 handshake를 각각 성사시켜 놓고 실제 쓰기를 누락하는 회로가 된다. 검증에서 주소와 데이터를 항상 동시에 제공했다면 이 문제는 드러나지 않을 수 있다.

하나의 쓰기만 추적하는 구현이라면 주소 보관 여부와 데이터 보관 여부를 각각 두고, 둘 다 채워졌을 때 처리하는 방식으로 생각할 수 있다. 이미 보관한 주소를 잃지 않으려면 주소 저장 공간이 찬 동안 추가 주소를 받지 않아야 한다. 데이터도 마찬가지다. ready를 올려 실제 수락했다면, 그 정보에 필요한 저장과 후속 처리의 책임을 맡았다는 뜻이다. 슬롯이 하나인데 두 주소를 연속 수락해 첫 주소를 덮어쓰는 것은 독립 채널의 허용 범위를 잘못 이용한 것이다.

여러 요청을 동시에 처리하면 이 상태는 큐와 거래별 추적으로 확장된다. 특히 AXI4의 W 채널에는 WID가 없다. 따라서 데이터 묶음을 주소의 순서에 맞게 연결해야 하며, AW와 W가 시간상 독립이라고 해서 임의의 주소와 임의의 데이터를 짝지을 수는 없다. 독립성은 전달 시점의 유연성이지 요청의 대응 관계를 없애는 규칙이 아니다. [Arm IHI0022H, A5.2의 표 A5-1·Write data ordering](https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/IHI0022H_amba_axi_protocol_spec.pdf)

응답도 별도로 세어야 한다. AXI4에서는 주소와 마지막 쓰기 데이터가 수락되기 전에 그 거래의 쓰기 응답을 내면 안 된다. 그러나 둘이 수락된 뒤 처리에 시간이 걸릴 수 있고, 응답이 준비되어도 송신자가 BREADY를 내릴 수 있다. 이때 응답을 보존하고 나중의 handshake까지 기다리는 것이 정상이다. 응답 valid를 한 사이클만 펄스로 내보내면 경계 8의 수락 기회를 잃는다.

여기서 응답을 받았다는 표현을 물리적인 최종 메모리 셀의 쓰기가 끝났다는 표현과 무조건 같게 쓰지 않아야 한다. 버퍼 가능한 쓰기 등에서는 중간 지점의 응답과 최종 목적지의 완료가 구분된다. 실제 소프트웨어가 필요로 하는 가시성과 순서의 의미는 거래 속성과 시스템 계약까지 확인해야 한다.

다섯 채널을 나눈 비용은 저장 상태와 대응 관계를 회로가 관리해야 한다는 데 있다. 그 대신 한 경로의 지연이 모든 정보의 전달을 똑같이 묶지 않도록 구현할 수 있다. AXI를 읽을 때 “요청을 받았다”는 말을 주소 수락, 데이터 수락, 응답 수락으로 나누어 적어 보자. 서로 다른 경계에서 일어난 세 사건을 하나의 쓰기로 연결하는 것이 독립 채널 구현의 핵심이다.

