본문으로 바로가기

LED 켜보기

category 칩설계 연구방/디지털설계 2018. 10. 19. 21:24

이번 포스트에서는 가장 쉬운 LED 켜는 방법에 대해 알아본다. 프로그래밍 언어를 배우면 가장 먼저 해보는 Hello world 출력해보기 단계라고 보면 된다. 이번 단계의 주요 목적은 개발 전체 flow를 한 번 훝어보면서, 현재 구성된 개발 환경이 제대로 동작하는 지 확인해보는 것이다. 참고로 기본적인 Verilog 언어에 대해서는 따로 설명하지 않으니 이 부분은 다른 자료를 참고해야 한다. 그리고, 기본 vivado 툴 사용법도 따로 설명하지 않는다. 이 부분은 유튜브나 다른 사이트에 자세하게 설명되있으니 참고하면 된다. (사실, GUI 툴이기 때문에 글로 설명하기가 굉장히 피곤하다....) 꼭 체크해야 하는 중요한 기능은 그 때마다 따로 설명한다. 




1. LED 관련 회로 확인


LED를 켜보기로 했다는 것은 FPGA 외부에 있는 디바이스(장치)를 조작시켜보겠다는 뜻이므로, 가장 먼저 시작해야 할 것은 LED와 FPGA간의 보드 회로가 어떻게 구성되어 있는지 살펴봐야 한다. 그래야 보드 설계자가 생각한 조작 방식 의도를 이해하고 실제 제어 로직을 구상해 볼 수 있다. Nexsys4 보드 홈페이지에서 구할 수 있는 데이터북을 보면 쉽게 이해할 수 있게 그림으로 그려두었는데, 그 부분부터 살펴보자. 보드 데이터 시트 내용 중 LED 부분을 확인해 보면 다음과 같은 그림을 볼 수 있다.



LED는 빛이 발생하는 다이오드라고 보면 되는데, 보통 삼각형 방향으로 높은 전압을 걸어 주면 다이오드에 전류가 통하면서 빛이 나는 구조로 되어 있다. 다이오드 뒤에 연결된 저항들은 다이오드가 버틸 수 있는 전류를 제한하는 용도로 사용된다. 일반적인 LED 부품 설명서를 보면 해당 부품이 몇 A까지 전류를 견딜 수 있는지 나와있으며, 저항을 달아 전류를 조절해 LED가 손상되는 것을 방지한다. 어쨋든, 첫 번째 LED를 켜고 싶으면 H17 핀으로 높은 전압을 걸어 주면 된다.




2. 코드 작성


Vivado에서 프로젝트를 생성한 뒤, 다음과 같은 코드를 추가한다. LED 전부 켜면 되기 때문에 LED가 연결된 모든 핀으로 1을 걸어주면 된다.

module top (
    output [15:0] o_led
);
    assign o_led = 16'hFFFF;
endmodule

위와 같이 코드를 작성하면 o_led라는 16비트 output 포트로 전부 1이 나가게 FPGA 내부 회로가 구성이 된다. 이것으로 로직 설계는 끝났다. 소스 코드 외에 constraint 파일을 추가해줘야 하는데, 그 이유는 매우 간단하다.잘 생각해보면, FPGA 툴은 내부 회로를 위 코드만 보고 구성할 경우 o_led라는 output 포트를 어느 핀에 연결시켜야 하는지 알지 못한다. 즉, o_led를 보드 회로도에 나와 있는 LED가 연결된 핀에 연결하는 작업이 필요한데, 이를 위해 XDC라는 파일을 작성해야 한다. XDC는 design constraint 파일이라고 흔히 불리는데, 이 파일이 synthesis & implementation 과정에 적용되어 FGPA 합성 툴이 동작하게 된다. XDC에는 다양한 정보들을 정확히 적어줘야 FPGA 합성 툴이 의도대로 정확히 동작하게 된다. 정확히 어떤 정보를 써줘야 하는지는 차차 알아보기로 하고, 일단은 설계의 출력 포트를 FPGA 어떤 핀에 연결시킬 건지 XDC 파일에 적어줘야 한다고만 이해하고 넘어가자.


FPGA의 각 핀이 보드의 어느 부품과 연결되어 있는지는 보드 별로 다르기 때문에 보통 보드 제조사에서 기본적인 XDC 파일은 제공하며, Nexsys4 DDR 보드도 해당 파일을 제공하고 있다. 기본 제공되는 XDC를 열어보면 주저리 주저리 무슨 코드가 쭉 나와 있는데, 쭉 보다보면 LED 관련된 부분이 있는 것을 확인할 수 있다. 이를 다음과 같이 수정한다. 그 외의 라인은 전부 삭제해도 큰 문제는 없다.

set_property -dict {PACKAGE_PIN H17   IOSTANDARD LVCMOS33 } [get_ports { o_led[0] }];
set_property -dict {PACKAGE_PIN K15   IOSTANDARD LVCMOS33 } [get_ports { o_led[1] }];
set_property -dict {PACKAGE_PIN J13   IOSTANDARD LVCMOS33 } [get_ports { o_led[2] }];
set_property -dict {PACKAGE_PIN N14   IOSTANDARD LVCMOS33 } [get_ports { o_led[3] }];
set_property -dict {PACKAGE_PIN R18   IOSTANDARD LVCMOS33 } [get_ports { o_led[4] }];
set_property -dict {PACKAGE_PIN V17   IOSTANDARD LVCMOS33 } [get_ports { o_led[5] }];
set_property -dict {PACKAGE_PIN U17   IOSTANDARD LVCMOS33 } [get_ports { o_led[6] }];
set_property -dict {PACKAGE_PIN U16   IOSTANDARD LVCMOS33 } [get_ports { o_led[7] }];
set_property -dict {PACKAGE_PIN V16   IOSTANDARD LVCMOS33 } [get_ports { o_led[8] }];
set_property -dict {PACKAGE_PIN T15   IOSTANDARD LVCMOS33 } [get_ports { o_led[9] }];
set_property -dict {PACKAGE_PIN U14   IOSTANDARD LVCMOS33 } [get_ports { o_led[10] }];
set_property -dict {PACKAGE_PIN T16   IOSTANDARD LVCMOS33 } [get_ports { o_led[11] }];
set_property -dict {PACKAGE_PIN V15   IOSTANDARD LVCMOS33 } [get_ports { o_led[12] }];
set_property -dict {PACKAGE_PIN V14   IOSTANDARD LVCMOS33 } [get_ports { o_led[13] }];
set_property -dict {PACKAGE_PIN V12   IOSTANDARD LVCMOS33 } [get_ports { o_led[14] }];
set_property -dict {PACKAGE_PIN V11   IOSTANDARD LVCMOS33 } [get_ports { o_led[15] }];

첫 번째 줄만 살펴보면 쉽게 이해할 수 있는데, package pin H17번을 포트 o_led[0]에 연결하라는 뜻이다. 아래 줄 내용도 이와 유사한 내용이다. 중간에 보면 LVCMOS33이라는 것이 있는데, 이는 해당 포트를 LVCMOS33이라는 IO 표준 규격으로 설정하라는 뜻이다. FPGA는 프로그래밍 가능한 디바이스라서 그런지, 각 IO 포트가 여러가지 IO 표준을 지원하며, 어떤 표준으로 설정해야 할 지 사용자가 지정해 줘야 한다. 이러한 표준 규격을 사용하는 이유는 내가 만들지 않은 다른 칩과 연결할 때 문제가 생기지 않게 하기 위함이며, 이러한 규격은 서로 약속되어 있기 때문에 상대방 칩과 규격만 잘 맞추면 서로 문제 없이 연결시킬 수 있다. 지금 사용할 포트들은 LED에 연결할 것이기 때문에, 크게 신경 쓸 필요 없이 그대로 사용하면 된다.




3. 시뮬레이션


이제 우리가 만든 코드가 잘 동작되는지 시뮬레이션을 해야 한다. 보통 초보자들은 시뮬레이션보다는 일단 보드에 올려서 확인해보려는 삽질을 자주 하는데, 내 생각에는 보드에 올리기 전에 무조건 시뮬레이션부터 진행해 잘 동작된다는 것을 확인하는 것이 맞다고 생각한다. 설계가 잘못되어 문제가 생길 경우, 이를 보드 상에서 디버깅하는게 매우 어렵고 힘든 작업이기 때문이다. 시뮬레이션은 디자인 내부의 신호를 전부 보여주기 때문에 어떤 부분이 문제를 만들어 내는지 찾아내기 훨씬 쉽다. 

'칩설계 연구방 > 디지털설계' 카테고리의 다른 글

개발 환경 설정  (0) 2018.10.09