이 페이지는 전문 FPGA 설계자가 되는 방법을 다루는 연재의 다섯 번째이자 마지막 글입니다. 앞선 글들과 달리, 이번에는 기술적인 이야기를 하지 않습니다. 대신 인간으로서의 우리 자신, 그리고 어떤 특성이 FPGA 설계자의 삶을 더 쉽고 더 낫게 만드는지에 초점을 맞춥니다.
이것은 실제로 중요합니다
FPGA 설계자의 성격과 태도에 대해 이야기하는 것이, 특히 기술 주제에 집중하는 웹사이트에서, 이상하게 들릴 수 있습니다. 하지만 FPGA 설계자를 지망하는 분들을 위한 안내서라면, 모든 것을 통제 아래 두는 삶과 완전한 혼돈 속에서 일하는 삶을 가르는 인간적 자질과 행동에 대해서도 다루는 것이 적절하다고 봅니다.
거의 모든 직업에는 어울리는 성격이 있습니다. 사람을 잘 상대하지 못하면 자동차 영업사원이 되기 어렵고, 아이를 좋아하지 않으면 좋은 교사가 되지 못합니다. 마찬가지로, FPGA 엔지니어로서 도움이 되는 성격 특성이 있고, 그렇지 않은 특성도 있습니다.
저는 설교하려는 것도 아니고, 누군가의 의욕을 꺾으려는 것도 아닙니다. '열심히 일해야 한다'고 말하려는 것도 아닙니다. 오히려 반대입니다. 의도는 일을 올바르게 처리하고, 더 적은 노력으로 목표에 도달하는 것입니다.
이 페이지에서 저는 이러저러한 전문 지식을 갖추는 것에 더해, 이 직업과 평화롭게 살아가기 위해 성공적인 FPGA 설계자가 되려면 무엇이 필요한지 설명해 보겠습니다. 이 페이지는 엔지니어의 성격에 관한 것입니다. 자기 훈련 (self-discipline)과 자기 통제가 있고, 꼼꼼한 유형인 편이 낫다는 것은 놀라운 일이 아닐 것입니다. 세부 사항에 대한 약간의 집착도 나쁘지 않습니다.
하지만 이것을 인생의 고통이나 몸을 갈아 넣는 노동 같은 관념과 섞지 마세요. 정반대입니다. 어떤 방식으로 일할 수 있는 능력이 있다면, 일을 더 빠르고 더 쉽게 끝내게 됩니다. 재미있고 보람 있을 것입니다. 첫 시도에 제대로 해 내는 것이 이상이고, 그것은 달성 가능합니다.
반면, 아래에 제가 설명하는 이상적인 FPGA 설계자상에 자신이 전혀, 아니 조금도 맞지 않는다고 느낀다면, 음, 어떻게 말해야 할까요. 이 직업에 대한 생각을 한번 더 해 보시는 건 어떨까요?
"그냥 동작한다"로는 충분하지 않습니다
소프트웨어 세계, 특히 웹사이트와 앱에서는 대충 코드를 적고, 시험해 보고, 잘못된 것은 고치고 다시 시도하는 것이 일반적인 관행입니다. AI를 쓰면 코드를 적는 단계조차 건너뛰고, 기계가 코딩과 테스트를 모두 하며, 결국 결과를 Git 저장소에 커밋합니다.
그 바탕에 깔린 생각은 이렇습니다. 코드가 테스트를 통과하면 일은 끝난 것입니다. 아직 버그가 있으면 QA가 찾아내거나 사용자의 불만이 곧 들어올 것입니다. 그러면 표준 절차에 따라 수정 요청이 발행됩니다. 그리고 버그를 고칩니다. 아주 많은 소프트웨어 팀이 정확히 이렇게 일하도록 구성되어 있습니다.
이 관행이 소프트웨어 개발에 적합한지 아닌지는 별개의 논의입니다. 제가 분명히 하고 싶은 것은, 이것이 전문적인 FPGA 설계에는 크게 잘못된 것이라는 점입니다. "그냥 동작한다"는 FPGA 프로젝트에는 턱없이 부족합니다. 취미 개발자에게는 그럴지 몰라도, 실제로 양산에 들어가는 프로젝트에는 절대 아닙니다. 특히 긴 디버깅 끝에 마침내 뭔가 동작해서 기뻐하며 오늘은 이걸로 끝이라고 하고 싶을 때, 이 함정에 빠지기 쉽습니다.
너무 순수주의적인 설교처럼 들릴 수 있지만, 이것은 단순한 진실입니다. 신뢰할 수 있는 FPGA 설계를 얻는 유일한 방법은, 자신이 설계한 것이 반드시 동작한다는 것을 스스로에게 확실히 증명하는 것입니다. 설계가 모든 테스트를 통과했을 때 일이 끝나는 게 아니라, 그것이 실패할 수 없다는 것을 스스로 확신할 수 있을 때 끝나는 것입니다.
이것을 수학 정리에 비유해 보겠습니다. 숫자를 몇 번 넣어 시도해 보고 매번 맞았으니 옳다고 말하지는 않습니다. 수학적 증명이 있을 때 그 방정식이 옳다고 봅니다.
실제로 이것은 Verilog 파일의 모든 줄을 수학적 유도에서의 방정식처럼 다루고, 타이밍 제약 조건 (timing constraints)과 관련된 다른 소스 파일에도 똑같이 하라는 뜻입니다. 다소 극단적으로 들릴 수 있지만, 이렇게 세심하게 하는 것이 장기적으로는 이득입니다.
FPGA와 다른 전자 부품의 연결도 마찬가지입니다. 동작한다고 해서 전기적 인터페이스가 괜찮다고 가정하지 않습니다. FPGA의 데이터시트와 다른 부품의 데이터시트에 있는 요구 사항이 모두 충족된다는 것을 스스로 증명합니다. 전압 레벨이 맞는가? FPGA 설계가 양쪽의 모든 타이밍 요구 사항이 충족되도록 보장하는가?
그러면 제 설계에는 항상 버그가 없다는 뜻일까요? 물론 아닙니다. 저는 인간이고, 실수를 합니다. 수학적 증명을 애써서 100% 맞게 하지 못할 수 있는 것과 같습니다. 코너 케이스 점검을 빠뜨릴 수도 있고, 더하기를 빼기로 바꿔서 전반적으로 엉망이 될 수도 있습니다.
하지만 이 엄격한 접근법의 좋은 점은, 결국 남게 되는 몇 안 되는 버그가 보통 명백하고 고치기도 비교적 쉽다는 것입니다. 그리고 한 번 고치면 설계는 그냥 동작합니다. 버그도, 미스터리도, 흑마법도 없습니다. 탄탄하게 동작하는 전자 회로 한 조각입니다.
빨리 목표에 도달하는 느린 길인 셈입니다.
사람들이 정말 이렇게 엄격하게 일할까요?
짧게 답하면, 결코 그렇지 않습니다. 저는 특히 프리랜서로 일하던 시절에 이 사실을 잘 알게 되었습니다. 새 고객을 만날 때마다 제 첫 임무는 FPGA 프로젝트를 안정시키는 것이었습니다. 응급실에서 의사가 환자를 안정시키는 것과 조금 비슷했습니다. 그리고 프로젝트를 담당했던 엔지니어들도 오랜 스트레스와 좌절 끝에 일종의 안정이 필요한 경우가 많아 보였습니다.
대충 적고 나서 디버깅하는 태도는 불행히도 FPGA 업계에서도 흔합니다. 놀랄 일이 아닙니다. Verilog 강좌에서 시뮬레이터 (simulator)가 소프트웨어 세계의 디버거와 같은 정신으로 제시되는 경우가 많기 때문입니다. 그 바탕에 깔린 암시는 흔히 시행착오로 원하는 결과에 도달하라는 것입니다. 컴퓨터에서 동작할 때까지 시뮬레이션하고, 그다음 합성해서 하드웨어에서도 동작할 때까지 고치라는 것이죠.
설상가상으로, 이런 작업 방식을 부추기는 관리자들도 있습니다. 결과를 빨리 보고 싶어 하고, 괜찮아 보이는 게 보이면 다음 작업으로 넘어가기를 기대합니다. 일정은 촉박하고, "버그는 나중에 고치죠".
이런 접근법의 결과로, 진정으로 신뢰할 수 있는 FPGA 설계를 얻는 것이 어렵고, 때로는 불가능합니다. 이것은 시뮬레이션에서의 광범위한 회귀 테스트 (regression test)와 하드웨어에서의 광범위한 테스트로 보상됩니다. 어떤 회사들은 FPGA가 실린 보드가 생산 라인을 떠나기 전에 출하되는 모든 보드에 대해 온도 테스트를 돌립니다. 출하 전 하드웨어 테스트가 자체 하드웨어와 소프트웨어를 갖춘 별도의 부서가 되는데, 그 목적은 단 하나입니다. FPGA가 정말로 해야 할 일을 하는지 확인하는 것.
그 모든 것 뒤에는, 신비롭게 나타났다 사라지는 버그를 미친 듯이 쫓으며 일정에 뒤처진, 극도로 스트레스 받는 FPGA 엔지니어들이 있습니다.
항상 이렇게 나쁜 것은 아닙니다. FPGA가 비교적 낮은 주파수에서 동작하고, 요구 사항이 단순하고, 산발적 실패가 그렇게 큰 문제가 아닐 때는 시행착오 태도도 꽤 잘 통할 수 있습니다.
게다가 현실에서는 FPGA를 다루는 대부분의 사람이 그 척도의 중간 어딘가에 있습니다. Verilog를 수학 방정식으로 여기는 극단은 아니지만, 인내심과 자기 훈련, 정확성에 대한 존중이 높은 수준인 사람들이죠. 그렇게 해서 이 분야에서 일을 끝내 갑니다.
자신이 무엇을 하는지 아세요
제가 FPGA에서는 시행착오가 답이 아니라는 것을 납득시켰다면, 더 엄격하고 정확한 길이 필요하다는 것은 분명합니다. 하지만 그것만으로는 충분하지 않습니다. 자신이 무엇을 하는지 정확히 이해하지 못하면 엄격한 태도도 도움이 되지 않습니다.
예를 들어 Verilog 코드에서 비동기 리셋 (asynchronous reset)을 보는 것은 꽤 흔합니다(앞선 페이지들에서도 언급했습니다). 이것은 로직을 리셋하는 정당한 방법이지만, 올바르게 적용했을 때만 그렇습니다. 대다수의 경우 이 리셋은 잘못 사용되어서, 로직이 예상대로 동작한다는 것을 보장하지 못합니다. 그런데도 현실에서는 모든 것이 잘 동작합니다. 대개는요. 이 주제에 관한 별도 페이지가 있습니다.
비동기 리셋을 이렇게 잘못 사용하는 이유는 아마도 사람들이 다른 곳의 Verilog 코드를 자기 코드에 복사-붙여 넣기 하기 때문일 것입니다. 그 코딩 패턴이 너무 익숙하고 뻔해서, 사람들이 그것이 실제로 무엇을 뜻하는지 생각하려 멈추지 않습니다. 그리고 이 경우에는 무엇을 뜻하지 않고 무엇을 보장하지도 않는지도요.
자신이 무엇을 하는지 아는 것은, 설계가 반드시 동작한다는 것을 스스로에게 증명할 수 있기 위한 전제 조건입니다. 이는 각 Verilog 표현이 정확히 무엇을 뜻하는지, 그리고 합성기 (synthesizer)가 그것을 어떻게 해석할지 이해한다는 뜻입니다. 같은 원칙이 타이밍 제약 조건 (timing constraints)과, FPGA 설계와 관련해 개발 도구가 소비하는 다른 정보에도 적용됩니다.
하지만 이미 인정했듯이, 대부분의 FPGA 설계자는 설계가 동작한다는 것을 증명할 만큼 엄격하지 않습니다. 그래도 자신이 입력하는 것의 정확한 의미를 아는 것은 올바른 방향으로 가는 한 걸음입니다.
추상적으로 생각하세요
컴퓨터 과학을 학문으로 배웠다면, 소프트웨어를 기술하기 위해 얼마나 많은 추상적 존재가 발명되는지 보았을 것입니다. 예를 들어 항상 특정한 방식으로 구성되는 자료 구조, 클래스와 객체, 데이터 스트림, 루프를 한 번 돌 때마다 유지되는 불변식 등등이죠. 컴퓨터 과학에서는 상상 속의 존재가 끊임없이 발명됩니다. 그래야 우리 인간이 내부의 자잘한 세부 사항을 넘어서 더 단순한 표현과 관계를 맺을 수 있으니까요. 이것이 우리 뇌의 부담을 줄여 주고, 복잡한 소프트웨어 설계를 이해할 수 있게 합니다. 이것을 추상화라고 부릅니다.
추상화의 반대편에는 구체적인 사고방식이 있습니다. 아니면 '이야기하기'라고 불러야 할까요? 이런 태도에서는 컴퓨터 프로그램을 이야기처럼 다룹니다. 먼저 이것을 하고, 그다음 저것을 하고, 이것이 참이면 이걸 하고, 아니면 저걸 한다. 손가락으로 코드를 짚어 가며 사건의 순서를 따라가기만 하면 모든 것을 이해하는 셈입니다.
이야기하기는 단순한 스크립트 (script), 웹사이트, 모바일 앱, 그리고 다른 단순한 소프트웨어를 개발하는 데는 잘 통합니다. 사용자가 이 버튼을 누르면 이 화면이나 웹 페이지로 가고, 거기서부터 이어지는 식이죠. 소프트웨어가 하나의 단순한 실행 흐름으로 진행되고, 하나의 사고 흐름으로 이해될 수 있습니다.
두 사고방식의 차이를 예를 들어 보여 드리고 싶습니다. n의 팩토리얼인 n!을 계산하는, C로 작성된 이 함수를 봅시다.
unsigned int factorial(unsigned int n) {
if (n == 0)
return 1;
return n * factorial(n - 1);
}
이것은 재귀의 고전적인 예입니다. 위 코드를 어떻게 이해하시겠습니까?
이야기하기 방식은 '일단 해 보는' 것입니다. 대략 이렇게 들립니다. "함수가 n=3으로 호출되었다고 하자. 그러면 n=2로 자신을 호출하고, 그다음 n=1, 그다음 n=0으로 호출할 것이다. 이제 풀어 보면, n=0 호출에 대해 1을 반환하고, 그다음 1*1, 그다음 2*1을 반환하고, 마지막으로 3*2가 되어 6, 그게 정답이다. 좋아, 동작한다." 아마 이 사고 과정은 디버거로 한 단계씩 실행하면서 할 수도 있습니다.
다른 방식은 수학적 귀납법에 의한 증명과 비슷합니다. 함수가 정말로 n의 팩토리얼을 반환한다고 가정하고, n-1에 대해 동작하면 n에 대해서도 동작한다는 것을 확인합니다. 마지막으로 n=0에 대해 올바른 값을 준다는 것, 그리고 재귀가 항상 n=0에서 끝난다는 것을 확인합니다. 실행 순서는 무관합니다. 함수를 그저 자기 목적을 다하는 추상적 존재로 다루기 때문입니다.
그러면 이렇게 물을 수 있습니다. 왜 일을 복잡하게 만드는가? 이야기하기로도 잘 설명되었는데? 이에 대한 답은 이렇습니다. 맞습니다. 하지만 그 예제가 단순했기 때문에 잘 통했을 뿐입니다.
그리고 이제 마침내 핵심에 도달합니다. 소프트웨어를 이해하는 데 이야기하기에만 국한된다면, FPGA 설계자로서 그것은 장애물이 될 것입니다. 첫 번째이자 명백한 이유는 FPGA에서는 모든 것이 동시에 일어난다는 것입니다. FPGA에서 '먼저 이것, 그다음 저것'으로 설명할 수 있는 것은 아주 적습니다.
두 번째로 더 중요한 이유는 FPGA 설계가 흔히 복잡하다는 것입니다. 무슨 일이 벌어지는지 정신적으로 파악하려면 추상화가 필요한 경우가 많습니다. 예를 들어 Verilog 모듈을, 그 기능이 너무 많은 세부 사항 없이 몇 문장으로 설명될 수 있게 정의하는 것이 좋은 습관입니다. 포트로의 인터페이스도 설명하기 단순해야 합니다. 복잡한 로직 블록을 몇 가지 단순한 아이디어로 축약할 수 있을 때, 인간의 실수가 일어날 가능성이 더 작아집니다. 이 원칙은 소프트웨어에도 적용되지만, 항상 그렇게 결정적이지는 않습니다.
추상적 사고의 세 번째 이유는 정확성을 스스로에게 증명하는 능력과 관련이 있습니다. 이야기하기로는 자신이 생각할 수 있는 시나리오만 다루게 됩니다. 진짜 증명은 모든 것을 다룹니다.
복잡한 작업을 다룰 때는 Verilog 한 줄을 쓰기 전에 새로운 이론적 존재를 발명해야 할 수도 있습니다. 예를 들어 데이터 패킷을 입력받고 출력하는 모듈이 필요하다면, N을 현재 그 메모리 버퍼에 저장된 패킷의 수로 정의하는 것이 도움이 될 수 있습니다. 그러면 버퍼가 절대 꽉 차지 않는다는 것을 증명할 수 있습니다. 별것 아닌 것처럼 들릴 수 있지만, 수학적 사고로 나아가는 이 한 걸음이 큰 도움이 될 수 있습니다. 모듈 안의 모든 로직이 어떻게든 이 N을 올바른 한계 안에 유지하는 것과 관련되어 있을 수도 있습니다.
비결은 로직을 제대로 만드는 데 정말로 도움이 되는 올바른 추상적 존재를 찾는 것입니다. 그러면 며칠 동안 Verilog 한 줄도 쓰지 않다가, 갑자기 짧은 Verilog 모듈을 아주 빠르게 작성하게 될 수 있습니다. 이렇게 구상된 코드는 보통 짧고 우아하고 이해하기 쉽고, 첫 시도와 그 이후 영원히 동작합니다.
하지만 상사가 매일 무엇을 하는지 물어본다면 이것이 그렇게 잘 통하지 않을 수도 있습니다. 며칠 동안 보여 줄 것이 없고, 결국 뭔가를 떠올려도 반응이 "당신이 한 게 겨우 이 사소한 모듈이 전부라고요?"일 수 있으니까요.
다시 말하지만, FPGA 설계에 순수하게 수학적으로 접근하는 것이 모든 사람에게 맞는 길은 아닙니다. 그래도 이런 습관이 있다면 이야기하기 습관은 버리시길 권합니다.
도구를 믿지 마세요
더 정확히 말하면, 개발 도구는 여러분이 끔찍한 실수를 하는 것을 막아 주지 않습니다. 경고조차 해 주지 않을 수도 있습니다.
세상 어떤 소프트웨어 컴파일러도 소스 코드가 요청한 것과 다른 일을 하는 실행 코드를 만들어 내지 않습니다. 만약 그런다면 버그를 보고하세요. 반면 합성기 (synthesizer)는 Verilog 코드가 요청한 동작을 충족하지 않는 로직을 얼마든지 만들어 낼 수 있습니다. 운이 좋으면 그것에 대한 경고가 나올 것입니다. 운이 더 좋으면, 합성기가 쏟아 내는 수백 개의 무해한 메시지와 경고 속에서 그 경고를 알아챌 것입니다.
FPGA 개발 스위트의 다른 부분들도 고약한 장난을 칠 수 있습니다. 가장 명백한 것은, 타이밍 제약 조건 (timing constraints)이 충족되지 않았는데도 대부분이 FPGA에 로드할 수 있는 비트스트림 (bitstream)을 만들어 낸다는 점입니다. 즉 FPGA가 합성기가 의도한 대로 동작할 수도 있고 아닐 수도 있습니다. 아니면 조금 동작하다가 안 될 수도 있습니다. 경고가, 심지어 크리티컬 워닝 (Critical Warning)이 나올 것입니다. 그런데 소프트웨어 컴파일러가 컴파일을 끝내고 동작하지 않을 수도 있는 실행 파일을 내놓겠습니까?
도구가 막아 주지 않는 상태에서 FPGA 설계를 엉망으로 만드는 다른 방법은 끝이 없습니다. 이것은 어느 정도 문화적인 문제입니다. 마치 누군가 일부러 FPGA를 다루기 어렵게 만들고 싶어 하는 것 같습니다.
저는 여러 FPGA 벤더와, 꽤 많은 FPGA 개발 도구로 일해 봤습니다. 이들 모두가 이렇게 일을 어렵게 만들고, 안전망은 바라기만 해야 하는 것이라는 똑같은 경향을 가진다는 점이 참 흥미롭습니다. 특정한 저렴하고 악한 FPGA 벤더 하나의 문제가 아닙니다. 전부 그렇습니다.
무엇보다도, FPGA 개발 도구에 버그가 있는 경우도 드물지 않습니다. 운이 좋으면 프로젝트를 빌드하다가 크래시라도 나서, 적어도 설계를 오작동시키는 버그는 아니게 됩니다. 하지만 그렇게 자주는 아니어도, 비트스트림 (bitstream)에 결함을 일으키는 버그도 발생합니다. 새 개발 스위트가 나올 때가 더 나쁩니다. FPGA 세계에서는 최신이 반드시 최고를 뜻하지는 않습니다. 조심스럽게 말하자면요.
그렇긴 해도, 설계가 동작하지 않는다고 도구를 의심하지 마세요. 특히 이 분야에 처음이라면 더욱 그렇습니다. 그리고 도구가 자신을 배신했다고 생각한다면, 결정적 증거를 찾으세요. FPGA 안에서 하나여야 했는데 다른 것이 되어 버린 그 로직 셀을 찾으세요. 정말로 도구 탓으로 이렇게 되었다고 스스로를 확신시키세요. 도구가 미쳤다는 느낌만으로는 부족합니다. 그렇게 보이는 것에는 거의 항상 더 단순한 설명이 있습니다.
그리고 특히, Verilog 코드에서 무관한 것을 바꿨는데 버그가 사라진다고 해서 그것이 도구에 버그가 있다는 뜻은 아닙니다. 그런 동작은 제대로 정의되지 않은 타이밍 제약 조건 (timing constraints)이나 다른 비슷한 실수에서 더 전형적으로 나타납니다.
개발 도구에 관한 이 문제를 다루는 열쇠는, 반복해서 말하는 듯하지만, 자신이 무엇을 하는지 아는 것입니다. 이 주제에 국한해서 말하자면, 도구가 내놓는 경고와 메시지를 읽고, 그것들이 무엇을 뜻하는지, 적어도 대략 무엇과 관련된 것인지 이해하는 것입니다. 어떤 경고가 무해하고, 항상 나오고, 무시해도 되고 무시해야 하는지 배우는 것은 경험의 문제입니다. 도구가 왜 버전이 바뀌어도 계속 쓸모없는 경고를 많이 내놓는지는 — 제가 문화 이야기를 했던가요?
따라서 이따금 모든 경고를 훑어보면서 눈에 띄는 것이 있는지 보는 것이 좋은 습관입니다. 모든 것이 완벽하게 잘 동작할 때에도, 특히 그럴 때 이렇게 하세요. "그냥 동작한다"로는 충분하지 않기 때문만이 아니라, 어떤 경고가 무해한지 배우는 방법이기도 하기 때문입니다.
그리고 실제로, 어떤 경고는 여러분이 일을 제대로 했다는 표시입니다. 예를 들어 어떤 경고가 레지스터가 상수 값을 가지거나 다른 레지스터와 동등해서 설계에서 제거되었다고 말한다면, 그것은 잠시 멈춰서 그게 맥락상 말이 되는지 생각해 볼 기회입니다. 꽤 자주, 그런 경고는 자신의 코드에 관한 흥미로운 사실을 깨닫게 도와줍니다.
요구 사항에서 설계로
소프트웨어를 작성할 때는 보통 요구 사항과 작성해야 할 것 사이에 꽤 곧은 선이 있습니다. 특히 단순한 소프트웨어(예를 들어 웹사이트와 모바일 앱)에서는 더욱 그렇습니다.
FPGA 설계에서는 그렇게 쉽지 않을 수 있습니다. FPGA에 대한 요구 사항은 흔히 "여기 부품들이 있고, 우리는 이것이 이렇게 동작하기를 원한다"에 더 가깝게 들립니다.
예를 들어, 카메라 센서와 FPGA, 그리고 다른 장치로 이어지는 선으로 이루어진 보드가 있다고 합시다. 작업은 카메라 센서에서 이미지를 가져와, 픽셀에 기본적인 신호 처리를 수행하고, 비디오 데이터를 전송하기 위한 고용주의 특정 형식에 따라 출력을 다른 장치로 보내는 것입니다.
여러분은 FIFO, 상태 머신 (state machine), 파이프라인 (pipeline), RTL 설계에 대해 모든 것을 압니다. 요청받은 것을 어떻게 만들어 내야 할까요? 아무도 "상태 머신 (state machine)을 작성하세요"라고 말해 주지 않습니다. 동작하는 무언가를 만들어 내기를 기대받을 뿐입니다.
운이 좋으면 요구 사항이 이전의 많은 프로젝트와 비슷합니다. 블록 다이어그램을 복사하고, 로직을 모방하고, 어쩌면 몇 부분을 복사할 수도 있습니다. 하지만 꽤 자주, 프로젝트의 요구 사항에는 그런 모방이 부당하게 만드는 무언가가 있습니다.
그때 여러분은 FPGA 아키텍트가 됩니다. 작업을 어떻게 기능 단위로 나눌지, 각 단위가 무엇을 하는지, 그것들이 서로 어떻게 상호작용하는지를 스스로 결정합니다. 프로젝트 아주 초반에 이것을 잘할수록, 프로젝트를 작성하고 유지하기가 더 쉬워집니다. 너무 자주, 더 나은 대안이 없어서 기존 프로젝트의 블록 다이어그램이 새 프로젝트에 강제로 적용됩니다. 이 지름길에는 대가가 따릅니다.
그러면 좋은 아키텍트가 되려면 어떻게 해야 할까요? 대부분은 경험에서 나오고, 다른 프로젝트에서 선택된 해법을 관찰하는 것에서도 나옵니다. 앞서 추상화를 언급했습니다. 자기 것이든 남의 것이든 설계를 추상적인 용어로 이해하면 다음 프로젝트를 더 잘 만들 수 있습니다. Verilog 모듈을, 짧은 이름이 붙은 어떤 작업을 수행하는 기능 블록으로 보면, 자기 프로젝트에 쓸 팔레트를 가지게 되는 것입니다. 여러 선이 두 모듈을 어떻게 연결하는지 보고, 그 모듈들이 이 선을 통해 상호작용하는 방식에 이름을 붙일 수 있다면, 새 프로젝트의 여러 부분이 어떻게 상호작용할지 결정하는 데 더 나은 위치에 서게 됩니다. 기존 설계에서 이론적 존재를 잘 알아볼수록, 새 설계를 더 잘 만들게 됩니다.
FPGA 아키텍트 부분이 어렵게 들린다면, 작은 비밀 하나를 공유하겠습니다. 정말 어렵습니다. 저는 이 일을 몇 번 해 봤는데, 시간도 무척 많이 들고 후회도 무척 많이 따릅니다. 이 초기 단계의 사소한 실수 하나하나가 중대한 결과를 낳습니다.
하지만 기억하세요. 아마 프로젝트를 처음부터 설계할 필요는 없을 것이고, FPGA가 처음인 사람이라면 더더욱 그렇습니다. 이 작업은 보통 팀에서 가장 선임 FPGA 엔지니어에게 주어집니다. 그러니 시스템 아키텍트의 모자를 쓰기까지는 아마 시간이 좀 있을 것입니다. 그리고 팀에서 유일한 FPGA 엔지니어로 채용되더라도, 기존 코드를 유지 관리하거나 기존 프로젝트를 기반으로 새 프로젝트를 개발할 가능성이 큽니다.
하지만 이 작업을 준비하기에 너무 이른 때는 없습니다.
요약
여러모로, 이 페이지의 주제는 다양한 형태의 자기 훈련이었습니다. 그것은 흔히 인간의 행동으로 여겨지는 것을 극복하는 능력입니다. 부정확하게, 먼저 충분히 생각하지 않고 일을 해 두고(특히 Verilog 코드와 타이밍 제약 조건 (timing constraints)을 작성할 때), 나중에 실수를 고치는 것(시뮬레이션과 하드웨어에서의 디버깅). 뭔가 동작하는 것에 기뻐하며 다음 작업으로 서둘러 넘어가고 싶어 하는 것("그냥 동작한다"로는 충분하지 않습니다). 그 뒤에 있는 추상적 아이디어를 찾는 대신, 일을 단순하고 자연스러운(이야기하기) 방식으로 자신에게 설명하는 것. 도구가 내놓는 경고 같은, 작고 지루한 세부 사항을 건너뛰는 것.
우리의 인간적 본성은 불행히도 FPGA 설계자로서 우리에게 적입니다. 하지만 제가 '열심히 일하라'고는 한 마디도 하지 않았다는 점에 주목하세요. 일을 끝낸다면 더 적은 일을 지향하는 것은 게으름이 아닙니다. 목표는 사실 더 적게 일하고도 더 나은 결과를 얻는 것입니다. 그리고 제대로만 하면 가능합니다.
이것은 로봇이 되라는 것도 아닙니다. 일하는 삶에서 자기 통제와 정확성을 가지라는 것이지, 기계처럼 일하라는 것은 결코 아닙니다. 우리에게는 인간의 뇌가 필요합니다. 로봇은 여러 시간 일할 수 있지만, 우리의 뇌는 지칩니다. 자기 통제란 때로는 길고 지루한 하루를 보낸 뒤 책상에서 일어나 쉬는 것을 뜻합니다. 그 버그가 아직 남아 있을 때조차도요.
그리고 이 연재 전체를 요약하자면 — 이제 분명하겠지만, FPGA 설계는 가장 단순한 직업이 아니고, 제가 그 이유를 꽤 여러 가지 나열했습니다. 전자공학에 관한 새로운 것을 끊임없이 배우는 게 싫다면, 어쩌면 이 일은 맞지 않을 수 있습니다. 일을 철저하고 정확하게 해 낼 자기 훈련이 없다고 생각한다면, 그것도 다시 생각해 볼 또 하나의 이유입니다.
그리고 제가 여기까지 여러분을 겁주는 데 성공하지 못했다면, 클럽에 오신 것을 환영하며, 행운과 실력을 빌겠습니다. 그리고 무엇보다도, 제가 이 선택을 즐기듯 여러분도 이 선택을 즐기시길 바랍니다.