Python과 Jupyter Notebook을 사용하여 빠르게 FPGA 기반 설계 구축 및 프로그래밍
DigiKey 북미 편집자 제공
2019-04-03
설계자는 컴퓨터 비전, 통신, 산업용 내장형 시스템, 사물 인터넷(IoT) 등과 같은 컴퓨팅 집약적인 애플리케이션을 위한 하드웨어 설계 성능을 가속화하기 위해 전통적으로 현장 프로그래밍 가능한 게이트 어레이(FPGA)를 선택했습니다. 하지만 기존 FPGA 프로그래밍에 포함되는 세부 단계는 감당하기 어려울 정도로 까다롭기 때문에 설계자는 지금까지 대체 처리 솔루션을 찾고 있습니다.
Jupyter Notebook을 기반으로 하는 PYNQ(Python Productivity for Zynq) 개발 환경의 출현으로 FPGA 프로그래밍 가능성 문제는 해결되었습니다. PYNQ를 지원하도록 특별히 설계된 개발 기판을 사용하면 FPGA 경험이 적은 개발자도 FPGA 성능을 최대한 활용하여 컴퓨팅 집약적인 애플리케이션을 가속화할 수 있는 설계를 빠르게 구현할 수 있습니다.
이 기사에서는 FPGA 기반 시스템 개발을 가속화할 수 있는 강력한 오픈 소스 대안을 제공하는 Digilent의 개발 기판을 소개하고 개발 기판을 기반으로 시작하는 방법을 보여주기 전에 일반적인 PFGA 접근 방식을 설명합니다.
왜 FPGA를 선택해야 할까요?
복잡하고 컴퓨팅 집약적인 알고리즘을 선택해야 하는 엔지니어는 FPGA를 사용하여 빠듯한 전력 할당량 범위 내에서 실행을 가속화할 수 있습니다. 실제로 FPGA는 에지 컴퓨팅 시스템에서 인공 지능 알고리즘을 가속화하기 위한 주요 플랫폼으로 등장했습니다(“FPGA를 사용하여 머신 러닝을 통해 고성능 내장형 비전 애플리케이션 구축” 참조).
내장형 애플리케이션용으로 특별히 설계된 고급 FPGA SoC(시스템온칩) 장치는 프로그래밍 가능 논리(PL) 패브릭을 마이크로 컨트롤러와 통합합니다. 예를 들어, Xilinx Zynq-7000 SoC는 통합된 프로그래밍 가능 논리(PL) 패브릭에서 이중 코어 Arm® Cortex®-A9 프로세서 시스템을 최대 444,000개 논리 셀과 결합합니다(그림 1). 내장된 프로세서 및 주변 장치의 포괄적인 보완 부품과 함께 Zynq SoC는 최대 2,020개의 디지털 신호 처리(DSP) 블록 또는 슬라이스를 제공합니다. 이러한 리소스를 사용하여 개발자는 복잡한 컴퓨팅 집약적 알고리즘에서 처리량을 가속화하는 데 필요한 특수 처리 체인으로 PL 패브릭을 구성할 수 있습니다.

그림 1: Xilinx Zynq-7000 SoC는 이중 코어 Arm Cortex-A9 프로세서, 프로그래밍 가능 논리 패브릭, 많은 내장형 애플리케이션에 필요한 포괄적인 주변 장치 및 인터페이스를 결합합니다. (이미지 출처: Xilinx)
부품 수 감소 외에도 프로세서와 PL 패브릭을 통합하여 오프칩 액세스가 아닌 온칩 버스를 통해 작동할 수 있습니다. 이 통합은 전원 켜기 또는 리셋 시퀀스 중에 PL 패브릭을 로드하는 중요 작업을 더욱 간소화합니다.
FPGA를 통해 구축된 일반 마이크로 컨트롤러 기반 시스템에서는 FPGA를 프로그래밍하는 비트 스트림을 로드하기 위한 시퀀스와 보안을 개발자가 관리해야 합니다. Zynq SoC에서는 통합된 프로세서에서 PL 패브릭 및 기타 온칩 주변 장치 관리를 비롯한 기존 마이크로 컨트롤러 작업을 수행합니다. 따라서 FPGA 로드 공정이 기존 FPGA 비트 스트림 초기화보다 기존 마이크로 컨트롤러의 부트 공정과 더 흡사합니다.
이 부트 공정은 Zynq 프로세서 중 하나에 의해 관리되는 짧은 시퀀스 단계를 통해 수행됩니다(그림 2). 전원을 켜거나 리셋할 때, Zynq 프로세서가 부트 장치에서 실제 부트 코드를 가져오는 짧은 코드를 읽기 전용 BootROM에서 실행하면 부트 프로세스가 시작됩니다. 프로세서 시스템 부품을 구성하는 코드와 함께 부트 코드는 PL 비트 스트림과 사용자 애플리케이션을 모두 포함합니다. 부트 코드 로드가 완료되면 프로세서에서 포함된 비트 스트림을 사용하여 PL을 구성합니다. 구성 및 PL 구성이 완료되면 장치에서 부트 코드에 포함된 애플리케이션을 실행합니다.

그림 2: 기존 마이크로 컨트롤러와 비슷한 부트 시퀀스에서 Xilinx Zynq-7000 SoC는 부트 ROM에서 부트 로더를 로드하여 실행하는 코드를 실행합니다. 이 코드는 부트 코드에 패키지로 구성된 비트 스트림을 사용하여 프로그래밍 가능 논리 패브릭을 구성하는 작업을 비롯한 후속 단계를 처리합니다. (이미지 출처: Xilinx)
간소화된 PL 로드 처리에도 불구하고 개발자는 필요한 비트 스트림을 생성하는 데 필요한 복잡한 FPGA 개발 공정을 처리하는 과거에 머물러 있습니다. FPGA 성능을 활용하려는 개발자에게 기존 FGPA 개발 공정은 구현을 방해하는 커다란 장애물로 남아 있습니다. Xilinx는 PYNQ 환경을 통해 이러한 장벽을 효과적으로 제거했습니다.
PYNQ 환경
PYNQ에서 PL 비트 스트림은 개발 공정 및 실행 환경에서 소프트웨어 라이브러리와 비슷한 역할을 하는 오버레이라는 사전 빌드된 라이브러리에 캡슐화됩니다. 부트 로드 공정 중에 필요한 오버레이에 연결된 비트 스트림이 PL 패브릭을 구성합니다. 하지만 이 공정은 각 오버레이에 연결된 Python 애플리케이션 프로그래밍 인터페이스(API)를 통해 오버레이 기능을 활용하는 개발자에게 투명하게 공개됩니다. 개발 중에 엔지니어는 필요에 따라 소프트웨어 라이브러리와 오버레이를 결합하여 해당 API를 통해 애플리케이션을 구현합니다. 실행 중에 프로세서 시스템은 평소대로 소프트웨어 라이브러리 코드를 실행하는 반면에, PL 패브릭은 오버레이에 제공된 기능을 구현합니다. 그 결과 점점 더 까다로워지는 애플리케이션을 위한 FPGA 기반 설계에 대한 관심을 지속적으로 유도할 수 있는 가속화된 성능이 실현됩니다.
이름에서 알 수 있듯이 PYNQ는 Python 프로그래밍 언어와 연관된 개발 생산성 향상을 활용합니다. Python은 상대적인 단순성과 크고 증가하는 에코시스템으로 인해 주요 언어 중 하나로 부상했습니다. 개발자는 오픈 소스 Python 모듈 저장소의 지원 서비스 또는 특수 알고리즘에 필요한 소프트웨어 라이브러리를 찾으려고 합니다. 동시에 PYNQ는 Python 인터프리터의 일반 C 언어 구현을 사용하므로 개발자는 C 언어로 중요 기능을 구현할 수 있습니다. 이 구현을 사용하면 수천 개의 C 라이브러리에 쉽게 액세스하고 개발자가 제공한 C 언어 라이브러리를 간편하게 사용할 수 있습니다. 숙련된 개발자는 특수 하드웨어 오버레이와 C 언어 소프트웨어 라이브러리를 사용하여 PYNQ를 확장할 수 있지만 PYNQ의 강점은 Python 프로그램을 구축할 수 있는 개발자를 위해 생산성이 높은 개발자 환경을 제공하는 데 있습니다.
오픈 소스 프로젝트인 PYNQ는 다른 오픈 소스 프로젝트인 Jupyter Notebook을 기반으로 구축됩니다. Jupyter Notebook은 Python 또는 다른 지원되는 프로그래밍 언어에서 알고리즘을 대화식으로 탐색하고 복잡한 애플리케이션의 시제품을 제작하는 데 특히 효과적인 환경을 제공하며, 현재 40 이상의 번호가 지정되어 있습니다. Project Jupyter에서 커뮤니티의 합의를 통해 개발된 Jupyter Notebook은 실행 가능한 코드를 설명 텍스트 및 그래픽과 결합합니다. 이 기능을 사용하면 개별 개발자가 다른 개발 환경으로 이동하지 않고 진행 상황을 효과적으로 문서화할 수 있습니다. 예를 들어 개발자는 데이터를 보는 데 필요한 몇 줄의 코드를 코드에서 생성되는 그래픽과 결합하는 노트북을 사용할 수 있습니다(그림 3).

그림 3: Xilinx 샘플 저장소의 Jupyter Notebook은 설명 텍스트, 실행 코드, 애플리케이션과 연결된 출력 등을 결합합니다. (이미지 출처: Xilinx)
Jupyter Notebook은 Jupyter Notebook 서버에 제공되는 대화식 개발 환경에서 유지 관리되는 실시간 문서이므로 코드, 출력 및 설명 텍스트를 포함할 수 있습니다(그림 4). Jupyter 세션에서 서버는 기존 웹 브라우저에서 HTTP를 사용하거나 HTTP 및 Websockets 프로토콜 조합(렌더링된 문서의 정적 콘텐츠 및 동적 콘텐츠의 경우)을 사용하여 노트북 파일을 렌더링합니다. 백 엔드에서 서버는 오픈 소스 ZeroMQ(ØMQ) 메시징 프로토콜을 사용하여 코드 실행 커널과 통신합니다.

그림 4: Jupyter 세션에서 노트북 서버는 코드를 실행하는 백 엔드 커널과 상호 작용하면서 노트북 파일의 내용을 웹 브라우저에 렌더링합니다. (이미지 출처: Project Jupyter)
편집 모드에서 사용자는 텍스트와 코드를 수정할 수 있습니다. 그러면 서버에서 해당 노트북 파일 즉, JSON 키/값 쌍을 구성하는 텍스트 파일을 업데이트합니다. Jupyter 환경에서는 이러한 쌍을 셀이라고 합니다. 예를 들어 앞서 표시된 Jupyter Notebook의 웹 브라우저 표시는 코드 및 markdown 텍스트를 위한 몇 개의 셀로 구성됩니다(목록 1).
복사 { "cell_type": "markdown", "metadata": {}, "source": [ "## Error plot with Matplotlib\n", "이 예는 노트북의 그림을 보여줍니다(별도의 창에 표시 안 함)."
] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAA[truncated]", "text/plain": [ "<matplotlib.figure.Figure at 0x2f85ef50>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", " \n", "X = np.arange(len(values))\n", "plt.bar(X + 0.0, values, facecolor='blue', \n", " edgecolor='white', width=0.5, label=\"Written_to_DAC\")\n", "plt.bar(X + 0.25, samples, facecolor='red', \n", " edgecolor='white', width=0.5, label=\"Read_from_ADC\")\n", "\n", "plt.title('DAC-ADC Linearity')\n", "plt.xlabel('Sample_number')\n", "plt.ylabel('Volts')\n", "plt.legend(loc='upper left', frameon=False)\n", "\n", "plt.show()" ] },
목록 1: Jupyter Notebook은 그림 3에 표시된 렌더링된 페이지와 같이 코드 섹션, 태그, 출력으로 구성된 JSON 키/값 쌍을 포함하는 텍스트 파일입니다. 프레젠테이션의 목적상 여기서는 그림의 .png 이미지에 해당하는 문자열이 잘려 있습니다. (코드 출처: Xilinx)
설명서 기능 외에도 Jupyter 환경은 코드 셀을 대화식으로 실행할 수 있습니다. 개발자는 브라우저에서 원하는 셀을 선택하고(그림 3의 파란색 테두리) 브라우저 창의 맨 위에 있는 Jupyter 메뉴에서 실행 버튼을 클릭하면 됩니다. 그러면 Jupyter Notebook 서버가 해당 코드 셀을 코드 실행 커널로 전달합니다. PYNQ 환경에서 이 커널은 대화식 Python(IPython) 커널입니다. 코드 실행 후 서버는 렌더링된 웹 페이지 및 노트북 파일을 커널에서 생성된 출력으로 비동기적으로 업데이트합니다.
PYNQ는 IPython 커널 및 노트북 웹 서버를 비롯한 Jupyter 프레임워크를 Zynq SoC의 Arm 프로세서에 내장하여 이 접근 방식을 FPGA 기반 개발로 확장합니다. 환경에 포함된 pynq Python 모듈은 프로그래머에게 Python 프로그램에서 PYNQ 서비스에 액세스하는 데 필요한 Python API를 제공합니다.
FPGA 개발 환경
PYNQ를 지원하도록 특별히 설계된 Digilent PYNQ-Z1 개발 키트를 사용하면 개발자가 사용 가능한 PYNQ 부트 가능한 Linux 이미지를 로드하여 FPGA 가속 애플리케이션을 빠르게 탐색할 수 있습니다. PYNQ-Z1 기판은 Xilinx XC7Z020 Zynq SoC를 512MB RAM, 16MB 플래시, 추가 외부 플래시 메모리를 위한 microSD 슬롯 등과 결합합니다. 스위치, 버튼, LED, 여러 입력/출력 포트와 함께 기판에는 Digilent Pmod(주변 장치 모듈) 인터페이스 및 Arduino 실드 및 Digilent chipKIT 실드를 통해 타사 하드웨어에 연결하기 위한 확장 커넥터가 제공됩니다. 또한 XADC라는 Zynq SoC의 아날로그 디지털 컨버터(ADC)가 6개의 단일 종단 아날로그 입력 포트 또는 4개의 차동 아날로그 입력 포트로 제공됩니다. 또한 Digilent는 전원 공급 장치, 마이크로 USB 케이블, PYNQ 이미지와 함께 사전 로드된 microSD 카드, Python 모듈 업데이트 또는 추가를 위한 이더넷 케이블로 구성된 별도의 PYNQ-Z1 생산성 키트를 제공합니다.
개발자의 경우 Jupyter Notebook을 통해 SoC와 기판의 모든 기능을 즉시 사용할 수 있습니다. 예를 들어 기판의 Pmod 인터페이스에 액세스하여 루프백 테스트에서 ADC를 읽고 디지털 아날로그 컨버터(DAC) 값을 쓰려면 단 몇 줄의 코드만 입력하면 됩니다(그림 5). 필요한 Python 모듈을 가져온 후 SoC PL이 “기본” 오버레이로 초기화됩니다(그림 5의 셀 2). 기존 기판 지원 패키지와 마찬가지로 이 기본 오버레이를 통해 기판 주변 장치에 액세스할 수 있습니다.

그림 5: Xilinx 샘플 저장소에 포함된 Jupyter Notebook은 입/출력 트랜잭션을 위한 하드웨어 서비스 액세스와 관련된 간단한 설계 패턴을 보여줍니다. (이미지 출처: Xilinx)
개발자는 값을 읽고 쓰기 위해 가져온 모듈만 호출하면 됩니다(그림의 셀 3). 그림의 동일한 노트북에서 노트북 서버는 시퀀스의 각 셀을 발급하고 노트북을 생성된 결과로 업데이트합니다. 이 경우 유일한 출력 값은 0.3418이지만 모든 실행 오류가 해당 코드 셀과 함께 일반 Python 역추적 스택으로 표시됩니다.
복잡한 애플리케이션 구축
광범위한 사용 가능한 Python 모듈과 결합된 내장형 애플리케이션 개발에 대한 믿을 수 없을 정도로 간단한 이 접근 방식에서는 복잡한 컴퓨팅 집약적인 애플리케이션을 빠르게 구현하기 위해 강한 플랫폼을 마스킹합니다. 예를 들어 개발자는 PYNQ-Z1 HDMI 입력 및 인기 있는 OpenCV 컴퓨터 비전 라이브러리를 사용하여 얼굴 인식 웹캠을 빠르게 구현할 수 있습니다. 기본 오버레이 및 웹캠 인터페이스를 로드한 후 개발자는 OpenCV 카메라 피사체 비디오 입력을 초기화합니다(그림 6). 비디오 이미지를 읽는 것은 videoIn.read()를 호출하는 것만큼 간단합니다(이 예제의 경우 frame_vga 반환).

그림 6: Xilinx 샘플 저장소에 포함된 Jupyter Notebook은 PYNQ-Z1 개발 기판의 하드웨어 리소스를 OpenCV 라이브러리(cv2)에 제공되는 강력한 이미지 처리 기능과 결합하여 웹캠 얼굴 인식 시스템을 빠르게 구축할 수 있는 방법을 보여줍니다. (이미지 출처: Xilinx)
후속 단계에서 개발자는 사전 설정된 기준에 따라 노트북에서 별도의 셀로 관리되는 OpenCV(cv2) 분류자 개체를 생성하고 기능을 식별하는 경계 상자를 추가합니다(이 예제에서 눈은 녹색, 얼굴은 파란색). 다른 셀 쌍에서 기판의 HDMI 출력을 사용하여 출력을 표시한 후 애플리케이션이 완료됩니다(그림 7).

그림 7: Xilinx 웹캠 얼굴 인식 노트북의 최종 셀은 OpenCV 분류자 사용을 보여줍니다. 이 결과는 원본 이미지에 경계 상자를 추가하는 데 사용되며 PYNQ-Z1 개발 기판의 HDMI 출력 포트를 사용하여 표시됩니다. (이미지 출처: Xilinx)
Jupyter Notebook은 복잡한 소프트웨어를 대화식을 구축 및 테스트하고 소프트웨어 관련 토론을 공유할 수 있는 기능을 제공하므로 인공 지능 애플리케이션을 위한 알고리즘을 최적화하려는 과학자 및 엔지니어 사이에서 널리 사용됩니다. 작업이 전개되면서 노트북에는 코드와 코드의 출력뿐 아니라 결과에 대한 개발자의 분석 내용을 표시하여 팀원과 동료 간에 공유할 수 있는 컴퓨팅 설명을 제공합니다.
하지만 개발자는 노트북이 생산 지향적인 노력을 위한 저장소가 아니라는 점을 이해해야 합니다. 예를 들어 이미지 데이터에 대해 큰 16진수로 인코딩된 문자열을 포함하여 문서 크기가 증가할 뿐만 아니라 일반 소스 버전 제어 시스템에서 사용되는 다른 방법을 복잡하게 만들 수 있습니다. 코드와 비기능성 텍스트를 인터레이싱하면 이전 분석 단계에서 생성된 코드를 프로덕션 수준 개발 공정으로 마이그레이션하는 과정이 복잡해질 수 있습니다. 하지만 코드 탐색 및 빠른 시제품 제작을 위해 Jupyter Notebook은 강력한 개발 환경을 제공합니다.
결론
FPGA는 IoT, 컴퓨터 비전, 산업 자동화, 자동차 등을 위해 설계된 내장형 시스템의 수요 증가를 충족하는 데 필요한 성능 향상을 제공합니다. 기존 FPGA 개발 방법이 많은 개발자에게 장애물이 되고 있지만 Jupyter Notebook을 기반으로 하는 Python 기반 PYNQ 개발 환경의 등장은 효과적인 대안을 제시합니다. PYNQ를 지원하도록 특별히 설계된 개발 기판을 사용하면 FPGA 경험이 적은 개발자가 FPGA 성능을 최대한 활용하여 컴퓨팅 집약적인 애플리케이션을 가속화할 수 있는 설계를 빠르게 구현할 수 있습니다.
면책 조항: 이 웹 사이트에서 여러 작성자 및/또는 포럼 참가자가 명시한 의견, 생각 및 견해는 DigiKey의 의견, 생각 및 견해 또는 DigiKey의 공식 정책과 관련이 없습니다.


