NIC-301/400 CDAS의 이해

NIC-301과 NIC-400은 ARM사의 on-chip interconnect IP인데, NIC-301의 경우 AXI3 프로토콜까지를 지원하며 NIC-400에는 NIC-301에 더해 AXI4 프로토콜 지원, QoS Virtual Networks, Thin Links 등의 기능이 추가되었습니다. NIC-301과 NIC-400이 처음 발표된 해가 각각 2006년과 2012년이니 매년 새로운 기술이 발표되는 칩 설계 분야에서는 꽤나 오래된 IP이긴 합니다만 여전히 다양한 칩설계에 활발히 적용되고 있습니다. 이번 글에서는 NIC-301/400 의 여러기능 중에 Cyclic Dependency Avoidance Scheme(이하 CDAS)에 대해서 살펴보도록 하겠습니다.

AXI 프로토콜의 특징 중 CDAS와 관련된 두가지는 Multiple Outstanding Request(이하 MOR)와 AXI ID를 이용한 transaction의 tagging입니다. MOR은 이전 transaction이 완료되기 전에 다음 transaction을 시작하는 방식으로 transaction을 pipeline화 하여 DRAM 컨트롤러 등과 같이 latency가 긴 IP를 접근할 때의 성능을 향상 시키는 기능이며, AXI ID의 경우 순서가 상관없는 transaction간에는 서로 다른 ID로 tagging하고 순서가 반드시 지켜져야할 transaction들은 같은 ID를 tagging하면 꼭 필요한 부분 이외에는 on-chip 트래픽의 비순차(out-of-order) 진행을 통해 시스템의 전반적인 성능 향상을 기대할 수 있습니다. AXI 프로토콜의 특징에 대해 조금 더 자세한 내용이 궁금하실 경우 제가 예전에 썼던 글을 참고하시기 바랍니다.

Master 1개와 Slave 2개가 연결된 간단한 AXI 버스

공학에서는 항상 얻는것이 있으면 잃는것이 있기 마련이라, AXI 프로토콜은 MOR과 AXI ID tagging을 통해 on-chip interconnect의 사용률을 높일 수 있는 가능성을 열었지만 위의 그림과 같이 단지 Master 1개와 Slave 2개로 이루어진 아주 간단한 버스에서 조차 deadlock이 생길 수 있는 가능성도 함께 얻었습니다. NIC-301/400의 CDAS는 AXI transaction의 비순차 실행에 의한 deadlock을 피하기 위한 방법인데, 먼저 deadlock 발생 조건을 살펴본 후에 NIC-301/400에서 지원하는 CDAS가 어떤 방식으로 이를 회피하는지 살펴보도록 하겠습니다. 참고로 이 글에서 예로 들고있는 deadlock 시나리오는 “On Deadlock Problem of On-Chip Buses… (링크)” 라는 논문에 나와있는 예를 사용했음을 알려 드립니다.

4개의 AXI transaction이 순차적으로 실행되는 경우

먼저 이해를 위해 앞에서 예로 든 간단한 버스에서 위의 그림과 같이 4개의 transaction (T0~T3)이 순차적으로 진행하는 경우를 생각해 보도록 하겠습니다. 실제 AXI 프로토콜에는 phase가 보다 자세히 나눠져 있지만 설명상의 편의를 위해 간단히 각 transaction은 request(Req)와 response(Resp) phase로 이루어져 있고 Master가 Slave에 Req를 보낸 후 Resp를 받으면 하나의 transaction이 완료된다고 가정합니다. 위의 그림에서 transaction별로 다른 색상이 사용되었는데 붉은색 계열은 AXI ID 0를, 파란색 계열은 AXI ID 1을 사용한 transaction으로 정하겠습니다. 위의 예에서는 Master 0가 첫번째와 네번째 (T0 와 T3) transaction을 통해서 Slave 0를 접근하고 두번째와 세번재 (T1 과 T2) transaction을 통해서 Slave 1을 접근하는데, 각 slave 마다 다른 AXI ID를 번갈아 사용하는 상황을 보여 주고 있습니다. 이 경우에는 deadlock은 발생하지 않고 각각의 Master가 Req를 보낸 순서대로 Resp가 돌아와 T0~T3 transaction들은 문제없이 진행됩니다.

Slave의 비순차 Resp 생성으로 인한 deadlock 발생

이제는 앞의 상황에서 Slave가 Resp를 비순차적으로 발생시킴으로서 deadlock이 발생하는 상황을 설명할 차례인데, 그 전에 AXI 프로토콜 스펙문서에서 정의하고 있는 Transaction Ordering에 대해 짚고 넘어가는 것이 좋을 것 같습니다. 아래는 transaction 간의 순서에 대해 정해진 규칙의 일부를 발췌한 내용인데 보다 자세한 내용이 궁금하실 경우 AXI 프로토콜 스펙문서의 “A5.3 Trasaction Ordering” 섹션을 읽어보시기 바랍니다.

AXI transaction ordering rule(일부 발췌)
1. 같은 AXI ID에 대해 Master에 되돌아오는 Resp는 Master가 Req를 보낸 순서와 일치해야 한다.
2. Slave에서 다른 AXI ID를 사용하는 transaction들에 대해서는 Req를 받은 순서에 상관없이 Resp을 보낼 수 있다.

윗 그림의 예에서 Slave 0와 Slave 1 모두 다른 AXI ID를 가진 transaction 2개를 처리하는 상황이기 때문에 Resp를 보내는 순서가 바뀌어도 문제가 없으며(AXI transaction ordering rule 2번) Slave 1의 경우 비순차 실행을 하여 T2(Resp)을 선행 transaction의 T1(Resp) 보다 먼저 Master로 되돌리고 있습니다. 반면 Master 쪽에서 보면 아직 같은 AXI ID를 사용하고 먼저 시작된 T0(Req)에 대한 T0(Resp)이 Slave 0로 부터 돌아오지 않은 상황이기 때문에 AXI 버스는 T2(Resp)을 Master에 전달하지 않고 버스 내부의 buffer에 저장합니다(AXI transaction ordering rule 1번). 그 다음 Slave 0에서 발생하는 T3(Resp)의 경우도 동일한 이유로 T1(Resp)이 Master에 돌아올 때 까지 전달되지 못하고 버스 내부의 buffer에 저장되지요. 일반적으로 버스 내부의 response buffer는 slave 별 FIFO 로 구현이 되기 때문에 Slave 1의 경우 T2(Resp)에 막혀 이후 발생된 T1(Resp)을 Master로 전달하지 못하고 Slave 0의 경우 T3(Resp)에 막혀 이후 발생된 T0(Resp)을 Master로 전달하지 못하게 되는데, 이 때문에 위의 그림에서 붉은 화살표로 표시한 것과 같이 T0(Resp) ~ T3(Resp) 사이의 의존관계가 서로가 서로를 기다리는형태(Cyclic Dependency)가 되어 어느 transaction도 더 이상 진행하지 못하는 deadlock이 발생합니다.

ARM의 NIC-301/400은 이러한 deadlock을 피하기 위해 아래와 같은 두 가지 방식의 CDAS를 제공하는데 두 가지 방법에는 성능과 resource의 trade-off 관계가 있습니다. 

  1. Single Slave
  2. Single Slave per ID

먼저 “Single Slave” 방식은 가장 간단하게 AXI ID에 상관없이 master가 한번에 하나씩의 slave 만을 access하도록 허용하는 방법입니다. 위의 예에서 T0와 T1은 각각 다른 slave를 접근하므로 T1(Req)는 T0(Resp)을 받기전에 시작될 수 없으며 마찬가지로 T3(Req)는 T2(Resp)이 돌아오기 전에 시작될 수 없습니다. 아래 그림은 처음에 예로 들었던 T0~T3 transaction 4개가 순차적으로 실행되는 경우에 대해 “Single Slave” CDAS가 적용된 상황을 보여 주고 있는데 deadlock의 가능성은 없앴지만 다른 slave로 가는 transaction이 이어지는 시점에서 transaction이 pipeline되지 못하므로 성능이 떨어지는 단점이 있습니다.

순차적으로 실행하는 4개의 AXI transaction에 대해 “Single Slave” CDAS가 적용되었을 경우

두 번째 CDAS 방식인 “Single Slave per ID” 의 경우 첫번째 방식의 단점을 보완하기 위해 AXI ID가 같은 transaction에 대해서만 single slave rule을 적용하는 방법인데, 각 ID 별로 진행중인 transaction이 어떤 slave를 접근 중인지 기억할 저장공간이 필요한 관계로 버스의 구현이 복잡해 지는 단점이 있지만, ID가 다르면 이어지는 transaction이 다른 slave로 향하더라도 transaction pipeline이 유지되어 성능저하를 피할 가능성이 좀 더 높습니다. 처음 예로든 T0~T3 transaction 순차 진행의 경우 “Single Slave per ID” CDAS가 적용되더라도 CDAS가 적용되지 않은 것과 동일한 transaction 진행이 가능하여 성능저하를 피할 수 있습니다. 위에서 예를 든 deadlock 발생 시나리오에 “Single Slave per ID” CDAS가 적용된다면 T1(Req) 이후 T0(Resp)이 돌아올 때 까지 T2(Req)가 시작되지 않아 T2(Resp)이 T1(Resp)을 막을 가능성을 차단합니다.

마지막으로 한 가지 더 언급하면 NIC-400의 경우 위에서 설명한 두가지 CDAS 방식 이외에 “Single Active Slave (이하 SAS)” CDAS를 지원하는데 이 부분은 설명이 복잡하여 이번 글 에서는 다루지 않고 다음 글로 남겨두겠습니다. 한 가지 짚고 넘어갈 부분은, 앞에서 설명한 두 가지 CDAS 방식이 버스 외부에 드러나는 Master 인터페이스 별로 설정하는 옵션이라면, SAS의 경우 버스 내부의 스위치 포트에 적용되는 CDAS 방식이며 설정이 필요할 경우 AMBA Designer 툴에서 자동으로 deadlock 발생조건을 판단해서 알려주기 때문에 반드시 원리를 이해하지 않고 NIC-301/400을 사용하더라도 크게 문제는 없습니다.

 

You may also like...

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.