자 단순하게 간단한 작업을 해보자.
BRAM 하나의 용량만큼 1을 저장해보자.
예를들어 BRAM이 4x4 사이즈라고 치면
[1,1,1,1,
1,1,1,1,
1,1,1,1,
1,1,1,1]
으로 저장하는 것이다.
시작해보자.
실습 워크플로우에서 참고할때는 이 글의 lab13을 참고한다.
https://learn-future.tistory.com/3515
당연히 다음 workflow대로 진행할 것이다.
[1.ip생성 - 2. Vivado HW - 3. Vitis SW - 4. FPGA]
[1.ip생성]
vivado proj 생성
lab13_matbi 환경을 불러와서 lab01 로 커스텀해준 후
01_bram_ip폴더에 ip를 패키징해준다.
[2.Vivado SW]
vivado proj 생성
생성한 ip 그리고 zynq ip를 호출 + axi ila 추가 (지금은 공부목적이니 추가하는데, 빼면 훨씬 라이트해질듯)
wrapper
bitstream (참 시간 오래 걸린다. 마치 딥러닝 학습과정 에폭처럼.)
hw export
[3.Vitis SW]
create project
customize (XPAR_LAB13_MATBI_0_BASEADDR -> XPAR_LAB01_0_BASEADDR)
[4.FPGA]
그러고나서, 기존 C코드의 프로그램이 정상 동작하는 것을 확인했다.
---
자 이제부터 시작이다.
(1)
프로그램은 원래 다음과 같았다.
'srand seed값을 입력받아, random생성을 하여
그 값을 저장한다.'
이 프로그램을
'srand seed값을 1로 하여, random생성을 하여
그 값을 저장한다.'
로 간단하게 베이스라인 수정을 해주었고
문구를 몇가지 바꾸어주었다.
(2)
지금은 random값을 저장하는 상태라서 vitis hw manager에서는 다음과 같이 확인된다.
이 프로그램을 1을 저장하게끔 바꾸어보았다.
잘 된 것으로 보인다. 하지만 여기서 짧게 확인할 부분이 있는데, 여기는 왜 0일까?
또한 현재 vivado에서 sample을 1024번밖에 못하니
이 노이즈를 빼고 보기 위하여
MEM_DEPTH 만큼 저장하던 것도 4로 우선 바꿔두자.
데이터는 4번 모두 1로 잘 저장된다.
---
위에서 확인하고자했던 앞에서 0이 등장하는 것은
WDATA 신호가 0으로 초기화되는 작업으로 추측되는데 이를 확인해보자.
SW 코드를 확인했다. 당연히 관련 부분은 나오지 않는다.
HW 코드를 확인했다. 여기서 나올줄 알았는데 나오지 않는다.
왜 없을까 생각해보았더니, 지금 저 waveform이 만들어지는 것은 simulation 즉 tb의 영역이다.
ILA와 관련된 원본 리소스를 확인해주어야 한다.
ILA에 대한 리소스를 찾았다.
ILA = Integrated Logic Analyzer
https://www.xilinx.com/support/documentation/ip_documentation/ila/v6_2/pg172-ila.pdf
하지만 본 문서에서는 그러한 부분까지를 다루지는 않는다.
이 부분을 찾는것을 생략할 수도 있지만 유의미하다고 생각하기에 조금 더 찾아본다.
xil_io.h 의 Xil_Out32 함수
다시 HW Source Code 추적
ex. slv_reg_wren
mem0_addr_cnt
음 우선 이 부분을 파악하기는 해야한다.
왜냐하면 내가 지금 다루고자 하는 논리가
일종의 memory controller 이기 때문에
addr 관련 정보를 정확히 파악해야 한다.
하지만 어떤 논리가 전개될지 약간 예상은 되어도
잘 찾아지지 않는데, 이건 우리가 할 작업에 충실하다 보면 찾아질 것 같다고 예상된다.
---
다시 원래 흐름으로 돌아온다.
자 이제 1을 4번 저장하는 것에 성공했다.
MEM_DEPTH = 512 만큼 다시 저장하자.
왜 'MEM_DEPTH = 512' 인가? 점검하자.
Resource Utilization for Block Memory Generator v8.4
https://www.xilinx.com/htmldocs/ip_docs/pru_files/blk-mem-gen.html
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ansdbtls4067&logNo=221281079043
현재 우리의 확인 대상물은 본 BRAM Tile이다.
우리가 잡은 값인건데 32b*512 = 16,384b,
36b*1024 = 36,864b
즉 우리가 쓰는 BRAM은 36Kb 까지 제공하는데 우리가 Depth를 512로 잡아서 그 중 16KB 정도를 사용하고 있다.
그럼 Depth를 1024로 잡으면 문제가 발생하지 않을 것이고 (32KB) 1536 or 2048로 잡으면 문제가 발생할 것이다.
문제가 SW적으로 HW적으로 발생하는지를 확인하고, 적당한 치유를 해주자.
우선 WIDTH=4로 줄이고나서
printf 로 log 측정을 붙혔다.
음 다시 에러가 나는 상황인데
확인해보자.
(설마 2048을 한번 WRITE 하는 과정에서 HW적으로 에러났나?
근데 그럼 다시 Program 시키는 과정에서 덮여야 하는 것 아닌가...)
BASEADDR을 기준으로 8씩 증가시킨다.
아 여기서 위에서 찾던 초기화의 정체도 찾았다. 여기서 이뤄졌었구나.
그리고 메모하자면 현재 우리는 BRAM을 HW적으로 3% Utilization 하고있다.
여기에 영향을 주는곳은 이쪽(ip)이다.
음 근데 에러가 해소가 안되길래,
lab13-main.c로 다시 데려와서 해봤는데, 그래도 안된다.
vivado & vitis 껐다 켜본다.
그래도 안된다. ...
음 우선 여기서 한번 끊고 넘어가자.
뭐가 문제일까 ...
몇시간후에 다시 시도중인데
그럼에도 불구하고 잘 안된다.
한번 정상적으로 실행되었을때의 타이밍 다이어그램과 값을 비교해보자.
현재 직관적으로 느껴지는 이슈의 가능성이 '주소'에 문제가 있는 것 같다.
이게 그나마 멀쩡했을 때의 상태인데
여기에서도 'A'채널에 대해 실수로 열어두지 않아서 추적이 안된다.
=====
아~ 해결의 실마리를 찾았다.
지금 트리거링을 통한 시뮬레이션에서 문제가 있다.
우선 지금 잘 되는 경우가 왜 잘되는지를 언어로 표현해서 이해해보자.
그래야 내가 지금 왜 안되는지를 해결할 수 있다.
-----
[1] Run Trigger를 1회 실행한다.
Vitis Serial Terminal에서 1.write를 입력한다.
다음과 같은 시뮬레이션 결과가 나온다.
[2] 자 여기서 다시 Run Trigger를 2번째로 실행한다.
Vitis Serial Terminal에서 srand seed값을 입력한다.
다음과 같은 시뮬레이션 결과가 나온다.
-----
위의 끊어줌을 활용하여
원래 에러가 나던 A코드를 B코드와 같이 바꾸었다.
[A코드]
//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin / Aiden
//
// Create Date:
// Design Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: test read and write in bram using AXI4-Lite
//
// 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
#define MEM0_ADDR_REG 2
#define MEM0_DATA_REG 3
//#define FSM_COUNTER // (lab10)
#define MEM_DEPTH 512
int main() {
int data;
int read_data;
int reg_num;
XTime tStart, tEnd;
int i;
int write_buf[MEM_DEPTH];
int read_buf[MEM_DEPTH];
while (1) {
printf("======= Hello Lab 01 ======\n");
printf("plz input run mode\n");
printf("1. write (CTRL) \n");
printf("2. read (REG) \n");
scanf("%d",&data);
if(data == WRITE){
#ifdef FSM_COUNTER
Xil_Out32((XPAR_LAB01_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_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & IDLE) != IDLE);
// start core
printf("LAB01_0 Start\n");
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
XTime_GetTime(&tStart);
// wait done
do{
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & DONE) != DONE );
XTime_GetTime(&tEnd);
printf("LAB01_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));
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
//for(i=0; i<MEM_DEPTH ; i++){
for(i=0; i<4 ; i++){
write_buf[i] = 1;
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE), write_buf[i]); // Clear
printf("%d, %d\n",(XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE), write_buf[i]);
}
printf("Success/Write\n");
} else if (data == READ){
#ifdef FSM_COUNTER
printf("plz input READ reg number (0~3)\n");
scanf("%d",®_num);
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (reg_num*AXI_DATA_BYTE));
printf("LAB01_0 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF); // no check run value
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
//for(i=0; i<MEM_DEPTH ; i++){
for(i=0; i<4 ; i++){
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE));
if(read_data != write_buf[i]){ // Check Read Result
printf("Mismatch!! plz contact me. idx : %d, Write_data : %d, Read_data : %d\n", i, write_buf[i], read_data);
}
}
printf("Success/Read\n");
} else {
// no operation, exit
//break;
}
}
return 0;
}
[B코드]
//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin / Aiden
//
// Create Date:
// Design Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: test read and write in bram using AXI4-Lite
//
// 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
#define MEM0_ADDR_REG 2
#define MEM0_DATA_REG 3
//#define FSM_COUNTER // (lab10)
#define MEM_DEPTH 512
int main() {
int data;
int read_data;
int reg_num;
XTime tStart, tEnd;
int i;
int write_buf[MEM_DEPTH];
int read_buf[MEM_DEPTH];
while (1) {
printf("======= Hello Lab 01 ======\n");
printf("plz input run mode\n");
printf("1. write (CTRL) \n");
printf("2. read (REG) \n");
scanf("%d",&data);
if(data == WRITE){
#ifdef FSM_COUNTER
Xil_Out32((XPAR_LAB01_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_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & IDLE) != IDLE);
// start core
printf("LAB01_0 Start\n");
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
XTime_GetTime(&tStart);
// wait done
do{
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & DONE) != DONE );
XTime_GetTime(&tEnd);
printf("LAB01_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));
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
printf("Initialize Done. plz enter any int value.\n");
scanf("%d",&data);
for(i=0; i<MEM_DEPTH ; i++){
//for(i=0; i<4 ; i++){
write_buf[i] = i;
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE), write_buf[i]); // Clear
printf("%d, %d\n",(XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE), write_buf[i]);
}
printf("Success/Write\n");
} else if (data == READ){
#ifdef FSM_COUNTER
printf("plz input READ reg number (0~3)\n");
scanf("%d",®_num);
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (reg_num*AXI_DATA_BYTE));
printf("LAB01_0 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF); // no check run value
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
for(i=0; i<MEM_DEPTH ; i++){
//for(i=0; i<4 ; i++){
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE));
if(read_data != write_buf[i]){ // Check Read Result
printf("Mismatch!! plz contact me. idx : %d, Write_data : %d, Read_data : %d\n", i, write_buf[i], read_data);
}
}
printf("Success/Read\n");
} else {
// no operation, exit
//break;
}
}
return 0;
}
음 근데 이래도 안된다.
- Initialize 이전의 waveform
- Burst Write 이후의 waveform
두 이미지를 비교한 사진
자 그럼 한번 더 보자.
잘 되던 코드랑. 지금 내 코드랑 뭐가 차이나지?
딱
write_buf[i] = rand();
대신에
write_buf[i] = i;
넣어주니깐
잘된다.
이거 왜 잘되지.
잘 되는게 더 마음에 안드는데.
자 이 코드를 기준으로 해서
내 코드랑 다시 비교해보자.
어떤 개념을 잘못 접근했는지에 대하여.
//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin
//
// Create Date:
// Design Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: test read and write in bram using AXI4-Lite
//
// 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
#include <stdlib.h> // To generate rand value
#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
#define MEM0_ADDR_REG 2
#define MEM0_DATA_REG 3
//#define FSM_COUNTER // (lab10)
#define MEM_DEPTH 512
int main() {
int data;
int read_data;
int reg_num;
XTime tStart, tEnd;
int i;
int write_buf[MEM_DEPTH];
int read_buf[MEM_DEPTH];
while (1) {
printf("======= Hello Lab13 Matbi ======\n");
printf("plz input run mode\n");
printf("1. write (CTRL) \n");
printf("2. read (REG) \n");
scanf("%d",&data);
if(data == WRITE){
#ifdef FSM_COUNTER
Xil_Out32((XPAR_LAB01_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_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & IDLE) != IDLE);
// start core
printf("LAB13_MATBI_0 Start\n");
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
XTime_GetTime(&tStart);
// wait done
do{
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & DONE) != DONE );
XTime_GetTime(&tEnd);
printf("LAB13_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));
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
printf("plz input srand value.\n");
scanf("%d",&data);
srand(data);
for(i=0; i< MEM_DEPTH ; i++){
write_buf[i] = i;
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE), write_buf[i]); // Clear
}
} else if (data == READ){
#ifdef FSM_COUNTER
printf("plz input READ reg number (0~3)\n");
scanf("%d",®_num);
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (reg_num*AXI_DATA_BYTE));
printf("LAB13_MATBI_0 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF); // no check run value
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
for(i=0; i< MEM_DEPTH ; i++){
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE));
if(read_data != write_buf[i]){ // Check Read Result
printf("Matbi!! Mismatch!! plz contact me. idx : %d, Write_data : %d, Read_data : %d\n", i, write_buf[i], read_data);
}
}
printf("Matbi!! Success Test Program.\n");
} else {
// no operation, exit
//break;
}
}
return 0;
}
아~ printf 가 문제였는데
주소와 관련된 연산을 1사이클 해야할 것을 2사이클 한듯하다.
어 근데 코드를 이렇게 수정하면 되어야 하는데
아직도 되지 않는다.
그럼 뭐가 문제라는거지
아직 문제를 해결하지는 못했다.
//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin
//
// Create Date:
// Design Name:
// Project Name:
// Target Devices:
// Tool Versions:
// Description: test read and write in bram using AXI4-Lite
//
// 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
#include <stdlib.h> // To generate rand value
#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
#define MEM0_ADDR_REG 2
#define MEM0_DATA_REG 3
//#define FSM_COUNTER // (lab10)
#define MEM_DEPTH 512
int main() {
int data;
int read_data;
int reg_num;
XTime tStart, tEnd;
int i;
int write_buf[MEM_DEPTH];
int read_buf[MEM_DEPTH];
int addr; // Added
while (1) {
printf("======= Hello Lab13 Matbi ======\n");
printf("plz input run mode\n");
printf("1. write (CTRL) \n");
printf("2. read (REG) \n");
scanf("%d",&data);
if(data == WRITE){
#ifdef FSM_COUNTER
Xil_Out32((XPAR_LAB01_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_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & IDLE) != IDLE);
// start core
printf("LAB13_MATBI_0 Start\n");
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (CTRL_REG*AXI_DATA_BYTE), (u32)(data | 0x80000000)); // MSB run
XTime_GetTime(&tStart);
// wait done
do{
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (STATUS_REG*AXI_DATA_BYTE));
} while( (read_data & DONE) != DONE );
XTime_GetTime(&tEnd);
printf("LAB13_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));
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
printf("plz input srand value.\n");
scanf("%d",&data);
srand(data);
for(i=0; i< MEM_DEPTH ; i++){
write_buf[i] = i; // Changed
addr = (XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE); // Added
Xil_Out32(addr, write_buf[i]); // Clear
printf("%d, %d\n",addr, write_buf[i]); // Added
}
} else if (data == READ){
#ifdef FSM_COUNTER
printf("plz input READ reg number (0~3)\n");
scanf("%d",®_num);
read_data = Xil_In32((XPAR_LAB01_0_BASEADDR) + (reg_num*AXI_DATA_BYTE));
printf("LAB13_MATBI_0 REG read done reg_number (%d), value : %d\n", reg_num, read_data & 0x7FFFFFFF); // no check run value
#endif
// (lab13 Memory Test)
Xil_Out32((XPAR_LAB01_0_BASEADDR) + (MEM0_ADDR_REG*AXI_DATA_BYTE), (u32)(0x00000000)); // Clear
for(i=0; i< MEM_DEPTH ; i++){
addr = (XPAR_LAB01_0_BASEADDR) + (MEM0_DATA_REG*AXI_DATA_BYTE);
read_data = Xil_In32(addr);
printf("%d, %d\n",addr, read_data); // Added
if(read_data != write_buf[i]){ // Check Read Result
printf("Matbi!! Mismatch!! plz contact me. idx : %d, Write_data : %d, Read_data : %d\n", i, write_buf[i], read_data);
}
}
printf("Matbi!! Success Test Program.\n");
} else {
// no operation, exit
//break;
}
}
return 0;
}
Xil_Out32() 함수에서
Addr는 int가 아니라 UINTPTR이다.
UINTPTR Usage by Xilinx
내가 지금 쓰는 C는 C가 아니라
Xilinx가 쓰는 C라는 것도 인식해야함.
(자세히는 모르겠는데 뭔가 조금은 다름)
https://support.xilinx.com/s/question/0D52E00006hpUztSAE/uintptr-usage?language=en_US
https://docs.oracle.com/cd/E19253-01/817-6223/chp-typeopexpr-2/index.html
해당 자료형이 특수한 포인터임을 감안하여
다음과 같은 수정을 가해주었는데
그래도 에러가 동일히 발생한다.
프로그램이 돌아가버리는 주소관련 에러가 가장 무서운법
경고메시지를 조금 더 들여다보자.
음 ...
이것도 잠시 넘어가자.
현재 console에 print를 해주는 것이 목적이었기 때문에
지금으로서는 아주 중요하지 않으며,
또한 다음번에 보면 더 잘 풀릴 수 있을 것 같다.
=====
그럼 여기 기준으로
512번 또는 1024번이 아닌
2048번을 넣을때
보드가 뻑나는지 보자.
1024는 정상 동작한다.
2048은
이상하게 정상작동 하면서도 : 왜 돌아가지
중간에 이상한 불균형지점이 생긴다. : 저건 뭐지
왜 돌아가지~
확인할 방법이 현재로서는 없다.
왜냐면 '보드내의 BRAM의 주소값'을 출력해주는 로그콘솔이 없어서인데
(위에서 못 해결한 문제와도 간접적 연관)
이 부분을 확인하기 위해서 BASE_ADDR을 파보아야겠다.
보드 내부를 자유자재로 다루기 위해서는 여기서 주소를 잘 다뤄야 한다.