본문 바로가기
IT & 코딩

FPGA 메모 겸 예제 하나

by 에일라거 2019. 7. 2.

일단, 나의 삽력도 에지간한 경지에 올랐다고 생각했지만 FPGA 이건 와 당췌.... 아무리 뒤져도 정보가 거의 전무한 느낌? 뭔가 있다 해도 본인만 알아볼 수 있게끔 정리된 그런 글이랄까....

 

그래서 메모도 할 겸 어제 짠 예제 하나 남기겠어요. 그 전에! FPGA의 종류가 뭐가 있는지 간단히 먼저 분류

 

그보다 더 전에! FPGA란 Field Programmable Gate Array의 약자인 것으로... 에또 이것이 나한테는 전혀 신세계로, 나는 항상 순차적으로 실행하는 프로그램만 쿵짝쿵짝 해왔는데 이건 프로그래밍을 하면 그 코드가 칩 내부의 논리 회로로 구현되는 신기한 물건이다. 

 

보통 프로그래밍 → 컴파일 → 기계가 알아듣는다! (01010010 ...) → 순차실행 이런 식이라면 이놈은 프로그래밍 → 합성 → 회로가 구현된다! → 병렬/순차 실행 이런 식. 결과가 회로로써 구현되기 때문에 예를 들어 8개의 신호가 동시에 입력되면 동시에 처리할 수 있다. 사실 이 부분이 몹시 헷갈리는 부분.... 이렇게 다른 점 때문에 설계 방식 (코딩이 아니라 설계라고 하더라) 도 달라진다는데 아직 감이 별로 없다... 이럴거면 그냥 전자과 갈걸 닝기리 ㅠㅠ

 

갑자기 신세한탄이 되어버린 의식의 흐름을 끊고 다시 내용으로 돌아오면, 어쨌든 FPGA라는 건 대충 그런 것인데 크게 2개 회사에서 만든다. 하나는 Xilinx, 다른 하나는 Altera. 후자는 인텔 자회사. 그래서 더 클 줄 알았는데 시장 점유율은 Xilinx가 더 높다고 한다. 두개 사의 칩을 프로그래밍하는 언어는 비슷해 보여도 좀 다르기 때문에 하나를 선택해서 쭉 가져가는 게 낫다고 함. 그래서 나는 Xilinx를 선택했다!

 

FPGA 양대산맥!

그러면 이렇게 회사를 선택하고 나서 또 선택이 생기는데 PL (Programmable Logic)만 있는 애로 할 건지, PL/PS (Processing System)이 함께 있는 애로 할 건지.... 거칠게 봐서 전자는 Spartan 시리즈고 후자는 Zynq 시리즈인 거 같다. PL/PS도 뭔소린지 몰랐는데 이번에 보니 PL은 사용자가 구성한 논리 회로이고 (FPGA) PS는 사용자가 작성한 소프트웨어 (CPU 기반으로 돌아가는) 를 뜻함. 즉, FPGA와 CPU의 장점을 하나로 합쳐놓은 디바이스다. 이런 걸 SoC (System on Chip) 이라고 하데...

 

Spartan (PL) vs ZYNQ (PS/PL)

 

이런 놈을 Xilinx에서 먼저 출시를 해서 뜨악한 Altera가 비슷한 놈을 출시했다고 한다. 쨌든 난 Xilinx

 

이렇게 알고 나면 또 프로그래밍할 때 IDE에 해당하는 프로그램을 선택해야 한다. (뭐가 이래 많아 ㅠㅠ) Spartan은 ISE, ZYNQ는 VIVADO 를 사용해야 한다고. 일단 나는 Spartan의 예제를 보일 거라 ISE로 보여줌

 

일단 여기까지가 배경 설명이고, ISE를 깔고 여차저차 하는 건 엄청 좋은 블로그를 발견했다! 아래 링크를 참고!! 

 

 

[FPGA 강의] 1강 - FPGA 강의 오리엔테이션

0. 들어가며...안녕하세요? 다시 블로그 관리의 필요성을 느끼고 다시금 블로그를 붙잡고 열심히 포스팅을 ...

blog.naver.com

일단 여기의 1강~8강까지는 무조건 한번 다 따라해봐야 하고, 9강의 프로그램 구조, 10강의 문법과 데이터형까지 따라하고 나면!! 이 예제를 보면 된다.

 

아니 그럼 저 블로그를 보면 되지 왜 이런걸 또 쓰냔 말이오... 근데 8강까지 따라하는 건 쉬운데 이제 9강의 프로그램 구조를 보면, 뭐지 소스를 어떻게 하라는 거지? 저렇게만 하면 그냥 빈껍닥 아닌가...라는 생각이 들게 되어서 이 글을 쓰게 됨

 

일단 오늘 짤 회로? 프로그램?은 전가산기(Full-adder)를 이용한 8-bit 숫자 두 개를 더해주는 회로인데 이걸 구조적으로 짜는 거임. 위 블로그의 9강의 프로그램 구조에 나와 있는 내용을 좀 더 상세히 풀어쓴다고 생각하면 된다.

 

일단 전가산기가 무엇인가! 어떻게 구현하는가! 하는 거도 저 블로그에 다 나와 있다. 아래를 참고

 

 

[FPGA 강의] 16강 - 전가산기 설계 따라하기

0. 들어가며...안녕하세요? 땜쓰입니다. 이번 강의 포스팅에서는 이전 강의 포스팅에서 소개했던 반가산기...

blog.naver.com

전가산기는 간단히 말해서 두개의 비트 입력과 이전 자리에서 계산한 자리올림 정보까지 총 3개의 입력을 받아 이번 자리의 합과 다음 자리올림 정보, 총 2개의 출력을 내주는 가산기다. 이걸 하나의 비트에 대해 수행을 하고, 이걸 연쇄적으로 물려 두면 n-bit adder로 작용한다. 다음 그림을 보자

 

4-bit adder (출처 : arith-matic.com)

위 그림에서, (A.4 A.3 A.2 A.1) + (B.4 B.3 B.2 B.1) = C.out R.4 R.3 R.2 R.1 이라는 수가 된다. C.in = 0 을 넣으면 된다. 예를 들면, 1001 + 1010 = 10011 이 되는데... 이걸 암산으로 할 게 아니라 저 FULL-ADDER의 진리표를 따라서 해 보면 그렇게 나온다.

 

인제 ISE에서 프로젝트를 어떻게 하는지 안다치고 설명을 하면, 일단 New Source를 추가해서 FULL_ADDER.vhd 등 파일 이름을 맘대로 하고 위 강의에 나온 소스대로 코딩하면 전가산기가... 되지 않고, 링크 글의 댓글에 있는 것처럼 AND를 OR로 바꿔주면 잘 작동한다. 아래를 보자.

 

남의 소스를 그대로 따라 쓴거라 그림으로 넣는 것을 용서하시옵소서

마지막에 빨간 네모로 or라고 적혀있는데, 이게 저 블로그에는 and라고 되어 있다. and로 쓰면 동작을 제대로 안하니까 or로 고쳐쓰자. 그러면 전가산기로 잘 작동한다.

 

자 이렇게 소스 파일을 하나 작성해두고! 또 다른 소스를 추가한다. 한 비트에 대해 전가산기를 설계했으니까, 이걸 이제 연속으로 나열해주기만 하면 된다. EIGHT_BIT_ADDER.vhd 라는 식으로 하나 작성하고 다음과 같이 코딩한다.

 

각 전가산기를 입출력에 연결

보통 C++이든 뭐든 뭔가 소스를 하나 작성하고 거깄는걸 써먹으려면 다른 데서 좀 #include로 불러오든 뭐든 해야되는데, 이건 그런거 없다. 그냥 이렇게 architecture 안에 component로 이름을 똑같이 해서 작성을 하고, U1,U2, ..., U8까지 IN/OUT을 정의하면 그냥 지가 알아서 연결한다. 결국 위의 4 bit-adder 그림처럼 똑같은 걸 여러개 연결해서 8 bit-adder가 된 거임.

 

프로그래밍으로 치면 FULL_ADDER라는 객체를 하나 정의해놓고 U1, U2, ... , U8 이라는 인스턴스를 정의해서 사용하는 느낌? 이런 걸 구조적인 설계라고 얘기하더라고. 

 

근데 여기서 사실 잘 모르겠는 거 하나가... 결국 이짓을 해서 얻는 게 8비트짜리 숫자 두개 더해서 아웃으로 내보내는 거란 말이야. 근데 이렇게 하려면 사실은

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity HELLO_WORLD is
    Port ( IN1 : in  STD_LOGIC_VECTOR (8 downto 0);
        IN2 : in  STD_LOGIC_VECTOR (8 downto 0);
           OUTPUT : out STD_LOGIC_VECTOR (8 downto 0));
end HELLO_WORLD;

architecture Behavioral of HELLO_WORLD is
begin
process(IN1,IN2)
begin
OUTPUT <= IN1 + IN2;
end process;
end Behavioral;

 

이렇게만 해도 되는데... 왜 이런 짓을 하는 건지 모르겠단 말이지. 그리고 실제로 어떤 경우에 저런 식으로 component를 만들어두고 그걸 갖다 쓰는 식의 설계를 하는 건지 잘 모르겠다. 하나의 entity에서 게이트 갯수가 3천~5천개 정도로 설계할 때 최적이라고 하는걸 어디서 또 봤는데, 얼마나 소스를 작성해야 그정도가 나오는 건지 일절-_- 감이 없으니 이거야 원 난감하구먼

 

쨌든 컴포넌트 만드는 예제를 이번에 썼고, 다음번엔 SENT 통신 입력을 받으면 nibble 값을 출력해주는 프로그램 예제...!

댓글