// DMA_multi2_ap_fixed.cpp
// 2020/10/06 by marsee
//
#include <ap_fixed.h>
int DMA_multi2_ap_fixed(ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> *in, ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> *out){
#pragma HLS INTERFACE m_axi depth=10 port=out offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=in offset=slave
#pragma HLS INTERFACE s_axilite port=return
for (int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> temp = in[i];
out[i] = temp + temp;
}
return(0);
}
// DMA_multi2_ap_fixed_tb.cpp
// 2020/10/06 by marsee
//
#include <iostream>
#include <ap_fixed.h>
int DMA_multi2_ap_fixed(ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> *in, ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> *out);
int main(){
ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> data[10] = {0, 0.0078125, 0.015625, 0.0234375, 0.03125, 0.0390625, 0.046875, 0.0546875, 0.5, -0.5};
ap_fixed<8, 1, AP_TRN_ZERO, AP_SAT> result[10];
DMA_multi2_ap_fixed(data, result);
for(int i=0; i<10; i++){
std::cout << "data[" << i << "]= " << data[i] <<
", result[" << i << "] = " <<
result[i] << std::endl;
}
}
data[0]= 0, result[0] = 0
data[1]= 0.0078125, result[1] = 0.015625
data[2]= 0.015625, result[2] = 0.03125
data[3]= 0.0234375, result[3] = 0.046875
data[4]= 0.03125, result[4] = 0.0625
data[5]= 0.0390625, result[5] = 0.078125
data[6]= 0.046875, result[6] = 0.09375
data[7]= 0.0546875, result[7] = 0.109375
data[8]= 0.5, result[8] = 0.992188
data[9]= -0.5, result[9] = -1
acc_sensor_init(axi_iic_ad);
acc_sensor_write(axi_iic_ad, 0x3a, 0x2f, 0x52); // Reset
usleep(1000);
acc_sensor_write(axi_iic_ad, 0x3a, 0x2c, 0x82); // I2C speed is Hi speed, +-4g
でエラーになってしまう。ERROR: [XFORM 203-801] Interface parameter bitwidth 'in.V' (DMA_pow2_XX/DMA_pow2_XX.cpp:9:1) must be a multiple of 8 for AXI4 master port.
というエラーになった。ERROR: [XFORM 203-801] Bitwidth of (packed) data on axi master must be power of 2: Found 'in.V' (DMA_pow2_XX/DMA_pow2_XX.cpp:9:1) (packed) has a bitwidth of 120.
entity DMA_pow2_XX is
generic (
C_M_AXI_GMEM_ADDR_WIDTH : INTEGER := 32;
C_M_AXI_GMEM_ID_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_AWUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_DATA_WIDTH : INTEGER := 32;
C_M_AXI_GMEM_WUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_ARUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_RUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_BUSER_WIDTH : INTEGER := 1;
C_S_AXI_AXILITES_ADDR_WIDTH : INTEGER := 6;
C_S_AXI_AXILITES_DATA_WIDTH : INTEGER := 32;
C_M_AXI_GMEM_USER_VALUE : INTEGER := 0;
C_M_AXI_GMEM_PROT_VALUE : INTEGER := 0;
C_M_AXI_GMEM_CACHE_VALUE : INTEGER := 3 );
port (
ap_clk : IN STD_LOGIC;
ap_rst_n : IN STD_LOGIC;
m_axi_gmem_AWVALID : OUT STD_LOGIC;
m_axi_gmem_AWREADY : IN STD_LOGIC;
m_axi_gmem_AWADDR : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ADDR_WIDTH-1 downto 0);
m_axi_gmem_AWID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_AWLEN : OUT STD_LOGIC_VECTOR (7 downto 0);
m_axi_gmem_AWSIZE : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_AWBURST : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_AWLOCK : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_AWCACHE : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWPROT : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_AWQOS : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWREGION : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_AWUSER_WIDTH-1 downto 0);
m_axi_gmem_WVALID : OUT STD_LOGIC;
m_axi_gmem_WREADY : IN STD_LOGIC;
m_axi_gmem_WDATA : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH-1 downto 0);
m_axi_gmem_WSTRB : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH/8-1 downto 0);
m_axi_gmem_WLAST : OUT STD_LOGIC;
m_axi_gmem_WID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_WUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_WUSER_WIDTH-1 downto 0);
m_axi_gmem_ARVALID : OUT STD_LOGIC;
m_axi_gmem_ARREADY : IN STD_LOGIC;
m_axi_gmem_ARADDR : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ADDR_WIDTH-1 downto 0);
m_axi_gmem_ARID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_ARLEN : OUT STD_LOGIC_VECTOR (7 downto 0);
m_axi_gmem_ARSIZE : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_ARBURST : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_ARLOCK : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_ARCACHE : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARPROT : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_ARQOS : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARREGION : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ARUSER_WIDTH-1 downto 0);
m_axi_gmem_RVALID : IN STD_LOGIC;
m_axi_gmem_RREADY : OUT STD_LOGIC;
m_axi_gmem_RDATA : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH-1 downto 0);
m_axi_gmem_RLAST : IN STD_LOGIC;
m_axi_gmem_RID : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_RUSER : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_RUSER_WIDTH-1 downto 0);
m_axi_gmem_RRESP : IN STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_BVALID : IN STD_LOGIC;
m_axi_gmem_BREADY : OUT STD_LOGIC;
m_axi_gmem_BRESP : IN STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_BID : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_BUSER : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_BUSER_WIDTH-1 downto 0);
s_axi_AXILiteS_AWVALID : IN STD_LOGIC;
s_axi_AXILiteS_AWREADY : OUT STD_LOGIC;
s_axi_AXILiteS_AWADDR : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_ADDR_WIDTH-1 downto 0);
s_axi_AXILiteS_WVALID : IN STD_LOGIC;
s_axi_AXILiteS_WREADY : OUT STD_LOGIC;
s_axi_AXILiteS_WDATA : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH-1 downto 0);
s_axi_AXILiteS_WSTRB : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH/8-1 downto 0);
s_axi_AXILiteS_ARVALID : IN STD_LOGIC;
s_axi_AXILiteS_ARREADY : OUT STD_LOGIC;
s_axi_AXILiteS_ARADDR : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_ADDR_WIDTH-1 downto 0);
s_axi_AXILiteS_RVALID : OUT STD_LOGIC;
s_axi_AXILiteS_RREADY : IN STD_LOGIC;
s_axi_AXILiteS_RDATA : OUT STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH-1 downto 0);
s_axi_AXILiteS_RRESP : OUT STD_LOGIC_VECTOR (1 downto 0);
s_axi_AXILiteS_BVALID : OUT STD_LOGIC;
s_axi_AXILiteS_BREADY : IN STD_LOGIC;
s_axi_AXILiteS_BRESP : OUT STD_LOGIC_VECTOR (1 downto 0);
interrupt : OUT STD_LOGIC );
end;
// DMA_pow2_XX.h
// 2020/09/25 by marsee
//
#ifndef __DMA_POW2_XX_H__
#define __DMA_POW2_XX_H__
#define BIT_LEN 128
#endif
// DMA_pow2_XX.cpp
// 2020/09/25 by marsee
#include <ap_int.h>
#include "DMA_pow2_XX.h"
int DMA_pow2_XX(volatile ap_int<BIT_LEN> *in, volatile ap_int<BIT_LEN> *out){
#pragma HLS INTERFACE m_axi depth=10 port=out offset=slave
#pragma HLS INTERFACE m_axi depth=10 port=in offset=slave
#pragma HLS INTERFACE s_axilite port=return
for (int i=0; i<10; i++){
#pragma HLS PIPELINE II=1
ap_int<BIT_LEN> temp = in[i];
out[i] = temp * temp;
}
return(0);
}
// DMA_pow2_XX_tb.cpp
// 2020/09/25 by marsee
//
#include <iostream>
#include <ap_int.h>
#include "DMA_pow2_XX.h"
int DMA_pow2_XX(volatile ap_int<BIT_LEN> *in, volatile ap_int<BIT_LEN> *out);
int main(){
ap_int<BIT_LEN> data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ap_int<BIT_LEN> result[10];
DMA_pow2_XX(data, result);
for(int i=0; i<10; i++){
std::cout << "data[" << i << "]= " << data[i] <<
", result[" << i << "] = " <<
result[i] << std::endl;
}
}
entity DMA_pow2_XX is
generic (
C_M_AXI_GMEM_ADDR_WIDTH : INTEGER := 32;
C_M_AXI_GMEM_ID_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_AWUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_DATA_WIDTH : INTEGER := 128;
C_M_AXI_GMEM_WUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_ARUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_RUSER_WIDTH : INTEGER := 1;
C_M_AXI_GMEM_BUSER_WIDTH : INTEGER := 1;
C_S_AXI_AXILITES_ADDR_WIDTH : INTEGER := 6;
C_S_AXI_AXILITES_DATA_WIDTH : INTEGER := 32;
C_M_AXI_GMEM_USER_VALUE : INTEGER := 0;
C_M_AXI_GMEM_PROT_VALUE : INTEGER := 0;
C_M_AXI_GMEM_CACHE_VALUE : INTEGER := 3 );
port (
ap_clk : IN STD_LOGIC;
ap_rst_n : IN STD_LOGIC;
m_axi_gmem_AWVALID : OUT STD_LOGIC;
m_axi_gmem_AWREADY : IN STD_LOGIC;
m_axi_gmem_AWADDR : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ADDR_WIDTH-1 downto 0);
m_axi_gmem_AWID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_AWLEN : OUT STD_LOGIC_VECTOR (7 downto 0);
m_axi_gmem_AWSIZE : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_AWBURST : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_AWLOCK : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_AWCACHE : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWPROT : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_AWQOS : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWREGION : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_AWUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_AWUSER_WIDTH-1 downto 0);
m_axi_gmem_WVALID : OUT STD_LOGIC;
m_axi_gmem_WREADY : IN STD_LOGIC;
m_axi_gmem_WDATA : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH-1 downto 0);
m_axi_gmem_WSTRB : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH/8-1 downto 0);
m_axi_gmem_WLAST : OUT STD_LOGIC;
m_axi_gmem_WID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_WUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_WUSER_WIDTH-1 downto 0);
m_axi_gmem_ARVALID : OUT STD_LOGIC;
m_axi_gmem_ARREADY : IN STD_LOGIC;
m_axi_gmem_ARADDR : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ADDR_WIDTH-1 downto 0);
m_axi_gmem_ARID : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_ARLEN : OUT STD_LOGIC_VECTOR (7 downto 0);
m_axi_gmem_ARSIZE : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_ARBURST : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_ARLOCK : OUT STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_ARCACHE : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARPROT : OUT STD_LOGIC_VECTOR (2 downto 0);
m_axi_gmem_ARQOS : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARREGION : OUT STD_LOGIC_VECTOR (3 downto 0);
m_axi_gmem_ARUSER : OUT STD_LOGIC_VECTOR (C_M_AXI_GMEM_ARUSER_WIDTH-1 downto 0);
m_axi_gmem_RVALID : IN STD_LOGIC;
m_axi_gmem_RREADY : OUT STD_LOGIC;
m_axi_gmem_RDATA : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_DATA_WIDTH-1 downto 0);
m_axi_gmem_RLAST : IN STD_LOGIC;
m_axi_gmem_RID : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_RUSER : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_RUSER_WIDTH-1 downto 0);
m_axi_gmem_RRESP : IN STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_BVALID : IN STD_LOGIC;
m_axi_gmem_BREADY : OUT STD_LOGIC;
m_axi_gmem_BRESP : IN STD_LOGIC_VECTOR (1 downto 0);
m_axi_gmem_BID : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_ID_WIDTH-1 downto 0);
m_axi_gmem_BUSER : IN STD_LOGIC_VECTOR (C_M_AXI_GMEM_BUSER_WIDTH-1 downto 0);
s_axi_AXILiteS_AWVALID : IN STD_LOGIC;
s_axi_AXILiteS_AWREADY : OUT STD_LOGIC;
s_axi_AXILiteS_AWADDR : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_ADDR_WIDTH-1 downto 0);
s_axi_AXILiteS_WVALID : IN STD_LOGIC;
s_axi_AXILiteS_WREADY : OUT STD_LOGIC;
s_axi_AXILiteS_WDATA : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH-1 downto 0);
s_axi_AXILiteS_WSTRB : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH/8-1 downto 0);
s_axi_AXILiteS_ARVALID : IN STD_LOGIC;
s_axi_AXILiteS_ARREADY : OUT STD_LOGIC;
s_axi_AXILiteS_ARADDR : IN STD_LOGIC_VECTOR (C_S_AXI_AXILITES_ADDR_WIDTH-1 downto 0);
s_axi_AXILiteS_RVALID : OUT STD_LOGIC;
s_axi_AXILiteS_RREADY : IN STD_LOGIC;
s_axi_AXILiteS_RDATA : OUT STD_LOGIC_VECTOR (C_S_AXI_AXILITES_DATA_WIDTH-1 downto 0);
s_axi_AXILiteS_RRESP : OUT STD_LOGIC_VECTOR (1 downto 0);
s_axi_AXILiteS_BVALID : OUT STD_LOGIC;
s_axi_AXILiteS_BREADY : IN STD_LOGIC;
s_axi_AXILiteS_BRESP : OUT STD_LOGIC_VECTOR (1 downto 0);
interrupt : OUT STD_LOGIC );
end;
// mnist_nn_test.c
// 2020/09/08 by marsee
//
#include <stdio.h>
#include <stdint.h>
#include "xtime_l.h"
#include "af1_weight_float.h"
#include "af1_bias_float.h"
#include "af2_weight_float.h"
#include "af2_bias_float.h"
#include "mnist_data_10.h"
#include "xmnist_nn.h"
int mnist_nn_float(float in[784], float out[10]);
int max_float(float out[10]);
int max_int32_t(int32_t out[10]);
void Xil_DCacheFlush(void);
#define NUM_ITERATIONS 10 // C Simulation
// #define NUM_ITERATIONS 2 // C/RTL CoSimulation
int main(){
float t_tran_float[NUM_ITERATIONS][784];
uint8_t t_tran_uint8_t[NUM_ITERATIONS][784];
int32_t result_hard[NUM_ITERATIONS][10];
float result_soft[NUM_ITERATIONS][10];
int max_id_hw, max_id_sw, max_id_ref;
XMnist_nn mnits_nn_ap;
int32_t res;
XTime hw_start_time, hw_end_time;
XTime sw_start_time, sw_end_time;
for(int i=0; i<NUM_ITERATIONS; i++){
for(int j=0; j<784; j++){
t_tran_float[i][j] = (float)(t_train_256[i][j])/256.0;
t_tran_uint8_t[i][j] = (uint32_t)(t_train_256[i][j]);
}
}
Xil_DCacheFlush();
// Initialize tht Device
int XMinst_status = XMnist_nn_Initialize(&mnits_nn_ap, 0);
if (XMinst_status != XST_SUCCESS){
fprintf(stderr, "Could not Initialize XMnist_nn\n");
return(-1);
}
for(int i=0; i<NUM_ITERATIONS; i++){
u32 char_num = (u32)(&t_tran_uint8_t[i][0]);
XMnist_nn_Set_in_V(&mnits_nn_ap, char_num);
XTime_GetTime(&hw_start_time);
XMnist_nn_Start(&mnits_nn_ap);
while(!XMnist_nn_IsDone(&mnits_nn_ap));
XTime_GetTime(&hw_end_time);
// minst nn result check
for(int j=0; j<5; j++){
XMnist_nn_Read_out_V_Words(&mnits_nn_ap, j, &res, 1);
result_hard[i][j*2] = res & 0x1fff; // 13 bit
if(result_hard[i][j*2] & 0x1000) // minus
result_hard[i][j*2] = 0xffffe000 | result_hard[i][j*2]; // Sign extension
result_hard[i][j*2+1] = (res & 0x1fff0000) >> 16;
if(result_hard[i][j*2+1] & 0x1000) // minus
result_hard[i][j*2+1] = 0xffffe000 | result_hard[i][j*2+1]; // Sign extension
}
XTime_GetTime(&sw_start_time);
mnist_nn_float(&t_tran_float[i][0], &result_soft[i][0]);
XTime_GetTime(&sw_end_time);
printf("i = %d, HW Execution time = %lf ms, SW Execution time = %lf ms\n", i,
(double)((long long int)hw_end_time-(long long int)hw_start_time)/333333.0,
(double)((long long int)sw_end_time-(long long int)sw_start_time)/333333.0);
}
int errflag=0;
for(int i=0; i<NUM_ITERATIONS; i++){
max_id_hw = max_int32_t(&result_hard[i][0]);
max_id_sw = max_float(&result_soft[i][0]);
max_id_ref = max_float(&t_test[i][0]);
if(max_id_ref != max_id_hw){
printf("id = %d, max_id_ref = %d, max_id_hw = %d\n", i, max_id_ref, max_id_hw);
errflag = 1;
}
if(max_id_ref != max_id_sw){
printf("id = %d, max_id_ref = %d, max_id_sw = %d\n", i, max_id_ref, max_id_sw);
errflag = 1;
}
}
if(errflag == 0)
printf("No Error\n");
return(0);
}
int mnist_nn_float(float in[784], float out[10]){
float dot1[50];
float dot2[10];
for(int col=0; col<50; col++){
dot1[col] = 0;
for(int row=0; row<784; row++){
dot1[col] += in[row]*af1_fweight[row][col];
}
dot1[col] += af1_fbias[col];
if(dot1[col] < 0) // ReLU
dot1[col] = 0;
}
for(int col=0; col<10; col++){
dot2[col] = 0;
for(int row=0; row<50; row++){
dot2[col] += dot1[row]*af2_fweight[row][col];
}
dot2[col] += af2_fbias[col];
if(dot2[col] < 0) // ReLU
dot2[col] = 0;
out[col] = dot2[col];
}
return(0);
}
int max_float(float out[10]){
int max_id;
float max;
for(int i=0; i<10; i++){
if(i == 0){
max = out[0];
max_id = 0;
}else if(out[i]>max){
max = out[i];
max_id = i;
}
}
return(max_id);
}
int max_int32_t(int32_t out[10]){
int max_id;
int32_t max;
for(int i=0; i<10; i++){
if(i == 0){
max = out[0];
max_id = 0;
}else if(out[i]>max){
max = out[i];
max_id = i;
}
}
return(max_id);
}
// mnist_nn_test.c
// 2020/09/08 by marsee
// 2020/09/24 : removed weights and biases.
//
#include <stdio.h>
#include <stdint.h>
#include "mnist_data_10.h"
#include "xmnist_nn.h"
int max_float(float out[10]);
int max_int32_t(int32_t out[10]);
#define NUM_ITERATIONS 10 // C Simulation
// #define NUM_ITERATIONS 2 // C/RTL CoSimulation
int main(){
uint8_t t_tran_uint8_t[NUM_ITERATIONS][784];
int32_t result_hard[NUM_ITERATIONS][10];
int max_id_hw, max_id_ref;
XMnist_nn mnits_nn_ap;
int32_t res;
for(int i=0; i<NUM_ITERATIONS; i++){
for(int j=0; j<784; j++){
t_tran_uint8_t[i][j] = (uint8_t)(t_train_256[i][j]);
}
}
// Initialize tht Device
int XMinst_status = XMnist_nn_Initialize(&mnits_nn_ap, 0);
if (XMinst_status != XST_SUCCESS){
fprintf(stderr, "Could not Initialize XMnist_nn\n");
return(-1);
}
for(int i=0; i<NUM_ITERATIONS; i++){
u32 char_num = (u32)(&t_tran_uint8_t[i][0]);
XMnist_nn_Set_in_V(&mnits_nn_ap, char_num);
XMnist_nn_Start(&mnits_nn_ap);
while(!XMnist_nn_IsDone(&mnits_nn_ap));
// minst nn result check
for(int j=0; j<5; j++){
XMnist_nn_Read_out_V_Words(&mnits_nn_ap, j, &res, 1);
result_hard[i][j*2] = res & 0x1fff; // 13 bit
if(result_hard[i][j*2] & 0x1000) // minus
result_hard[i][j*2] = 0xffffe000 | result_hard[i][j*2]; // Sign extension
result_hard[i][j*2+1] = (res & 0x1fff0000) >> 16;
if(result_hard[i][j*2+1] & 0x1000) // minus
result_hard[i][j*2+1] = 0xffffe000 | result_hard[i][j*2+1]; // Sign extension
}
}
int errflag=0;
for(int i=0; i<NUM_ITERATIONS; i++){
max_id_hw = max_int32_t(&result_hard[i][0]);
max_id_ref = max_float(&t_test[i][0]);
if(max_id_ref != max_id_hw){
printf("id = %d, max_id_ref = %d, max_id_hw = %d\n", i, max_id_ref, max_id_hw);
errflag = 1;
}
}
if(errflag == 0)
printf("No Error\n");
return(0);
}
int max_float(float out[10]){
int max_id;
float max;
for(int i=0; i<10; i++){
if(i == 0){
max = out[0];
max_id = 0;
}else if(out[i]>max){
max = out[i];
max_id = i;
}
}
return(max_id);
}
int max_int32_t(int32_t out[10]){
int max_id;
int32_t max;
for(int i=0; i<10; i++){
if(i == 0){
max = out[0];
max_id = 0;
}else if(out[i]>max){
max = out[i];
max_id = i;
}
}
return(max_id);
}
を実行したところ、AXI4-Lite インターフェースに Write アクセスが発生した。XMnist_nn_Set_in_V(&mnits_nn_ap, char_num);
を過ぎたときにトリガーがかかった。XDma_pow2_Set_in_r(&XDMA_pow2_ap, (u32)&data[0]);
を過ぎたときに Vivado Analyzer のトリガーがかかった。XDma_pow2_Set_out_r(&XDMA_pow2_ap, (u32)&result[0]);
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | - |