01signal.com

덜 중요한 실전 FPGA 역량

이 페이지는 전문 FPGA 설계자가 되는 방법을 다루는 다섯 편짜리 연재의 네 번째 글입니다. 이번에는 처음 시작할 때는 덜 중요하지만 언젠가는 유용할 수 있는 역량 몇 가지를 다룹니다. 무엇보다 이런 이야기를 왜 하는지부터 설명하겠습니다.

중요하지 않은 것을 왜 언급할까요?

역량에 관한 페이지를 쓰면서 동시에 "음, 이건 별로 중요하지 않습니다"라고 말하는 것이 좀 이상하게 들릴 수 있습니다. 하지만 이 연재는 제가 여러분에게 무엇을 하라고 지시하는 글이 아닙니다. 오히려 각 주제가 왜 중요한지(혹은 그다지 중요하지 않은지)를 설명하려는 것입니다. 그러니 덜 중요한 주제에 대해서도 같은 방식으로 다루는 것이 자연스럽습니다.

어떤 실전 역량은 자주 유용하지만 과대평가되기도 합니다. 언젠가 익혀야 할 수도 있지만, 평생 필요 없을 수도 있는 역량이죠. 어떤 주제가 과대평가되는 이유는, 보드용 예제 설계에 자주 등장하기 때문입니다. 그것이 중요해서가 아니라, 특정 기법으로 멋지고 인상적인 데모를 만들기가 상대적으로 쉽기 때문입니다.

분명히 해 두자면, 아래에서 언급하는 역량은 모두 유용합니다. 다만 프로젝트를 진행하면서 필요에 따라, 그리고 그 프로젝트의 요구 사항에 특화된 다른 수많은 기술 주제들과 함께 익히게 되는 경우가 많다는 것뿐입니다.

I2C와 SPI

이 두 가지에 대해 아무것도 모른 채 FPGA 설계자로 평생 일할 수도 있습니다. 하지만 현실적으로는 실무에서 꽤 일찍 마주칠 가능성이 큽니다.

I2C(IIC, Inter-Integrated Circuit)와 그것과 아주 비슷한 프로토콜들, 그리고 SPI(Serial Peripheral Interface)는 PCB 위의 전자 부품과 데이터를 주고받기 위한, 단연 가장 흔한 표준입니다. 이들은 마스터 / 슬레이브 (master / slave) 구성에 기반하는데, 마스터가 읽기나 쓰기 동작을 시작하면 슬레이브가 거기에 응답할 수 있습니다. 대부분의 경우 마스터는 프로세서나 비교적 정교한 부품이고, 슬레이브는 전자 설계에서 주변 기능을 담당하는 더 단순한 부품입니다.

I2C와 그에서 파생된 프로토콜들은 데이터 레이트가 아주 낮고(보통 100 kbit/s 정도), 주로 부품의 파라미터를 설정하는 데 쓰입니다. 예를 들어 부품이 A/D 변환기라면, I2C로 그 부품이 어떤 전압 기준을 쓸지, 출력을 부호 있는 정수로 낼지 부호 없는 정수로 낼지를 선택할 수 있습니다. 이 프로토콜의 주된 장점은 연결이 단 두 가닥의 선, 즉 클록(SCL)과 데이터(SDA)로 이루어진다는 것입니다. 그라운드(GND) 연결도 있지만, 이는 보통 PCB의 공통 그라운드를 통해 이루어지고 별도의 선이 필요한 경우는 거의 없습니다.

이 프로토콜은 사실 버스이므로, 각 데이터 교환 사이클에 7 비트 주소가 포함됩니다. 따라서 이 두 가닥의 선에 여러 부품을 병렬로 연결할 수 있습니다. 이 경우 각 부품은 서로 다른 주소를 가져야 합니다.

I2C 표준은 원래 Philips가 특허를 냈습니다. 너무 유용했기 때문에, 이와 놀랄 만큼 비슷한 변형들이 흔히 쓰입니다. 예를 들어 SMBus, PMBus, DDC2 같은 것들입니다. 이 표준들은 I2C의 핵심 아이디어를 받아들이되 파라미터(특히 데이터 레이트)와 주 용도가 조금씩 다릅니다. 예를 들어 오늘날 판매되는 모든 컴퓨터 모니터에는 어떤 그래픽 모드를 지원하는지에 대한 정보를 담은 작은 플래시 메모리가 있습니다. 컴퓨터의 그래픽 카드와 모니터 사이의 케이블에는 이 플래시 메모리에 연결되는 두 가닥의 선이 있습니다. 그래서 그래픽 카드가 DDC2 프로토콜로 이 메모리의 데이터를 읽을 수 있는데, 이는 사실상 I2C와 같습니다.

그러니 I2C를 이해하면, 아주 다양한 부품들이 서로 어떻게 대화하는지 아는 셈입니다.

다음은 SPI입니다. 이 프로토콜은 보통 마스터와 슬레이브 부품 사이에 네 가닥의 선(SCLK, MOSI, MISO, SSn)이 필요합니다. 때로는 I2C와 그 변형들처럼 부품을 설정하는 데 쓰이기도 합니다. 그러나 SPI의 주 용도는 더 높은 데이터 레이트로 데이터를 전송하는 것입니다. 부품이 20–50 MHz의 SCLK 주파수를 지원하는 경우도 드물지 않아서, 응용 데이터를 전송하기에 실용적인 프로토콜입니다. 예를 들어 두 개의 오디오 채널용 A/D 변환기는 48,000 Hz × 2 × 16 비트 = 1.536 Mbit/s를 만들어 냅니다. 이런 데이터 레이트는 SPI에게 식은 죽 먹기입니다. 실제로 샘플 전송에 SPI를 쓰는 오디오 칩도 여럿 있습니다.

FPGA와, FPGA가 비트스트림 (bitstream)을 읽어 오는 플래시 메모리 사이의 연결이 흔히 QSPI라는 점도 언급할 가치가 있습니다. 이 인터페이스는 일반 SPI와 같지만 데이터 선이 하나가 아니라 네 개라서 데이터 전송이 더 빠릅니다.

그러면 결론적인 질문으로 돌아가 보죠. FPGA 설계자가 되기 위한 과정에서 I2C와 SPI를 배워야 할까요? 제 생각에는 이것들 자체는 FPGA 설계와 아무 관련이 없습니다. 하지만 전자 제품을 개발하는 작은 팀에서 일한다면, I2C로 부품 하나를 설정해야 할 가능성이 큽니다. 아니면 FPGA에 연결된 부품 중 하나가 통신에 SPI를 쓸 수도 있고요. 혹은 FPGA의 비트스트림이 담긴 플래시 메모리를 자기 로직에서 직접 사용할 수도 있습니다.

이 두 프로토콜에는 용도가 아주 많지만, 가장 중요한 것은 데이터시트에서 이것들과 그 변형들을 알아보는 것입니다. 어떤 부품이 이 프로토콜 중 하나를 쓰면서 그 이름을 명시하지 않는 경우가 많습니다. I2C의 원리를 알고 있다면, 데이터시트가 비슷한 인터페이스를 설명할 때 그것을 놓칠 수 없습니다. SPI도 마찬가지입니다.

그리고 취업 면접에서 경험 많은 FPGA 설계자라고 주장하면서 이 두 프로토콜에 대해 아무것도 모른다면, 그다지 인상적이지 않을 수 있습니다.

덧붙여, 경험을 쌓기 위한 프로젝트 하나를 제안하겠습니다. I2C나 그 변형을 쓰는 저렴한 온도 센서나 다른 단순 부품을 찾기는 꽤 쉽습니다. 그런 부품을 하나 사서 듀폰 와이어나 다른 편법으로 FPGA 보드에 연결하세요. 그런 다음 I2C로 그것과 상호작용하는 데 필요한 모든 것을 처음부터 작성해 보세요. 오실로스코프가 있다면 그것으로 신호를 관찰하세요. 이것이 여러분의 첫 번째 직접 만드는 프로젝트가 될 수 있습니다.

블록 디자인

대부분의 FPGA 설계 도구는 로직 설계 블록을 그래픽 인터페이스로 연결할 수 있는 기능을 제공합니다. 원칙적으로 이 인터페이스를 쓰는 것은 Verilog에서 모듈을 인스턴스화 (instantiation)하는 것과 상당히 비슷합니다. 그래픽으로 그린 와이어는 Verilog의 포트 연결과 같습니다. 블록 디자인 도구는 보통 몇 가지 기능을 더 제공하는데, 예를 들어 GUI에서 만든 연결이 사용자가 의도한 대로 동작하도록 보장하는 작은 로직 조각을 자동으로 끼워 넣는 기능이 있습니다.

블록 디자인 방법은 모든 블록, 혹은 대부분의 블록을 FPGA 벤더가 (IP 블록 형태로) 공급할 때 가장 빛을 발합니다. 특히 프로세서가 관련된 경우, 블록 디자인은 보통 주변 기능을 구현하는 IP 블록들과 프로세서를 연결하는 자연스러운 방법입니다. 인터럽트 컨트롤러, DMA 컨트롤러, 버스 중재기 등등이죠. 이더넷 컨트롤러처럼 더 '고전적인' 주변 장치도 있습니다.

프로세서와 분명히 관련된 블록 외에도, FPGA에서 흔히 구현되는 다양한 기능을 구현하는 IP 블록이 많이 있습니다. 클록 자원이나 I/O 핀에 인접한 로직 같은 FPGA 요소부터, 단순한 산술 연산 장치, 디지털 필터, 심지어 더 복잡한 로직까지 아우릅니다. 블록 디자인만으로 FPGA 설계 전체를 만들 수 있게 하려는 의도였던 것 같습니다.

그렇긴 해도, 이런 기성 IP 블록만으로 제대로 쓸모 있는 FPGA 프로젝트를 만들었다는 사람은 들어 본 적이 없습니다. 프로세서와 그 주변 장치만으로 이루어진 프로젝트라면 예외겠지만, 프로세서만 원한다면 왜 FPGA를 쓰겠습니까? 훨씬 비싸고 복잡한데 말이죠.

하지만 블록 디자인 전체는 다른 Verilog 모듈이나 IP와 마찬가지로 Verilog 모듈 안에서 인스턴스화 (instantiation)할 수 있고, 보통 그렇게 합니다. 따라서 블록 디자인은 대개 더 큰 Verilog 기반 프로젝트의 일부입니다. 이런 맥락에서 프로세서와 그 주변 장치만 담은 블록 디자인은 말이 됩니다. 더 큰 프로젝트 안의 모듈 하나일 뿐이니까요.

그러면 이것이 여러분이 배워야 할, 아니 어쩌면 배우지 말아야 할 역량이라는 관점에서 무슨 뜻일까요?

가장 단순한 역량은 블록 디자인을 만들고, 블록을 추가하고, 그것들을 연결하는 것입니다. 무엇을 언제 클릭하라고 알려 주는 튜토리얼이 얼마든지 있습니다. 그런 튜토리얼은 따라 하기도 쉽고 완성하기도 쉬우니, 하나나 둘쯤 해 보는 건 어떨까요? 그리고 그렇게 한다면, 과정 전체에서 이루어지는 각 단계와 각 선택을 이해하려고 애쓰지는 마세요. 핵심은 블록 디자인이 어떻게 이루어지는지 감을 잡는 것입니다. 관련성이 생기면 그때 세부 사항을 파고드세요.

다음 역량은 블록 디자인을 프로젝트에 포함하고, Verilog 모듈에서 그것을 인스턴스화 (instantiation)하는 것입니다. 이것도 꽤 간단하고, 예제도 많습니다. 프로젝트에서 어떤 IP든 쓰는 것과 다르지 않습니다. Verilog 프로젝트에서 FIFO IP를 쓰는 법을 안다면, 블록 디자인도 같은 방식으로 쓸 줄 아는 것입니다.

가장 중요한 역량은 Verilog로 작성한 무언가를 블록 디자인에서 쓸 수 있는 블록으로 바꾸는 것입니다. 그리고 더 나아가, Vivado 자체 GUI(혹은 사용하는 개발 스위트)로 이 블록을 설정 가능하게 만드는 것입니다. 직접적인 목적이 있지 않다면 이것을 배우라고 권하지는 않겠습니다. 대부분의 FPGA 설계자는 이런 종류의 일을 할 필요가 전혀 없습니다.

그러면 결론은 무엇일까요? 여느 GUI 도구와 마찬가지로, 조금 가지고 놀아 보고, 그다음에는 작업을 완수하는 데 필요한 만큼 점진적으로 배우세요. 특히, 사용 가능한 블록들의 집합이 마치 그게 정답인 것처럼 오해하게 만들더라도, 블록 디자인만으로 모든 것을 하려고 기대하지 마세요.

FPGA 내부의 프로세서 다루기

많은 프로젝트, 특히 독립형 전자 제품에는 무언가 소프트웨어가 돌아가고 있어서 프로세서가 관련됩니다. 이 프로세서는 FPGA 내부의 블록일 수도 있고, FPGA 외부의 별도 물리적 부품일 수도 있습니다. 각 경우에 어려움은 완전히 다릅니다.

FPGA 내부에 프로세서가 있는 시나리오부터 시작하겠습니다. AMD의 Zynq 패밀리처럼 실리콘에 ARM 프로세서가 내장된 '하드 프로세서 (hard processor)'일 수 있습니다. '하드 프로세서'는 산술 연산 장치나 PLL, 블록 메모리와 비슷한, FPGA 내부의 여느 로직 소자와 같습니다. 다만 프로세서 블록은 상대적으로 크고 핀도 아주 많다는 것뿐이죠.

FPGA에 '하드 프로세서'가 없으면, '소프트 프로세서 (soft processor)'에서 소프트웨어를 돌릴 수 있습니다. 예를 들어 AMD의 Microblaze나 Altera의 Nios 프로세서입니다. 차이는 프로세서가 FPGA의 일반 로직 소자('로직 패브릭')로 구현된다는 점입니다. 이 방법은 더 느리고 전력도 더 먹고 로직 자원도 소모하지만, 흔히 충분히 쓸 만하고 비용 효율적인 선택입니다.

'하드 프로세서'든 '소프트 프로세서'든, 원칙적으로는 다른 어떤 IP와 마찬가지로 FPGA의 로직과 연결되는 Verilog 모듈과 같습니다. 따라서 이것들을 FPGA의 일부로 보고, FPGA 설계자가 그 책임을 진다고 보는 것이 꽤 자연스럽습니다.

로직 설계에서 프로세서를 설정하는 일은 보통 비교적 쉬운 작업입니다. 예제와 템플릿이 아주 많기 때문입니다. 하지만 거기서 끝나는 일은 드뭅니다. 프로세서에는 특정 주변 장치가 있어야 하고, 이들은 프로세서의 메모리 공간에서 알려진 주소로 소프트웨어에서 접근할 수 있어야 합니다. 주변 장치는 흔히 인터럽트 요청 출력을 가지고 있는데, 이것을 프로세서에 제대로 연결하고 올바르게 설정해야 합니다.

소프트웨어 팀은 보통 프로세서에 전원이 들어오거나 리셋 신호를 받을 때 돌아가는 소프트웨어 조각을 누군가가 처리해 주기를 기대합니다. 이 소프트웨어는 무엇보다도 프로세서를 설정된 대로 동작시키기 위해 프로세서 자체의 하드웨어 레지스터에 값을 쓰는 루틴으로 이루어져 있습니다. 이 목적을 위해 개발 도구가 더 큰 소프트웨어 프로젝트에 포함할 C 코드를 만들어 주므로, 들리는 것만큼 어렵지는 않습니다. 그런데 이 파일들을 생성하고, 그것들이 FPGA 설계의 나머지와 동기화되어 있도록 보장하는 책임은 누구에게 있을까요? 작은 개발 팀에서는 FPGA 설계자입니다.

그것으로 충분하지 않다면, FPGA 설계자는 개발 중인 제품에 특화된 로직을 구현하는 주변 장치를 프로세서용으로 만들어야 할 수도 있습니다. 이 로직을 위한 드라이버를 C로 작성하는 일은 대개 더없이 반가운 일이죠.

그러면 이것은 FPGA 설계자가 되기 위한 과정의 일부로 배우기 시작할 만한 것일까요? 소프트웨어와 하드웨어의 교차점에서 일하고 싶다면, 어쩌면 그렇다고 말하겠습니다. 이미 C 프로그래머이고 저수준 프로그래밍을 좋아한다면, 이것이 맞을 수 있습니다. 특히 프로세서의 아주 두꺼운 사용자 매뉴얼을 이따금 읽는 것도 개의치 않는다면요. '어떻게 주변 장치 X를 두 개, 주변 장치 Y를 세 개 가질 수 있나?'에 대한 답이 거기 있습니다.

그러면 어떤 주제를 배워야 할까요? 프로세서가 소프트웨어를 어떻게 실행하는지, 메모리에 어떻게 접근하는지, 인터럽트가 어떻게 동작하는지, 그리고 프로세서가 전원이 들어올 때 어떻게 시작하는지에 대한 기본적인 이해를 얻으라고 말하고 싶습니다. 프로세서의 주소 맵을 보고, 메모리 영역이 어떻게 여러 세그먼트(온칩 RAM, 외부 RAM, 내부 레지스터, 외부 버스 접근 세그먼트 등)로 나뉘는지 보고, 그 전체가 어떻게 동작하는지 이해하세요.

AMBA 프로토콜(AXI3, AXI4, AXI4 Lite 등)의 원리, 특히 VALID / READY 핸드셰이크를 이해하는 것도 권합니다. 언젠가 주변 장치를 설계하게 된다면 AXI 슬레이브를 구현해야 할 가능성이 큽니다. 그리고 AXI를 네이티브로 쓰지 않는 프로세서(예를 들어 Altera의 프로세서)로 작업하더라도 원리는 같습니다.

여러분은 아마 프로세서의 전원 투입과 리셋 시 돌아가는 소프트웨어도 책임지게 될 것입니다. 그러니 이 소프트웨어가 어떻게 만들어지고, 프로세서 자체의 하드웨어 레지스터와 어떻게 관련되는지 익숙해지면 도움이 될 수 있습니다. 그리고 설계해야 할 주변 장치에 접근하기 위한 드라이버 루틴을 직접 작성하면 더 쉽습니다. 이런 이유로, C 프로그래밍을 잘하지 못하면 멀리 가지 못합니다. AI를 써서 코드를 작성하더라도, 그 코드가 정확히 무엇을 하는지 이해해야 합니다.

하지만 무엇보다도, 프로세서를 설정하고 클릭, 클릭, 클릭해서 마지막에는 보드에서 아주 인상적인 일이 벌어지는 긴 예제 프로젝트를 따라 하는 것으로는 별로 배우는 게 없다는 점을 알아 두세요. 배울 가치가 있는 것은 이미 누군가 다 해 둔 것이고, 여러분은 마지막 줄까지 클릭해 가면서 중요한 부분들을 건너뛴 것입니다. 그런 예제 프로젝트에서 가치 있는 게 있다면, 그것은 다 끝난 뒤에 일어납니다. 그 예제에서 무엇을 이해했나요? 프로젝트에서 무엇을 바꿀 수 있나요? 스스로 무엇을 시험해 볼 수 있나요?

FPGA 외부의 프로세서 다루기

꽤 자주, FPGA가 관련된 프로젝트에서 프로세서는 독립형 부품이거나 별도 보드의 일부입니다. 일반 데스크톱이든 산업용 x86 기반 메인보드든, 완전한 PC가 제품의 중심부인 경우도 드물지 않습니다. 이런 환경에서는 FPGA를 주변 장치로 보는 것이 흔합니다. FPGA의 목적은 프로젝트마다 다르지만, 프로세서(혹은 PC)가 대개 프로젝트의 중심으로 여겨지고, FPGA(와 그 주변 전자 회로)는 소프트웨어가 통제하고 관리하는 부품으로 여겨집니다.

프로세서가 별도의 물리적 부품이므로, 보통 소프트웨어를 포함해 그것에 관한 모든 것을 담당하는 별도의 팀이 있습니다. 프로세서와 관련된 FPGA 설계자의 업무는 주로 그것과 인터페이스하는 것입니다. 프로세서가 FPGA의 동작을 제어하는 역할만 한다면, 통신이 명령만으로, 어쩌면 레지스터를 읽고 쓰는 방식으로 이루어질 수도 있습니다. 이 경우 더 단순한 프로토콜이 흔히 쓰이는데, 특히 I2C와 SPI가 그렇습니다. 이 둘은 위에서 이미 다뤘습니다. SPI는 비교적 낮은 데이터 레이트의 데이터 교환에도 선택될 수 있습니다.

I2C와 SPI가 흔히 임베디드 프로세서에만 쓰인다는 점도 언급할 가치가 있습니다. PC 메인보드가 관련된 경우, 이런 프로토콜은 프로젝트 전용 주변 장치에는 덜 흔합니다. 팬을 제어하고 온도를 읽는 데 SMBus가 흔히 쓰이긴 하지만, 자기 주변 장치에 이런 종류의 프로토콜을 쓰는 일은 덜 흔합니다.

임베디드 프로세서(와 DSP)의 경우, FPGA와의 인터페이스가 그 프로세서(혹은 특정 벤더의 프로세서 계열)에 특화된 인터페이스를 통해 이루어지기도 합니다. 예를 들어 프로세서가 주소 / 데이터 버스 인터페이스로 FPGA에 접근하기 위해 FPGA에 연결된 물리적 핀이 많이 있을 수 있습니다. 이 버스와 인터페이스하는 로직을 구현하려면, 프로세서 벤더가 정의한 (항상 영리하게 설계된 것은 아닌) 프로토콜을 정확히 이해해야 합니다. 충족해야 할 타이밍 요구 사항도 있습니다. 하지만 이런 종류의 작업을 미리 준비해 둘 필요는 없습니다. 복잡한 I/O 프로토콜을 가진 다른 외부 부품과 인터페이스하는 것과 다르지 않기 때문입니다.

PC나 고급 임베디드 프로세서와의 인터페이스는 보통 PCIe(PCI Express) 인터페이스로 이루어집니다. 이는 견고하고 지원이 잘 되는 통신 채널로, 가장 단순한 설정에서 200 MB/s(페이로드 데이터 기준)의 데이터 레이트를 낼 수 있지만 한계는 없습니다. PCIe 프로토콜의 새 버전이 규칙적으로 나오고, 새 버전마다 데이터 레이트가 더 높아집니다. 실제 데이터 레이트 한계는 흔히 프로세서 자체가 감당할 수 있는 정도입니다.

PCIe의 단점은 복잡한 프로토콜이고, 주로 컴퓨터 주변 장치 칩을 위해 만들어진 것입니다. PCIe용으로 무언가를 구현한다면, 컴퓨터와 인터페이스하는 로직을 개발할 전담 인력과, 드라이버를 개발할 소프트웨어 팀도 배정했다고 암묵적으로 가정합니다. Xillybus를 쓰면 이 작업이 현저히 쉬워집니다. 이 해법이 양쪽의 복잡함을 처리해 주기 때문입니다.

그러면 외부 프로세서가 있는 시나리오에 대비해 어떤 역량을 배워야 할까요? 무엇보다도, C 프로그래밍을 잘하면 큰 도움이 됩니다. 프로세서에서 FPGA에 접근하기 위한 드라이버 루틴을 직접 작성하거나, 적어도 예제 코드를 제공할 수 있으니까요. AI가 이 코드를 대신 써 줄 수 있지만, 그 코드가 무엇을 하는지 정확히 이해하지 못하면, 마치 FPGA에서 온 것처럼 보이는 C 쪽 버그를 만들게 될 수도 있습니다.

그 외에는 미리 배우라고 권할 것이 별로 없습니다. 필요한 기술 역량은 프로세서와 FPGA가 어떻게 연결되는지에 크게 달려 있고, 이는 프로젝트마다 다릅니다.

다른 인터페이스 표준

시중에 나온 FPGA 개발 보드 여러 개를 훑어보면, 특정 부품과 커넥터가 다른 것보다 더 흔히 달려 있는 경향이 있습니다. 이는 FPGA 프로젝트에서 어떤 기술이 자주 쓰이는지에 대한 지표로 해석할 수 있습니다. 어느 정도는 사실이고, 그중 몇 가지를 짚어 보겠습니다.

HDMI

FPGA 보드에는 HDMI 커넥터가 흔히 있습니다. 용도는 대개 FPGA가 컴퓨터 모니터에 표시할 비디오 출력을 만들어 내게 하는 것입니다. 이 커넥터의 선은 흔히 FPGA로 바로 이어집니다. FPGA가 I/O 블록의 SERDES 덕분에 필요한 고속 신호를 만들어 낼 수 있기 때문입니다. 어떤 보드에는 FPGA와 HDMI 커넥터 사이에 별도의 부품('비디오 인코더')이 있습니다.

이 커넥터가 흔하다는 것은 실제로 현실을 반영합니다. 많은 FPGA 프로젝트에 어떤 형태로든 비디오 처리와 출력이 관련됩니다. FPGA 보드를 컴퓨터 모니터에 연결해 실험해 보면 앞으로 도움이 될 수 있습니다. 특히 VGA의 기본을, 화면이 어떻게 수평 및 수직으로 주사되는지, 그리고 어떤 표준 디스플레이 모드들이 있는지 배우세요. HDMI 커넥터가 FPGA에 바로 연결되어 있다면 신호를 만들어 내는 로직을 구현해 볼 수도 있지만, 그만한 가치가 있는지는 잘 모르겠습니다. 배우기 간단한 프로토콜이 아니고, 동작하지 않으면 디버깅하기도 어렵습니다. 선 위의 데이터 레이트가 아주 높고, 컴퓨터 모니터는 FPGA의 출력에 반응하기를 거부할 때 무엇이 잘못됐는지 알려 주지 않습니다. 이 목적을 위한 기성 IP 블록이 있습니다. 그것을 쓰고, 대신 비디오 데이터를 생성하는 데 집중하시길 권합니다.

그리고 작은 팁 하나. 여러분은 아마 RGB 픽셀을 모니터로 보내고 싶을 것입니다. 이 경우 HDMI가 아니라 (VGA와 관련 있는) DVI 프로토콜을 따르세요. DVI와 HDMI의 신호는 서로 호환됩니다. 하지만 HDMI는 표준 고화질 TV를 겨냥한 더 엄격한 프로토콜이고, 지원하는 디스플레이 모드가 좁습니다. 흔히 쓰이는 디스플레이 모드의 픽셀은 YCbCr 형식으로 표현되는데, 이는 불필요한 어려움입니다. HDMI 커넥터를 쓰는 것은 DVI 커넥터와 케이블이 크고 투박하기 때문입니다. 하지만 컴퓨터 모니터로 가는 신호는 거의 항상 HDMI가 아니라 DVI 표준을 따릅니다.

비디오 출력 프로젝트를 시험해 보면, FPGA 자체의 블록 RAM만으로는 이미지 한 프레임을 담기에 충분하지 않은 경우가 많다는 것을 곧 알게 될 것입니다. 그렇다면 다음 주제로 넘어가겠습니다.

DDR 메모리

FPGA 자체의 RAM은 상대적으로 귀한 자원입니다. 프로젝트가 메가바이트와 기가바이트를 다뤄야 할 때는 외부 메모리가 필요합니다. 비디오가 관련된 프로젝트에서 흔히 그렇지만, 코프로세싱 / 하드웨어 가속, 네트워크 스위칭 등 다른 응용에서도 마찬가지입니다.

단연 가장 흔히 쓰이는 외부 RAM은 DDR SDRAM으로, 컴퓨터에 쓰이는 것과 같은 종류입니다. 그래서 FPGA 개발 보드에도 자주 등장하며, 때로는 SODIMM 형태로, 더 흔하게는 보드에 직접 실장되어 있습니다. 가격이 저렴하고 대역폭이 뛰어나지만, 컴퓨터를 염두에 두고 설계된 것입니다. 따라서 접근 요청이 연속된 주소 범위에 대한 긴 버스트일 때 대역폭 효율이 좋습니다. 이들에 대해 덜 알려진 사실은, 접근 패턴이 덜 규칙적일 때 성능이 정말 형편없다는 것입니다. '랜덤 액세스 메모리(RAM)'라고 불리지만, 다른 접근 패턴에서는 대역폭 성능이 극적으로 떨어집니다. 예를 들어 데이터 요소를 한 번에 하나씩, 매번 이전 것과 무관한 주소에서 가져와야 한다면, 이 메모리들은 성능이 극도로 나빠집니다.

DDR 메모리와의 인터페이스 프로토콜은 아주 복잡하지만, FPGA 설계자가 그것에 대해 많이 알 필요는 거의 없습니다. 이름 있는 모든 FPGA 벤더는 자기 FPGA에 쓸 수 있도록 신뢰할 수 있고 꽤 효율적인 DDR 메모리 컨트롤러를 무료 IP 코어 (IP core)로 공급합니다. 따라서 FPGA 설계자는 이 IP와 인터페이스하기만 하면 되는데, AXI4나 비슷한 프로토콜을 사용합니다.

DDR 메모리는 배울 가치가 있는 주제일까요? 여러 분야의 FPGA 프로젝트에서 자주 쓰이므로, 비교적 그럴 만한 이유가 있다고 말하고 싶습니다. DDR 메모리를 다루고 어쩌면 비디오 출력까지 만들어 내는 프로젝트는 좋은 연습이 될 수 있습니다. 또한 메모리의 어레이 구조와, 데이터에 접근하기 전에 행을 선택해야 하는 필요성을 이해하기 위해 DDR 메모리의 데이터시트를 한번 읽어 보시길 권합니다. 여러 동작(CAS, RAS, 리프레시 등) 사이의 지연 요구 사항을 살펴보면서 그것들이 어떻게 대역폭 효율을 떨어뜨릴 수 있는지 파악하는 것도 가치가 있습니다. 이 메모리에 대해 알아야 할 가장 중요한 것은, 언제 이것들을 쓰지 말아야 하는가입니다.

SFP+ 케이지

많은 개발 보드, 특히 벤더의 공식 보드에는 SFP+ 케이지가 있습니다. 이 부품은 보드 가장자리에 있는 비교적 큰 금속 부품이라 시각적으로 눈에 띕니다. 이 커넥터는 FPGA에 MGT(Multi-Gigabit Transceiver, AMD FPGA에서는 GTX, GTH, GTY 등으로 부릅니다)가 있을 때만 있습니다. 케이지 안쪽에는 FPGA의 MGT 하나 또는 여러 개에 직접 연결되는 커넥터가 있습니다.

MGT는 기가비트 레이트, 보통 1 Gbit/s 이상의 양방향 통신을 가능하게 하는 기능 단위입니다. PCIe, SuperSpeed USB, SATA, 기가비트 / 10G 이더넷, DisplayPort 등 여러 잘 알려진 프로토콜을 떠받치는 일꾼입니다. 이 웹사이트에 MGT에 관한 연재 전체가 있고, MGT를 전반적으로 설명하는 페이지로 시작합니다.

SFP+ 케이지의 주 용도는 여기에 광 모듈을 꽂는 것입니다. 그러면 광 케이블로 FPGA 보드 두 개를 연결하거나, FPGA 보드를 비슷한 인터페이스를 가진 다른 장치, 예를 들어 광 네트워크 라우터에 연결할 수 있습니다. 광 모듈은 보통 FPGA 개발 보드 키트에 포함되어 있지 않지만, 아주 비싼 편은 아닙니다. 광섬유 없이 두 SFP+ 커넥터를 직접 연결하게 해 주는 케이블도 있습니다.

SFP+ 케이지가 FPGA 보드에 이렇게 흔하다는 사실이, 가능한 한 빨리 MGT 전문가가 되어야 한다는 뜻일까요? 저는 그렇지 않다고 봅니다. 보드에 자주 등장하는 이유 중 하나는 보드 위의 부품이 저렴하고, 추가 부품이나 많은 연결이 필요하지 않기 때문입니다. 또한 FPGA 보드 두 개를 연결하는, 대안(보통 각 MGT에 연결되는 네 가닥의 RF 케이블로 이루어집니다)에 비해 세련된 방법이기도 합니다.

게다가 MGT를 다루는 것은 쉽지 않습니다. 어떤 면에서는 디지털 라디오 채널과 비슷합니다. 링크에 비트 에러가 있고, 송신기의 클록 주파수가 수신기의 클록과 정확히 같지 않은 경우가 많으며, 수신기는 데이터 채널에서 데이터 프레임의 시작을 찾아야 하고, 그 밖에도 할 일이 많습니다.

따라서 MGT는 통신 프로토콜을 처리하는 IP 블록과 함께 쓰이는 것이 보통입니다. 특히 MGT가 있는 FPGA는 사실상 모두 PCIe 프로토콜을 구현하는 하드 IP 블록도 가지고 있습니다. 컴퓨터와 쓰이는 여러 다른 잘 알려진 프로토콜을 위한 IP 코어 (IP core)도 있습니다. 두 FPGA를 연결할 때는 Xillyp2p가 간단한 인터페이스를 제공합니다.

그러니 MGT가 어디에나 있다고 해서 이것이 반드시 가장 먼저 배워야 할 주제는 아닙니다.

이더넷

많은 FPGA 개발 보드에 이더넷 커넥터가 있습니다. 그 이유는 FPGA의 종류에 따라 다릅니다.

가장 설명하기 쉬운 경우는 FPGA 안에 프로세서가 있는 경우입니다. 예를 들어 AMD의 Zynq 소자입니다. 이런 보드에서 이더넷 커넥터는 거의 항상 그 목적을 위한 프로세서의 전용 핀에 연결됩니다. 임베디드 프로세서가 있는 어떤 보드의 이더넷 커넥터와 다르지 않습니다.

프로세서가 없는 FPGA가 달린 보드는 어떨까요? 우선, 그런 FPGA에도 '소프트 프로세서 (soft processor)'(예: MicroBlaze나 Nios)를 넣을 수 있습니다. 그런 프로세서는 다른 프로세서 못지않게 이더넷 커넥터를 잘 활용할 수 있습니다. 반드시 흔한 사용 시나리오는 아니지만, 오랫동안 FPGA 벤더들은 FPGA를 데이터 센터에서 쓰자는 아이디어를 홍보하려 애썼습니다. FPGA와 컴퓨터 사이에 심리적인 연결을 만들고 싶었던 것입니다. 이더넷 커넥터도 그 일부입니다.

FPGA에 프로세서가 전혀 없다면, 이더넷 커넥터로 컴퓨터와 통신할 수 있습니다. TCP/IP가 아마 가장 먼저 떠오를 텐데, 이 프로토콜은 소프트웨어로 구현하도록 맞춰져 있습니다. 이 프로토콜을 로직으로 구현하는 것은 복잡하고 기능도 제한됩니다. 프로토콜 스택은 ARP 요청에도 응답해야 하고, 가급적 ICMP 패킷에도 응답해야 합니다.

따라서 (프로세서가 없는) FPGA 보드를 컴퓨터에 연결하는 데 이더넷이 실용적으로 쓰이는 유일한 방법은 브로드캐스트 패킷을 이용하는 것입니다. FPGA 보드와 컴퓨터가 점대점으로 연결됩니다. 케이블 위로 전송되는 이더넷 프레임은 모두 브로드캐스트 MAC 주소를 가집니다. 흔히 브로드캐스트 UDP/IP 패킷을 사용해서 이룹니다. 그러니 우리가 보통 컴퓨터를 이더넷 네트워크에 연결하는 방식과는 거리가 아주 멉니다.

우아하지 않다는 것 외에도, 이 해법에는 중요한 단점이 있습니다. 이더넷 프로토콜은 패킷의 전달을 보장하지 않습니다. 이더넷 패킷에 비트 에러가 있으면 조용히 버려집니다. 컴퓨터의 네트워크 카드도 아무 이유 없이 패킷을 임의로 버릴 수 있습니다. 일반적인 사용에서는 이것이 눈에 띄지 않습니다.

따라서 데이터 손실이 허용되지 않는다면, FPGA는 재전송을 하기 위해 전송하는 모든 데이터를 버퍼에 담아 두어야 합니다. 이런 재전송을 요청하려면 오류 검출 메커니즘을 갖춘 프로토콜을 적용해야 합니다. 이걸 이더넷 위에서 제대로 하려면 정말 복잡해집니다.

아니면 데이터 손실 가능성을 받아들이는 것입니다. 혹은 학생이나 취미 프로젝트에서 흔히 그렇듯이, 시스템을 시험할 때는 일어나지 않으니 이 가능성을 무시하는 것입니다. 프로젝트가 전문적이지 않다면 그 정도면 충분합니다.

결론은 이렇습니다. 보드에서 프로세서가 돌아간다면, 특히 Linux가 돌아간다면 이더넷 커넥터를 꼭 쓰세요. 하지만 그보다 더 깊이 파고들라고는 권하지 않겠습니다.

이것으로 이 연재의 네 번째 페이지를 마치며, 전문 역량에 대한 논의도 끝납니다. 다음 페이지는 완전히 다른 방향으로 갑니다. 이 직업에는 어떤 성향이 선호될까요?

이 페이지는 영어 원문을 기계 번역한 것입니다. 의문이 드는 부분이 있으면 원문을 참조하시기 바랍니다.
Copyright © 2021-2026. All rights reserved. (852e87d4)