두 채널짜리 TL-UL에서도 요청을 끝까지 기억해야 하는 이유
TL-UL은 채널이 적고 burst가 없어 주변장치 버스가 간단해진다. 그러나 요청을 한 번 내보내고 응답을 기다리는 선 두 개라고만 생각하면, 여러 요청이 진행 중인 순간에 답이 엉뚱한 요청에 연결될 수 있다. TL-UL의 단순함은 기능 범위가 작다는 뜻이며, 수락한 요청을 끝까지 추적하는 책임까지 줄어든다는 뜻은 아니다.
TileLink Uncached Lightweight는 Get 읽기와 Put 쓰기를 지원하는 최소 구현 수준이다. 요청은 A 채널, 응답은 D 채널을 사용하며 각 메시지는 한 beat 안에 들어간다. burst나 캐시 일관성 거래를 이 수준에 포함시키지 않는다. Put에는 전체 활성 바이트를 쓰는 PutFullData와 일부 바이트를 고르는 PutPartialData가 있고, 읽기는 AccessAckData, 쓰기는 AccessAck로 응답한다. TileLink 1.7.1, 6장 TL-UL
A와 D의 정보가 같은 경계에 움직여야 하는 것은 아니다. valid와 ready가 함께 성립하는 경계에서 해당 메시지가 전달되며, 요청을 수락한 뒤 응답이 나중에 돌아올 수 있다. 준비된 응답이 먼저 돌아오는 순서도 가능하다. 여기서 요청의 source와 응답의 source가 같은 거래를 가리켜야 한다.
32비트의 가상 인터페이스에서 두 요청을 보자. 장치는 정렬된 4바이트 접근을 지원하고, 두 주소는 독립된 메모리 위치라고 하자. 각각의 크기는 a_size=2이고 mask는 0b1111이다.
| A 요청 | source | 주소 | 동작 |
|---|---|---|---|
| X | 2 | 0x1000 | Get, 예상 읽기 값 0x11223344 |
| Y | 5 | 0x1004 | PutFullData, 값 0xAABBCCDD 쓰기 |
Y의 쓰기가 먼저 끝나면 D에서 source 5, AccessAck가 올 수 있다. 다음 source 2, AccessAckData와 0x11223344가 오면 X를 완료한다. 요청을 넣은 순서대로 응답의 첫 항목과만 비교하면 Y의 합법적인 응답을 X의 잘못된 응답으로 판단하게 된다. source별 pending 상태로 어느 요청을 완료하는지 알아야 한다.
AXI에서 익숙한 ID별 큐를 같은 의미로 가져오면 안 되는 부분도 있다. TileLink에서는 같은 링크의 A 채널에서 진행 중인 요청의 source가 유일해야 한다. X가 아직 응답을 받지 않았는데 새 Z도 source 2로 보낼 수는 없다. 응답을 완료한 뒤에야 그 source를 새 요청에 사용할 수 있다. OpenTitan의 protocol checker도 source 하나당 미완료 요청 하나라는 조건을 검사한다. TileLink 1.7.1, 5.4 Source and Sink Identifiers, OpenTitan TL-UL Protocol Checker
가상 host가 source를 2비트로 쓰면 가능한 이름은 0부터 3까지 네 개다. 미완료 거래가 네 개면 이름을 그대로 재사용해서 다섯 번째 요청을 진행시킬 수 없다. 더 많은 동시 요청을 원하면 필요한 식별자 범위와 저장 공간을 함께 늘려야 한다. 실제 interconnect는 host의 source에 경로 비트를 덧붙이거나 다시 매핑할 수 있으므로, 링크를 지날 때 보존되는 범위도 확인해야 한다. source가 시스템 전체의 고정된 host 번호라는 가정은 맞지 않는다.
크기와 mask도 단순한 메모리 바이트 수가 아니다. 예를 들어 32비트 버스에서 2바이트 범위를 쓰려면 a_size=1이며, 주소는 그 크기에 맞춰 정렬되고 mask는 해당 활성 lane을 골라야 한다. PutPartialData는 크기로 정한 범위 안에서 일부 바이트만 쓰는 것을 표현한다. 따라서 a_size=2라고 해서 mask에 반드시 네 비트가 켜지는 것은 아니다. 대상 장치가 어떤 부분 쓰기를 지원하는지는 또 다른 조건이다.
OpenTitan은 기본 TL-UL에 user 정보를 더해 instruction 종류와 command·data·response integrity 정보를 전달한다. 이는 해당 프로젝트의 확장이며, 기본 TL-UL의 모든 구현에 같은 필드와 검사 방식이 있다는 뜻은 아니다. 주소·opcode·mask와 데이터가 검사 정보와 맞게 함께 전달되어야 하며, 변환기가 payload만 수정하고 검사 정보를 그대로 두면 정상적인 변환이 오류로 보일 수 있다. OpenTitan TL-UL, Signals·Usage of User Bits
검사 역시 구현 수준이 나뉜다. OpenTitan 문서는 일부 요청 위반을 runtime d_error로 알리는 검사와, 설계 검증에서 assertion으로 확인하는 기본 조건을 구별한다. 프로토콜 checker가 있다는 말만으로 모든 위반에 회로가 오류 응답을 생성한다고 생각하면 안 된다. 실패한 읽기의 응답을 정상 데이터로 사용하지 않도록 host도 error와 응답 종류를 함께 처리해야 한다.
TL-UL 회로를 이해하려면 요청 수락 시 source·종류·크기를 기록하고, D 응답에서 대응하는 항목을 확인하는 작은 표부터 만들어 보자. 한 beat 메시지라는 단순한 구조 안에서도 여러 요청의 동시 진행, 주소와 mask의 일치, 프로젝트별 검사 정보가 남는다. 기능을 덜어낸 만큼 무엇을 지원하고 어떤 조건에서 응답하는지 선명하게 정하는 것이 TL-UL의 장점이다.