적극적 생각/FPGA

0717 - 섹션3 - HW Sleep, FSM(IDLE→RUN→DONE)

무말랭이 2022. 7. 17. 10:11

하드웨어 가속 부분을 

내가 만들었던 CPU와 연결하는 것도 할 수 있겠다.

 

---

 

Core Diagram

(중심 타이밍 다이어그램은 프로젝트 개발 중 늘 가까이 두어야 함)

 

Register Map

 

---

 

코드 리뷰

 

---

 

1. IP 생성

프로젝트 생성 10_fsm_counter_ctrl_ip

design source import

create new ip

package

 

2. HW Project

프로젝트 생성 10_fsm_counter_ctrl_project

create block design

zynq 호출

... 중간과정생략

 

(차이를 두기 위해 ip를 하나 더 불러오겠다.

1:2 interconnect가 생성된 것을 볼 수 있다.)

(이 부분 강의와 조금 다름 주의하자 이야기 했었음)

 

validate

wrapper

bitstream

export hw

 

 

vitis

 

프로세스 타임 측정을 위한 헤더

//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin
//
// Create Date:
// Design Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: test fsm_ctrl. Check to HW Sleep Function
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
 
#include <stdio.h>
#include "xparameters.h"
#include "xil_io.h"
#include "xtime_l.h"  // To measure of processing time

#define WRITE 1
#define READ 2
#define AXI_DATA_BYTE 4
 
#define IDLE 1
#define RUN 1 << 1
#define DONE 1 << 2

#define CTRL_REG 0
#define STATUS_REG 1

int main() {
    int data;
    int read_data;
    int reg_num;
    XTime tStart, tEnd;
    while (1) {
    	printf("======= Hello Lab10 Matbi ======\n");
    	printf("plz input run mode\n");
    	printf("1. write (CTRL) \n");
    	printf("2. read (REG) \n");
    	scanf("%d",&data);

    	if(data == WRITE){
    		Xil_Out32((XPAR_LAB10_MATBI_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
    		printf("plz input Value 31bit. MSB is the run signal\n");
    		scanf("%d",&data);

    		printf("Test SW uSleep\n");
    		XTime_GetTime(&tStart);
    		usleep(data/100);
    		XTime_GetTime(&tEnd);
    		printf("Output took %llu clock cycles.\n", 2*(tEnd - tStart));
    		printf("Output took %.2f us.\n",
    		       1.0 * (tEnd - tStart) / (COUNTS_PER_SECOND/1000000));

    		// check IDLE
    		do{
    			read_data = Xil_In32((XPAR_LAB10_MATBI_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
    		} while( (read_data & IDLE) != IDLE);
    		// start core
    		printf("LAB10_MATBI_0 Start\n");
    		Xil_Out32((XPAR_LAB10_MATBI_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
    		XTime_GetTime(&tStart);
    		// wait done
    		do{
    			read_data = Xil_In32((XPAR_LAB10_MATBI_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
    		} while( (read_data & DONE) != DONE );
    		XTime_GetTime(&tEnd);
    		printf("LAB10_MATBI_0 Done\n");
    		printf("Output took %llu clock cycles.\n", 2*(tEnd - tStart));
    		printf("Output took %.2f us.\n",
    		       1.0 * (tEnd - tStart) / (COUNTS_PER_SECOND/1000000));

    		Xil_Out32((XPAR_LAB10_MATBI_1_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
    		// check IDLE
    		do{
    			read_data = Xil_In32((XPAR_LAB10_MATBI_1_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
    		} while( (read_data & IDLE) != IDLE);
    		// start core
    		printf("LAB10_MATBI_1 Start\n");
    		Xil_Out32((XPAR_LAB10_MATBI_1_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
    		XTime_GetTime(&tStart);
    		// wait done
    		do{
    			read_data = Xil_In32((XPAR_LAB10_MATBI_1_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
    		} while( (read_data & DONE) != DONE );
    		XTime_GetTime(&tEnd);
    		printf("LAB10_MATBI_1 Done\n");
    		printf("Output took %llu clock cycles.\n", 2*(tEnd - tStart));
    		printf("Output took %.2f us.\n",
    		       1.0 * (tEnd - tStart) / (COUNTS_PER_SECOND/1000000));

    	} else if (data == READ){
    		printf("plz input READ reg number (0~3)\n");
    		scanf("%d",&reg_num);
    		read_data = Xil_In32((XPAR_LAB10_MATBI_0_BASEADDR) + (reg_num*AXI_DATA_BYTE));
    		printf("LAB10_MATBI_0 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF); // no check run val
    		read_data = Xil_In32((XPAR_LAB10_MATBI_1_BASEADDR) + (reg_num*AXI_DATA_BYTE));
    		printf("LAB10_MATBI_1 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF);
    	} else {
    		// no operation, exit
    		//break;
    	}
    }
    return 0;
}

 

시간관련함수, 주파수, 단위, 시간범위 측정

그리고 우리가 2개의 module을 만들었음을 인지.

 

RUN완료

 

---

 

중간에 잡썰로 나온 AREA 최소화/최적화

 

 

---

 

RUN을 하게 되었을때

100MHz에서 1초를 만들려면 10+000,000

(ready로 인한 delay 반영 등)

(그나저나 여기서 병렬처리가 되어있는 것인지 확인할 필요)

 

 

---

 

HW Sleep 만드는 것이 목적이 아니라

HW 가속화가 핵심임을 다시한번 상기.

'적극적 생각 > FPGA' 카테고리의 다른 글

(중요) 0721 - 섹션4 - AXI4Lite 이용해 BRAM에 RW  (0) 2022.07.21
모식도 작성툴, gliffy, drawio  (0) 2022.07.17
이더넷  (0) 2022.07.17
0717 - 섹션3 - AXI4Lite를 활용한 LED제어  (0) 2022.07.17
0717 - 섹션3 - AXI4Lite  (0) 2022.07.17