Git Product home page Git Product logo

chess_soc's Introduction

Chess_SoC

수강정보 : ITEC0412-001/SoC 설계 및 프로그래밍/문병인 교수님
SoC 설계 및 프로그래밍 강의를 수강하면서 진행한 텀프로젝트를 정리하여 공유한 포트폴리오입니다.

1. 프로젝트 개요

본 강의에서 학습한 verilog HDL, C 프로그래밍, FPGA 및 xilinx vivado를 사용하여 제작한 프로젝트입니다.
사용한 HW는 7segment, text lcd, TFT lcd(4.3inch), pushbutton 입니다.

본 repo에 PS영역에서 사용한 main.c와 ip repo를 업로드하였습니다.

Chess on Zynq

본 강의에서 사용하는 보드인 Zynq-7000을 사용해서 구현한 체스게임입니다.
시연 동영상 링크

  • UART 통신을 통해 좌표, 움직일 말을 입력받 을수 있습니다. (pw A2 A3) 형식
  • PS의 알고리즘으로 선택한 좌표로 말을 이동할 수 있습니다.
  • 만약 잘못된 turn에 이동하려고 시도하면(white turn에 black piece 이동) 경고 메세지를 출력하면서 다시 입력받습니다.
  • push button을 눌러서 interrupt service routine을 호출할 수 있고, 이동 확정과 되돌리기 기능을 구현했습니다.
  • turn이 바뀔 때 마다 99.99초 timer가 초기화됩니다.

2. Design overview

2-1. Block diagram

block_diagram UART로 부터 input 정보를 받고, 각 PS에서 처리 후 각 IP에 뿌려주는 방식입니다. 그리고 push button을 통해 ISR에 진입합니다.

2-2. Flow chart

flow_chart

3. SDK

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ff.h"
#include "xil_printf.h"
#include "xil_io.h"

#include "xil_exception.h"
#include "xparameters.h"
#include "xscugic.h"
#include "pushbutton.h"
#include "textlcd.h"
#include "timer_seven_seg.h"
// Above are header file for interrupt

/////
#include "xil_types.h"
#include "xuartps_hw.h"
/////

/////
#define		CR				0x0D						// carriage return
#define 	FORM_MAX		20							// number maximum
#define 	NAME_MAX		10							// name maximum
/////

#define		TextLine1			0				// Text LCD line1 indicator
#define 	TextLine2			1				// Text LCD line2 indicator
#define		SP					0x20			// Space
#define		MAX					17				// Number maximum

#define		TextLine1			0				// Text LCD line1 indicator
#define 	TextLine2			1				// Text LCD line2 indicator
#define		SP					0x20			// Space
#define		MAX					17				// Number maximum

#define INTC_DEVICE_ID		XPAR_SCUGIC_0_DEVICE_ID
#define INTC_DEVICE_INT_ID	31

static FATFS fatfs;
static FIL fil;

static char white_turn[32] = "wt.bin";
static char black_turn[32] = "bt.bin";
static char chess_board[32] = "cb.bin";		// cb : chess board
static char king_white[32] = "kw.bin";		// kw : king white
static char king_black[32] = "kb.bin"; 		// kb : king black
static char queen_white[32] = "qw.bin";		// qw : queen white
static char queen_black[32] = "qb.bin";		// qb : queen black
static char rook_white[32] = "rw.bin";		// rw : rook white
static char rook_black[32] = "rb.bin";		// rb : rook black
static char bishop_white[32] = "bw.bin";
static char bishop_black[32] = "bb.bin";
static char night_white[32] = "nw.bin";
static char night_black[32] = "nb.bin";
static char pawn_white[32] = "pw.bin";
static char pawn_black[32] = "pb.bin";

static int vertical_formation[9] = {0, 34, 68, 102, 136, 170, 204, 238, 272};
static int horizontal_formation[9] = {208, 242, 276, 310, 344, 378, 412, 446, 480};

static int Data;
static int R;
static int G;
static int B;

FRESULT Res;
TCHAR *Path = "0:/";
u32 * buffer[65280];
u32 data_size = 4 * 65280; // 4byte * buffer_size because integer(u32) is 4byte
u32 NumBytesRead;

XScuGic InterruptController; 	     // Instance of the Interrupt Controller
static XScuGic_Config *GicConfig;    // The configuration parameters of the controller

void 	SD_read(char *filename);
void 	TFTLCD_write_background();
void 	TFTLCD_write_sector(char horizontal, int vertical);
void 	TFTLCD_write_turnflag(char *filename);
void 	move(int start[2], int end[2], char *piece_moved);
void 	chess_default();

void	InitMsg(void);
void	PrintChar(u8 *str);
void	PrintMsg(u8 *str);
void 	GetPieceFormation(u8 *piece_formation);
void	SetPiece(u8 *start_piece);
void 	InitValue(u8 *formation, u8 *piece);

int 	GicConfigure(u16 DeviceId);
void 	ServiceRoutine(void *CallbackRef);

//void 	GetTextLine(char *ReadReg, unsigned int TextLine);
//void	ReadTLCDReg(void);

char	*piece;
int		sp[2];
int		ep[2];
int 	turn_flag = 1;
int 	flag = 0;

int main()
{
	// TRUE : white turn
	// FALSE : black turn
	int Status;

	//////
	u32	CntrlRegister;
	u8  piece_formation[FORM_MAX]	=	{0, };
	char  start_piece[2];
	char  start_point[2];
	char  end_point[2];

	char  *ptr;
	//////

	int 	i = 0;
	char	line1[17];//line1[16]; ZYNQ CHESS
	char	line2[17];//line2[17]; Player1 - WHITE
	char	line3[17];//line3[17]; Player2 - BLACK
	char	lineW[17];//lineW[17]; PUSH THE BUTTON
	char	lineB[17];//lineB[17]; PB2:UNDO|PB3:DO

	sprintf(line1, "    ZYNQ CHESS  ");
	sprintf(lineW, " PLAYER1 - WHITE");
	sprintf(lineB, " PLAYER2 - BLACK");

	sprintf(line2, " PUSH THE BUTTON");
	sprintf(line3, " PB2:UNDO|PB3:DO");

	CntrlRegister = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_CR_OFFSET);

	XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_CR_OFFSET,
					  ((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) | XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN) );

	NumBytesRead = 0;

	InitMsg();
	chess_default();

	while(TRUE)
	{
		if((turn_flag==1)) {
			TIMER_SEVEN_SEG_mWriteReg(XPAR_TIMER_SEVEN_SEG_0_S00_AXI_BASEADDR, 4, 1);
			TIMER_SEVEN_SEG_mWriteReg(XPAR_TIMER_SEVEN_SEG_0_S00_AXI_BASEADDR, 4, 0);
			do {
				for(i = 0; i < 4; i++)
				{
					TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4, line1[i*4+3] + (line1[i*4+2]<<8) + (line1[i*4+1]<<16) + (line1[i*4]<<24));
					TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4+16, lineW[i*4+3] + (lineW[i*4+2]<<8) + (lineW[i*4+1]<<16) + (lineW[i*4]<<24));
				}
				PrintChar("Enter the piece and start, end formation(format : pw A2 A3) : ");

				GetPieceFormation(piece_formation);

				ptr = strtok(piece_formation, " ");
				strcpy(start_piece, ptr);

				ptr = strtok(NULL, " ");
				strcpy(start_point, ptr);

				ptr = strtok(NULL, " ");
				strcpy(end_point, ptr);
				if (start_piece[1] == 'b') {
					PrintChar("It is the white turn. Please reenter\n");
					TFTLCD_write_turnflag(&white_turn);
					sleep(4);
					TFTLCD_write_turnflag(&chess_board);
					continue;
				}
			} while(start_piece[1] != 'w');

			SetPiece(start_piece); // Setting pointer of piece wanted to move

			sp[0] = start_point[0];
			sp[1] = (int)start_point[1] - 48;

			ep[0] = end_point[0];
			ep[1] = (int)end_point[1] - 48;

			move(sp, ep, piece);

			for(i = 0; i < 4; i++)
			{
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4, line2[i*4+3] + (line2[i*4+2]<<8) + (line2[i*4+1]<<16) + (line2[i*4]<<24));
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4+16, line3[i*4+3] + (line3[i*4+2]<<8) + (line3[i*4+1]<<16) + (line3[i*4]<<24));
			}
			turn_flag=3;
			flag = 1;
			// Jump to function that process interrupt(push button)
			Status = GicConfigure(INTC_DEVICE_ID);
			if (Status != XST_SUCCESS) {
				xil_printf("GIC Configure Failed\r\n");
				return XST_FAILURE;
			}
		}
		else if(turn_flag==0)
		{
			TIMER_SEVEN_SEG_mWriteReg(XPAR_TIMER_SEVEN_SEG_0_S00_AXI_BASEADDR, 4, 2);
			TIMER_SEVEN_SEG_mWriteReg(XPAR_TIMER_SEVEN_SEG_0_S00_AXI_BASEADDR, 4, 0);
			for(i = 0; i < 4; i++)
			{
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4, line1[i*4+3] + (line1[i*4+2]<<8) + (line1[i*4+1]<<16) + (line1[i*4]<<24));
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4+16, lineB[i*4+3] + (lineB[i*4+2]<<8) + (lineB[i*4+1]<<16) + (lineB[i*4]<<24));
			}
			do {
				PrintChar("Enter the piece and start, end formation(format : pb A7 A6) : ");
				GetPieceFormation(piece_formation);

				ptr = strtok(piece_formation, " ");
				strcpy(start_piece, ptr);

				ptr = strtok(NULL, " ");
				strcpy(start_point, ptr);

				ptr = strtok(NULL, " ");
				strcpy(end_point, ptr);
				if (start_piece[1] == 'w') {
					PrintChar("It is the black turn. Please reenter\n");
					TFTLCD_write_turnflag(&black_turn);
					sleep(4);
					TFTLCD_write_turnflag(&chess_board);
					continue;
				}
			} while(start_piece[1] != 'b');

			SetPiece(start_piece); // Setting pointer of piece wanted to move

			sp[0] = start_point[0];
			sp[1] = (int)start_point[1] - 48;

			ep[0] = end_point[0];
			ep[1] = (int)end_point[1] - 48;

			move(sp, ep, piece);
			for(i = 0; i < 4; i++)
			{
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4, line2[i*4+3] + (line2[i*4+2]<<8) + (line2[i*4+1]<<16) + (line2[i*4]<<24));
				TEXTLCD_mWriteReg(XPAR_TEXTLCD_0_S00_AXI_BASEADDR, i*4+16, line3[i*4+3] + (line3[i*4+2]<<8) + (line3[i*4+1]<<16) + (line3[i*4]<<24));
			}
			turn_flag=3;
			flag = 0;
			// Jump to function that process interrupt(push button)
			Status = GicConfigure(INTC_DEVICE_ID);
			if (Status != XST_SUCCESS) {
				xil_printf("GIC Configure Failed\r\n");
				return XST_FAILURE;
			}
		}

	}
}

user define function은 repo의 main.c 파일 및 문서를 통해 확인하시면 됩니다.

4. 한계점

4-1. 체스 알고리즘 구현 실패
프로젝트의 처음 목표는 체스 알고리즘을 이용해서 컴퓨터 대전까지 구현하는 것 이였습니다. 하지만 코딩 실력 부족으로 PS에 체스 알고리즘을 이식하는데 실패했고, TFT 상에 체스 게임을 출력하는데 그쳤습니다.
시간이 더 있었다면 현재 체스말의 위치를 기억하는 logic을 추가하여 이동가능한 영역을 표시하는 기능을 추가하고 싶었는데 그러지 못해서 아쉽습니다.

4-2. timer가 끝날 때 interrupt를 발생시켜 turn을 넘기는 기능을 구현 실패
PL 상에서 IP간의 interconnect를 이해하지 못해서 구현에 실패했습니다. 다른 조에서 이 기능을 구현했는데, push button IP에 wire을 연결해 timer의 각 자릿수가 0이 되었을 때 turn을 변경하라는 signal을 보내주는 방식이였습니다.

5. 후기

전자공학부에 입학하고 들었던 과목중에 제일 어려웠고 텀프로젝트도 힘들었지만, 제일 배워간게 많았고 실력이 늘었다는 느낌이 많이 들었습니다.

개인적으로 전자공학을 제대로 이해하려면 꼭 들어아하는 과목이라고 생각합니다. 그만큼 디지털회로와 FPGA를 이해하는데 많은 도움이 되었습니다.

후배분들이 이 문서를 본다면 본 강의 수강하기를 추천드립니다!

chess_soc's People

Contributors

kim-jiwan avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.