---
title: "같은 길이의 AXI burst가 시작 주소에 따라 실패하는 이유"
author: "브레이브브라우저쓰자"
published_at: "2026-10-27T07:31:03.765Z"
updated_at: "2026-10-06T02:44:56.241Z"
tags: ["axi burst 경계"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/%EA%B0%99%EC%9D%80-%EA%B8%B8%EC%9D%B4%EC%9D%98-axi-burst%EA%B0%80-%EC%8B%9C%EC%9E%91-%EC%A3%BC%EC%86%8C%EC%97%90-%EB%94%B0%EB%9D%BC-%EC%8B%A4%ED%8C%A8%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0"
ai_assisted: true
---

# 같은 길이의 AXI burst가 시작 주소에 따라 실패하는 이유

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

[원문](https://ariser.io/@writer_a9817d5a8de0/%EA%B0%99%EC%9D%80-%EA%B8%B8%EC%9D%B4%EC%9D%98-axi-burst%EA%B0%80-%EC%8B%9C%EC%9E%91-%EC%A3%BC%EC%86%8C%EC%97%90-%EB%94%B0%EB%9D%BC-%EC%8B%A4%ED%8C%A8%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0)

DMA가 연속된 메모리에 긴 burst를 보냈는데, 같은 크기의 전송이 어떤 시작 주소에서는 되고 다른 주소에서는 거절될 수 있다. AXI burst 경계는 데이터 총량만으로 판단하지 않기 때문이다. beat의 크기와 개수, 시작 위치가 함께 한 거래의 주소 범위를 결정한다. 특히 4KB 경계는 긴 전송을 만들 때 따로 계산해야 하는 조건이다.

AXI4 INCR burst의 개수는 AxLEN+1이고, 한 beat의 최대 바이트 수는 2^AxSIZE다. INCR에서는 주소가 전송 크기에 맞춰 증가한다. 규격은 한 burst가 4KB 주소 경계를 넘는 것을 금지한다. 이 제한은 경계를 사이에 둔 목적지 분리를 다루는 데도 의미가 있다. [Arm IHI0022H, A3.4.1 Address structure](https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/IHI0022H_amba_axi_protocol_spec.pdf)

시작 주소가 beat 크기에 정렬된 INCR burst부터 보자. 주소를 a, beat 수를 n, beat 크기를 s라고 하면 마지막 beat의 시작 주소는 a+(n-1)s다. 마지막으로 접근 가능한 바이트는 a+ns-1이다. 이 둘은 서로 다른 숫자다. 마지막 beat 시작이 경계 안에 있는지만 보는 검사보다 마지막 바이트까지 같은 4KB 영역에 있는지 확인하는 것이 분명하다.

가상 64비트 데이터 버스에서 8바이트 beat 8개를 0x0FE0부터 요청한다고 하자. AxSIZE=3이고 AxLEN=7이다. 시작점의 4KB 안쪽 오프셋은 4064이며 경계까지 4096-4064=32바이트가 남았다. 요청은 64바이트를 담는 burst이므로 범위를 넘는다. 마지막 beat 시작은 0x1018, 마지막 바이트는 0x101F다.

경계를 지키려면 요청을 만들 때 네 beat와 네 beat로 나눌 수 있다. 첫 burst는 0x0FE0에서 시작해 마지막 beat 시작 0x0FF8, 마지막 바이트 0x0FFF까지 간다. 두 번째는 0x1000에서 시작해 마지막 바이트 0x101F까지 간다. 각각 AxLEN=3이며, 둘을 합치면 원래 의도한 64바이트를 같은 순서로 전달한다. 이것은 일반 메모리의 연속 데이터를 두 요청으로 발행하는 가상 예다.

정렬된 INCR에 대해 다음 계산은 경계 안에 담을 수 있는 최대 beat 수를 알려 준다.

```text
remaining_bytes = 4096 - (start_address mod 4096)
boundary_beats  = remaining_bytes / beat_bytes
issue_beats     = min(wanted_beats, boundary_beats, interface_limit)
AxLEN           = issue_beats - 1
```

여기서는 시작점이 beat 크기에 정렬되어 나눗셈이 정확히 떨어진다. interface_limit에는 AXI4 INCR의 최대 256뿐 아니라 실제 연결 대상이 지원하는 더 작은 한계도 반영해야 한다. burst가 경계를 지켰다고 해서 수신기가 모든 길이와 크기를 지원한다는 뜻은 아니다.

비정렬 요청까지 같은 공식에 넣으면 틀릴 수 있다. INCR의 후속 beat 주소는 첫 시작 주소에 계속 s를 더하는 대신, 크기 s로 정렬한 주소를 기준으로 증가한다. 8바이트 크기, 한 beat를 0x0FFD에서 시작하는 경우를 보자. 유효한 첫 beat의 바이트 범위는 0x0FFD부터 0x0FFF까지이며, 정렬 기준은 0x0FF8이다. 시작 주소에 단순히 8을 더해 마지막 바이트를 0x1004로 계산하면 존재하지 않는 부분까지 센다. 쓰기라면 strobe도 이 합법적인 바이트 위치와 맞아야 한다. [Arm IHI0022H, A3.4.1의 Burst address 수식·A3.4.4](https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/IHI0022H_amba_axi_protocol_spec.pdf)

같은 비정렬 시작점에서 두 beat를 요청하면 다음 beat 주소는 0x1000이 된다. 이때는 경계를 넘어선다. 반대로 주소 0x1000에서의 요청은 새 4KB 영역 안에서 시작한다. 경계 검사는 주소의 낮은 12비트와 크기만 보고 익숙한 계산을 적용하기보다, burst 종류의 실제 주소 생성 규칙에 맞추어야 한다.

WRAP에서는 지정된 범위 끝에 도달하면 그 범위의 처음으로 되돌아간다. FIXED는 각 beat가 같은 주소를 사용한다. 따라서 INCR용 범위 공식으로 세 종류를 모두 검사하면 안 된다. 예를 들어 4바이트씩 네 beat를 0x003C에서 시작하는 합법적인 WRAP의 주소는 0x003C, 0x0030, 0x0034, 0x0038이다. 단순 증가로 0x0048까지 간다고 해석하면 원래 거래와 다른 주소들을 검사한다.

분할할 때도 “데이터만 이어 보내면 된다”는 가정은 부족하다. 쓰기 요청을 두 burst로 나누면 각 burst의 마지막 데이터 표시와 쓰기 응답을 각각 처리해야 한다. 읽기도 요청한 beat 수와 마지막 표시가 새 거래에 맞아야 한다. 주변장치나 exclusive access처럼 요청 단위 자체에 의미가 있는 경우에는 일반 메모리 전송처럼 자유롭게 바꿀 수 있다고 가정하지 말고 속성과 허용 변환을 확인해야 한다.

AXI burst 경계를 다룰 때 가장 유용한 습관은 마지막 주소를 하나 더 쓰는 것이다. 마지막 beat 시작 주소 옆에 마지막 합법 바이트 주소를 적고, 시작점과 같은 4KB 영역인지 확인해 보자. 정렬된 INCR의 간단한 산식과 비정렬·WRAP의 실제 주소 규칙을 구분하면, 길이를 늘렸을 때 생기는 주소 오류를 전송 전에 찾아낼 수 있다.

