적극적 생각/FPGA

0715 - 섹션2 - 기초 PL영역을 활용한 LED Blinking (2)

무말랭이 2022. 7. 15. 21:05

연결 환경설정

 

컴퓨터를 포맷해서 연결이 정상적으로 이뤄지는지에 대하여

board 파일에 대해서 다음 경로에 넣어주고

C:\Xilinx\Vivado\2022.1\data\boards\board_parts

샘플 bitstream을 hardware manager를 통해서 program device 해준다.

확인완료! 

https://learn-future.tistory.com/3345

 

0713 - 섹션1 - 환경설정

용량문제로 hard format을 했고 vatis와 vivado를 다시 설치했다 zybo 보드를 preset 해주었다. design sources + constraints + simulation sources 조합을 로드했고 RTL > Schematic 기능은 사용해보았다. FPGA..

aidenkang.me

 

XDC File

 

XDC = Xilinx design constraints file

Port와 Pin의 Mapping 관계를 XDC파일에 descript한다.

(Zybo board에서 제공하는 Master XDC File이 그 예시)

Mapping관계 뿐만 아니라 Constraints도 그 안에 넣는다.

(아직 Constraints에 대해서는 이해도가 부족하다.)

 

XSA File

 

Xilinx Support Archive

 

IP

 

Intellectual Property

https://wiki.kldp.org/HOWTO/html/CPU-Design-HOWTO/ip.html

 

IP란 무엇인가?

IP란 무엇인가? IP는 Intellectual Property의 약자이다. 좀더 구체적으로 말하면, ASIC [1] 이나 FPGA를 만들 때 사용될 수 있는 논리 회로 블럭을 의미한다. "IP Cores"의 예로는, UART, CPU, Ethernet 콘트롤러, PCI

wiki.kldp.org

 

아직 이하 개념들에 대해서 직관적으로 받아들여지지 않는데

이 부분에 대한 메타인지를 조금 더 많이 높여야겠다. 

 

IP Create and Import

 

하나의 프로젝트를 통해 두개의 .v 파일을 통해 IP를 생성했고

다른 하나의 프로젝트에서 Constraints에 Create IP Block Design을 수행해서 해당 IP를 호출했다.

 

 

여기서 LED와 SW의 경우 바로 포트로 만들어줄 수 있다.

 

포트와 핀의 이름의 경우 XDC에서 기술된 것과 동일해야 하기 때문에

led_0같은 네이밍은 led로 통일해준다.

 

clk과 reset신호를 어떻게 넣어주어야 하는가?

Zynq에서 clk을 만들 수 있다.

 

Zynq를 추가해주자. 그리고 거기있는 clk을 쓰자.

(단, 현재 우리는 AXI에 대해서 배우지는 않았다.)

 

 

우선 Run block automation을 한번 해주고 (FixedIO, DDR 확인)

사용하지 않는 부분을 다시 제거해주자. 지금은 오직 Clk(현재 100MHZ기준)만 쓴다.

 

 

그리고나서 핀 연결해주고

regenerate layout (auto)

 

 

이게 우리가 구성한 Hardware System이다.

그리고 이 디자인이 유효한지를 체크해주어야 하는데

Validate Design

이제는 Wrapper를 씌우자.

 

 

이게 우리가 생성한 Wrapper File이다.

//Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2022.1 (win64) Build 3526262 Mon Apr 18 15:48:16 MDT 2022
//Date        : Fri Jul 15 22:17:39 2022
//Host        : DESKTOP-T288I0O running 64-bit major release  (build 9200)
//Command     : generate_target design_1_wrapper.bd
//Design      : design_1_wrapper
//Purpose     : IP block netlist
//--------------------------------------------------------------------------------
`timescale 1 ps / 1 ps

module design_1_wrapper
   (DDR_addr,
    DDR_ba,
    DDR_cas_n,
    DDR_ck_n,
    DDR_ck_p,
    DDR_cke,
    DDR_cs_n,
    DDR_dm,
    DDR_dq,
    DDR_dqs_n,
    DDR_dqs_p,
    DDR_odt,
    DDR_ras_n,
    DDR_reset_n,
    DDR_we_n,
    FIXED_IO_ddr_vrn,
    FIXED_IO_ddr_vrp,
    FIXED_IO_mio,
    FIXED_IO_ps_clk,
    FIXED_IO_ps_porb,
    FIXED_IO_ps_srstb,
    led,
    sw);
  inout [14:0]DDR_addr;
  inout [2:0]DDR_ba;
  inout DDR_cas_n;
  inout DDR_ck_n;
  inout DDR_ck_p;
  inout DDR_cke;
  inout DDR_cs_n;
  inout [3:0]DDR_dm;
  inout [31:0]DDR_dq;
  inout [3:0]DDR_dqs_n;
  inout [3:0]DDR_dqs_p;
  inout DDR_odt;
  inout DDR_ras_n;
  inout DDR_reset_n;
  inout DDR_we_n;
  inout FIXED_IO_ddr_vrn;
  inout FIXED_IO_ddr_vrp;
  inout [53:0]FIXED_IO_mio;
  inout FIXED_IO_ps_clk;
  inout FIXED_IO_ps_porb;
  inout FIXED_IO_ps_srstb;
  output [3:0]led;
  input [3:0]sw;

  wire [14:0]DDR_addr;
  wire [2:0]DDR_ba;
  wire DDR_cas_n;
  wire DDR_ck_n;
  wire DDR_ck_p;
  wire DDR_cke;
  wire DDR_cs_n;
  wire [3:0]DDR_dm;
  wire [31:0]DDR_dq;
  wire [3:0]DDR_dqs_n;
  wire [3:0]DDR_dqs_p;
  wire DDR_odt;
  wire DDR_ras_n;
  wire DDR_reset_n;
  wire DDR_we_n;
  wire FIXED_IO_ddr_vrn;
  wire FIXED_IO_ddr_vrp;
  wire [53:0]FIXED_IO_mio;
  wire FIXED_IO_ps_clk;
  wire FIXED_IO_ps_porb;
  wire FIXED_IO_ps_srstb;
  wire [3:0]led;
  wire [3:0]sw;

  design_1 design_1_i
       (.DDR_addr(DDR_addr),
        .DDR_ba(DDR_ba),
        .DDR_cas_n(DDR_cas_n),
        .DDR_ck_n(DDR_ck_n),
        .DDR_ck_p(DDR_ck_p),
        .DDR_cke(DDR_cke),
        .DDR_cs_n(DDR_cs_n),
        .DDR_dm(DDR_dm),
        .DDR_dq(DDR_dq),
        .DDR_dqs_n(DDR_dqs_n),
        .DDR_dqs_p(DDR_dqs_p),
        .DDR_odt(DDR_odt),
        .DDR_ras_n(DDR_ras_n),
        .DDR_reset_n(DDR_reset_n),
        .DDR_we_n(DDR_we_n),
        .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
        .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
        .FIXED_IO_mio(FIXED_IO_mio),
        .FIXED_IO_ps_clk(FIXED_IO_ps_clk),
        .FIXED_IO_ps_porb(FIXED_IO_ps_porb),
        .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
        .led(led),
        .sw(sw));
endmodule

 

그리고나서 bitstream 생성

언제 cancel해서 나가는지

언제 open design 하는지

 

오 뭔가 오밀조밀하게 생긴게 보인다.

 

 

현재 Timing도 너무 쉬워서 Violation이 날 수가 없다.(그래서 굳이 Check를 하지 않은 것)

 

그리고 현재 전체 리소스 중에서 1% 정도를 사용하고 있다.

 

추가적으로 더 보면 좋은게  있는데

Report Utilization

 

 

각 모듈별로 어느 정도의 리소스를 활용하는지를 알 수 있다.

 

추가적으로 Highlight Leaps를 통해서, 이 모듈이 어디 구현되어있는지도 알 수 있다.

 

나중에 고급되면 이러한 디테일들을 많이 확인해야 할 것.

 

---

 

Export Hardware (XSA 파일을 생성중)

이것으로 Launch Vitis를 해준다.

 

 

네이밍 컨벤션

 

 

vitis에서 xsa file load

 

 

어플리케이션 이름은 _app

 

blank C project

 

 

main.c 생성

코드작성

빌드

실행

 

 

불이 잘 들어옴을 확인할 수 있다.

 

순간 왜 C코드를 작성하지 않았는데 동작하지 생각했는데

우리가 만든건 하드웨어 카운터의 구현이기 때문에

클락 주파수에 따라 각각 맞추어서 LED ON OFF signal을 주고 있는 것이다.

PL 영역을 활용해 HW Programming 한다는 것이 이제 이해가 갔다.

 

우리가 C를 통해 이렇게 실행하는 이유는

VITIS에서 Zynq를 통해 Reset 신호를 제대로 주기 위하여이다.

 

 

(잠시, 귀여운 우리 말랑이다.)

 

정리해보자.

 

 

(30:00)

 

Zynq의 PS로부터 Clk을 생성했다.

VHDL을 Xilinx의 IP로 만들었다.

Vivado Project에서 해당 IP를 연결해서 HW를 만들었다.

Implementation 이후에 Report에 대해서도 확인했다.

 

PS의 Clk Reset을 생성하기 위해 Vitis에서 Dummy program을 실행했다.

결과를 확인했다.