개발 편의성을 위한 소소한 Tips/04 질의 응답 정리

[FPGA Q/A. 008] FCLK_Reset 을 PS 에서 제어하기.

반응형

 

Q

Hello Matbi world 를 진행하던 도중, zynq processor 와 제가 만든 user ip 를 create block design 을 통해 연결하는 부분이 있습니다.

이 부분에서, run block automation 을 하게 되면 zynq의 FCLK 신호와 reset 신호가 user ip  부분에 연결이 됩니다. CLK는 이해가 되는데 FCLK_Reset 이 어떤 역할을 하는 신호인지 잘 모르겠습니다.  verilog 코드 상에서 reset 신호를 받아서 말 그대로 reset 신호로 사용하기에 reset 신호를 sw 따위로 주겠구나 생각했는데 그냥 zynq 로 주게 되면 그 FCLK_reset 신호는 vitis 의 c코드로 제어할수 있는 것인가요?

 

A

안녕하세요 :)

먼저 사전 설명을 위해서, 다음 문서를 참고했습니다.

https://www.xilinx.com/support/documentation/boards_and_kits/zc702_zvik/2015_2/ug925-zynq-zc702-base-trd.pdf

해당 FCLK_Reset 은 앞으로 만들 PL의 IP 에 적극 사용될 예정입니다. 

PS는 4개의 FCLK_RESET[3:0]_N 완전 프로그래밍 가능한 리셋 신호를 PL에 제공합니다. 이 신호는 PS 클록과 비동기식입니다.

이 디자인의 PL 로직 리셋 블록은 FCLK_RESET0_N에서 입력을 수신하고 PL에서 구현된 디자인에 필요한 리셋 신호를 생성합니다.

 

질문의 내용을 살펴보겠습니다.

verilog 코드 상에서 reset 신호를 받아서 말 그대로 reset 신호로 사용하기에 reset 신호를 sw 따위로 주겠구나 생각했는데 그냥 zynq 로 주게 되면 그 FCLK_reset 신호는 vitis 의 c코드로 제어할수 있는 것인가요?

전원을 키고 bitstream 을 올리면, reset 은 "한번" default 로 걸리는 것으로 알고 있습니다. 즉, 제 강의에서 별도로 reset 을 프로그래밍 하진 않았구요. reset 이 걸린 상태이기 때문에, 동작에는 문제는 없었어요.

<여쭤보신, c 코드 제어에 대하여>

문서상에서는 "프로그래밍 가능한 리셋" 이라는 표현으로 사용한 것으로 봐서, vitis 의 c코드상에서 제어 가능하지 않을까 생각하였습니다. 

방법은 여러 링크? 들을 통해 찾아보았구요. 다음과 같이 정리했습니다. 동작 확인 부탁드려요.

참고한 링크입니다.

https://github.com/fpga-theremin/theremin/blob/master/fpga/ip_repo/theremin_ip/drivers/theremin_ip/src/theremin_ip.c

https://forums.xilinx.com/t5/%E5%B5%8C%E5%85%A5%E5%BC%8F-%E5%B7%A5%E5%85%B7-%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/PS%E6%8E%A7%E5%88%B6PL%E7%AB%AF%E5%A4%8D%E4%BD%8D%E5%A4%B1%E8%B4%A5/m-p/980501

https://forums.xilinx.com/t5/Processor-System-Design-and-AXI/Asserting-FCLK-RESET0-N-FPGA-RST-CTRL-from-baremetal-system/m-p/779766

다음은 소스코드입니다. 적용 후 확인부탁드려요.

(빌드는 정상적으로 됨을 확인했습니다.. 만 동작은 미확인 하였습니다. 될거라고 생각해요.)

#include <xil_misc_psreset_api.h>  // ps reset 관련 API 헤더

#ifndef XSLCR_FPGA_RST_CTRL_ADDR    // 2015 버전에는 이 헤더가 존재 했었는데, 이후부터 사라짐. 그래서 별도의 REG Address 를 추가함.
#define XSLCR_FPGA_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000240U)
#endif
#ifndef XSLCR_LOCK_ADDR
#define XSLCR_LOCK_ADDR (XSLCR_BASEADDR + 0x4)
#endif
#ifndef XSLCR_LOCK_CODE
#define XSLCR_LOCK_CODE 0x0000767B
#endif

<사용방법>

int main() {

// reset 을 걸고 싶은 부분
    // assert FPGA Reset Signal  (reset 걸기!)
    Xil_Out32(XSLCR_UNLOCK_ADDR, XSLCR_UNLOCK_CODE); // ps 의 lock 을 해제함.
    Xil_Out32(XSLCR_FPGA_RST_CTRL_ADDR, 0x0F);    // 0x0f 면, 1111  즉, 4개의 reset 을 제어 가능함. 여기서 저희는 한개의 clock 만 사용하기 때문에, 0x0f 대신 0x01 을 사용해도 무방함.

    // and release the FPGA Reset Signal (reset 해제하기!)
    Xil_Out32(XSLCR_FPGA_RST_CTRL_ADDR, 0x00);    // 0 으로 값을 셋팅 함으로써, reset 을 풀어버림.
    Xil_Out32(XSLCR_LOCK_ADDR, XSLCR_LOCK_CODE);   // PS 의 lock 을 다시 복구.
}

 

즐공하세요 :)

반응형