SPI 통신은 거리가 짧은 장치들끼리 통신할때 많이 쓰이는 프로토콜입니다.

최근에 Xilinx社의 FPGA에서 SPI 통신을 구현하여 동작시킬 일이 있어서 코드를 짜봤습니다.

FPGA의 경우엔 구글에서 좀 뒤져봤는데 프로토콜을 잘못 이해하고 짠 것들이 많아 힘들었는데, [여기]가 기반코드를 잘 짜놔서 여기에서부터 시작했습니다.

참고로 Xlinx社 제품들의 디지털 신호는 LVCMOS33(3.3V)이 대부분인데 아두이노는 5V입니다. 따라서 아두이노에서 FPGA로 신호를 보낼때는 전압 강하를 시키던가 하지 않으면 보드가 죽을 수 있습니다.  저는 [여기]를 참고(2N3094, 2N3906이 필요)해서 강하 회로를 만들었습니다만, Level Shifter 칩을 구해서 써도 됩니다. 정 아니면 저항만 써도 되긴 하다만 안전한 방법은 아닙니다.

아래는 코드 주요 사항 설명입니다.

# SPI 구현 형식
* MSB 우선
* SPI MODE3 (CPOL=CPHA=1)
* 8비트 단위 송신
# 테스트 환경
Master: Arduino MEGA
Slave: CMOD A7(Artix 35T/35tcpg236-1)
# 주요 기능 (Slave)
* 마스터가 보내는 하나의 8비트 데이터를 명령어로 해석한다.
* 슬레이브는 명령어에 따라 다양한 크기(8,16,32 등)의 데이터를 보낼 수 있다.
  – 8비트를 초과하는 데이터는 8비트 단위로 쪼개져서 마스터가 통신을 시도할때마다 한 단위씩 보내진다.
아래는 소스코드입니다.
Master.ino

 

Slave.v


아래는 위 코드를 실행했을 때 나오는 파형입니다. 마스터가 CMD_TEST3을 보내면 아스키코드로 “EDCB”에 해당하는 비트를 슬레이브가 보냅니다.

FPGA 프로그래밍은 뭐랄까… 디버깅이 물리적이라는 점도 진입장벽이긴 하지만 Verilog 특유의 시스템(always, Blocking/Non-Blocking Assignment 등)이 참 새롭네요.

시뮬레이션에서 원하는대로 된다고 해도 합성&구현하고나서 안되는 경우도 있고.. Vivado에서 합성했을때 나오는 Critical Warning 메시지는 꼭 읽고 해결해야합니다. Warning은 가능하면 해결해야하구요. 안그럼 Bitstream이 안 만들어지는 경우가 대다수고 만들어진다해도 생각하던대로 동작하지 않을겁니다.

특히 논리회로에서 Finite State Machine(FSM) 공부를 애매하게 해놓으면 C++, Java 등으로 소프트웨어 짜듯이 Verilog 코드를 짜게되어서 힘들어지네요. ㅠㅠ

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.