From 4bd463522564bb41988a9569b3b96285067d3c0e Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Mon, 13 Nov 2023 14:31:53 +0900 Subject: [PATCH 01/26] Code Cleanup, system clock cycle --- src/testdriver/multi_NPU_RISCV_test.c | 387 +++++++++++++++----------- 1 file changed, 217 insertions(+), 170 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 7b697d3..c4ca691 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -4,17 +4,15 @@ #include #include -//#define DATA_SIZE 2048 // Data Size -#define DATA_SIZE 16 // Data Size +#define DATA_SIZE 2048 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define NUMBER_OF_CORES 4 // Number f Cores used at the same time -#define SYS_CLK 12500000 +#define SYS_CLK 26000000 // RISC-V: 26MHz 26,000,000 -#define KERNEL_WITH_LOAD_STORE 0 +#define KERNEL_WITH_LOAD_STORE 1 #define NPU_REG_ID_OFFSET 3 -#define LOAD_STORE_TEST 1 #define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ @@ -34,6 +32,55 @@ typedef struct { uint16_t sign : 1; } BF16; +// 4096 Size Input data +__attribute__ ((aligned (128))) volatile BF16 input_A[DATA_SIZE]; +__attribute__ ((aligned (128))) volatile BF16 input_B[DATA_SIZE]; + +__attribute__ ((aligned (128))) volatile BF16 output_npu_0[DATA_SIZE]; // NPU 0 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_1[DATA_SIZE]; // NPU 1 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_2[DATA_SIZE]; // NPU 2 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_3[DATA_SIZE]; // NPU 3 Output + +__attribute__ ((aligned (64))) volatile BF16 output_riscv_add[DATA_SIZE]; +__attribute__ ((aligned (64))) volatile BF16 output_riscv_sub[DATA_SIZE]; +__attribute__ ((aligned (64))) volatile BF16 output_riscv_mul[DATA_SIZE]; +__attribute__ ((aligned (64))) volatile BF16 output_riscv_div[DATA_SIZE]; + + // Kernel: need to align by 8bytes 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 31 32 33 34 35 36 37 38 39 + // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 + // 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 + // 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 +#if KERNEL_WITH_LOAD_STORE +// With load/store, vadd.bf16 +__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, + 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, + 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x40, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, + 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, + 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, + 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x60, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, + 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, + 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, + 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x80, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, + 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, + 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, + 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0xa0, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, + 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; +#else + // Without load/store, vadd.bf16 +__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +#endif + static inline void npu_regSet(int idx, unsigned long data) { ROCC_INSTRUCTION_SS(3, data, idx, 0); @@ -63,10 +110,30 @@ static inline void npu_store() ROCC_INSTRUCTION(3, 4); } -uint64_t get_time() { +/* riscv issues store command to npu */ +static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { + + npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + trace_pc_position() + npu_load(); + +} + +/* riscv issues store command to npu */ +static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { + + npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + npu_store(); +} + +static inline uint64_t get_time() { uint64_t tmp; - asm volatile("csrr %0,time":"=r"(tmp)); + asm volatile("csrrs %0, cycle, x0":"=r"(tmp)); return tmp; } @@ -197,6 +264,63 @@ static void kernel_op_change(uint8_t* kernel, char* op) { #endif } +static void kernel_input_a_addr_change(uint8_t* kernel, BF16* data) { + + unsigned long addr; + uint8_t byte_low; + uint8_t byte_high; + + addr = (unsigned long)data; + addr = (addr + 127)/128; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store + kernel[4] = byte_low; + kernel[5] = byte_high; +#endif +} + +static void kernel_input_b_addr_change(uint8_t* kernel, BF16* data) { + + unsigned long addr; + uint8_t byte_low; + uint8_t byte_high; + + addr = (unsigned long)data; + addr = (addr + 127)/128; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store + kernel[20] = byte_low; + kernel[21] = byte_high; +#endif +} + +static void kernel_input_c_addr_change(uint8_t* kernel, BF16* data) { + + unsigned long addr; + uint8_t byte_low; + uint8_t byte_high; + + addr = (unsigned long)data; + addr = (addr + 127)/128; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store + kernel[52] = byte_low; + kernel[53] = byte_high; +#endif +} + static void riscv_calculate(BF16* output, BF16* input_A, BF16* input_B, char* op, int size) { for (int i = 0; i < size; i++) { @@ -235,6 +359,7 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o char riscvStrValue[50]; char npuStrValue[50]; char diffStrValue[50]; + for (int i = 0; i < count; i++) { out_risc_flt = bf16_to_float(out_risc_bf16[i]); out_npu_flt = bf16_to_float(out_npu_bf16[i]); @@ -260,69 +385,21 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o return check; } -/* riscv issues store command to npu */ -static void store_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { - - trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); - trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); - trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); - trace_pc_position() - npu_load(); - trace_pc_position() - -} - -/* riscv issues store command to npu */ -static void load_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { +void init_variavles() { - npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); - npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); - npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); - npu_store(); -} - -int main() { - // 4096 Size Input data - BF16 input_A[DATA_SIZE]; - BF16 input_B[DATA_SIZE]; - float f_val_A; float f_val_B; - BF16 output_riscv_add[DATA_SIZE]; - BF16 output_riscv_sub[DATA_SIZE]; - BF16 output_riscv_mul[DATA_SIZE]; - BF16 output_riscv_div[DATA_SIZE]; - - BF16 output_npu_0[DATA_SIZE]; // NPU 0 Output - BF16 output_npu_1[DATA_SIZE]; // NPU 1 Output - BF16 output_npu_2[DATA_SIZE]; // NPU 2 Output - BF16 output_npu_3[DATA_SIZE]; // NPU 3 Output - - printf("\n========Init========\n\n"); - printf("Multi NAU Test\n"); - printf("[%s Test] Using %d Cores\n", TEST_OP_TYPE, NUMBER_OF_CORES); - if(KERNEL_WITH_LOAD_STORE == 0) { - printf(" Kernel without load/store functions\n\n"); - } else { - printf(" Kernel with load/store functions\n\n"); - } - memset(output_riscv_add, 0, sizeof(output_riscv_add)); memset(output_riscv_sub, 0, sizeof(output_riscv_sub)); memset(output_riscv_mul, 0, sizeof(output_riscv_mul)); memset(output_riscv_div, 0, sizeof(output_riscv_div)); - trace_pc_position() memset(output_npu_0, 0, sizeof(output_npu_0)); memset(output_npu_1, 0, sizeof(output_npu_1)); memset(output_npu_2, 0, sizeof(output_npu_2)); memset(output_npu_3, 0, sizeof(output_npu_3)); - trace_pc_position() // Random Data Input for (int temp_count = 0; temp_count < DATA_SIZE; temp_count++) { f_val_A = (float)rand() / RAND_MAX * 2000.0 - 1000.0; @@ -331,68 +408,23 @@ int main() { input_A[temp_count] = float_to_bf16(f_val_A); input_B[temp_count] = float_to_bf16(f_val_B); } +} - printf("\ninput_A & input_B are filled with random data.\n"); +void riscv_calculate_result() { - trace_pc_position() riscv_calculate(output_riscv_add, input_A, input_B, "vadd.bf16", DATA_SIZE); riscv_calculate(output_riscv_sub, input_A, input_B, "vsub.bf16", DATA_SIZE); riscv_calculate(output_riscv_mul, input_A, input_B, "vmul.bf16", DATA_SIZE); riscv_calculate(output_riscv_div, input_A, input_B, "vdiv.bf16", DATA_SIZE); +} - printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); - - trace_pc_position() -#if 1 // *** FAILED *** (tohost = 7) - // Memory Input - memcpy((BF16*)0x200000, input_A, sizeof(BF16) * DATA_SIZE); - memcpy((BF16*)0x201000, input_B, sizeof(BF16) * DATA_SIZE); -#endif - - trace_pc_position() - // Kernel: need to align by 8bytes 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 - // Kernel: need to align by 8bytes 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 31 32 33 34 35 36 37 38 39 - // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 - // 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 - // 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 -#if KERNEL_WITH_LOAD_STORE - // With load/store, vadd.bf16 - __attribute__ ((aligned (8))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x40, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x60, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x80, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0xa0, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; -#else - // Without load/store, vadd.bf16 - __attribute__ ((aligned (8))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; - __attribute__ ((aligned (8))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; -#endif +void adjust_kernel() { - trace_pc_position() resize_op_iteration_kernel(kernel_0, DATA_SIZE); resize_op_iteration_kernel(kernel_1, DATA_SIZE); resize_op_iteration_kernel(kernel_2, DATA_SIZE); resize_op_iteration_kernel(kernel_3, DATA_SIZE); - - trace_pc_position() + // Change Kernel's Opcode kernel_op_change(kernel_0, TEST_OP_TYPE); kernel_op_change(kernel_1, TEST_OP_TYPE); @@ -400,49 +432,103 @@ int main() { kernel_op_change(kernel_3, TEST_OP_TYPE); #if KERNEL_WITH_LOAD_STORE // with-load-store + // Change Kernel's input_A address + kernel_input_a_addr_change(kernel_0, input_A); + kernel_input_a_addr_change(kernel_1, input_A); + kernel_input_a_addr_change(kernel_2, input_A); + kernel_input_a_addr_change(kernel_3, input_A); + + // Change Kernel's input_A address + kernel_input_b_addr_change(kernel_0, input_B); + kernel_input_b_addr_change(kernel_1, input_B); + kernel_input_b_addr_change(kernel_2, input_B); + kernel_input_b_addr_change(kernel_3, input_B); + + // Change Kernel's input_A address + kernel_input_c_addr_change(kernel_0, output_npu_0); + kernel_input_c_addr_change(kernel_1, output_npu_1); + kernel_input_c_addr_change(kernel_2, output_npu_2); + kernel_input_c_addr_change(kernel_3, output_npu_3); + resize_converted_data_size_kernel(kernel_0, (int)((DATA_SIZE * 2 + 3)/4)); resize_converted_data_size_kernel(kernel_1, (int)((DATA_SIZE * 2 + 3)/4)); resize_converted_data_size_kernel(kernel_2, (int)((DATA_SIZE * 2 + 3)/4)); resize_converted_data_size_kernel(kernel_3, (int)((DATA_SIZE * 2 + 3)/4)); #endif +} - printf("\nKernel images for each NPU have been prepared.\n\n"); +void load_kernel_data_into_npu() { - trace_pc_position() // Load kernel code at address 0 of npu - store_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)kernel_0, (int)sizeof(kernel_0)); - store_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)kernel_1, (int)sizeof(kernel_1)); - store_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)kernel_2, (int)sizeof(kernel_2)); - store_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)kernel_3, (int)sizeof(kernel_3)); + load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)kernel_0, (int)sizeof(kernel_0)); + load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)kernel_1, (int)sizeof(kernel_1)); + load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)kernel_2, (int)sizeof(kernel_2)); + load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)kernel_3, (int)sizeof(kernel_3)); printf("Kernel images are stored in each NPU.\n\n"); - trace_pc_position() #if !KERNEL_WITH_LOAD_STORE // without-load-store // Load input_A at address 0x80 of npu - store_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)0x200000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)0x200000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)0x200000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)0x200000, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); printf("input_A is stored in all NPUs.\n\n"); - trace_pc_position() // Load input_B at address 0x1080 of npu - store_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)0x201000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)0x201000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)0x201000, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)0x201000, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); printf("input_B is stored in all NPUs.\n\n"); #endif +} - trace_pc_position() - // sys-clk time_start, time_end; - //uint32_t time_start, time_end; - uint64_t time_start, time_end; +void store_result_into_ddr() { + + // Load output_C at address 0x202000 of riscv + store_command_to_npu(0, (long unsigned int)output_npu_0, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); + store_command_to_npu(1, (long unsigned int)output_npu_1, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); + store_command_to_npu(2, (long unsigned int)output_npu_2, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); + store_command_to_npu(3, (long unsigned int)output_npu_3, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); +} + +int main() { + + uint64_t cycle_start; + uint64_t cycle_end; + int check0 = 0; + int check1 = 0; + int check2 = 0; + int check3 = 0; + char elapsedTimeStrValue[50]; + + printf("\n========Init========\n\n"); + printf("Multi NAU Test\n"); + printf("[%s Test] Using %d Cores\n", TEST_OP_TYPE, NUMBER_OF_CORES); + if(KERNEL_WITH_LOAD_STORE == 0) { + printf(" Kernel without load/store functions\n\n"); + } else { + printf(" Kernel with load/store functions\n\n"); + } + + init_variavles(); + printf("\ninput_A & input_B are filled with random data.\n"); + + riscv_calculate_result(); + printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); + + adjust_kernel(); + printf("\nKernel images for each NPU have been prepared.\n\n"); + + + load_kernel_data_into_npu(); printf("\nRuns all NPUs.\n"); + cycle_start = get_time(); + #if 0 // NPU Set volatile uint32_t *npu_base = (uint32_t*)0x43C00000; // kernel offset @@ -450,8 +536,7 @@ int main() { npu_base[0] = (uint32_t)kernel_0;// the address of kernel in main memory npu_base[1] = sizeof(kernel_0); // the size of kernel, also need to align by 8bytes - //XTime_GetTime(&time_start); // Start Measuring Time when core 0 is Start - time_start = get_time(); + cycle_start = get_time(); npu_base[2] = 0; // Core Id //Core 1 npu_base[0] = (uint32_t)kernel_1; @@ -470,55 +555,19 @@ int main() { //Xil_DCacheInvalidateRange(&npu_base[3], (uint32_t)sizeof(npu_base[3])); //invalidate_data_cache(&npu_base[3], (uint32_t)sizeof(npu_base[3])); }; - // XTime_GetTime(&time_end); // Get End Time + // XTime_GetTime(&cycle_end); // Get End Time #endif - trace_pc_position() - //time_start = get_time(); - trace_pc_position() - //time_end = get_time(); - + cycle_end = get_time(); printf("\nAll NPUs have completed calculations.\n\n"); - trace_pc_position() - #if !KERNEL_WITH_LOAD_STORE // without-load-store -#if LOAD_STORE_TEST - // Load input_A at address 0x202000 of riscv - load_command_to_npu(0, (long unsigned int)0x202000, (long unsigned int)0x0080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x203000, (long unsigned int)0x0080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x204000, (long unsigned int)0x0080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x205000, (long unsigned int)0x0080, (int)(sizeof(BF16) * DATA_SIZE)); -#else - // Load output_C at address 0x202000 of riscv - load_command_to_npu(0, (long unsigned int)0x202000, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x203000, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x204000, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x205000, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); -#endif - + store_result_into_ddr(); printf("The calculated result values were loaded into external memory.\n\n"); #endif - trace_pc_position() -#if 1 // *** FAILED *** (tohost = 5) - // Memory Output - memcpy(output_npu_0, 0x202000, sizeof(BF16) * DATA_SIZE); - memcpy(output_npu_1, 0x203000, sizeof(BF16) * DATA_SIZE); - memcpy(output_npu_2, 0x204000, sizeof(BF16) * DATA_SIZE); - memcpy(output_npu_3, 0x205000, sizeof(BF16) * DATA_SIZE); - - printf("Copy the result values loaded in external memory to local variables of risc-v.\n\n"); -#endif - - trace_pc_position() - printf("\nCompare the results calculated by risc-v and the results calculated by NPUs.\n"); // Check RISCV's Outpus & NPUs's Outputs Are Same, Input RISCV's OP Output Array in 1st Parameter - int check0 = 0; - int check1 = 0; - int check2 = 0; - int check3 = 0; if (TEST_OP_TYPE == "vadd.bf16") { check0 = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_add, output_npu_0, DATA_SIZE); check1 = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_add, output_npu_1, DATA_SIZE); @@ -541,7 +590,6 @@ int main() { check3 = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_div, output_npu_3, DATA_SIZE); } - trace_pc_position() // If All Pass, Print if (check0 == DATA_SIZE) { printf("[NPU 0 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); @@ -556,8 +604,7 @@ int main() { printf("[NPU 3 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } - char elapsedTimeStrValue[50]; - floatToString(2.0 * (time_end - time_start) / (SYS_CLK / 1000000), + floatToString(2.0 * (cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); printf("\nRISC-V Time: %s us.\n", elapsedTimeStrValue); From b552cf53d36bbfcd390009c11c55c3b8866fd3e4 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Mon, 13 Nov 2023 16:40:46 +0900 Subject: [PATCH 02/26] iUsed seti_low/seti_high to allow npu to access DDR memory --- asm/asm.py | 2 ++ asm/sim.py | 2 ++ examples/with-load-store-vadd.bf16.asm | 12 +++++++++--- examples/with-load-store-vdiv.bf16.asm | 12 +++++++++--- examples/with-load-store-vmul.bf16.asm | 12 +++++++++--- examples/with-load-store-vsub.bf16.asm | 12 +++++++++--- 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/asm/asm.py b/asm/asm.py index 5bc3121..ad555d6 100644 --- a/asm/asm.py +++ b/asm/asm.py @@ -123,6 +123,8 @@ def write(token, value, bits): elif kind == 'i20': value = self.parse_int(20, token) write(token, value, 20) + elif kind == 'p4': + write(token, 0, 4) elif kind == 'p8': write(token, 0, 8) elif kind == 'p16': diff --git a/asm/sim.py b/asm/sim.py index 95c7cec..4f9f7d8 100644 --- a/asm/sim.py +++ b/asm/sim.py @@ -313,6 +313,8 @@ def read(bits): result.append(read(16)) elif kind == 'i20': result.append(read(20)) + elif kind == 'p4': + pass elif kind == 'p8': pass elif kind == 'p16': diff --git a/examples/with-load-store-vadd.bf16.asm b/examples/with-load-store-vadd.bf16.asm index fb4b2a9..ae0659e 100644 --- a/examples/with-load-store-vadd.bf16.asm +++ b/examples/with-load-store-vadd.bf16.asm @@ -30,13 +30,17 @@ def finalize(host): # Load 0x200000 into A seti %a 0x20 # (128) / 4 -seti %b 0x4000 # 0x200000 / 128 +# seti %b 0x4000 # 0x200000 / 128 +seti_low %b 0x4000 # 0x200000 / 128 +seti_high %b 0x0000 # 0x200000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c # Load 0x201000 into B seti %a 0x420 # (128 + 4096) / 4 -seti %b 0x4020 # 0x201000 / 128 +# seti %b 0x4020 # 0x201000 / 128 +seti_low %b 0x4020 # 0x201000 / 128 +seti_high %b 0x0000 # 0x201000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c @@ -49,7 +53,9 @@ seti %d 2048 # count is 2048 vadd.bf16 %c %a %b %d # Store C to 0x202000 -seti %a 0x4040 # 0x202000 / 128 +# seti %a 0x4040 # 0x202000 / 128 +seti_low %a 0x4040 # 0x202000 / 128 +seti_high %a 0x0000 # 0x202000 / 128 seti %b 0x820 # (128 + 4096 + 4096) / 4 seti %c 1024 # (2048 * 2) / 4 store %a %b %c diff --git a/examples/with-load-store-vdiv.bf16.asm b/examples/with-load-store-vdiv.bf16.asm index e866a0b..66e0707 100644 --- a/examples/with-load-store-vdiv.bf16.asm +++ b/examples/with-load-store-vdiv.bf16.asm @@ -30,13 +30,17 @@ def finalize(host): # Load 0x200000 into A seti %a 0x20 # (128) / 4 -seti %b 0x4000 # 0x200000 / 128 +# seti %b 0x4000 # 0x200000 / 128 +seti_low %b 0x4000 # 0x200000 / 128 +seti_high %b 0x0000 # 0x200000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c # Load 0x201000 into B seti %a 0x420 # (128 + 4096) / 4 -seti %b 0x4020 # 0x201000 / 128 +# seti %b 0x4020 # 0x201000 / 128 +seti_low %b 0x4020 # 0x201000 / 128 +seti_high %b 0x0000 # 0x201000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c @@ -49,7 +53,9 @@ seti %d 2048 # count is 2048 vdiv.bf16 %c %a %b %d # Store C to 0x202000 -seti %a 0x4040 # 0x202000 / 128 +# seti %a 0x4040 # 0x202000 / 128 +seti_low %a 0x4040 # 0x202000 / 128 +seti_high %a 0x0000 # 0x202000 / 128 seti %b 0x820 # (128 + 4096 + 4096) / 4 seti %c 1024 # (2048 * 2) / 4 store %a %b %c diff --git a/examples/with-load-store-vmul.bf16.asm b/examples/with-load-store-vmul.bf16.asm index b819b73..bbc6d4d 100644 --- a/examples/with-load-store-vmul.bf16.asm +++ b/examples/with-load-store-vmul.bf16.asm @@ -30,13 +30,17 @@ def finalize(host): # Load 0x200000 into A seti %a 0x20 # (128) / 4 -seti %b 0x4000 # 0x200000 / 128 +# seti %b 0x4000 # 0x200000 / 128 +seti_low %b 0x4000 # 0x200000 / 128 +seti_high %b 0x0000 # 0x200000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c # Load 0x201000 into B seti %a 0x420 # (128 + 4096) / 4 -seti %b 0x4020 # 0x201000 / 128 +# seti %b 0x4020 # 0x201000 / 128 +seti_low %b 0x4020 # 0x201000 / 128 +seti_high %b 0x0000 # 0x201000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c @@ -49,7 +53,9 @@ seti %d 2048 # count is 2048 vmul.bf16 %c %a %b %d # Store C to 0x202000 -seti %a 0x4040 # 0x202000 / 128 +# seti %a 0x4040 # 0x202000 / 128 +seti_low %a 0x4040 # 0x202000 / 128 +seti_high %a 0x0000 # 0x202000 / 128 seti %b 0x820 # (128 + 4096 + 4096) / 4 seti %c 1024 # (2048 * 2) / 4 store %a %b %c diff --git a/examples/with-load-store-vsub.bf16.asm b/examples/with-load-store-vsub.bf16.asm index 99dabb2..be43773 100644 --- a/examples/with-load-store-vsub.bf16.asm +++ b/examples/with-load-store-vsub.bf16.asm @@ -30,13 +30,17 @@ def finalize(host): # Load 0x200000 into A seti %a 0x20 # (128) / 4 -seti %b 0x4000 # 0x200000 / 128 +# seti %b 0x4000 # 0x200000 / 128 +seti_low %b 0x4000 # 0x200000 / 128 +seti_high %b 0x0000 # 0x200000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c # Load 0x201000 into B seti %a 0x420 # (128 + 4096) / 4 -seti %b 0x4020 # 0x201000 / 128 +# seti %b 0x4020 # 0x201000 / 128 +seti_low %b 0x4020 # 0x201000 / 128 +seti_high %b 0x0000 # 0x201000 / 128 seti %c 1024 # (2048 * 2) / 4 load %a %b %c @@ -49,7 +53,9 @@ seti %d 2048 # count is 2048 vsub.bf16 %c %a %b %d # Store C to 0x202000 -seti %a 0x4040 # 0x202000 / 128 +# seti %a 0x4040 # 0x202000 / 128 +seti_low %a 0x4040 # 0x202000 / 128 +seti_high %a 0x0000 # 0x202000 / 128 seti %b 0x820 # (128 + 4096 + 4096) / 4 seti %c 1024 # (2048 * 2) / 4 store %a %b %c From 87b20fedb44ee514b3f64f73882a510ced60f78b Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Mon, 13 Nov 2023 22:46:56 +0900 Subject: [PATCH 03/26] add load & store test xode --- src/testdriver/multi_NPU_RISCV_test.c | 119 ++++++++++++++++++++++---- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index c4ca691..07dcb1f 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -13,6 +13,7 @@ #define KERNEL_WITH_LOAD_STORE 1 #define NPU_REG_ID_OFFSET 3 +#define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ @@ -116,9 +117,6 @@ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); - trace_pc_position() - npu_load(); - } /* riscv issues store command to npu */ @@ -127,7 +125,6 @@ static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigne npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); - npu_store(); } static inline uint64_t get_time() { @@ -460,27 +457,30 @@ void adjust_kernel() { void load_kernel_data_into_npu() { // Load kernel code at address 0 of npu - load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)kernel_0, (int)sizeof(kernel_0)); - load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)kernel_1, (int)sizeof(kernel_1)); - load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)kernel_2, (int)sizeof(kernel_2)); - load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)kernel_3, (int)sizeof(kernel_3)); + load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)(kernel_0/128), (int)sizeof(kernel_0)); + load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)(kernel_1/128), (int)sizeof(kernel_1)); + load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)(kernel_2/128), (int)sizeof(kernel_2)); + load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)(kernel_3/128), (int)sizeof(kernel_3)); + npu_load(); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store // Load input_A at address 0x80 of npu - load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + npu_load(); printf("input_A is stored in all NPUs.\n\n"); // Load input_B at address 0x1080 of npu - load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)input_B, (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + npu_load(); printf("input_B is stored in all NPUs.\n\n"); #endif @@ -493,8 +493,87 @@ void store_result_into_ddr() { store_command_to_npu(1, (long unsigned int)output_npu_1, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); store_command_to_npu(2, (long unsigned int)output_npu_2, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); store_command_to_npu(3, (long unsigned int)output_npu_3, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); + npu_store(); } +#ifdef _NPU_LOAD_STORE_TEST_MODE_ + +void delay_in_usec(int us) { + uint64_t cycle_start; + uint64_t cycle_end; + int elapsedTime; + + cycle_start = get_time(); + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + while(elapsedTime < us) { + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + } +} + +void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { + + int mismatch = 0; + int idx; + + for(idx = 0;idx < size;idx++) { + if(org[idx] != npu_ls[idx]) { + printf("NPU%d Mismatch - kernel[%4d]: 0x%02x, output_npu[%4d]: 0x%02x\n", + npu, idx, org[idx], idx, npu_ls[idx]); + mismatch = 1; + } + } + + if(mismatch) { + printf("[NPU%d] Fail to load & store\n", npu); + } else { + printf("[NPU%d] Success to load & store\n", npu); + } +} + +void load_store_test() { + + char *org; + char *npu_ls; + + // Load kernel code at address 0 of npu + load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)(kernel_0/128), (int)sizeof(kernel_0)); + load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)(kernel_1/128), (int)sizeof(kernel_1)); + load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)(kernel_2/128), (int)sizeof(kernel_2)); + load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)(kernel_3/128), (int)sizeof(kernel_3)); + npu_load(); + + delay_in_usec(1000000); + + // Store kernel code + store_command_to_npu(0, (long unsigned int)(output_npu_0/128), (long unsigned int)0x00, (int)sizeof(kernel_0)); + store_command_to_npu(1, (long unsigned int)(output_npu_1/128), (long unsigned int)0x00, (int)sizeof(kernel_1)); + store_command_to_npu(2, (long unsigned int)(output_npu_2/128), (long unsigned int)0x00, (int)sizeof(kernel_2)); + store_command_to_npu(3, (long unsigned int)(output_npu_3/128), (long unsigned int)0x00, (int)sizeof(kernel_3)); + npu_store(); + + delay_in_usec(1000000); + + org = (char *)kernel_0; + npu_ls = (char *)output_npu_0; + compare_load_store_data(0, org, npu_ls, (int)sizeof(kernel_0)); + + org = (char *)kernel_1; + npu_ls = (char *)output_npu_1; + compare_load_store_data(1, org, npu_ls, (int)sizeof(kernel_1)); + + org = (char *)kernel_2; + npu_ls = (char *)output_npu_2; + compare_load_store_data(2, org, npu_ls, (int)sizeof(kernel_2)); + + org = (char *)kernel_3; + npu_ls = (char *)output_npu_3; + compare_load_store_data(3, org, npu_ls, (int)sizeof(kernel_3)); +} + +#endif + int main() { uint64_t cycle_start; @@ -523,6 +602,12 @@ int main() { adjust_kernel(); printf("\nKernel images for each NPU have been prepared.\n\n"); +#ifdef _NPU_LOAD_STORE_TEST_MODE_ + + load_store_test(); + + return 0; +#endif load_kernel_data_into_npu(); @@ -604,7 +689,7 @@ int main() { printf("[NPU 3 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } - floatToString(2.0 * (cycle_end - cycle_start) / (SYS_CLK / 1000000), + floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); printf("\nRISC-V Time: %s us.\n", elapsedTimeStrValue); From df07e253d3d55e46c1a2123d743efc52f01e8b74 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Tue, 14 Nov 2023 08:59:43 +0900 Subject: [PATCH 04/26] compile error fixed --- src/testdriver/multi_NPU_RISCV_test.c | 51 ++++++++++++++++----------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 07dcb1f..853837d 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -122,9 +122,13 @@ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned /* riscv issues store command to npu */ static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + trace_pc_position() } static inline uint64_t get_time() { @@ -457,29 +461,29 @@ void adjust_kernel() { void load_kernel_data_into_npu() { // Load kernel code at address 0 of npu - load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)(kernel_0/128), (int)sizeof(kernel_0)); - load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)(kernel_1/128), (int)sizeof(kernel_1)); - load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)(kernel_2/128), (int)sizeof(kernel_2)); - load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)(kernel_3/128), (int)sizeof(kernel_3)); + load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)((int)kernel_0/128), (int)sizeof(kernel_0)); + load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)((int)kernel_1/128), (int)sizeof(kernel_1)); + load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)((int)kernel_2/128), (int)sizeof(kernel_2)); + load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)((int)kernel_3/128), (int)sizeof(kernel_3)); npu_load(); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store // Load input_A at address 0x80 of npu - load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)(input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); npu_load(); printf("input_A is stored in all NPUs.\n\n"); // Load input_B at address 0x1080 of npu - load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)(input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)(i(int)nput_B/128), (int)(sizeof(BF16) * DATA_SIZE)); npu_load(); printf("input_B is stored in all NPUs.\n\n"); @@ -537,24 +541,31 @@ void load_store_test() { char *org; char *npu_ls; + printf("\n>>> %s\n\n", __func__); // Load kernel code at address 0 of npu - load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)(kernel_0/128), (int)sizeof(kernel_0)); - load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)(kernel_1/128), (int)sizeof(kernel_1)); - load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)(kernel_2/128), (int)sizeof(kernel_2)); - load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)(kernel_3/128), (int)sizeof(kernel_3)); + load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)((int)kernel_0/128), (int)sizeof(kernel_0)); + load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)((int)kernel_1/128), (int)sizeof(kernel_1)); + load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)((int)kernel_2/128), (int)sizeof(kernel_2)); + load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)((int)kernel_3/128), (int)sizeof(kernel_3)); + printf("\ncomplete all load_command_to_npu\n\n"); npu_load(); + printf("\ncomplete npu_load\n\n"); delay_in_usec(1000000); + printf("\nstart all store_command_to_npu\n\n"); // Store kernel code - store_command_to_npu(0, (long unsigned int)(output_npu_0/128), (long unsigned int)0x00, (int)sizeof(kernel_0)); - store_command_to_npu(1, (long unsigned int)(output_npu_1/128), (long unsigned int)0x00, (int)sizeof(kernel_1)); - store_command_to_npu(2, (long unsigned int)(output_npu_2/128), (long unsigned int)0x00, (int)sizeof(kernel_2)); - store_command_to_npu(3, (long unsigned int)(output_npu_3/128), (long unsigned int)0x00, (int)sizeof(kernel_3)); + store_command_to_npu(0, (long unsigned int)((int)output_npu_0/128), (long unsigned int)0x00, (int)sizeof(kernel_0)); + store_command_to_npu(1, (long unsigned int)((int)output_npu_1/128), (long unsigned int)0x00, (int)sizeof(kernel_1)); + store_command_to_npu(2, (long unsigned int)((int)output_npu_2/128), (long unsigned int)0x00, (int)sizeof(kernel_2)); + store_command_to_npu(3, (long unsigned int)((int)output_npu_3/128), (long unsigned int)0x00, (int)sizeof(kernel_3)); + printf("\ncomplete all store_command_to_npu\n\n"); npu_store(); + printf("\ncomplete npu_store\n\n"); delay_in_usec(1000000); + printf("\nstart all compare_load_store_data\n\n"); org = (char *)kernel_0; npu_ls = (char *)output_npu_0; compare_load_store_data(0, org, npu_ls, (int)sizeof(kernel_0)); From 5ed6d0fa66f6acbb176a344b6afc73e4b15ab257 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Tue, 14 Nov 2023 11:13:48 +0900 Subject: [PATCH 05/26] When npu simulates with the kernel, pad data is read and discarded. --- asm/sim.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asm/sim.py b/asm/sim.py index 4f9f7d8..99440ba 100644 --- a/asm/sim.py +++ b/asm/sim.py @@ -314,13 +314,13 @@ def read(bits): elif kind == 'i20': result.append(read(20)) elif kind == 'p4': - pass + read(4) elif kind == 'p8': - pass + read(8) elif kind == 'p16': - pass + read(16) elif kind == 'p20': - pass + read(20) else: raise Exception(f'Illegal parameter type: {kind}') From 87e6330b629b7e1fccb18ef78f7a2b189e8a004a Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Tue, 14 Nov 2023 12:20:32 +0900 Subject: [PATCH 06/26] seti_low, seti_high, kernel image modify --- examples/with-load-store-vadd.bf16.asm | 4 +- src/testdriver/multi_NPU_RISCV_test.c | 113 ++++++++++++++++--------- 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/examples/with-load-store-vadd.bf16.asm b/examples/with-load-store-vadd.bf16.asm index ae0659e..f601579 100644 --- a/examples/with-load-store-vadd.bf16.asm +++ b/examples/with-load-store-vadd.bf16.asm @@ -52,9 +52,9 @@ seti %d 2048 # count is 2048 vadd.bf16 %c %a %b %d -# Store C to 0x202000 +# Store C to 0x202000 0x203000 0x204000 0x205000 # seti %a 0x4040 # 0x202000 / 128 -seti_low %a 0x4040 # 0x202000 / 128 +seti_low %a 0x4040 # 0x202000 / 128 0x4040 0x4060 0x4080 0x40a0 seti_high %a 0x0000 # 0x202000 / 128 seti %b 0x820 # (128 + 4096 + 4096) / 4 seti %c 1024 # (2048 * 2) / 4 diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 853837d..221487f 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -48,38 +48,51 @@ __attribute__ ((aligned (64))) volatile BF16 output_riscv_mul[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_div[DATA_SIZE]; // Kernel: need to align by 8bytes 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 31 32 33 34 35 36 37 38 39 - // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 - // 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 - // 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 + // 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 31 32 33 34 35 36 37 38 39 + // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 + // 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 + // 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 #if KERNEL_WITH_LOAD_STORE // With load/store, vadd.bf16 -__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x40, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x60, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0x80, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x04, 0x10, 0x02, - 0x20, 0x40, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, - 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, 0xa0, 0x40, 0x10, 0x02, 0x20, 0x08, 0x20, 0x02, - 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { + 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x40, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { + 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x60, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { + 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x80, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { + 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0xa0, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, + 0x00, 0x00, 0x00, 0xff}; #else // Without load/store, vadd.bf16 -__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = {0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { + 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, + 0x00, 0x00, 0x00, 0xff}; #endif static inline void npu_regSet(int idx, unsigned long data) @@ -216,12 +229,12 @@ static void resize_converted_data_size_kernel(uint8_t* kernel, int size) { byte_high = size >> 8; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[8] = byte_low; - kernel[9] = byte_high; - kernel[24] = byte_low; - kernel[25] = byte_high; - kernel[60] = byte_low; - kernel[61] = byte_high; + kernel[12] = byte_low; + kernel[13] = byte_high; + kernel[32] = byte_low; + kernel[33] = byte_high; + kernel[72] = byte_low; + kernel[73] = byte_high; #endif } @@ -236,8 +249,8 @@ static void resize_op_iteration_kernel(uint8_t* kernel, int size) { byte_high = size >> 8; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[44] = byte_low; - kernel[45] = byte_high; + kernel[52] = byte_low; + kernel[53] = byte_high; #else kernel[12] = byte_low; kernel[13] = byte_high; @@ -259,7 +272,7 @@ static void kernel_op_change(uint8_t* kernel, char* op) { printf("Wrong OP!!!\n"); } #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[51] = opcode; + kernel[59] = opcode; #else kernel[19] = opcode; #endif @@ -281,6 +294,12 @@ static void kernel_input_a_addr_change(uint8_t* kernel, BF16* data) { #if KERNEL_WITH_LOAD_STORE // with-load-store kernel[4] = byte_low; kernel[5] = byte_high; + + byte_low = (addr >> 16) & 0xff; + byte_high = (addr >> 24) & 0xFF; + + kernel[8] = byte_low; + kernel[9] = byte_high; #endif } @@ -298,8 +317,14 @@ static void kernel_input_b_addr_change(uint8_t* kernel, BF16* data) { byte_high = (addr >> 8) & 0xFF; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[20] = byte_low; - kernel[21] = byte_high; + kernel[24] = byte_low; + kernel[25] = byte_high; + + byte_low = (addr >> 16) & 0xff; + byte_high = (addr >> 24) & 0xFF; + + kernel[28] = byte_low; + kernel[29] = byte_high; #endif } @@ -317,8 +342,14 @@ static void kernel_input_c_addr_change(uint8_t* kernel, BF16* data) { byte_high = (addr >> 8) & 0xFF; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[52] = byte_low; - kernel[53] = byte_high; + kernel[60] = byte_low; + kernel[61] = byte_high; + + byte_low = (addr >> 16) & 0xff; + byte_high = (addr >> 24) & 0xFF; + + kernel[64] = byte_low; + kernel[65] = byte_high; #endif } From 4b61a7c82abf796f38b1c23ad27f83395fb9091e Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Tue, 14 Nov 2023 14:16:53 +0900 Subject: [PATCH 07/26] compile error fixed when KERNEL_WITH_LOAD_STORE 0 --- src/testdriver/multi_NPU_RISCV_test.c | 71 ++++++++++----------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 221487f..2ea067e 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -10,10 +10,10 @@ #define SYS_CLK 26000000 // RISC-V: 26MHz 26,000,000 -#define KERNEL_WITH_LOAD_STORE 1 +#define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 -#define _NPU_LOAD_STORE_TEST_MODE_ +//#define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ @@ -127,9 +127,13 @@ static inline void npu_store() /* riscv issues store command to npu */ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + trace_pc_position() } /* riscv issues store command to npu */ @@ -151,6 +155,21 @@ static inline uint64_t get_time() { return tmp; } +void delay_in_usec(int us) { + + uint64_t cycle_start; + uint64_t cycle_end; + int elapsedTime; + + cycle_start = get_time(); + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + while(elapsedTime < us) { + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + } +} + BF16 float_to_bf16(float value) { FloatUnion fu; @@ -498,6 +517,7 @@ void load_kernel_data_into_npu() { load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)((int)kernel_3/128), (int)sizeof(kernel_3)); npu_load(); + delay_in_usec(1000000); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store @@ -508,15 +528,17 @@ void load_kernel_data_into_npu() { load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); npu_load(); + delay_in_usec(1000000); printf("input_A is stored in all NPUs.\n\n"); // Load input_B at address 0x1080 of npu load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)(i(int)nput_B/128), (int)(sizeof(BF16) * DATA_SIZE)); + load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); npu_load(); + delay_in_usec(1000000); printf("input_B is stored in all NPUs.\n\n"); #endif } @@ -533,20 +555,6 @@ void store_result_into_ddr() { #ifdef _NPU_LOAD_STORE_TEST_MODE_ -void delay_in_usec(int us) { - uint64_t cycle_start; - uint64_t cycle_end; - int elapsedTime; - - cycle_start = get_time(); - cycle_end = get_time(); - elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); - while(elapsedTime < us) { - cycle_end = get_time(); - elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); - } -} - void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { int mismatch = 0; @@ -656,34 +664,7 @@ int main() { printf("\nRuns all NPUs.\n"); cycle_start = get_time(); -#if 0 - // NPU Set - volatile uint32_t *npu_base = (uint32_t*)0x43C00000; // kernel offset - //Core 0 - npu_base[0] = (uint32_t)kernel_0;// the address of kernel in main memory - npu_base[1] = sizeof(kernel_0); // the size of kernel, also need to align by 8bytes - - cycle_start = get_time(); - npu_base[2] = 0; // Core Id - //Core 1 - npu_base[0] = (uint32_t)kernel_1; - npu_base[1] = sizeof(kernel_1); - npu_base[2] = 1; - //Core 2 - npu_base[0] = (uint32_t)kernel_2; - npu_base[1] = sizeof(kernel_2); - npu_base[2] = 2; - //Core 3 - npu_base[0] = (uint32_t)kernel_3; - npu_base[1] = sizeof(kernel_3); - npu_base[2] = 3; - - while(npu_base[3] & 0b1111) { // wait until operation is done (not busy) - //Xil_DCacheInvalidateRange(&npu_base[3], (uint32_t)sizeof(npu_base[3])); - //invalidate_data_cache(&npu_base[3], (uint32_t)sizeof(npu_base[3])); - }; - // XTime_GetTime(&cycle_end); // Get End Time -#endif + npu_exec(); cycle_end = get_time(); printf("\nAll NPUs have completed calculations.\n\n"); From 09db4164466cb66286ab3e42b9c9583c739e0d3f Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Wed, 15 Nov 2023 10:50:06 +0900 Subject: [PATCH 08/26] define MAX_LOAD_STORE_CHUNK_SIZE --- src/testdriver/multi_NPU_RISCV_test.c | 213 ++++++++++++++++++++------ 1 file changed, 162 insertions(+), 51 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 2ea067e..b19f539 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -13,6 +13,13 @@ #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 + +#define DDR_M 128 // DDR_ADDR_MAGNIFICATION +#define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION +#define SIZE_M 4 // SIZE_MAGNIFICATION + +#define MAX_LOAD_STORE_CHUNK_SIZE 64 // must be >= 128 + //#define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ @@ -128,11 +135,11 @@ static inline void npu_store() static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); trace_pc_position() } @@ -140,11 +147,11 @@ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)r_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 2), size); + npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); trace_pc_position() - npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)l_addr); + npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); trace_pc_position() } @@ -508,49 +515,167 @@ void adjust_kernel() { #endif } +void load_kernel_into_npu() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)sizeof(kernel_0); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x00 + len; + + ddr_a = (long unsigned int)kernel_0 + len; + load_command_to_npu(0, sram_a, ddr_a, loadSize); + ddr_a = (long unsigned int)kernel_1 + len; + load_command_to_npu(1, sram_a, ddr_a, loadSize); + ddr_a = (long unsigned int)kernel_2 + len; + load_command_to_npu(2, sram_a, ddr_a, loadSize); + ddr_a = (long unsigned int)kernel_3 + len; + load_command_to_npu(3, sram_a, ddr_a, loadSize); + + npu_load(); + + printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(1000000); + } +} + +void load_input_A_into_npu() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)(sizeof(BF16) * DATA_SIZE); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x200 + len; + + ddr_a = (long unsigned int)input_A + len; + load_command_to_npu(0, sram_a, ddr_a, loadSize); + load_command_to_npu(1, sram_a, ddr_a, loadSize); + load_command_to_npu(2, sram_a, ddr_a, loadSize); + load_command_to_npu(3, sram_a, ddr_a, loadSize); + + npu_load(); + + printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(1000000); + } +} + +void load_input_B_into_npu() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)(sizeof(BF16) * DATA_SIZE); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x4200 + len; + + ddr_a = (long unsigned int)input_B + len; + load_command_to_npu(0, sram_a, ddr_a, loadSize); + load_command_to_npu(1, sram_a, ddr_a, loadSize); + load_command_to_npu(2, sram_a, ddr_a, loadSize); + load_command_to_npu(3, sram_a, ddr_a, loadSize); + + npu_load(); + + printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(1000000); + } +} + void load_kernel_data_into_npu() { // Load kernel code at address 0 of npu - load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)((int)kernel_0/128), (int)sizeof(kernel_0)); - load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)((int)kernel_1/128), (int)sizeof(kernel_1)); - load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)((int)kernel_2/128), (int)sizeof(kernel_2)); - load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)((int)kernel_3/128), (int)sizeof(kernel_3)); - npu_load(); - - delay_in_usec(1000000); + load_kernel_into_npu(); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store - // Load input_A at address 0x80 of npu - load_command_to_npu(0, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x80, (long unsigned int)((int)input_A/128), (int)(sizeof(BF16) * DATA_SIZE)); - npu_load(); - delay_in_usec(1000000); + load_input_A_into_npu(); printf("input_A is stored in all NPUs.\n\n"); - // Load input_B at address 0x1080 of npu - load_command_to_npu(0, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(1, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(2, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - load_command_to_npu(3, (long unsigned int)0x1080, (long unsigned int)((int)input_B/128), (int)(sizeof(BF16) * DATA_SIZE)); - npu_load(); - - delay_in_usec(1000000); + load_input_B_into_npu(); printf("input_B is stored in all NPUs.\n\n"); #endif } void store_result_into_ddr() { - // Load output_C at address 0x202000 of riscv - store_command_to_npu(0, (long unsigned int)output_npu_0, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(1, (long unsigned int)output_npu_1, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(2, (long unsigned int)output_npu_2, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - store_command_to_npu(3, (long unsigned int)output_npu_3, (long unsigned int)0x2080, (int)(sizeof(BF16) * DATA_SIZE)); - npu_store(); + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)(sizeof(BF16) * DATA_SIZE); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x8200 + len; + + ddr_a = (long unsigned int)output_npu_0 + len; + store_command_to_npu(0, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_1 + len; + store_command_to_npu(1, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_2 + len; + store_command_to_npu(2, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_3 + len; + store_command_to_npu(3, ddr_a, sram_a, loadSize); + + npu_store(); + + delay_in_usec(1000000); + } +} + +void store_kernel_into_ddr() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)sizeof(kernel_0); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x00 + len; + + ddr_a = (long unsigned int)output_npu_0 + len; + store_command_to_npu(0, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_1 + len; + store_command_to_npu(1, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_2 + len; + store_command_to_npu(2, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_3 + len; + store_command_to_npu(3, ddr_a, sram_a, loadSize); + + npu_store(); + + delay_in_usec(1000000); + } } #ifdef _NPU_LOAD_STORE_TEST_MODE_ @@ -581,25 +706,11 @@ void load_store_test() { char *npu_ls; printf("\n>>> %s\n\n", __func__); - // Load kernel code at address 0 of npu - load_command_to_npu(0, (long unsigned int)0x00, (long unsigned int)((int)kernel_0/128), (int)sizeof(kernel_0)); - load_command_to_npu(1, (long unsigned int)0x00, (long unsigned int)((int)kernel_1/128), (int)sizeof(kernel_1)); - load_command_to_npu(2, (long unsigned int)0x00, (long unsigned int)((int)kernel_2/128), (int)sizeof(kernel_2)); - load_command_to_npu(3, (long unsigned int)0x00, (long unsigned int)((int)kernel_3/128), (int)sizeof(kernel_3)); - printf("\ncomplete all load_command_to_npu\n\n"); - npu_load(); - printf("\ncomplete npu_load\n\n"); - delay_in_usec(1000000); + load_kernel_into_npu(); + printf("\ncomplete npu_load\n\n"); - printf("\nstart all store_command_to_npu\n\n"); - // Store kernel code - store_command_to_npu(0, (long unsigned int)((int)output_npu_0/128), (long unsigned int)0x00, (int)sizeof(kernel_0)); - store_command_to_npu(1, (long unsigned int)((int)output_npu_1/128), (long unsigned int)0x00, (int)sizeof(kernel_1)); - store_command_to_npu(2, (long unsigned int)((int)output_npu_2/128), (long unsigned int)0x00, (int)sizeof(kernel_2)); - store_command_to_npu(3, (long unsigned int)((int)output_npu_3/128), (long unsigned int)0x00, (int)sizeof(kernel_3)); - printf("\ncomplete all store_command_to_npu\n\n"); - npu_store(); + store_kernel_into_ddr(); printf("\ncomplete npu_store\n\n"); delay_in_usec(1000000); From 2158e9fd6dddc434b8288e1015add54f769ccdf7 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 11:37:25 +0900 Subject: [PATCH 09/26] load/store test --- src/testdriver/multi_NPU_RISCV_test.c | 311 ++++++++++++++++++++------ 1 file changed, 244 insertions(+), 67 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index b19f539..84dcfb8 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -4,7 +4,8 @@ #include #include -#define DATA_SIZE 2048 // Data Size +//#define DATA_SIZE 2048 // Data Size +#define DATA_SIZE 16 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define NUMBER_OF_CORES 4 // Number f Cores used at the same time @@ -14,13 +15,19 @@ #define NPU_REG_ID_OFFSET 3 +#if 1 +#define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION +#define SRAM_M 1 // 4 // SRAM_ADDR_MAGNIFICATION +#define SIZE_M 1 // 4 // SIZE_MAGNIFICATION +#else #define DDR_M 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION #define SIZE_M 4 // SIZE_MAGNIFICATION +#endif -#define MAX_LOAD_STORE_CHUNK_SIZE 64 // must be >= 128 +#define MAX_LOAD_STORE_CHUNK_SIZE 16 // must be >= 128 -//#define _NPU_LOAD_STORE_TEST_MODE_ +#define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ @@ -134,25 +141,25 @@ static inline void npu_store() /* riscv issues store command to npu */ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); - trace_pc_position() +// trace_pc_position() } /* riscv issues store command to npu */ static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); - trace_pc_position() +// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); - trace_pc_position() +// trace_pc_position() } static inline uint64_t get_time() { @@ -470,10 +477,41 @@ void init_variavles() { void riscv_calculate_result() { + uint64_t cycle_start; + uint64_t cycle_end; + char elapsedTimeStrValue[50]; + + cycle_start = get_time(); riscv_calculate(output_riscv_add, input_A, input_B, "vadd.bf16", DATA_SIZE); + cycle_end = get_time(); + memset(elapsedTimeStrValue, 0, 50); + floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), + elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); + printf("\nTime spent by RISC-V calculating vadd.bf16: %s us.\n", elapsedTimeStrValue); + + cycle_start = get_time(); riscv_calculate(output_riscv_sub, input_A, input_B, "vsub.bf16", DATA_SIZE); + cycle_end = get_time(); + memset(elapsedTimeStrValue, 0, 50); + floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), + elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); + printf("\nTime spent by RISC-V calculating vsub.bf16: %s us.\n", elapsedTimeStrValue); + + cycle_start = get_time(); riscv_calculate(output_riscv_mul, input_A, input_B, "vmul.bf16", DATA_SIZE); + cycle_end = get_time(); + memset(elapsedTimeStrValue, 0, 50); + floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), + elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); + printf("\nTime spent by RISC-V calculating vmul.bf16: %s us.\n", elapsedTimeStrValue); + + cycle_start = get_time(); riscv_calculate(output_riscv_div, input_A, input_B, "vdiv.bf16", DATA_SIZE); + cycle_end = get_time(); + memset(elapsedTimeStrValue, 0, 50); + floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), + elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); + printf("\nTime spent by RISC-V calculating vdiv.bf16: %s us.\n", elapsedTimeStrValue); } void adjust_kernel() { @@ -515,7 +553,7 @@ void adjust_kernel() { #endif } -void load_kernel_into_npu() { +void load_kernel_into_npu(int npus) { long unsigned int sram_a; long unsigned int ddr_a; @@ -525,28 +563,43 @@ void load_kernel_into_npu() { size = (int)sizeof(kernel_0); + for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { + if(((npus >> npu) & 0x1) == 0) { /* Not included */ + load_command_to_npu(npu, 0, (long unsigned int)kernel_0, 0); + } + } + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; sram_a = 0x00 + len; - ddr_a = (long unsigned int)kernel_0 + len; - load_command_to_npu(0, sram_a, ddr_a, loadSize); - ddr_a = (long unsigned int)kernel_1 + len; - load_command_to_npu(1, sram_a, ddr_a, loadSize); - ddr_a = (long unsigned int)kernel_2 + len; - load_command_to_npu(2, sram_a, ddr_a, loadSize); - ddr_a = (long unsigned int)kernel_3 + len; - load_command_to_npu(3, sram_a, ddr_a, loadSize); + if(npus & 0x1) { + ddr_a = (long unsigned int)kernel_0 + len; + load_command_to_npu(0, sram_a, ddr_a, loadSize); + } + if(npus & 0x2) { + ddr_a = (long unsigned int)kernel_1 + len; + load_command_to_npu(1, sram_a, ddr_a, loadSize); + } + if(npus & 0x4) { + ddr_a = (long unsigned int)kernel_2 + len; + load_command_to_npu(2, sram_a, ddr_a, loadSize); + } + if(npus & 0x8) { + ddr_a = (long unsigned int)kernel_3 + len; + load_command_to_npu(3, sram_a, ddr_a, loadSize); + } npu_load(); printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - delay_in_usec(1000000); + //delay_in_usec(1000000); + delay_in_usec(10000); } } -void load_input_A_into_npu() { +void load_input_A_into_npu(int npus) { long unsigned int sram_a; long unsigned int ddr_a; @@ -556,25 +609,41 @@ void load_input_A_into_npu() { size = (int)(sizeof(BF16) * DATA_SIZE); + for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { + if(((npus >> npu) & 0x1) == 0) { /* Not included */ + load_command_to_npu(npu, 0, (long unsigned int)input_A, 0); + } + } + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - sram_a = 0x200 + len; + //sram_a = 0x200 + len; + sram_a = 0x00 + len; ddr_a = (long unsigned int)input_A + len; - load_command_to_npu(0, sram_a, ddr_a, loadSize); - load_command_to_npu(1, sram_a, ddr_a, loadSize); - load_command_to_npu(2, sram_a, ddr_a, loadSize); - load_command_to_npu(3, sram_a, ddr_a, loadSize); + if(npus & 0x1) { + load_command_to_npu(0, sram_a, ddr_a, loadSize); + } + if(npus & 0x2) { + load_command_to_npu(1, sram_a, ddr_a, loadSize); + } + if(npus & 0x4) { + load_command_to_npu(2, sram_a, ddr_a, loadSize); + } + if(npus & 0x8) { + load_command_to_npu(3, sram_a, ddr_a, loadSize); + } npu_load(); printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - delay_in_usec(1000000); + //delay_in_usec(1000000); + delay_in_usec(10000); } } -void load_input_B_into_npu() { +void load_input_B_into_npu(int npus) { long unsigned int sram_a; long unsigned int ddr_a; @@ -584,36 +653,52 @@ void load_input_B_into_npu() { size = (int)(sizeof(BF16) * DATA_SIZE); + for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { + if(((npus >> npu) & 0x1) == 0) { /* Not included */ + load_command_to_npu(npu, 0, (long unsigned int)input_B, 0); + } + } + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - sram_a = 0x4200 + len; + //sram_a = 0x1200 + len; + sram_a = 0x00 + len; ddr_a = (long unsigned int)input_B + len; - load_command_to_npu(0, sram_a, ddr_a, loadSize); - load_command_to_npu(1, sram_a, ddr_a, loadSize); - load_command_to_npu(2, sram_a, ddr_a, loadSize); - load_command_to_npu(3, sram_a, ddr_a, loadSize); + if(npus & 0x1) { + load_command_to_npu(0, sram_a, ddr_a, loadSize); + } + if(npus & 0x2) { + load_command_to_npu(1, sram_a, ddr_a, loadSize); + } + if(npus & 0x4) { + load_command_to_npu(2, sram_a, ddr_a, loadSize); + } + if(npus & 0x8) { + load_command_to_npu(3, sram_a, ddr_a, loadSize); + } npu_load(); printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - delay_in_usec(1000000); + //delay_in_usec(1000000); + delay_in_usec(10000); } } void load_kernel_data_into_npu() { // Load kernel code at address 0 of npu - load_kernel_into_npu(); + load_kernel_into_npu(0xF); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store - load_input_A_into_npu(); + load_input_A_into_npu(0xF); printf("input_A is stored in all NPUs.\n\n"); - load_input_B_into_npu(); + load_input_B_into_npu(0xF); printf("input_B is stored in all NPUs.\n\n"); #endif } @@ -631,7 +716,7 @@ void store_result_into_ddr() { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - sram_a = 0x8200 + len; + sram_a = 0x2200 + len; ddr_a = (long unsigned int)output_npu_0 + len; store_command_to_npu(0, ddr_a, sram_a, loadSize); @@ -644,7 +729,8 @@ void store_result_into_ddr() { npu_store(); - delay_in_usec(1000000); + //delay_in_usec(1000000); + delay_in_usec(10000); } } @@ -674,7 +760,70 @@ void store_kernel_into_ddr() { npu_store(); - delay_in_usec(1000000); +// delay_in_usec(1000000); + delay_in_usec(10000); + } +} + +void store_input_A_into_ddr() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)(sizeof(BF16) * DATA_SIZE); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + //sram_a = 0x200 + len; + sram_a = 0x00 + len; + + ddr_a = (long unsigned int)output_npu_0 + len; + store_command_to_npu(0, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_1 + len; + store_command_to_npu(1, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_2 + len; + store_command_to_npu(2, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_3 + len; + store_command_to_npu(3, ddr_a, sram_a, loadSize); + + npu_store(); + + delay_in_usec(10000); + } +} + +void store_input_B_into_ddr() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = (int)(sizeof(BF16) * DATA_SIZE); + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + //sram_a = 0x1200 + len; + sram_a = 0x00 + len; + + ddr_a = (long unsigned int)output_npu_0 + len; + store_command_to_npu(0, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_1 + len; + store_command_to_npu(1, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_2 + len; + store_command_to_npu(2, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)output_npu_3 + len; + store_command_to_npu(3, ddr_a, sram_a, loadSize); + + npu_store(); + + delay_in_usec(10000); } } @@ -687,7 +836,7 @@ void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { for(idx = 0;idx < size;idx++) { if(org[idx] != npu_ls[idx]) { - printf("NPU%d Mismatch - kernel[%4d]: 0x%02x, output_npu[%4d]: 0x%02x\n", + printf("NPU%d Mismatch - origin[%4d]: 0x%02x, output_npu[%4d]: 0x%02x\n", npu, idx, org[idx], idx, npu_ls[idx]); mismatch = 1; } @@ -700,37 +849,63 @@ void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { } } -void load_store_test() { +void load_store_test(int id) { char *org; char *npu_ls; + int size; - printf("\n>>> %s\n\n", __func__); + printf("\n>>> %s(%d)\n\n", __func__, id); - load_kernel_into_npu(); + if(id == 0) { + load_kernel_into_npu(0xF); + } else if(id == 1) { + load_input_A_into_npu(0xF); + } else if(id == 1) { + load_input_B_into_npu(0xF); + } else { + return; + } printf("\ncomplete npu_load\n\n"); - store_kernel_into_ddr(); - printf("\ncomplete npu_store\n\n"); - - delay_in_usec(1000000); - - printf("\nstart all compare_load_store_data\n\n"); - org = (char *)kernel_0; - npu_ls = (char *)output_npu_0; - compare_load_store_data(0, org, npu_ls, (int)sizeof(kernel_0)); - - org = (char *)kernel_1; - npu_ls = (char *)output_npu_1; - compare_load_store_data(1, org, npu_ls, (int)sizeof(kernel_1)); - - org = (char *)kernel_2; - npu_ls = (char *)output_npu_2; - compare_load_store_data(2, org, npu_ls, (int)sizeof(kernel_2)); - - org = (char *)kernel_3; - npu_ls = (char *)output_npu_3; - compare_load_store_data(3, org, npu_ls, (int)sizeof(kernel_3)); + if(id == 0) { + + store_kernel_into_ddr(); + + org = (char *)kernel_0; + npu_ls = (char *)output_npu_0; + compare_load_store_data(0, org, npu_ls, (int)sizeof(kernel_0)); + + org = (char *)kernel_1; + npu_ls = (char *)output_npu_1; + compare_load_store_data(1, org, npu_ls, (int)sizeof(kernel_1)); + + org = (char *)kernel_2; + npu_ls = (char *)output_npu_2; + compare_load_store_data(2, org, npu_ls, (int)sizeof(kernel_2)); + + org = (char *)kernel_3; + npu_ls = (char *)output_npu_3; + compare_load_store_data(3, org, npu_ls, (int)sizeof(kernel_3)); + } else if(id == 1) { + size = (int)(sizeof(BF16) * DATA_SIZE); + store_input_A_into_ddr(); + + org = (char *)input_A; + compare_load_store_data(0, org, (char *)output_npu_0, size); + compare_load_store_data(1, org, (char *)output_npu_1, size); + compare_load_store_data(2, org, (char *)output_npu_2, size); + compare_load_store_data(3, org, (char *)output_npu_3, size); + } else if(id == 2) { + size = (int)(sizeof(BF16) * DATA_SIZE); + store_input_B_into_ddr(); + + org = (char *)input_B; + compare_load_store_data(0, org, (char *)output_npu_0, size); + compare_load_store_data(1, org, (char *)output_npu_1, size); + compare_load_store_data(2, org, (char *)output_npu_2, size); + compare_load_store_data(3, org, (char *)output_npu_3, size); + } } #endif @@ -765,7 +940,9 @@ int main() { #ifdef _NPU_LOAD_STORE_TEST_MODE_ - load_store_test(); +// load_store_test(0); + load_store_test(1); +// load_store_test(2); return 0; #endif From bcf2a372627d6b87fe29a99fb8aad0d64efc4d6c Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 15:55:06 +0900 Subject: [PATCH 10/26] =?UTF-8?q?{byte0,=20byte1,=20byte2,=20byte3,=20byte?= =?UTF-8?q?4,=20byte5,=20byte6,=20byte7=20}=20=3D>=20byte=2045670123=20?= =?UTF-8?q?=EC=9D=B4=EB=A0=87=EA=B2=8C=20=EB=90=98=EC=96=B4=20=EC=9E=88?= =?UTF-8?q?=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/testdriver/multi_NPU_RISCV_test.c | 168 +++++++++++++------------- 1 file changed, 86 insertions(+), 82 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 84dcfb8..38553db 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -5,7 +5,7 @@ #include //#define DATA_SIZE 2048 // Data Size -#define DATA_SIZE 16 // Data Size +#define DATA_SIZE 32 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define NUMBER_OF_CORES 4 // Number f Cores used at the same time @@ -14,18 +14,23 @@ #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 +#define INPUT_A_SRAM_BASE_ADDRESS 0x200 +#define INPUT_B_SRAM_BASE_ADDRESS 0x1200 +#define RESULT_SRAM_BASE_ADDRESS 0x2200 + +#define NPU_LOAD_STORE_MICRO_DELAY 100000 #if 1 #define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION -#define SRAM_M 1 // 4 // SRAM_ADDR_MAGNIFICATION -#define SIZE_M 1 // 4 // SIZE_MAGNIFICATION +#define SRAM_M 4 // 4 // SRAM_ADDR_MAGNIFICATION +#define SIZE_M 16 // 4 // SIZE_MAGNIFICATION #else #define DDR_M 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION #define SIZE_M 4 // SIZE_MAGNIFICATION #endif -#define MAX_LOAD_STORE_CHUNK_SIZE 16 // must be >= 128 +#define MAX_LOAD_STORE_CHUNK_SIZE 64 // must be >= 128 #define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ @@ -70,43 +75,43 @@ __attribute__ ((aligned (64))) volatile BF16 output_riscv_div[DATA_SIZE]; #if KERNEL_WITH_LOAD_STORE // With load/store, vadd.bf16 __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { - 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x40, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, - 0x00, 0x00, 0x00, 0xff}; + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; __attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { - 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x60, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, - 0x00, 0x00, 0x00, 0xff}; + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; __attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { - 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x80, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, - 0x00, 0x00, 0x00, 0xff}; + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { - 0x20, 0x00, 0x10, 0x02, 0x00, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x04, 0x10, 0x02, 0x20, 0x40, 0x20, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x07, - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0xa0, 0x40, 0x10, 0x03, 0x00, 0x00, 0x10, 0x04, 0x20, 0x08, 0x20, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x30, 0x12, 0x08, - 0x00, 0x00, 0x00, 0xff}; + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; #else // Without load/store, vadd.bf16 __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x24, 0x31, 0x09}; __attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x24, 0x31, 0x09}; __attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x24, 0x31, 0x09}; __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { - 0x20, 0x00, 0x10, 0x02, 0x20, 0x04, 0x20, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x08, 0x40, 0x02, 0x00, 0x24, 0x31, 0x09, - 0x00, 0x00, 0x00, 0xff}; + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x24, 0x31, 0x09}; #endif static inline void npu_regSet(int idx, unsigned long data) @@ -141,6 +146,7 @@ static inline void npu_store() /* riscv issues store command to npu */ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { +// printf("%s(%d, 0x%lx, 0x%lx, %d)\n", __func__, npu, l_addr, r_addr, size); // trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); // trace_pc_position() @@ -153,6 +159,7 @@ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned /* riscv issues store command to npu */ static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { +// printf("%s(%d, 0x%lx, 0x%lx, %d)\n", __func__, npu, r_addr, l_addr, size); // trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); // trace_pc_position() @@ -262,12 +269,12 @@ static void resize_converted_data_size_kernel(uint8_t* kernel, int size) { byte_high = size >> 8; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[12] = byte_low; - kernel[13] = byte_high; - kernel[32] = byte_low; - kernel[33] = byte_high; - kernel[72] = byte_low; - kernel[73] = byte_high; + kernel[8] = byte_low; + kernel[9] = byte_high; + kernel[36] = byte_low; + kernel[37] = byte_high; + kernel[76] = byte_low; + kernel[77] = byte_high; #endif } @@ -282,11 +289,11 @@ static void resize_op_iteration_kernel(uint8_t* kernel, int size) { byte_high = size >> 8; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[52] = byte_low; - kernel[53] = byte_high; + kernel[48] = byte_low; + kernel[49] = byte_high; #else - kernel[12] = byte_low; - kernel[13] = byte_high; + kernel[8] = byte_low; + kernel[9] = byte_high; #endif } @@ -305,9 +312,9 @@ static void kernel_op_change(uint8_t* kernel, char* op) { printf("Wrong OP!!!\n"); } #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[59] = opcode; + kernel[63] = opcode; #else - kernel[19] = opcode; + kernel[23] = opcode; #endif } @@ -325,14 +332,14 @@ static void kernel_input_a_addr_change(uint8_t* kernel, BF16* data) { byte_high = (addr >> 8) & 0xFF; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[4] = byte_low; - kernel[5] = byte_high; + kernel[0] = byte_low; + kernel[1] = byte_high; byte_low = (addr >> 16) & 0xff; byte_high = (addr >> 24) & 0xFF; - kernel[8] = byte_low; - kernel[9] = byte_high; + kernel[12] = byte_low; + kernel[13] = byte_high; #endif } @@ -350,14 +357,14 @@ static void kernel_input_b_addr_change(uint8_t* kernel, BF16* data) { byte_high = (addr >> 8) & 0xFF; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[24] = byte_low; - kernel[25] = byte_high; + kernel[28] = byte_low; + kernel[29] = byte_high; byte_low = (addr >> 16) & 0xff; byte_high = (addr >> 24) & 0xFF; - kernel[28] = byte_low; - kernel[29] = byte_high; + kernel[24] = byte_low; + kernel[25] = byte_high; #endif } @@ -375,14 +382,14 @@ static void kernel_input_c_addr_change(uint8_t* kernel, BF16* data) { byte_high = (addr >> 8) & 0xFF; #if KERNEL_WITH_LOAD_STORE // with-load-store - kernel[60] = byte_low; - kernel[61] = byte_high; + kernel[56] = byte_low; + kernel[57] = byte_high; byte_low = (addr >> 16) & 0xff; byte_high = (addr >> 24) & 0xFF; - kernel[64] = byte_low; - kernel[65] = byte_high; + kernel[68] = byte_low; + kernel[69] = byte_high; #endif } @@ -593,9 +600,8 @@ void load_kernel_into_npu(int npus) { npu_load(); - printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - //delay_in_usec(1000000); - delay_in_usec(10000); + //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -618,8 +624,7 @@ void load_input_A_into_npu(int npus) { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - //sram_a = 0x200 + len; - sram_a = 0x00 + len; + sram_a = INPUT_A_SRAM_BASE_ADDRESS + len; ddr_a = (long unsigned int)input_A + len; if(npus & 0x1) { @@ -637,9 +642,8 @@ void load_input_A_into_npu(int npus) { npu_load(); - printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - //delay_in_usec(1000000); - delay_in_usec(10000); + //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -662,8 +666,7 @@ void load_input_B_into_npu(int npus) { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - //sram_a = 0x1200 + len; - sram_a = 0x00 + len; + sram_a = INPUT_B_SRAM_BASE_ADDRESS + len; ddr_a = (long unsigned int)input_B + len; if(npus & 0x1) { @@ -681,9 +684,8 @@ void load_input_B_into_npu(int npus) { npu_load(); - printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); - //delay_in_usec(1000000); - delay_in_usec(10000); + //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -716,7 +718,7 @@ void store_result_into_ddr() { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - sram_a = 0x2200 + len; + sram_a = RESULT_SRAM_BASE_ADDRESS + len; ddr_a = (long unsigned int)output_npu_0 + len; store_command_to_npu(0, ddr_a, sram_a, loadSize); @@ -729,8 +731,7 @@ void store_result_into_ddr() { npu_store(); - //delay_in_usec(1000000); - delay_in_usec(10000); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -760,8 +761,7 @@ void store_kernel_into_ddr() { npu_store(); -// delay_in_usec(1000000); - delay_in_usec(10000); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -778,8 +778,7 @@ void store_input_A_into_ddr() { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - //sram_a = 0x200 + len; - sram_a = 0x00 + len; + sram_a = INPUT_A_SRAM_BASE_ADDRESS + len; ddr_a = (long unsigned int)output_npu_0 + len; store_command_to_npu(0, ddr_a, sram_a, loadSize); @@ -792,7 +791,7 @@ void store_input_A_into_ddr() { npu_store(); - delay_in_usec(10000); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -809,8 +808,7 @@ void store_input_B_into_ddr() { for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - //sram_a = 0x1200 + len; - sram_a = 0x00 + len; + sram_a = INPUT_B_SRAM_BASE_ADDRESS + len; ddr_a = (long unsigned int)output_npu_0 + len; store_command_to_npu(0, ddr_a, sram_a, loadSize); @@ -823,7 +821,7 @@ void store_input_B_into_ddr() { npu_store(); - delay_in_usec(10000); + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); } } @@ -840,6 +838,12 @@ void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { npu, idx, org[idx], idx, npu_ls[idx]); mismatch = 1; } +#ifdef __DEBUG_MODE__ + else { + printf("NPU%d Match - origin[%4d]: 0x%02x, output_npu[%4d]: 0x%02x\n", + npu, idx, org[idx], idx, npu_ls[idx]); + } +#endif } if(mismatch) { @@ -940,8 +944,8 @@ int main() { #ifdef _NPU_LOAD_STORE_TEST_MODE_ -// load_store_test(0); - load_store_test(1); + load_store_test(0); +// load_store_test(1); // load_store_test(2); return 0; From cbfb14e7c8da381a3f6d87bad10e3ac8589b1fec Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 17:29:27 +0900 Subject: [PATCH 11/26] kernel print --- src/testdriver/multi_NPU_RISCV_test.c | 116 +++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 11 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 38553db..b42ded2 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -5,7 +5,7 @@ #include //#define DATA_SIZE 2048 // Data Size -#define DATA_SIZE 32 // Data Size +#define DATA_SIZE 64 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define NUMBER_OF_CORES 4 // Number f Cores used at the same time @@ -14,9 +14,9 @@ #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 -#define INPUT_A_SRAM_BASE_ADDRESS 0x200 -#define INPUT_B_SRAM_BASE_ADDRESS 0x1200 -#define RESULT_SRAM_BASE_ADDRESS 0x2200 +#define INPUT_A_SRAM_BASE_ADDRESS 0x40 // 0x200 +#define INPUT_B_SRAM_BASE_ADDRESS 0xC0 // 0x1200 +#define RESULT_SRAM_BASE_ADDRESS 0x140 // 0x2200 #define NPU_LOAD_STORE_MICRO_DELAY 100000 @@ -30,10 +30,10 @@ #define SIZE_M 4 // SIZE_MAGNIFICATION #endif -#define MAX_LOAD_STORE_CHUNK_SIZE 64 // must be >= 128 +#define MAX_LOAD_STORE_CHUNK_SIZE 128 // must be >= 128 -#define _NPU_LOAD_STORE_TEST_MODE_ -#define __DEBUG_MODE__ +//#define _NPU_LOAD_STORE_TEST_MODE_ +//#define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ #define trace_pc_position() printf("%s - %d \n", __func__, __LINE__); @@ -318,6 +318,60 @@ static void kernel_op_change(uint8_t* kernel, char* op) { #endif } +static void kernel_input_a_sram_addr_change(uint8_t* kernel, unsigned long addr) { + + uint8_t byte_low; + uint8_t byte_high; + + addr = (addr + 3)/4; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store +#else + kernel[4] = byte_low; + kernel[5] = byte_high; +#endif +} + +static void kernel_input_b_sram_addr_change(uint8_t* kernel, unsigned long addr) { + + uint8_t byte_low; + uint8_t byte_high; + + addr = (addr + 3)/4; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store +#else + kernel[0] = byte_low; + kernel[1] = byte_high; +#endif +} + +static void kernel_output_c_sram_addr_change(uint8_t* kernel, unsigned long addr) { + + uint8_t byte_low; + uint8_t byte_high; + + addr = (addr + 3)/4; + + // Devide Size + byte_low = addr & 0xff; + byte_high = (addr >> 8) & 0xFF; + +#if KERNEL_WITH_LOAD_STORE // with-load-store +#else + kernel[12] = byte_low; + kernel[13] = byte_high; +#endif +} + static void kernel_input_a_addr_change(uint8_t* kernel, BF16* data) { unsigned long addr; @@ -534,6 +588,21 @@ void adjust_kernel() { kernel_op_change(kernel_2, TEST_OP_TYPE); kernel_op_change(kernel_3, TEST_OP_TYPE); + kernel_input_a_sram_addr_change(kernel_0, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); + kernel_input_a_sram_addr_change(kernel_1, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); + kernel_input_a_sram_addr_change(kernel_2, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); + kernel_input_a_sram_addr_change(kernel_3, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); + + kernel_input_b_sram_addr_change(kernel_0, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); + kernel_input_b_sram_addr_change(kernel_1, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); + kernel_input_b_sram_addr_change(kernel_2, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); + kernel_input_b_sram_addr_change(kernel_3, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); + + kernel_output_c_sram_addr_change(kernel_0, (unsigned long )RESULT_SRAM_BASE_ADDRESS); + kernel_output_c_sram_addr_change(kernel_1, (unsigned long )RESULT_SRAM_BASE_ADDRESS); + kernel_output_c_sram_addr_change(kernel_2, (unsigned long )RESULT_SRAM_BASE_ADDRESS); + kernel_output_c_sram_addr_change(kernel_3, (unsigned long )RESULT_SRAM_BASE_ADDRESS); + #if KERNEL_WITH_LOAD_STORE // with-load-store // Change Kernel's input_A address kernel_input_a_addr_change(kernel_0, input_A); @@ -560,6 +629,16 @@ void adjust_kernel() { #endif } +void dump_data(char * data, int size) { + for(int id = 0; id < size; id++) { + printf("0x%02x, ", data[id] & 0xFF); + if(((id+1) % 16) == 0) { + printf("\n"); + } + } + printf("\n\n"); +} + void load_kernel_into_npu(int npus) { long unsigned int sram_a; @@ -865,7 +944,7 @@ void load_store_test(int id) { load_kernel_into_npu(0xF); } else if(id == 1) { load_input_A_into_npu(0xF); - } else if(id == 1) { + } else if(id == 2) { load_input_B_into_npu(0xF); } else { return; @@ -936,17 +1015,31 @@ int main() { init_variavles(); printf("\ninput_A & input_B are filled with random data.\n"); + printf("[input_A]\n"); + dump_data((char *)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + printf("[input_B]\n"); + dump_data((char *)input_B, (int)(sizeof(BF16) * DATA_SIZE)); + riscv_calculate_result(); printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); adjust_kernel(); printf("\nKernel images for each NPU have been prepared.\n\n"); + printf("[kernel_0]\n"); + dump_data((char *)kernel_0, (int)sizeof(kernel_0)); + printf("[kernel_1]\n"); + dump_data((char *)kernel_1, (int)sizeof(kernel_1)); + printf("[kernel_2]\n"); + dump_data((char *)kernel_2, (int)sizeof(kernel_2)); + printf("[kernel_3]\n"); + dump_data((char *)kernel_3, (int)sizeof(kernel_3)); + #ifdef _NPU_LOAD_STORE_TEST_MODE_ - load_store_test(0); -// load_store_test(1); -// load_store_test(2); +// load_store_test(0); + load_store_test(1); + load_store_test(2); return 0; #endif @@ -957,6 +1050,7 @@ int main() { cycle_start = get_time(); npu_exec(); + delay_in_usec(10000000); cycle_end = get_time(); printf("\nAll NPUs have completed calculations.\n\n"); From 68ae17ec9c085ee9e5a6be22880e7b19fef64a04 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 20:43:08 +0900 Subject: [PATCH 12/26] NPU exec complete interrupt --- src/testdriver/multi_NPU_RISCV_test.c | 55 +++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index b42ded2..8fd0f0b 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -20,6 +20,10 @@ #define NPU_LOAD_STORE_MICRO_DELAY 100000 +#define NPU_COMPLETE_EXEC_INTERRUPT 0 +#define NPU_COMPLETE_EXEC_REG 13 +#define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 + #if 1 #define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 4 // 4 // SRAM_ADDR_MAGNIFICATION @@ -548,7 +552,7 @@ void riscv_calculate_result() { memset(elapsedTimeStrValue, 0, 50); floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); - printf("\nTime spent by RISC-V calculating vadd.bf16: %s us.\n", elapsedTimeStrValue); + printf("Time spent by RISC-V calculating vadd.bf16: %s us.\n", elapsedTimeStrValue); cycle_start = get_time(); riscv_calculate(output_riscv_sub, input_A, input_B, "vsub.bf16", DATA_SIZE); @@ -556,7 +560,7 @@ void riscv_calculate_result() { memset(elapsedTimeStrValue, 0, 50); floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); - printf("\nTime spent by RISC-V calculating vsub.bf16: %s us.\n", elapsedTimeStrValue); + printf("Time spent by RISC-V calculating vsub.bf16: %s us.\n", elapsedTimeStrValue); cycle_start = get_time(); riscv_calculate(output_riscv_mul, input_A, input_B, "vmul.bf16", DATA_SIZE); @@ -564,7 +568,7 @@ void riscv_calculate_result() { memset(elapsedTimeStrValue, 0, 50); floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); - printf("\nTime spent by RISC-V calculating vmul.bf16: %s us.\n", elapsedTimeStrValue); + printf("Time spent by RISC-V calculating vmul.bf16: %s us.\n", elapsedTimeStrValue); cycle_start = get_time(); riscv_calculate(output_riscv_div, input_A, input_B, "vdiv.bf16", DATA_SIZE); @@ -572,7 +576,7 @@ void riscv_calculate_result() { memset(elapsedTimeStrValue, 0, 50); floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); - printf("\nTime spent by RISC-V calculating vdiv.bf16: %s us.\n", elapsedTimeStrValue); + printf("Time spent by RISC-V calculating vdiv.bf16: %s us.\n", elapsedTimeStrValue); } void adjust_kernel() { @@ -993,6 +997,37 @@ void load_store_test(int id) { #endif +static inline void init_complete_exec() { + + npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); +} + +static uint64_t check_complete_exec(uint64_t start) { + + unsigned long value = 0x0; + uint64_t end; + + end = get_time(); +#if NPU_COMPLETE_EXEC_INTERRUPT + value = npu_regGet(NPU_COMPLETE_EXEC_REG); +#endif + + while(((value & 0xF) != 0xF) && + ((float)((end - start) / (SYS_CLK / 1000000)) < NPU_COMPLETE_EXEC_TIMEOUT)) { + end = get_time(); +#if NPU_COMPLETE_EXEC_INTERRUPT + value = npu_regGet(NPU_COMPLETE_EXEC_REG); +#else + printf("end: %016x\r", end); + fflush(stdout); +#endif + } + printf("\nsrart: %016x\n", start); + printf("end: %016x\n", end); + + return end; +} + int main() { uint64_t cycle_start; @@ -1046,14 +1081,20 @@ int main() { load_kernel_data_into_npu(); + init_complete_exec(); + printf("\nRuns all NPUs.\n"); cycle_start = get_time(); npu_exec(); - delay_in_usec(10000000); - cycle_end = get_time(); - printf("\nAll NPUs have completed calculations.\n\n"); + cycle_end = check_complete_exec(cycle_start); + if(((cycle_end - cycle_start) / (SYS_CLK / 1000000)) < NPU_COMPLETE_EXEC_TIMEOUT) { + printf("\nAll NPUs have completed calculations.\n\n"); + } else { + printf("\nTimeout - Waiting for all npu execs to finish.\n\n"); + return 0; + } #if !KERNEL_WITH_LOAD_STORE // without-load-store store_result_into_ddr(); From bae46e9ff6f3988445ccbcc5fb6903892e3ad5f0 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 20:48:23 +0900 Subject: [PATCH 13/26] NPU exec complete interrupt --- src/testdriver/multi_NPU_RISCV_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 8fd0f0b..1b33c41 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -20,7 +20,7 @@ #define NPU_LOAD_STORE_MICRO_DELAY 100000 -#define NPU_COMPLETE_EXEC_INTERRUPT 0 +#define NPU_COMPLETE_EXEC_INTERRUPT 1 #define NPU_COMPLETE_EXEC_REG 13 #define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 From 9ae3a36df718a5fe9ce143bdf835a1651549293a Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Fri, 17 Nov 2023 23:37:53 +0900 Subject: [PATCH 14/26] compare with epsilon --- src/testdriver/multi_NPU_RISCV_test.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 1b33c41..87c4de1 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -23,6 +23,7 @@ #define NPU_COMPLETE_EXEC_INTERRUPT 1 #define NPU_COMPLETE_EXEC_REG 13 #define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 +#define EPSILON 0.01 #if 1 #define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION @@ -486,6 +487,7 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o int error_cnt = 0; float out_risc_flt; float out_npu_flt; + float diff; char riscvStrValue[50]; char npuStrValue[50]; char diffStrValue[50]; @@ -493,7 +495,12 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o for (int i = 0; i < count; i++) { out_risc_flt = bf16_to_float(out_risc_bf16[i]); out_npu_flt = bf16_to_float(out_npu_bf16[i]); - if (out_risc_flt != out_npu_flt) { + if(out_risc_flt > out_npu_flt) { + diff = out_risc_flt - out_npu_flt; + } else { + diff = out_npu_flt - out_risc_flt; + } + if (diff > EPSILON) { error_cnt += 1; #ifdef __DEBUG_MODE__ memset(riscvStrValue, 0, 50); From eecd1c385a7c1cdc8aa498e4acc0df3293ec5ca7 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sat, 18 Nov 2023 07:42:14 +0900 Subject: [PATCH 15/26] =?UTF-8?q?=EC=BB=A4=EB=84=90=EC=97=90=EC=84=9C=20fo?= =?UTF-8?q?r=EB=AC=B8=EC=9D=84=20=EB=8F=8C=EB=A0=A4=EC=84=9C=20vadd.bf16?= =?UTF-8?q?=EC=9D=84=200x400=EB=B2=88=20=EB=8F=8C=EB=A0=A4=EB=B2=84?= =?UTF-8?q?=EB=A6=AC=EB=8A=94=20=EC=BD=94=EB=93=9C=EC=9E=85=EB=8B=88?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/without-load-store-vadd.bf16.asm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/without-load-store-vadd.bf16.asm b/examples/without-load-store-vadd.bf16.asm index 9506b36..264d984 100644 --- a/examples/without-load-store-vadd.bf16.asm +++ b/examples/without-load-store-vadd.bf16.asm @@ -38,8 +38,12 @@ seti %a 0x20 # 128 / 4 # A is stored at 128 seti %b 0x420 # (128 + 4096) / 4 # B is stored at 128 + 4096 seti %c 0x820 # (128 + 4096 *2) / 4 # C is stored at 128 + 4096 + 4096 seti %d 2048 # count is 2048 +seti %e 0x400 # 1024 +seti %f 0x0 vadd.bf16 %c %a %b %d +add.int32 %f %zero 0x1 +ifneq %e %f 0xc010 # Interrupt to CPU return From cb04665a58f4792e6a0860256fa2b554adb8d537 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sat, 18 Nov 2023 10:55:49 +0900 Subject: [PATCH 16/26] core 6 --- examples/without-load-store-vadd.bf16.asm | 5 +- src/testdriver/multi_NPU_RISCV_test.c | 283 ++++++++++++++++------ 2 files changed, 211 insertions(+), 77 deletions(-) diff --git a/examples/without-load-store-vadd.bf16.asm b/examples/without-load-store-vadd.bf16.asm index 264d984..7fc31a9 100644 --- a/examples/without-load-store-vadd.bf16.asm +++ b/examples/without-load-store-vadd.bf16.asm @@ -42,8 +42,9 @@ seti %e 0x400 # 1024 seti %f 0x0 vadd.bf16 %c %a %b %d -add.int32 %f %zero 0x1 -ifneq %e %f 0xc010 +add.i32 %f %zero 0x1 +#ifneq %e %f 0xc010 +ifneq %e %f -8 # Interrupt to CPU return diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 87c4de1..fe1b126 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -4,31 +4,32 @@ #include #include -//#define DATA_SIZE 2048 // Data Size -#define DATA_SIZE 64 // Data Size +#define MAX_DATA_SIZE 2048 // Data Size +#define DATA_SIZE 1024 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" -#define NUMBER_OF_CORES 4 // Number f Cores used at the same time +#define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time +#define NUMBER_OF_CORES 4 // Number of Cores used at the same time #define SYS_CLK 26000000 // RISC-V: 26MHz 26,000,000 #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 -#define INPUT_A_SRAM_BASE_ADDRESS 0x40 // 0x200 -#define INPUT_B_SRAM_BASE_ADDRESS 0xC0 // 0x1200 -#define RESULT_SRAM_BASE_ADDRESS 0x140 // 0x2200 +#define INPUT_A_SRAM_BASE_ADDRESS 0x80 // 128 // 0x40 // 0x200 +#define INPUT_B_SRAM_BASE_ADDRESS 0x1080 // 128 + 4096 // 0xC0 // 0x1200 +#define RESULT_SRAM_BASE_ADDRESS 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 -#define NPU_LOAD_STORE_MICRO_DELAY 100000 +#define NPU_LOAD_STORE_MICRO_DELAY 10000 #define NPU_COMPLETE_EXEC_INTERRUPT 1 -#define NPU_COMPLETE_EXEC_REG 13 +#define NPU_COMPLETE_EXEC_REG (NUMBER_OF_CORES * 3 + 1) // 13 #define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 #define EPSILON 0.01 #if 1 #define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION -#define SRAM_M 4 // 4 // SRAM_ADDR_MAGNIFICATION -#define SIZE_M 16 // 4 // SIZE_MAGNIFICATION +#define SRAM_M 4 // 4 // SRAM_ADDR_MAGNIFICATION +#define SIZE_M 16 // 4 // SIZE_MAGNIFICATION #else #define DDR_M 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION @@ -65,6 +66,8 @@ __attribute__ ((aligned (128))) volatile BF16 output_npu_0[DATA_SIZE]; // NPU 0 __attribute__ ((aligned (128))) volatile BF16 output_npu_1[DATA_SIZE]; // NPU 1 Output __attribute__ ((aligned (128))) volatile BF16 output_npu_2[DATA_SIZE]; // NPU 2 Output __attribute__ ((aligned (128))) volatile BF16 output_npu_3[DATA_SIZE]; // NPU 3 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_4[DATA_SIZE]; // NPU 3 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_5[DATA_SIZE]; // NPU 3 Output __attribute__ ((aligned (64))) volatile BF16 output_riscv_add[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_sub[DATA_SIZE]; @@ -103,8 +106,40 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_4[] = { + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { + 0x00, 0x40, 0x20, 0x03, 0x20, 0x00, 0x10, 0x02, 0x00, 0x04, 0x30, 0x02, 0x00, 0x00, 0x20, 0x04, 0x20, 0x04, 0x10, 0x02, + 0x00, 0x30, 0x12, 0x07, 0x00, 0x00, 0x20, 0x04, 0x20, 0x40, 0x20, 0x03, 0x00, 0x30, 0x12, 0x07, 0x00, 0x04, 0x30, 0x02, + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x40, 0x40, 0x10, 0x03, + 0x00, 0x24, 0x31, 0x09, 0x20, 0x08, 0x20, 0x02, 0x00, 0x00, 0x10, 0x04, 0x00, 0x30, 0x12, 0x08, 0x00, 0x04, 0x30, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; #else // Without load/store, vadd.bf16 +#if 1 // ifneq %e %f -12 +__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_4[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +__attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { + 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; +#else __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, 0x00, 0x24, 0x31, 0x09}; @@ -118,6 +153,9 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, 0x00, 0x24, 0x31, 0x09}; #endif +#endif + +unsigned long g_interrupt_mask = 0xF; static inline void npu_regSet(int idx, unsigned long data) { @@ -319,7 +357,7 @@ static void kernel_op_change(uint8_t* kernel, char* op) { #if KERNEL_WITH_LOAD_STORE // with-load-store kernel[63] = opcode; #else - kernel[23] = opcode; + kernel[31] = opcode; #endif } @@ -536,6 +574,8 @@ void init_variavles() { memset(output_npu_1, 0, sizeof(output_npu_1)); memset(output_npu_2, 0, sizeof(output_npu_2)); memset(output_npu_3, 0, sizeof(output_npu_3)); + memset(output_npu_4, 0, sizeof(output_npu_3)); + memset(output_npu_5, 0, sizeof(output_npu_3)); // Random Data Input for (int temp_count = 0; temp_count < DATA_SIZE; temp_count++) { @@ -592,27 +632,37 @@ void adjust_kernel() { resize_op_iteration_kernel(kernel_1, DATA_SIZE); resize_op_iteration_kernel(kernel_2, DATA_SIZE); resize_op_iteration_kernel(kernel_3, DATA_SIZE); + resize_op_iteration_kernel(kernel_4, DATA_SIZE); + resize_op_iteration_kernel(kernel_5, DATA_SIZE); // Change Kernel's Opcode kernel_op_change(kernel_0, TEST_OP_TYPE); kernel_op_change(kernel_1, TEST_OP_TYPE); kernel_op_change(kernel_2, TEST_OP_TYPE); kernel_op_change(kernel_3, TEST_OP_TYPE); - - kernel_input_a_sram_addr_change(kernel_0, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); - kernel_input_a_sram_addr_change(kernel_1, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); - kernel_input_a_sram_addr_change(kernel_2, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); - kernel_input_a_sram_addr_change(kernel_3, (unsigned long )INPUT_A_SRAM_BASE_ADDRESS); - - kernel_input_b_sram_addr_change(kernel_0, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); - kernel_input_b_sram_addr_change(kernel_1, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); - kernel_input_b_sram_addr_change(kernel_2, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); - kernel_input_b_sram_addr_change(kernel_3, (unsigned long )INPUT_B_SRAM_BASE_ADDRESS); - - kernel_output_c_sram_addr_change(kernel_0, (unsigned long )RESULT_SRAM_BASE_ADDRESS); - kernel_output_c_sram_addr_change(kernel_1, (unsigned long )RESULT_SRAM_BASE_ADDRESS); - kernel_output_c_sram_addr_change(kernel_2, (unsigned long )RESULT_SRAM_BASE_ADDRESS); - kernel_output_c_sram_addr_change(kernel_3, (unsigned long )RESULT_SRAM_BASE_ADDRESS); + kernel_op_change(kernel_4, TEST_OP_TYPE); + kernel_op_change(kernel_5, TEST_OP_TYPE); + + kernel_input_a_sram_addr_change(kernel_0, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_1, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_2, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_3, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_4, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_5, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); + + kernel_input_b_sram_addr_change(kernel_0, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + kernel_input_b_sram_addr_change(kernel_1, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + kernel_input_b_sram_addr_change(kernel_2, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + kernel_input_b_sram_addr_change(kernel_3, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + kernel_input_b_sram_addr_change(kernel_4, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + kernel_input_b_sram_addr_change(kernel_5, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); + + kernel_output_c_sram_addr_change(kernel_0, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_output_c_sram_addr_change(kernel_1, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_output_c_sram_addr_change(kernel_2, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_output_c_sram_addr_change(kernel_3, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_output_c_sram_addr_change(kernel_4, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_output_c_sram_addr_change(kernel_5, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); #if KERNEL_WITH_LOAD_STORE // with-load-store // Change Kernel's input_A address @@ -620,18 +670,24 @@ void adjust_kernel() { kernel_input_a_addr_change(kernel_1, input_A); kernel_input_a_addr_change(kernel_2, input_A); kernel_input_a_addr_change(kernel_3, input_A); + kernel_input_a_addr_change(kernel_4, input_A); + kernel_input_a_addr_change(kernel_5, input_A); // Change Kernel's input_A address kernel_input_b_addr_change(kernel_0, input_B); kernel_input_b_addr_change(kernel_1, input_B); kernel_input_b_addr_change(kernel_2, input_B); kernel_input_b_addr_change(kernel_3, input_B); + kernel_input_b_addr_change(kernel_4, input_B); + kernel_input_b_addr_change(kernel_5, input_B); // Change Kernel's input_A address kernel_input_c_addr_change(kernel_0, output_npu_0); kernel_input_c_addr_change(kernel_1, output_npu_1); kernel_input_c_addr_change(kernel_2, output_npu_2); kernel_input_c_addr_change(kernel_3, output_npu_3); + kernel_input_c_addr_change(kernel_4, output_npu_3); + kernel_input_c_addr_change(kernel_5, output_npu_3); resize_converted_data_size_kernel(kernel_0, (int)((DATA_SIZE * 2 + 3)/4)); resize_converted_data_size_kernel(kernel_1, (int)((DATA_SIZE * 2 + 3)/4)); @@ -660,12 +716,6 @@ void load_kernel_into_npu(int npus) { size = (int)sizeof(kernel_0); - for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { - if(((npus >> npu) & 0x1) == 0) { /* Not included */ - load_command_to_npu(npu, 0, (long unsigned int)kernel_0, 0); - } - } - for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; @@ -687,6 +737,14 @@ void load_kernel_into_npu(int npus) { ddr_a = (long unsigned int)kernel_3 + len; load_command_to_npu(3, sram_a, ddr_a, loadSize); } + if(npus & 0x10) { + ddr_a = (long unsigned int)kernel_4 + len; + load_command_to_npu(4, sram_a, ddr_a, loadSize); + } + if(npus & 0x20) { + ddr_a = (long unsigned int)kernel_5 + len; + load_command_to_npu(5, sram_a, ddr_a, loadSize); + } npu_load(); @@ -705,12 +763,6 @@ void load_input_A_into_npu(int npus) { size = (int)(sizeof(BF16) * DATA_SIZE); - for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { - if(((npus >> npu) & 0x1) == 0) { /* Not included */ - load_command_to_npu(npu, 0, (long unsigned int)input_A, 0); - } - } - for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; @@ -729,6 +781,12 @@ void load_input_A_into_npu(int npus) { if(npus & 0x8) { load_command_to_npu(3, sram_a, ddr_a, loadSize); } + if(npus & 0x10) { + load_command_to_npu(4, sram_a, ddr_a, loadSize); + } + if(npus & 0x20) { + load_command_to_npu(5, sram_a, ddr_a, loadSize); + } npu_load(); @@ -747,12 +805,6 @@ void load_input_B_into_npu(int npus) { size = (int)(sizeof(BF16) * DATA_SIZE); - for(int npu = 0; npu < NUMBER_OF_CORES; npu++) { - if(((npus >> npu) & 0x1) == 0) { /* Not included */ - load_command_to_npu(npu, 0, (long unsigned int)input_B, 0); - } - } - for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; @@ -771,6 +823,12 @@ void load_input_B_into_npu(int npus) { if(npus & 0x8) { load_command_to_npu(3, sram_a, ddr_a, loadSize); } + if(npus & 0x10) { + load_command_to_npu(4, sram_a, ddr_a, loadSize); + } + if(npus & 0x20) { + load_command_to_npu(5, sram_a, ddr_a, loadSize); + } npu_load(); @@ -781,16 +839,26 @@ void load_input_B_into_npu(int npus) { void load_kernel_data_into_npu() { + int npus; + + if(NUMBER_OF_CORES == 5) { + npus = 0x1F; + } else if(NUMBER_OF_CORES == 6) { + npus = 0x3F; + } else { + npus = 0x0F; + } + // Load kernel code at address 0 of npu - load_kernel_into_npu(0xF); + load_kernel_into_npu(npus); printf("Kernel images are stored in each NPU.\n\n"); #if !KERNEL_WITH_LOAD_STORE // without-load-store - load_input_A_into_npu(0xF); + load_input_A_into_npu(npus); printf("input_A is stored in all NPUs.\n\n"); - load_input_B_into_npu(0xF); + load_input_B_into_npu(npus); printf("input_B is stored in all NPUs.\n\n"); #endif } @@ -952,11 +1020,11 @@ void load_store_test(int id) { printf("\n>>> %s(%d)\n\n", __func__, id); if(id == 0) { - load_kernel_into_npu(0xF); + load_kernel_into_npu(g_interrupt_mask); } else if(id == 1) { - load_input_A_into_npu(0xF); + load_input_A_into_npu(g_interrupt_mask); } else if(id == 2) { - load_input_B_into_npu(0xF); + load_input_B_into_npu(g_interrupt_mask); } else { return; } @@ -981,6 +1049,16 @@ void load_store_test(int id) { org = (char *)kernel_3; npu_ls = (char *)output_npu_3; compare_load_store_data(3, org, npu_ls, (int)sizeof(kernel_3)); + if(NUMBER_OF_CORES >= 5) { + org = (char *)kernel_4; + npu_ls = (char *)output_npu_4; + compare_load_store_data(4, org, npu_ls, (int)sizeof(kernel_4)); + } + if(NUMBER_OF_CORES >= 6) { + org = (char *)kernel_5; + npu_ls = (char *)output_npu_5; + compare_load_store_data(5, org, npu_ls, (int)sizeof(kernel_5)); + } } else if(id == 1) { size = (int)(sizeof(BF16) * DATA_SIZE); store_input_A_into_ddr(); @@ -990,6 +1068,12 @@ void load_store_test(int id) { compare_load_store_data(1, org, (char *)output_npu_1, size); compare_load_store_data(2, org, (char *)output_npu_2, size); compare_load_store_data(3, org, (char *)output_npu_3, size); + if(NUMBER_OF_CORES >= 5) { + compare_load_store_data(4, org, (char *)output_npu_4, size); + } + if(NUMBER_OF_CORES >= 6) { + compare_load_store_data(5, org, (char *)output_npu_5, size); + } } else if(id == 2) { size = (int)(sizeof(BF16) * DATA_SIZE); store_input_B_into_ddr(); @@ -999,6 +1083,12 @@ void load_store_test(int id) { compare_load_store_data(1, org, (char *)output_npu_1, size); compare_load_store_data(2, org, (char *)output_npu_2, size); compare_load_store_data(3, org, (char *)output_npu_3, size); + if(NUMBER_OF_CORES >= 5) { + compare_load_store_data(4, org, (char *)output_npu_4, size); + } + if(NUMBER_OF_CORES >= 6) { + compare_load_store_data(5, org, (char *)output_npu_5, size); + } } } @@ -1019,7 +1109,7 @@ static uint64_t check_complete_exec(uint64_t start) { value = npu_regGet(NPU_COMPLETE_EXEC_REG); #endif - while(((value & 0xF) != 0xF) && + while(((value & g_interrupt_mask) != g_interrupt_mask) && ((float)((end - start) / (SYS_CLK / 1000000)) < NPU_COMPLETE_EXEC_TIMEOUT)) { end = get_time(); #if NPU_COMPLETE_EXEC_INTERRUPT @@ -1039,10 +1129,7 @@ int main() { uint64_t cycle_start; uint64_t cycle_end; - int check0 = 0; - int check1 = 0; - int check2 = 0; - int check3 = 0; + int check[NUMBER_OF_CORES]; char elapsedTimeStrValue[50]; printf("\n========Init========\n\n"); @@ -1054,6 +1141,8 @@ int main() { printf(" Kernel with load/store functions\n\n"); } + memset(check, 0, NUMBER_OF_CORES * sizeof(int)); + init_variavles(); printf("\ninput_A & input_B are filled with random data.\n"); @@ -1076,6 +1165,16 @@ int main() { dump_data((char *)kernel_2, (int)sizeof(kernel_2)); printf("[kernel_3]\n"); dump_data((char *)kernel_3, (int)sizeof(kernel_3)); + if(NUMBER_OF_CORES >= 5) { + g_interrupt_mask = 0x1F; + printf("[kernel_4]\n"); + dump_data((char *)kernel_4, (int)sizeof(kernel_4)); + } + if(NUMBER_OF_CORES >= 6) { + g_interrupt_mask = 0x3F; + printf("[kernel_5]\n"); + dump_data((char *)kernel_5, (int)sizeof(kernel_5)); + } #ifdef _NPU_LOAD_STORE_TEST_MODE_ @@ -1111,40 +1210,74 @@ int main() { printf("\nCompare the results calculated by risc-v and the results calculated by NPUs.\n"); // Check RISCV's Outpus & NPUs's Outputs Are Same, Input RISCV's OP Output Array in 1st Parameter if (TEST_OP_TYPE == "vadd.bf16") { - check0 = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_add, output_npu_0, DATA_SIZE); - check1 = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_add, output_npu_1, DATA_SIZE); - check2 = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_add, output_npu_2, DATA_SIZE); - check3 = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_add, output_npu_3, DATA_SIZE); + check[0] = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_add, output_npu_0, DATA_SIZE); + check[1] = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_add, output_npu_1, DATA_SIZE); + check[2] = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_add, output_npu_2, DATA_SIZE); + check[3] = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_add, output_npu_3, DATA_SIZE); + if(NUMBER_OF_CORES >= 5) { + check[4] = compare_riscv_and_npu(4, TEST_OP_TYPE, output_riscv_add, output_npu_4, DATA_SIZE); + } + if(NUMBER_OF_CORES >= 6) { + check[5] = compare_riscv_and_npu(5, TEST_OP_TYPE, output_riscv_add, output_npu_5, DATA_SIZE); + } } else if (TEST_OP_TYPE == "vsub.bf16") { - check0 = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_sub, output_npu_0, DATA_SIZE); - check1 = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_sub, output_npu_1, DATA_SIZE); - check2 = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_sub, output_npu_2, DATA_SIZE); - check3 = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_sub, output_npu_3, DATA_SIZE); + check[0] = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_sub, output_npu_0, DATA_SIZE); + check[1] = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_sub, output_npu_1, DATA_SIZE); + check[2] = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_sub, output_npu_2, DATA_SIZE); + check[3] = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_sub, output_npu_3, DATA_SIZE); + if(NUMBER_OF_CORES >= 5) { + check[4] = compare_riscv_and_npu(4, TEST_OP_TYPE, output_riscv_sub, output_npu_4, DATA_SIZE); + } + if(NUMBER_OF_CORES >= 6) { + check[5] = compare_riscv_and_npu(5, TEST_OP_TYPE, output_riscv_sub, output_npu_5, DATA_SIZE); + } } else if (TEST_OP_TYPE == "vmul.bf16"){ - check0 = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_mul, output_npu_0, DATA_SIZE); - check1 = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_mul, output_npu_1, DATA_SIZE); - check2 = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_mul, output_npu_2, DATA_SIZE); - check3 = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_mul, output_npu_3, DATA_SIZE); + check[0] = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_mul, output_npu_0, DATA_SIZE); + check[1] = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_mul, output_npu_1, DATA_SIZE); + check[2] = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_mul, output_npu_2, DATA_SIZE); + check[3] = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_mul, output_npu_3, DATA_SIZE); + if(NUMBER_OF_CORES >= 5) { + check[4] = compare_riscv_and_npu(4, TEST_OP_TYPE, output_riscv_mul, output_npu_4, DATA_SIZE); + } + if(NUMBER_OF_CORES >= 6) { + check[5] = compare_riscv_and_npu(5, TEST_OP_TYPE, output_riscv_mul, output_npu_5, DATA_SIZE); + } } else if (TEST_OP_TYPE == "vdiv.bf16") { - check0 = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_div, output_npu_0, DATA_SIZE); - check1 = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_div, output_npu_1, DATA_SIZE); - check2 = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_div, output_npu_2, DATA_SIZE); - check3 = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_div, output_npu_3, DATA_SIZE); + check[0] = compare_riscv_and_npu(0, TEST_OP_TYPE, output_riscv_div, output_npu_0, DATA_SIZE); + check[1] = compare_riscv_and_npu(1, TEST_OP_TYPE, output_riscv_div, output_npu_1, DATA_SIZE); + check[2] = compare_riscv_and_npu(2, TEST_OP_TYPE, output_riscv_div, output_npu_2, DATA_SIZE); + check[3] = compare_riscv_and_npu(3, TEST_OP_TYPE, output_riscv_div, output_npu_3, DATA_SIZE); + if(NUMBER_OF_CORES >= 5) { + check[4] = compare_riscv_and_npu(4, TEST_OP_TYPE, output_riscv_div, output_npu_4, DATA_SIZE); + } + if(NUMBER_OF_CORES >= 6) { + check[5] = compare_riscv_and_npu(5, TEST_OP_TYPE, output_riscv_div, output_npu_5, DATA_SIZE); + } } // If All Pass, Print - if (check0 == DATA_SIZE) { + if (check[0] == DATA_SIZE) { printf("[NPU 0 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } - if (check1 == DATA_SIZE) { + if (check[1] == DATA_SIZE) { printf("[NPU 1 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } - if (check2 == DATA_SIZE) { + if (check[2] == DATA_SIZE) { printf("[NPU 2 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } - if (check3 == DATA_SIZE) { + if (check[3] == DATA_SIZE) { printf("[NPU 3 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); } + if(NUMBER_OF_CORES >= 5) { + if (check[4] == DATA_SIZE) { + printf("[NPU 4 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); + } + } + if(NUMBER_OF_CORES >= 6) { + if (check[5] == DATA_SIZE) { + printf("[NPU 5 Test Case %d] %s All Pass\n", DATA_SIZE, TEST_OP_TYPE); + } + } floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); From 7ab10c6bedb4d05297a3501b797f02d62777940f Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sat, 18 Nov 2023 16:20:10 +0900 Subject: [PATCH 17/26] load/store not ok --- src/testdriver/multi_NPU_RISCV_test.c | 103 ++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index fe1b126..36f9106 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -5,7 +5,7 @@ #include #define MAX_DATA_SIZE 2048 // Data Size -#define DATA_SIZE 1024 // Data Size +#define DATA_SIZE 64 // 1024 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time #define NUMBER_OF_CORES 4 // Number of Cores used at the same time @@ -15,9 +15,9 @@ #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 -#define INPUT_A_SRAM_BASE_ADDRESS 0x80 // 128 // 0x40 // 0x200 -#define INPUT_B_SRAM_BASE_ADDRESS 0x1080 // 128 + 4096 // 0xC0 // 0x1200 -#define RESULT_SRAM_BASE_ADDRESS 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 +#define INPUT_A_SRAM_BASE_ADDRESS 0x00 // 0x80 // 128 // 0x40 // 0x200 +#define INPUT_B_SRAM_BASE_ADDRESS 0x00 //0x1080 // 128 + 4096 // 0xC0 // 0x1200 +#define RESULT_SRAM_BASE_ADDRESS 0x140 // 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 #define NPU_LOAD_STORE_MICRO_DELAY 10000 @@ -26,20 +26,22 @@ #define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 #define EPSILON 0.01 +#define DUMMY_DATA_SIZE 16 + #if 1 -#define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION -#define SRAM_M 4 // 4 // SRAM_ADDR_MAGNIFICATION -#define SIZE_M 16 // 4 // SIZE_MAGNIFICATION +#define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION +#define SRAM_M 1 // 4 // SRAM_ADDR_MAGNIFICATION +#define SIZE_M 16 // 4 // SIZE_MAGNIFICATION #else #define DDR_M 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION #define SIZE_M 4 // SIZE_MAGNIFICATION #endif -#define MAX_LOAD_STORE_CHUNK_SIZE 128 // must be >= 128 +#define MAX_LOAD_STORE_CHUNK_SIZE 128 // 128 // must be >= 128 -//#define _NPU_LOAD_STORE_TEST_MODE_ -//#define __DEBUG_MODE__ +#define _NPU_LOAD_STORE_TEST_MODE_ +#define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ #define trace_pc_position() printf("%s - %d \n", __func__, __LINE__); @@ -74,6 +76,13 @@ __attribute__ ((aligned (64))) volatile BF16 output_riscv_sub[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_mul[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_div[DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_0[DUMMY_DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_1[DUMMY_DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_2[DUMMY_DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_3[DUMMY_DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_4[DUMMY_DATA_SIZE]; +__attribute__ ((aligned (128))) volatile uint8_t dummy_output_5[DUMMY_DATA_SIZE]; + // Kernel: need to align by 8bytes 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // 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 31 32 33 34 35 36 37 38 39 @@ -574,8 +583,8 @@ void init_variavles() { memset(output_npu_1, 0, sizeof(output_npu_1)); memset(output_npu_2, 0, sizeof(output_npu_2)); memset(output_npu_3, 0, sizeof(output_npu_3)); - memset(output_npu_4, 0, sizeof(output_npu_3)); - memset(output_npu_5, 0, sizeof(output_npu_3)); + memset(output_npu_4, 0, sizeof(output_npu_4)); + memset(output_npu_5, 0, sizeof(output_npu_5)); // Random Data Input for (int temp_count = 0; temp_count < DATA_SIZE; temp_count++) { @@ -706,6 +715,44 @@ void dump_data(char * data, int size) { printf("\n\n"); } +void dummy_store() { + + long unsigned int sram_a; + long unsigned int ddr_a; + int remaining; + int loadSize; + int size; + + size = DUMMY_DATA_SIZE; + + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { + remaining = size - len; + loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; + sram_a = 0x00 + len; + + ddr_a = (long unsigned int)dummy_output_0 + len; + store_command_to_npu(0, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)dummy_output_1 + len; + store_command_to_npu(1, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)dummy_output_2 + len; + store_command_to_npu(2, ddr_a, sram_a, loadSize); + ddr_a = (long unsigned int)dummy_output_3 + len; + store_command_to_npu(3, ddr_a, sram_a, loadSize); + if(NUMBER_OF_CORES >= 5) { + ddr_a = (long unsigned int)dummy_output_4 + len; + store_command_to_npu(4, ddr_a, sram_a, loadSize); + } + if(NUMBER_OF_CORES >= 6) { + ddr_a = (long unsigned int)dummy_output_5 + len; + store_command_to_npu(5, ddr_a, sram_a, loadSize); + } + + npu_store(); + + delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); + } +} + void load_kernel_into_npu(int npus) { long unsigned int sram_a; @@ -750,6 +797,7 @@ void load_kernel_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); + dummy_store(); } } @@ -792,6 +840,7 @@ void load_input_A_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); + dummy_store(); } } @@ -834,6 +883,7 @@ void load_input_B_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); + dummy_store(); } } @@ -916,6 +966,14 @@ void store_kernel_into_ddr() { store_command_to_npu(2, ddr_a, sram_a, loadSize); ddr_a = (long unsigned int)output_npu_3 + len; store_command_to_npu(3, ddr_a, sram_a, loadSize); + if(NUMBER_OF_CORES >= 5) { + ddr_a = (long unsigned int)output_npu_4 + len; + store_command_to_npu(4, ddr_a, sram_a, loadSize); + } + if(NUMBER_OF_CORES >= 6) { + ddr_a = (long unsigned int)output_npu_5 + len; + store_command_to_npu(5, ddr_a, sram_a, loadSize); + } npu_store(); @@ -946,6 +1004,14 @@ void store_input_A_into_ddr() { store_command_to_npu(2, ddr_a, sram_a, loadSize); ddr_a = (long unsigned int)output_npu_3 + len; store_command_to_npu(3, ddr_a, sram_a, loadSize); + if(NUMBER_OF_CORES >= 5) { + ddr_a = (long unsigned int)output_npu_4 + len; + store_command_to_npu(4, ddr_a, sram_a, loadSize); + } + if(NUMBER_OF_CORES >= 6) { + ddr_a = (long unsigned int)output_npu_5 + len; + store_command_to_npu(5, ddr_a, sram_a, loadSize); + } npu_store(); @@ -976,6 +1042,14 @@ void store_input_B_into_ddr() { store_command_to_npu(2, ddr_a, sram_a, loadSize); ddr_a = (long unsigned int)output_npu_3 + len; store_command_to_npu(3, ddr_a, sram_a, loadSize); + if(NUMBER_OF_CORES >= 5) { + ddr_a = (long unsigned int)output_npu_4 + len; + store_command_to_npu(4, ddr_a, sram_a, loadSize); + } + if(NUMBER_OF_CORES >= 6) { + ddr_a = (long unsigned int)output_npu_5 + len; + store_command_to_npu(5, ddr_a, sram_a, loadSize); + } npu_store(); @@ -1060,6 +1134,7 @@ void load_store_test(int id) { compare_load_store_data(5, org, npu_ls, (int)sizeof(kernel_5)); } } else if(id == 1) { + size = (int)(sizeof(BF16) * DATA_SIZE); store_input_A_into_ddr(); @@ -1075,6 +1150,7 @@ void load_store_test(int id) { compare_load_store_data(5, org, (char *)output_npu_5, size); } } else if(id == 2) { + size = (int)(sizeof(BF16) * DATA_SIZE); store_input_B_into_ddr(); @@ -1121,6 +1197,7 @@ static uint64_t check_complete_exec(uint64_t start) { } printf("\nsrart: %016x\n", start); printf("end: %016x\n", end); + printf("complete_exec_state: %lx\n", value); return end; } @@ -1180,7 +1257,7 @@ int main() { // load_store_test(0); load_store_test(1); - load_store_test(2); +// load_store_test(2); return 0; #endif From d9ae8b7d66d14fa9b3985e5c22a98e714f552588 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sat, 18 Nov 2023 23:11:20 +0900 Subject: [PATCH 18/26] load store ok --- src/testdriver/multi_NPU_RISCV_test.c | 47 +++++++++++++++++++-------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 36f9106..e7fe9c6 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -5,7 +5,7 @@ #include #define MAX_DATA_SIZE 2048 // Data Size -#define DATA_SIZE 64 // 1024 // Data Size +#define DATA_SIZE 1024 // Data Size #define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time #define NUMBER_OF_CORES 4 // Number of Cores used at the same time @@ -15,15 +15,15 @@ #define KERNEL_WITH_LOAD_STORE 0 #define NPU_REG_ID_OFFSET 3 -#define INPUT_A_SRAM_BASE_ADDRESS 0x00 // 0x80 // 128 // 0x40 // 0x200 -#define INPUT_B_SRAM_BASE_ADDRESS 0x00 //0x1080 // 128 + 4096 // 0xC0 // 0x1200 -#define RESULT_SRAM_BASE_ADDRESS 0x140 // 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 +#define INPUT_A_SRAM_BASE_ADDRESS 0x80 // 128 // 0x40 // 0x200 +#define INPUT_B_SRAM_BASE_ADDRESS 0x1080 // 128 + 4096 // 0xC0 // 0x1200 +#define RESULT_SRAM_BASE_ADDRESS 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 #define NPU_LOAD_STORE_MICRO_DELAY 10000 #define NPU_COMPLETE_EXEC_INTERRUPT 1 #define NPU_COMPLETE_EXEC_REG (NUMBER_OF_CORES * 3 + 1) // 13 -#define NPU_COMPLETE_EXEC_TIMEOUT 5000000.00 +#define NPU_COMPLETE_EXEC_TIMEOUT 10000000.00 #define EPSILON 0.01 #define DUMMY_DATA_SIZE 16 @@ -38,9 +38,9 @@ #define SIZE_M 4 // SIZE_MAGNIFICATION #endif -#define MAX_LOAD_STORE_CHUNK_SIZE 128 // 128 // must be >= 128 +#define MAX_LOAD_STORE_CHUNK_SIZE 128 // must be >= 128 -#define _NPU_LOAD_STORE_TEST_MODE_ +//#define _NPU_LOAD_STORE_TEST_MODE_ #define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ @@ -797,7 +797,7 @@ void load_kernel_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); - dummy_store(); +// dummy_store(); } } @@ -840,7 +840,7 @@ void load_input_A_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); - dummy_store(); +// dummy_store(); } } @@ -883,7 +883,7 @@ void load_input_B_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); - dummy_store(); +// dummy_store(); } } @@ -990,7 +990,7 @@ void store_input_A_into_ddr() { int size; size = (int)(sizeof(BF16) * DATA_SIZE); - + for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { remaining = size - len; loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; @@ -1070,7 +1070,7 @@ void compare_load_store_data(int npu, char *org, char *npu_ls, int size) { npu, idx, org[idx], idx, npu_ls[idx]); mismatch = 1; } -#ifdef __DEBUG_MODE__ +#if 0 // def __DEBUG_MODE__ else { printf("NPU%d Match - origin[%4d]: 0x%02x, output_npu[%4d]: 0x%02x\n", npu, idx, org[idx], idx, npu_ls[idx]); @@ -1172,7 +1172,25 @@ void load_store_test(int id) { static inline void init_complete_exec() { + unsigned long value = 0x0; + printf(">>> %s()\n", __func__); + + npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); + + printf("Before npu_regGet(NPU_COMPLETE_EXEC_REG)\n"); + +#if NPU_COMPLETE_EXEC_INTERRUPT + value = npu_regGet(NPU_COMPLETE_EXEC_REG); +#endif + printf("complete_exec_state: %lx\n", value); + npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x0F); +#if NPU_COMPLETE_EXEC_INTERRUPT + value = npu_regGet(NPU_COMPLETE_EXEC_REG); +#endif + printf("complete_exec_state: %lx\n", value); + npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); + printf("<<< %s()\n", __func__); } static uint64_t check_complete_exec(uint64_t start) { @@ -1255,9 +1273,9 @@ int main() { #ifdef _NPU_LOAD_STORE_TEST_MODE_ -// load_store_test(0); + load_store_test(0); load_store_test(1); -// load_store_test(2); + load_store_test(2); return 0; #endif @@ -1373,3 +1391,4 @@ int main() { return 0; } + From 6713c3de8d36c6a897d675e0a76747902da81980 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sun, 19 Nov 2023 02:00:51 +0900 Subject: [PATCH 19/26] 20231119 2:00 --- src/testdriver/multi_NPU_RISCV_test.c | 203 ++++++++++++++++++-------- 1 file changed, 142 insertions(+), 61 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index e7fe9c6..3e94ac5 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -6,9 +6,10 @@ #define MAX_DATA_SIZE 2048 // Data Size #define DATA_SIZE 1024 // Data Size -#define TEST_OP_TYPE "vadd.bf16" // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" #define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time -#define NUMBER_OF_CORES 4 // Number of Cores used at the same time +#define NUMBER_OF_CORES 6 // Number of Cores used at the same time + +#define LOOP_COUNT 1024 // Number of loop #define SYS_CLK 26000000 // RISC-V: 26MHz 26,000,000 @@ -41,7 +42,7 @@ #define MAX_LOAD_STORE_CHUNK_SIZE 128 // must be >= 128 //#define _NPU_LOAD_STORE_TEST_MODE_ -#define __DEBUG_MODE__ +//#define __DEBUG_MODE__ #ifdef __DEBUG_MODE__ #define trace_pc_position() printf("%s - %d \n", __func__, __LINE__); @@ -164,7 +165,9 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { #endif #endif +uint64_t elapsedCsrrsCycle = 0; unsigned long g_interrupt_mask = 0xF; +char* TEST_OP_TYPE = "vadd.bf16"; // Op Type for Test, Use "vadd.bf16", "vsub.bf16", "vmul.bf16", "vdiv.bf16" static inline void npu_regSet(int idx, unsigned long data) { @@ -330,6 +333,23 @@ static void resize_converted_data_size_kernel(uint8_t* kernel, int size) { #endif } +static void kernel_loop_count_change(uint8_t* kernel, int count) { + + // Seperate Size Bytes Low and High + uint8_t byte_low; + uint8_t byte_high; + + // Devide Size + byte_low = count & 0xff; + byte_high = count >> 8; + +#if KERNEL_WITH_LOAD_STORE // with-load-store +#else + kernel[20] = byte_low; + kernel[21] = byte_high; +#endif +} + static void resize_op_iteration_kernel(uint8_t* kernel, int size) { // Seperate Size Bytes Low and High @@ -564,7 +584,7 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o } } - printf("\n[Test Case %s, NPU%d] FAIL(Equal: %d, Not equal: %d)\n", op, npu, check, error_cnt); + printf("[Test Case %s, NPU%d] Result(matched: %d, unmatched: %d)\n", op, npu, check, error_cnt); return check; } @@ -644,6 +664,13 @@ void adjust_kernel() { resize_op_iteration_kernel(kernel_4, DATA_SIZE); resize_op_iteration_kernel(kernel_5, DATA_SIZE); + kernel_loop_count_change(kernel_0, LOOP_COUNT); + kernel_loop_count_change(kernel_1, LOOP_COUNT); + kernel_loop_count_change(kernel_2, LOOP_COUNT); + kernel_loop_count_change(kernel_3, LOOP_COUNT); + kernel_loop_count_change(kernel_4, LOOP_COUNT); + kernel_loop_count_change(kernel_5, LOOP_COUNT); + // Change Kernel's Opcode kernel_op_change(kernel_0, TEST_OP_TYPE); kernel_op_change(kernel_1, TEST_OP_TYPE); @@ -906,7 +933,7 @@ void load_kernel_data_into_npu() { #if !KERNEL_WITH_LOAD_STORE // without-load-store load_input_A_into_npu(npus); - printf("input_A is stored in all NPUs.\n\n"); + printf("input_A is stored in all NPUs.\n"); load_input_B_into_npu(npus); printf("input_B is stored in all NPUs.\n\n"); @@ -1172,25 +1199,7 @@ void load_store_test(int id) { static inline void init_complete_exec() { - unsigned long value = 0x0; - printf(">>> %s()\n", __func__); - npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); - - printf("Before npu_regGet(NPU_COMPLETE_EXEC_REG)\n"); - -#if NPU_COMPLETE_EXEC_INTERRUPT - value = npu_regGet(NPU_COMPLETE_EXEC_REG); -#endif - printf("complete_exec_state: %lx\n", value); - npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x0F); -#if NPU_COMPLETE_EXEC_INTERRUPT - value = npu_regGet(NPU_COMPLETE_EXEC_REG); -#endif - printf("complete_exec_state: %lx\n", value); - - npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); - printf("<<< %s()\n", __func__); } static uint64_t check_complete_exec(uint64_t start) { @@ -1203,7 +1212,8 @@ static uint64_t check_complete_exec(uint64_t start) { value = npu_regGet(NPU_COMPLETE_EXEC_REG); #endif - while(((value & g_interrupt_mask) != g_interrupt_mask) && + //while(((value & g_interrupt_mask) != g_interrupt_mask) && + while(((value) == 0) && ((float)((end - start) / (SYS_CLK / 1000000)) < NPU_COMPLETE_EXEC_TIMEOUT)) { end = get_time(); #if NPU_COMPLETE_EXEC_INTERRUPT @@ -1220,38 +1230,38 @@ static uint64_t check_complete_exec(uint64_t start) { return end; } -int main() { +void get_average_csrrs_cycle() { + + uint64_t cycle_start; + uint64_t cycle_end; + + cycle_start = get_time(); + for(int count = 0; count < 10; count++) { + cycle_end = get_time(); + } + elapsedCsrrsCycle = (cycle_end - cycle_start ) / 10; + printf("elapsedCsrrsCycle: 0x%lx\n", elapsedCsrrsCycle); +} + +int main_function() { uint64_t cycle_start; uint64_t cycle_end; int check[NUMBER_OF_CORES]; char elapsedTimeStrValue[50]; + uint64_t elapsedCycle; + uint64_t flops; + float MFLOPS; + char megaFlopsStrValue[50]; - printf("\n========Init========\n\n"); - printf("Multi NAU Test\n"); - printf("[%s Test] Using %d Cores\n", TEST_OP_TYPE, NUMBER_OF_CORES); - if(KERNEL_WITH_LOAD_STORE == 0) { - printf(" Kernel without load/store functions\n\n"); - } else { - printf(" Kernel with load/store functions\n\n"); - } + printf("\n\n[%s Test] Using %d Cores\n", TEST_OP_TYPE, NUMBER_OF_CORES); memset(check, 0, NUMBER_OF_CORES * sizeof(int)); - init_variavles(); - printf("\ninput_A & input_B are filled with random data.\n"); - - printf("[input_A]\n"); - dump_data((char *)input_A, (int)(sizeof(BF16) * DATA_SIZE)); - printf("[input_B]\n"); - dump_data((char *)input_B, (int)(sizeof(BF16) * DATA_SIZE)); - - riscv_calculate_result(); - printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); - adjust_kernel(); - printf("\nKernel images for each NPU have been prepared.\n\n"); + printf("\nKernel images for each NPU have been prepared.\n"); +#ifdef __DEBUG_MODE__ printf("[kernel_0]\n"); dump_data((char *)kernel_0, (int)sizeof(kernel_0)); printf("[kernel_1]\n"); @@ -1270,14 +1280,6 @@ int main() { printf("[kernel_5]\n"); dump_data((char *)kernel_5, (int)sizeof(kernel_5)); } - -#ifdef _NPU_LOAD_STORE_TEST_MODE_ - - load_store_test(0); - load_store_test(1); - load_store_test(2); - - return 0; #endif load_kernel_data_into_npu(); @@ -1302,6 +1304,25 @@ int main() { printf("The calculated result values were loaded into external memory.\n\n"); #endif +#ifdef __DEBUG_MODE__ + printf("[output_npu_0]\n"); + dump_data((char *)output_npu_0, (int)(sizeof(BF16) * DATA_SIZE)); + printf("[output_npu_1]\n"); + dump_data((char *)output_npu_1, (int)(sizeof(BF16) * DATA_SIZE)); + printf("[output_npu_2]\n"); + dump_data((char *)output_npu_2, (int)(sizeof(BF16) * DATA_SIZE)); + printf("[output_npu_3]\n"); + dump_data((char *)output_npu_3, (int)(sizeof(BF16) * DATA_SIZE)); + if(NUMBER_OF_CORES >= 5) { + printf("[output_npu_4]\n"); + dump_data((char *)output_npu_4, (int)(sizeof(BF16) * DATA_SIZE)); + } + if(NUMBER_OF_CORES >= 6) { + printf("[output_npu_5]\n"); + dump_data((char *)output_npu_5, (int)(sizeof(BF16) * DATA_SIZE)); + } +#endif + printf("\nCompare the results calculated by risc-v and the results calculated by NPUs.\n"); // Check RISCV's Outpus & NPUs's Outputs Are Same, Input RISCV's OP Output Array in 1st Parameter if (TEST_OP_TYPE == "vadd.bf16") { @@ -1349,6 +1370,7 @@ int main() { check[5] = compare_riscv_and_npu(5, TEST_OP_TYPE, output_riscv_div, output_npu_5, DATA_SIZE); } } + printf("\n"); // If All Pass, Print if (check[0] == DATA_SIZE) { @@ -1374,21 +1396,80 @@ int main() { } } - floatToString((cycle_end - cycle_start) / (SYS_CLK / 1000000), + // 1 cycle = 25ns + elapsedCycle = cycle_end - cycle_start - elapsedCsrrsCycle; + +#ifdef __DEBUG_MODE__ + floatToString(elapsedCycle / (SYS_CLK / 1000000), elapsedTimeStrValue, sizeof(elapsedTimeStrValue)); printf("\nRISC-V Time: %s us.\n", elapsedTimeStrValue); +#endif + + flops = NUMBER_OF_CORES * DATA_SIZE * LOOP_COUNT; + + printf("flops: %ld, elapsedCycle: %ld(1 cycle = 25ns)\n", flops, elapsedCycle); + MFLOPS = (flops * 1000) / (elapsedCycle * 25); + floatToString(MFLOPS, megaFlopsStrValue, sizeof(megaFlopsStrValue)); + printf(" = %s MFLOPS.\n\n", megaFlopsStrValue); + + return 0; +} + +int main() { + + uint64_t cycle_start; + uint64_t cycle_end; + int check[NUMBER_OF_CORES]; + char elapsedTimeStrValue[50]; + + printf("\n========Init========\n\n"); + printf("Multi NAU Test\n"); + if(KERNEL_WITH_LOAD_STORE == 0) { + printf(" Kernel without load/store functions\n\n"); + } else { + printf(" Kernel with load/store functions\n\n"); + } + + memset(check, 0, NUMBER_OF_CORES * sizeof(int)); + + init_variavles(); + printf("\ninput_A & input_B are filled with random data.\n"); -#if 0 - // Test Case N's Total Cycles, NPU: 125MHz - printf("[#0 NPU] Total cycles: %d\tConvert Times: %.3fus\n", npu_base[4 + 0], npu_base[4 + 0] * 8.00 / 1000.00); - printf("[#1 NPU] Total cycles: %d\tConvert Times: %.3fus\n", npu_base[4 + 1], npu_base[4 + 1] * 8.00 / 1000.00); - printf("[#2 NPU] Total cycles: %d\tConvert Times: %.3fus\n", npu_base[4 + 2], npu_base[4 + 2] * 8.00 / 1000.00); - printf("[#3 NPU] Total cycles: %d\tConvert Times: %.3fus\n", npu_base[4 + 3], npu_base[4 + 3] * 8.00 / 1000.00); +#ifdef __DEBUG_MODE__ + printf("[input_A]\n"); + dump_data((char *)input_A, (int)(sizeof(BF16) * DATA_SIZE)); + printf("[input_B]\n"); + dump_data((char *)input_B, (int)(sizeof(BF16) * DATA_SIZE)); #endif + riscv_calculate_result(); + printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); + +#ifdef _NPU_LOAD_STORE_TEST_MODE_ + + load_store_test(0); + load_store_test(1); + load_store_test(2); + + return 0; +#endif + + get_average_csrrs_cycle(); + + TEST_OP_TYPE = "vadd.bf16"; + main_function(); + + TEST_OP_TYPE = "vsub.bf16"; + main_function(); + + TEST_OP_TYPE = "vmul.bf16"; + main_function(); + + TEST_OP_TYPE = "vdiv.bf16"; + main_function(); + printf("\n========Finish========\n\n"); return 0; } - From a0a36a243e6b976940dcc2116c55fb9548c5d71e Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sun, 19 Nov 2023 08:26:51 +0900 Subject: [PATCH 20/26] interrupt flags --- src/testdriver/multi_NPU_RISCV_test.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index 3e94ac5..b49e81d 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -1212,8 +1212,8 @@ static uint64_t check_complete_exec(uint64_t start) { value = npu_regGet(NPU_COMPLETE_EXEC_REG); #endif - //while(((value & g_interrupt_mask) != g_interrupt_mask) && - while(((value) == 0) && + while(((value & g_interrupt_mask) != g_interrupt_mask) && + //while(((value) == 0) && ((float)((end - start) / (SYS_CLK / 1000000)) < NPU_COMPLETE_EXEC_TIMEOUT)) { end = get_time(); #if NPU_COMPLETE_EXEC_INTERRUPT @@ -1455,6 +1455,13 @@ int main() { return 0; #endif + if(NUMBER_OF_CORES >= 5) { + g_interrupt_mask = 0x1F; + } + if(NUMBER_OF_CORES >= 6) { + g_interrupt_mask = 0x3F; + } + get_average_csrrs_cycle(); TEST_OP_TYPE = "vadd.bf16"; From b9aac9f926213be10f98b25bcce0622915660776 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sun, 19 Nov 2023 18:33:18 +0900 Subject: [PATCH 21/26] 20231119 18:33 --- src/testdriver/multi_NPU_RISCV_test.c | 131 ++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 8 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index b49e81d..bb6cfe3 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -4,8 +4,8 @@ #include #include -#define MAX_DATA_SIZE 2048 // Data Size -#define DATA_SIZE 1024 // Data Size +#define MAX_DATA_SIZE 512 // Data Size +#define DATA_SIZE 64 // Data Size #define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time #define NUMBER_OF_CORES 6 // Number of Cores used at the same time @@ -17,13 +17,14 @@ #define NPU_REG_ID_OFFSET 3 #define INPUT_A_SRAM_BASE_ADDRESS 0x80 // 128 // 0x40 // 0x200 -#define INPUT_B_SRAM_BASE_ADDRESS 0x1080 // 128 + 4096 // 0xC0 // 0x1200 -#define RESULT_SRAM_BASE_ADDRESS 0x2080 // 128 + 4096 * 2 // 0x140 // 0x2200 +#define INPUT_B_SRAM_BASE_ADDRESS (INPUT_A_SRAM_BASE_ADDRESS + MAX_DATA_SIZE * 2) // 0x480 128 + 1024 // 0xC0 // 0x1200 +#define RESULT_SRAM_BASE_ADDRESS (INPUT_A_SRAM_BASE_ADDRESS + MAX_DATA_SIZE * 2 * 2) // 0x880 128 + 1024 * 2 *2 // 0x140 // 0x2200 #define NPU_LOAD_STORE_MICRO_DELAY 10000 #define NPU_COMPLETE_EXEC_INTERRUPT 1 -#define NPU_COMPLETE_EXEC_REG (NUMBER_OF_CORES * 3 + 1) // 13 +#define NPU_COMPLETE_EXEC_REG (NUMBER_OF_CORES * 3 + 1) // 19 +#define NPU_COMPLETE_INTERRUPT_RST (NPU_COMPLETE_EXEC_REG + 1) // 20 #define NPU_COMPLETE_EXEC_TIMEOUT 10000000.00 #define EPSILON 0.01 @@ -246,8 +247,39 @@ void delay_in_usec(int us) { } } +BF16 swap_bf16_bytes(BF16 value) { +#if 1 + BF16 swap_value; + char *origin; + char *swap; + + origin = &value; + swap = &swap_value; + swap[0] = origin[1]; + swap[1] = origin[0]; + + return swap_value; +#else + return value; +#endif +} + BF16 float_to_bf16(float value) { + uint32_t f32_value_as_uint32; + uint16_t bf16_value; + + // Assuming little-endian architecture + memcpy(&f32_value_as_uint32, &value, sizeof(float)); + + // Extract the 16 most significant bits + bf16_value = (uint16_t)(f32_value_as_uint32 >> 16); + + BF16 bf16_result; + memcpy(&bf16_result, &bf16_value, sizeof(BF16)); + + return swap_bf16_bytes(bf16_result); +#if 0 FloatUnion fu; fu.f = value; BF16 bf16; @@ -268,10 +300,27 @@ BF16 float_to_bf16(float value) { } return bf16; +#endif } float bf16_to_float(BF16 bf16) { +#if 1 + BF16 swap_bf16; + uint32_t f32_value_as_uint32; + uint16_t zero_padding = 0; + + swap_bf16 = swap_bf16_bytes(bf16); + + // Assuming little-endian architecture + memcpy(&f32_value_as_uint32, &zero_padding, sizeof(uint16_t)); + memcpy(((uint8_t*)&f32_value_as_uint32) + sizeof(uint16_t), &swap_bf16, sizeof(uint16_t)); + + float f32_result; + memcpy(&f32_result, &f32_value_as_uint32, sizeof(float)); + + return f32_result; +#else FloatUnion fu; int biased_exponent; @@ -287,6 +336,7 @@ float bf16_to_float(BF16 bf16) { } return fu.f; +#endif } BF16 bf16_add(BF16 a, BF16 b) { @@ -569,18 +619,42 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o } if (diff > EPSILON) { error_cnt += 1; -#ifdef __DEBUG_MODE__ +#if 1 // def __DEBUG_MODE__ memset(riscvStrValue, 0, 50); memset(npuStrValue, 0, 50); memset(diffStrValue, 0, 50); floatToString(out_risc_flt, riscvStrValue, sizeof(riscvStrValue)); floatToString(out_npu_flt, npuStrValue, sizeof(npuStrValue)); floatToString(out_risc_flt - out_npu_flt, diffStrValue, sizeof(diffStrValue)); +#if 0 printf("[Test Case %d] %s - FAIL\nRISCV data[%d]: %s\nNPU%d data[%d]: %s\nRISCV data[%d] - NPU data[%d] = %s\n", count, op, i, riscvStrValue, npu, i, npuStrValue, i, i, diffStrValue); +#endif + char * r_data; + char * n_data; + char * a_data; + char * b_data; + a_data = (char *)&input_A[i]; + b_data = (char *)&input_B[i]; + r_data = (char *)&out_risc_bf16[i]; + n_data = (char *)&out_npu_bf16[i]; + printf("%s[%d/%d] - FAIL, A 0x%02x%02x B 0x%02x%02x = RISC-V 0x%02x%02x - NPU 0x%02x%02x\n", + op, i, count, a_data[1], a_data[0], b_data[1], b_data[0], r_data[1], r_data[0], n_data[1], n_data[0]); #endif } else { check += 1; +#if 1 + char * r_data; + char * n_data; + char * a_data; + char * b_data; + a_data = (char *)&input_A[i]; + b_data = (char *)&input_B[i]; + r_data = (char *)&out_risc_bf16[i]; + n_data = (char *)&out_npu_bf16[i]; + printf("%s[%d/%d] - SUCCESS, A 0x%02x%02x B 0x%02x%02x = RISC-V 0x%02x%02x - NPU 0x%02x%02x\n", + op, i, count, a_data[1], a_data[0], b_data[1], b_data[0], r_data[1], r_data[0], n_data[1], n_data[0]); +#endif } } @@ -608,11 +682,27 @@ void init_variavles() { // Random Data Input for (int temp_count = 0; temp_count < DATA_SIZE; temp_count++) { - f_val_A = (float)rand() / RAND_MAX * 2000.0 - 1000.0; - f_val_B = (float)rand() / RAND_MAX * 2000.0 - 1000.0; + +#if 0 +//host.data[0x200000] = jnp.array([(v + 1) * 1.1 for v in range(2048)], dtype=jnp.bfloat16).tobytes() +//host.data[0x201000] = jnp.array([(v + 1) * 0.1 for v in range(2048)], dtype=jnp.bfloat16).tobytes() + uint16_t a_val; + uint16_t b_val; + + a_val = (temp_count + 1) * 1.1; + b_val = (temp_count + 1) * 0.1; + + memcpy(&input_A[temp_count], &a_val, sizeof(uint16_t)); + memcpy(&input_B[temp_count], &b_val, sizeof(uint16_t)); +#else + //f_val_A = (temp_count + 1) * 1.1; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; + //f_val_B = (temp_count + 1) * 0.1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; + f_val_A = 2; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; + f_val_B = 1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; input_A[temp_count] = float_to_bf16(f_val_A); input_B[temp_count] = float_to_bf16(f_val_B); +#endif } } @@ -963,6 +1053,14 @@ void store_result_into_ddr() { store_command_to_npu(2, ddr_a, sram_a, loadSize); ddr_a = (long unsigned int)output_npu_3 + len; store_command_to_npu(3, ddr_a, sram_a, loadSize); + if(NUMBER_OF_CORES >= 5) { + ddr_a = (long unsigned int)output_npu_4 + len; + store_command_to_npu(4, ddr_a, sram_a, loadSize); + } + if(NUMBER_OF_CORES >= 6) { + ddr_a = (long unsigned int)output_npu_5 + len; + store_command_to_npu(5, ddr_a, sram_a, loadSize); + } npu_store(); @@ -1199,7 +1297,16 @@ void load_store_test(int id) { static inline void init_complete_exec() { + unsigned long value = 0x0; + + npu_regSet(NPU_COMPLETE_INTERRUPT_RST, (long unsigned int)0x01); // reset - active high npu_regSet(NPU_COMPLETE_EXEC_REG, (long unsigned int)0x00); + npu_regSet(NPU_COMPLETE_INTERRUPT_RST, (long unsigned int)0x00); + + value = npu_regGet(NPU_COMPLETE_EXEC_REG); + if(value != 0) { + printf("%s - Fail, value: %lx\r", value); + } } static uint64_t check_complete_exec(uint64_t start) { @@ -1464,17 +1571,25 @@ int main() { get_average_csrrs_cycle(); +#if 1 TEST_OP_TYPE = "vadd.bf16"; main_function(); +#endif +#if 0 TEST_OP_TYPE = "vsub.bf16"; main_function(); +#endif +#if 0 TEST_OP_TYPE = "vmul.bf16"; main_function(); +#endif +#if 0 TEST_OP_TYPE = "vdiv.bf16"; main_function(); +#endif printf("\n========Finish========\n\n"); From 3a2480c38c9fb3d65bc69580f4b5fb7de276edcc Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Sun, 19 Nov 2023 21:22:50 +0900 Subject: [PATCH 22/26] 20231119 21:22 --- src/testdriver/multi_NPU_RISCV_test.c | 78 ++++++++++++--------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index bb6cfe3..86e9001 100644 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -5,7 +5,7 @@ #include #define MAX_DATA_SIZE 512 // Data Size -#define DATA_SIZE 64 // Data Size +#define DATA_SIZE 512 // Data Size #define MAX_NUMBER_OF_CORES 6 // Max. Number of Cores used at the same time #define NUMBER_OF_CORES 6 // Number of Cores used at the same time @@ -70,8 +70,8 @@ __attribute__ ((aligned (128))) volatile BF16 output_npu_0[DATA_SIZE]; // NPU 0 __attribute__ ((aligned (128))) volatile BF16 output_npu_1[DATA_SIZE]; // NPU 1 Output __attribute__ ((aligned (128))) volatile BF16 output_npu_2[DATA_SIZE]; // NPU 2 Output __attribute__ ((aligned (128))) volatile BF16 output_npu_3[DATA_SIZE]; // NPU 3 Output -__attribute__ ((aligned (128))) volatile BF16 output_npu_4[DATA_SIZE]; // NPU 3 Output -__attribute__ ((aligned (128))) volatile BF16 output_npu_5[DATA_SIZE]; // NPU 3 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_4[DATA_SIZE]; // NPU 4 Output +__attribute__ ((aligned (128))) volatile BF16 output_npu_5[DATA_SIZE]; // NPU 5 Output __attribute__ ((aligned (64))) volatile BF16 output_riscv_add[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_sub[DATA_SIZE]; @@ -202,27 +202,17 @@ static inline void npu_store() /* riscv issues store command to npu */ static void load_command_to_npu(int npu, long unsigned int l_addr, long unsigned int r_addr, int size) { -// printf("%s(%d, 0x%lx, 0x%lx, %d)\n", __func__, npu, l_addr, r_addr, size); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); -// trace_pc_position() } /* riscv issues store command to npu */ static void store_command_to_npu(int npu, long unsigned int r_addr, long unsigned int l_addr, int size) { -// printf("%s(%d, 0x%lx, 0x%lx, %d)\n", __func__, npu, r_addr, l_addr, size); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 1), (long unsigned int)((r_addr + DDR_M - 1) / DDR_M)); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 2), (int)((size + SIZE_M - 1) / SIZE_M)); -// trace_pc_position() npu_regSet((npu * NPU_REG_ID_OFFSET + 3), (long unsigned int)((l_addr + SRAM_M - 1) / SRAM_M)); -// trace_pc_position() } static inline uint64_t get_time() { @@ -697,8 +687,8 @@ void init_variavles() { #else //f_val_A = (temp_count + 1) * 1.1; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; //f_val_B = (temp_count + 1) * 0.1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; - f_val_A = 2; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; - f_val_B = 1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; + f_val_A = (float)rand() / RAND_MAX * 2000.0 - 1000.0; + f_val_B = (float)rand() / RAND_MAX * 2000.0 - 1000.0; input_A[temp_count] = float_to_bf16(f_val_A); input_B[temp_count] = float_to_bf16(f_val_B); @@ -769,26 +759,26 @@ void adjust_kernel() { kernel_op_change(kernel_4, TEST_OP_TYPE); kernel_op_change(kernel_5, TEST_OP_TYPE); - kernel_input_a_sram_addr_change(kernel_0, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - kernel_input_a_sram_addr_change(kernel_1, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - kernel_input_a_sram_addr_change(kernel_2, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - kernel_input_a_sram_addr_change(kernel_3, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - kernel_input_a_sram_addr_change(kernel_4, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - kernel_input_a_sram_addr_change(kernel_5, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 4)); - - kernel_input_b_sram_addr_change(kernel_0, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - kernel_input_b_sram_addr_change(kernel_1, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - kernel_input_b_sram_addr_change(kernel_2, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - kernel_input_b_sram_addr_change(kernel_3, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - kernel_input_b_sram_addr_change(kernel_4, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - kernel_input_b_sram_addr_change(kernel_5, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 4)); - - kernel_output_c_sram_addr_change(kernel_0, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); - kernel_output_c_sram_addr_change(kernel_1, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); - kernel_output_c_sram_addr_change(kernel_2, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); - kernel_output_c_sram_addr_change(kernel_3, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); - kernel_output_c_sram_addr_change(kernel_4, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); - kernel_output_c_sram_addr_change(kernel_5, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 4)); + kernel_input_a_sram_addr_change(kernel_0, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + kernel_input_a_sram_addr_change(kernel_1, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + kernel_input_a_sram_addr_change(kernel_2, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + kernel_input_a_sram_addr_change(kernel_3, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + kernel_input_a_sram_addr_change(kernel_4, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + kernel_input_a_sram_addr_change(kernel_5, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + + kernel_input_b_sram_addr_change(kernel_0, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + kernel_input_b_sram_addr_change(kernel_1, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + kernel_input_b_sram_addr_change(kernel_2, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + kernel_input_b_sram_addr_change(kernel_3, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + kernel_input_b_sram_addr_change(kernel_4, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + kernel_input_b_sram_addr_change(kernel_5, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + + kernel_output_c_sram_addr_change(kernel_0, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + kernel_output_c_sram_addr_change(kernel_1, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + kernel_output_c_sram_addr_change(kernel_2, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + kernel_output_c_sram_addr_change(kernel_3, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + kernel_output_c_sram_addr_change(kernel_4, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + kernel_output_c_sram_addr_change(kernel_5, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); #if KERNEL_WITH_LOAD_STORE // with-load-store // Change Kernel's input_A address @@ -1553,15 +1543,6 @@ int main() { riscv_calculate_result(); printf("\nThe result values of risc-v for each function were calculated using input_A & input_B.\n"); -#ifdef _NPU_LOAD_STORE_TEST_MODE_ - - load_store_test(0); - load_store_test(1); - load_store_test(2); - - return 0; -#endif - if(NUMBER_OF_CORES >= 5) { g_interrupt_mask = 0x1F; } @@ -1571,6 +1552,15 @@ int main() { get_average_csrrs_cycle(); +#ifdef _NPU_LOAD_STORE_TEST_MODE_ + + load_store_test(0); + load_store_test(1); + load_store_test(2); + + return 0; +#endif + #if 1 TEST_OP_TYPE = "vadd.bf16"; main_function(); From 6fa3e6952da4cb826a7ab280b4bc5b30e103c076 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Mon, 20 Nov 2023 02:39:15 +0900 Subject: [PATCH 23/26] 20231120 02:38 kim byunggil --- src/testdriver/multi_NPU_RISCV_test.c | 68 ++++++++++++++------------- 1 file changed, 36 insertions(+), 32 deletions(-) mode change 100644 => 100755 src/testdriver/multi_NPU_RISCV_test.c diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c old mode 100644 new mode 100755 index 86e9001..cba31f2 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -133,22 +133,22 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { // Without load/store, vadd.bf16 #if 1 // ifneq %e %f -12 __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; __attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; __attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; __attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; __attribute__ ((aligned (128))) volatile uint8_t kernel_4[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; __attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, + 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; #else __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { @@ -268,7 +268,8 @@ BF16 float_to_bf16(float value) { BF16 bf16_result; memcpy(&bf16_result, &bf16_value, sizeof(BF16)); - return swap_bf16_bytes(bf16_result); + // return swap_bf16_bytes(bf16_result); + return bf16_result; #if 0 FloatUnion fu; fu.f = value; @@ -301,6 +302,7 @@ float bf16_to_float(BF16 bf16) { uint16_t zero_padding = 0; swap_bf16 = swap_bf16_bytes(bf16); + swap_bf16 = bf16; // Assuming little-endian architecture memcpy(&f32_value_as_uint32, &zero_padding, sizeof(uint16_t)); @@ -633,7 +635,7 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o #endif } else { check += 1; -#if 1 +#if 0 char * r_data; char * n_data; char * a_data; @@ -685,10 +687,12 @@ void init_variavles() { memcpy(&input_A[temp_count], &a_val, sizeof(uint16_t)); memcpy(&input_B[temp_count], &b_val, sizeof(uint16_t)); #else - //f_val_A = (temp_count + 1) * 1.1; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; - //f_val_B = (temp_count + 1) * 0.1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; + // f_val_A = (temp_count + 1) * 1.1; // (float)rand() / RAND_MAX * 2000.0 - 1000.0; + // f_val_B = (temp_count + 1) * 0.1; //(float)rand() / RAND_MAX * 2000.0 - 1000.0; f_val_A = (float)rand() / RAND_MAX * 2000.0 - 1000.0; f_val_B = (float)rand() / RAND_MAX * 2000.0 - 1000.0; + // f_val_A = (float)rand() / (float)(RAND_MAX ) * 5.0f; + // f_val_B = (float)rand() / (float)(RAND_MAX ) * 5.0f; input_A[temp_count] = float_to_bf16(f_val_A); input_B[temp_count] = float_to_bf16(f_val_B); @@ -759,26 +763,26 @@ void adjust_kernel() { kernel_op_change(kernel_4, TEST_OP_TYPE); kernel_op_change(kernel_5, TEST_OP_TYPE); - kernel_input_a_sram_addr_change(kernel_0, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - kernel_input_a_sram_addr_change(kernel_1, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - kernel_input_a_sram_addr_change(kernel_2, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - kernel_input_a_sram_addr_change(kernel_3, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - kernel_input_a_sram_addr_change(kernel_4, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - kernel_input_a_sram_addr_change(kernel_5, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); - - kernel_input_b_sram_addr_change(kernel_0, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - kernel_input_b_sram_addr_change(kernel_1, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - kernel_input_b_sram_addr_change(kernel_2, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - kernel_input_b_sram_addr_change(kernel_3, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - kernel_input_b_sram_addr_change(kernel_4, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - kernel_input_b_sram_addr_change(kernel_5, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); - - kernel_output_c_sram_addr_change(kernel_0, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); - kernel_output_c_sram_addr_change(kernel_1, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); - kernel_output_c_sram_addr_change(kernel_2, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); - kernel_output_c_sram_addr_change(kernel_3, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); - kernel_output_c_sram_addr_change(kernel_4, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); - kernel_output_c_sram_addr_change(kernel_5, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_0, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_1, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_2, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_3, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_4, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + // kernel_input_a_sram_addr_change(kernel_5, (unsigned long )(INPUT_A_SRAM_BASE_ADDRESS / 1)); + + // kernel_input_b_sram_addr_change(kernel_0, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + // kernel_input_b_sram_addr_change(kernel_1, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + // kernel_input_b_sram_addr_change(kernel_2, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + // kernel_input_b_sram_addr_change(kernel_3, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + // kernel_input_b_sram_addr_change(kernel_4, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + // kernel_input_b_sram_addr_change(kernel_5, (unsigned long )(INPUT_B_SRAM_BASE_ADDRESS / 1)); + + // kernel_output_c_sram_addr_change(kernel_0, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_output_c_sram_addr_change(kernel_1, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_output_c_sram_addr_change(kernel_2, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_output_c_sram_addr_change(kernel_3, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_output_c_sram_addr_change(kernel_4, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); + // kernel_output_c_sram_addr_change(kernel_5, (unsigned long )(RESULT_SRAM_BASE_ADDRESS / 1)); #if KERNEL_WITH_LOAD_STORE // with-load-store // Change Kernel's input_A address @@ -1561,7 +1565,7 @@ int main() { return 0; #endif -#if 1 +#if 0 TEST_OP_TYPE = "vadd.bf16"; main_function(); #endif @@ -1576,7 +1580,7 @@ int main() { main_function(); #endif -#if 0 +#if 1 TEST_OP_TYPE = "vdiv.bf16"; main_function(); #endif From aa725847fdecdd46219b994773eabca711982060 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Mon, 20 Nov 2023 08:55:05 +0900 Subject: [PATCH 24/26] 20231120 08:55 --- src/testdriver/multi_NPU_RISCV_test.c | 172 ++++++-------------------- 1 file changed, 37 insertions(+), 135 deletions(-) diff --git a/src/testdriver/multi_NPU_RISCV_test.c b/src/testdriver/multi_NPU_RISCV_test.c index cba31f2..fc5dc67 100755 --- a/src/testdriver/multi_NPU_RISCV_test.c +++ b/src/testdriver/multi_NPU_RISCV_test.c @@ -28,17 +28,9 @@ #define NPU_COMPLETE_EXEC_TIMEOUT 10000000.00 #define EPSILON 0.01 -#define DUMMY_DATA_SIZE 16 - -#if 1 #define DDR_M 1 // 128 // DDR_ADDR_MAGNIFICATION #define SRAM_M 1 // 4 // SRAM_ADDR_MAGNIFICATION #define SIZE_M 16 // 4 // SIZE_MAGNIFICATION -#else -#define DDR_M 128 // DDR_ADDR_MAGNIFICATION -#define SRAM_M 4 // SRAM_ADDR_MAGNIFICATION -#define SIZE_M 4 // SIZE_MAGNIFICATION -#endif #define MAX_LOAD_STORE_CHUNK_SIZE 128 // must be >= 128 @@ -51,11 +43,6 @@ #define trace_pc_position() #endif -typedef union { - float f; - uint32_t i; -} FloatUnion; - typedef struct { uint16_t mantissa : 7; uint16_t exponent : 8; @@ -78,14 +65,7 @@ __attribute__ ((aligned (64))) volatile BF16 output_riscv_sub[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_mul[DATA_SIZE]; __attribute__ ((aligned (64))) volatile BF16 output_riscv_div[DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_0[DUMMY_DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_1[DUMMY_DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_2[DUMMY_DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_3[DUMMY_DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_4[DUMMY_DATA_SIZE]; -__attribute__ ((aligned (128))) volatile uint8_t dummy_output_5[DUMMY_DATA_SIZE]; - - // Kernel: need to align by 8bytes 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + // Kernel: need to align by 8bytes 0 1 2 3 4 5 6 7 8 9 // 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 31 32 33 34 35 36 37 38 39 // 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 @@ -131,7 +111,6 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; #else // Without load/store, vadd.bf16 -#if 1 // ifneq %e %f -12 __attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; @@ -150,20 +129,6 @@ __attribute__ ((aligned (128))) volatile uint8_t kernel_4[] = { __attribute__ ((aligned (128))) volatile uint8_t kernel_5[] = { 0x80, 0x04, 0x20, 0x02, 0x80, 0x00, 0x10, 0x02, 0x20, 0x00, 0x40, 0x02, 0x80, 0x08, 0x30, 0x02, 0x00, 0x00, 0x60, 0x02, 0x00, 0x04, 0x50, 0x02, 0x01, 0x00, 0x60, 0x0d, 0x00, 0x24, 0x31, 0x09, 0x00, 0x00, 0x00, 0xff, 0xf8, 0xff, 0x56, 0x11}; -#else -__attribute__ ((aligned (128))) volatile uint8_t kernel_0[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x24, 0x31, 0x09}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_1[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x24, 0x31, 0x09}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_2[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x24, 0x31, 0x09}; -__attribute__ ((aligned (128))) volatile uint8_t kernel_3[] = { - 0x20, 0x04, 0x20, 0x02, 0x20, 0x00, 0x10, 0x02, 0x00, 0x08, 0x40, 0x02, 0x20, 0x08, 0x30, 0x02, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x24, 0x31, 0x09}; -#endif #endif uint64_t elapsedCsrrsCycle = 0; @@ -238,7 +203,7 @@ void delay_in_usec(int us) { } BF16 swap_bf16_bytes(BF16 value) { -#if 1 + BF16 swap_value; char *origin; char *swap; @@ -249,9 +214,6 @@ BF16 swap_bf16_bytes(BF16 value) { swap[1] = origin[0]; return swap_value; -#else - return value; -#endif } BF16 float_to_bf16(float value) { @@ -270,33 +232,10 @@ BF16 float_to_bf16(float value) { // return swap_bf16_bytes(bf16_result); return bf16_result; -#if 0 - FloatUnion fu; - fu.f = value; - BF16 bf16; - - // Extract the sign bit. - bf16.sign = (fu.i >> 31) & 0x1; - - // Extract the biased exponent (8 bits). - int biased_exponent = (fu.i >> 23) & 0xFF; - - if (biased_exponent == 0) { - bf16.exponent = 0; - bf16.mantissa = (fu.i >> 16) & 0x7F; - } else { - bf16.exponent = biased_exponent - 127; - - bf16.mantissa = (fu.i >> 16) & 0x7F; - } - - return bf16; -#endif } float bf16_to_float(BF16 bf16) { -#if 1 BF16 swap_bf16; uint32_t f32_value_as_uint32; uint16_t zero_padding = 0; @@ -312,23 +251,6 @@ float bf16_to_float(BF16 bf16) { memcpy(&f32_result, &f32_value_as_uint32, sizeof(float)); return f32_result; -#else - FloatUnion fu; - int biased_exponent; - - fu.i = (bf16.sign << 31); - - if (bf16.exponent == 0) { - fu.i |= ((bf16.mantissa & 0x7F) << 16); - } else { - biased_exponent = bf16.exponent + 127; - fu.i |= (biased_exponent << 23); - - fu.i |= ((bf16.mantissa & 0x7F) << 16); - } - - return fu.f; -#endif } BF16 bf16_add(BF16 a, BF16 b) { @@ -589,6 +511,36 @@ static void floatToString(float floatValue, char* strValue, int maxLength) { snprintf(strValue, maxLength, "%d.%03d", intPart, decimalPart); } +// void print_compared_bf16_recored(int s, int id, int total, char *op, char * a_data, char * b_data, char * r_data, char * n_data) { +static inline void print_compared_bf16_recored(int s, int id, int total, char *op, BF16 a, BF16 b, BF16 r, BF16 n) { + float f_a; + float f_b; + float f_r; + float f_n; + uint32_t i_a; + uint32_t i_b; + uint32_t i_r; + uint32_t i_n; + + f_a = bf16_to_float(a); + f_b = bf16_to_float(b); + f_r = bf16_to_float(r); + f_n = bf16_to_float(n); + + memcpy(&i_a, &f_a, sizeof(float)); + memcpy(&i_b, &f_b, sizeof(float)); + memcpy(&i_r, &f_r, sizeof(float)); + memcpy(&i_n, &f_n, sizeof(float)); + + if(s) { + printf("%s[%d/%d] - SUCCESS, A 0x%08x B 0x%08x = RISC-V 0x%08x - NPU 0x%08x\n", + op, id, total, i_a, i_b, i_r, i_n); + } else { + printf("%s[%d/%d] - FAIL, A 0x%08x B 0x%08x = RISC-V 0x%08x - NPU 0x%08x\n", + op, id, total, i_a, i_b, i_r, i_n); + } +} + static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* out_npu_bf16, int count) { // Check How Many Are Correct @@ -597,9 +549,6 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o float out_risc_flt; float out_npu_flt; float diff; - char riscvStrValue[50]; - char npuStrValue[50]; - char diffStrValue[50]; for (int i = 0; i < count; i++) { out_risc_flt = bf16_to_float(out_risc_bf16[i]); @@ -612,16 +561,8 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o if (diff > EPSILON) { error_cnt += 1; #if 1 // def __DEBUG_MODE__ - memset(riscvStrValue, 0, 50); - memset(npuStrValue, 0, 50); - memset(diffStrValue, 0, 50); - floatToString(out_risc_flt, riscvStrValue, sizeof(riscvStrValue)); - floatToString(out_npu_flt, npuStrValue, sizeof(npuStrValue)); - floatToString(out_risc_flt - out_npu_flt, diffStrValue, sizeof(diffStrValue)); -#if 0 - printf("[Test Case %d] %s - FAIL\nRISCV data[%d]: %s\nNPU%d data[%d]: %s\nRISCV data[%d] - NPU data[%d] = %s\n", - count, op, i, riscvStrValue, npu, i, npuStrValue, i, i, diffStrValue); -#endif + print_compared_bf16_recored( 0, i, count, op, input_A[i], input_B[i], out_risc_bf16[i], out_npu_bf16[i]); +#else char * r_data; char * n_data; char * a_data; @@ -635,7 +576,9 @@ static int compare_riscv_and_npu(int npu, char *op, BF16* out_risc_bf16, BF16* o #endif } else { check += 1; -#if 0 +#if 1 + print_compared_bf16_recored( 1, i, count, op, input_A[i], input_B[i], out_risc_bf16[i], out_npu_bf16[i]); +#else //def __DEBUG_MODE__ char * r_data; char * n_data; char * a_data; @@ -826,44 +769,6 @@ void dump_data(char * data, int size) { printf("\n\n"); } -void dummy_store() { - - long unsigned int sram_a; - long unsigned int ddr_a; - int remaining; - int loadSize; - int size; - - size = DUMMY_DATA_SIZE; - - for (int len = 0; len < size; len += MAX_LOAD_STORE_CHUNK_SIZE) { - remaining = size - len; - loadSize = remaining < MAX_LOAD_STORE_CHUNK_SIZE ? remaining : MAX_LOAD_STORE_CHUNK_SIZE; - sram_a = 0x00 + len; - - ddr_a = (long unsigned int)dummy_output_0 + len; - store_command_to_npu(0, ddr_a, sram_a, loadSize); - ddr_a = (long unsigned int)dummy_output_1 + len; - store_command_to_npu(1, ddr_a, sram_a, loadSize); - ddr_a = (long unsigned int)dummy_output_2 + len; - store_command_to_npu(2, ddr_a, sram_a, loadSize); - ddr_a = (long unsigned int)dummy_output_3 + len; - store_command_to_npu(3, ddr_a, sram_a, loadSize); - if(NUMBER_OF_CORES >= 5) { - ddr_a = (long unsigned int)dummy_output_4 + len; - store_command_to_npu(4, ddr_a, sram_a, loadSize); - } - if(NUMBER_OF_CORES >= 6) { - ddr_a = (long unsigned int)dummy_output_5 + len; - store_command_to_npu(5, ddr_a, sram_a, loadSize); - } - - npu_store(); - - delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); - } -} - void load_kernel_into_npu(int npus) { long unsigned int sram_a; @@ -908,7 +813,6 @@ void load_kernel_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); -// dummy_store(); } } @@ -951,7 +855,6 @@ void load_input_A_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); -// dummy_store(); } } @@ -994,7 +897,6 @@ void load_input_B_into_npu(int npus) { //printf("%s - Offset: 0x%x, loadSize: %d\n", __func__, len, loadSize); delay_in_usec(NPU_LOAD_STORE_MICRO_DELAY); -// dummy_store(); } } From bb890da7d6bf459e29e7a9eedf3a4eac4fd5dace Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Thu, 23 Nov 2023 10:15:22 +0900 Subject: [PATCH 25/26] include fpc.c fpc.h for lk1 fpu --- src/testdriver/fpc.c | 438 +++++++++++++++++++++++++++++++++++++++++++ src/testdriver/fpc.h | 44 +++++ 2 files changed, 482 insertions(+) create mode 100644 src/testdriver/fpc.c create mode 100644 src/testdriver/fpc.h diff --git a/src/testdriver/fpc.c b/src/testdriver/fpc.c new file mode 100644 index 0000000..5e94c5f --- /dev/null +++ b/src/testdriver/fpc.c @@ -0,0 +1,438 @@ +#include +#include +#include +#include +#include +#include "fpc.h" + +// operating frequence in MHz +#define FREQ 50 + +// the number of element to be tested +#define MAX_ELEMENT_SIZE 64 // 2048 +#define ELEMENT_SIZE 64 + +#define VARIABLE_ALIGN 128 + +#define START_CORE_ID 0 +#define END_CORE_ID 2 + +#define USED_DATA 0 // 0: random, 1: index + +#define PRINT_SUCCESS_RESULT_DATA + +//#define LOAD_STORE_TEST + +#ifdef LOAD_STORE_TEST +#define SRAM_POSITION 0 // 0: input_A, 1: input_B, 2: result_C +#endif + +// core id +#define CORE0 0 +#define CORE1 1 +#define CORE2 2 +#define CORE3 3 +#define MAX_CORE 2 + + +// registers +#define FPC_ID 0x00000000 +#define PROC_STATUS 0x00000008 +#define KERNEL_OFFSET 0x00000010 +#define KERNEL_SIZE 0x00000018 +#define KERNEL_LOAD 0x00000020 +#define RUN_FPU 0x00000028 +#define RUN_CYCLE 0x00000030 + +// FPU Code +#define FPU_ADD 0 +#define FPU_SUB 1 +#define FPU_MUL 2 +#define FPU_DIV 3 +#define MAX_FPU 4 + +#define SYS_CLK 50000000 + +#define SIZE_M 1 + +// variables +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float a[MAX_ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float b[MAX_ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y[MAX_ELEMENT_SIZE]; +#ifdef LOAD_STORE_TEST +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y1[MAX_ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y2[MAX_ELEMENT_SIZE]; +#endif +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float r[MAX_ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile uint32_t kbuf[1024]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile int load_cycle[MAX_FPU][MAX_CORE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile int fpu_cycle[MAX_FPU][MAX_CORE]; +volatile uint32_t klen = 0; + +volatile uint32_t not_ok = 0; +// functions +void reg_write(uint32_t adr, uint64_t wd) +{ + FpcWrite(adr, wd); +} + +uint64_t reg_read(uint64_t adr) +{ + uint64_t rd; + FpcRead(adr, rd); + return rd; +} + +static inline uint64_t get_time() { + uint64_t tmp; + + asm volatile("csrrs %0, cycle, x0":"=r"(tmp)); + return tmp; +} + +void delay_in_usec(int us) { + + uint64_t cycle_start; + uint64_t cycle_end; + int elapsedTime; + + cycle_start = get_time(); + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + while(elapsedTime < us) { + cycle_end = get_time(); + elapsedTime = (cycle_end - cycle_start) / (SYS_CLK / 1000000); + } +} + +//---- generate data +#define set_data(a, r, o) (((a) << 16) | ((r) << 8) | (o)) +void generate_kernel(int fpu) +{ + int size = MAX_ELEMENT_SIZE; + int count = ELEMENT_SIZE; + int bsiz, aa, ba, ya, am, bm, ym; + + bsiz = size * 4; + + // main memory address + am = (int)a; + bm = (int)b; + ym = (int)y; + + // local sram address + aa = 0x100; + ba = aa + bsiz; + ya = ba + bsiz; + + // create kernel message + int pos = 0; + + // load + kbuf[pos++] = set_data((am>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(am&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(aa&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, count&0xFFFF, 0x03); // load data + + // load + kbuf[pos++] = set_data((bm>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(bm&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((ba>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(ba&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, count&0xFFFF, 0x03); // load data + + // fpu + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(aa&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((ba>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(ba&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data((ya>>16)&0xFFFF, 0x03, 0x01); // set high value in reg3 + kbuf[pos++] = set_data(ya&0xFFFF, 0x03, 0x02); // set low value in reg3 + kbuf[pos++] = set_data(0x00, count&0xFFFF, fpu+5); // fpu code + + // store + kbuf[pos++] = set_data((ym>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(ym&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((ya>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(ya&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, count&0xFFFF, 0x04); // store data + + // return + kbuf[pos++] = set_data(0x00, 0x00, 0x09); // return + + klen = 4 * pos; +} + +#ifdef LOAD_STORE_TEST +void generate_load_store_kernel(int fpu) +{ + int size = MAX_ELEMENT_SIZE; + int count = ELEMENT_SIZE; + int bsiz, aa, am, y0m, y1m,y2m; + + // buffer size in 256 elements + bsiz = size; + + // main memory address + am = (int)a; + y0m = (int)y; + y1m = (int)y1; + y2m = (int)y2; + + printf("am: %08x, y0m: %08x, y1m: %08x, y2m: %08x\n", am, y0m, y1m, y2m); + + aa = 0x100 + bsiz * SRAM_POSITION; + + // create kernel message + int pos = 0; + + // load + kbuf[pos++] = set_data((am>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(am&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(aa&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, (count / SIZE_M)&0xFFFF, 0x03); // load data + + // store + kbuf[pos++] = set_data((y0m>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(y0m&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(aa&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, (count / SIZE_M)&0xFFFF, 0x04); // store data + + // store + kbuf[pos++] = set_data((y1m>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(y1m&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(aa&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, (count / SIZE_M)&0xFFFF, 0x04); // store data + + // store + kbuf[pos++] = set_data((y2m>>16)&0xFFFF, 0x01, 0x01); // set high value in reg1 + kbuf[pos++] = set_data(y2m&0xFFFF, 0x01, 0x02); // set low value in reg1 + kbuf[pos++] = set_data((aa>>16)&0xFFFF, 0x02, 0x01); // set high value in reg2 + kbuf[pos++] = set_data(aa&0xFFFF, 0x02, 0x02); // set low value in reg2 + kbuf[pos++] = set_data(0x00, (count / SIZE_M)&0xFFFF, 0x04); // store data + + // return + kbuf[pos++] = set_data(0x00, 0x00, 0x09); // return + + klen = 4 * pos; +} +#endif + +void wait_done(int core) +{ + uint64_t rd; + while((rd = reg_read(PROC_STATUS)) & (1 << core)) ; +} + +static void floatToString(float floatValue, char* strValue, int maxLength) { + + int intPart = (int)floatValue; + int decimalPart = (int)((floatValue - intPart) * 10000000); // Assuming 3 decimal places + + if(floatValue < 0) { + decimalPart = 0 - decimalPart; + } + if (maxLength < 40) { + // Buffer is too small to store anything meaningful + return; + } + + memset(strValue, 0, maxLength); + snprintf(strValue, maxLength, "%d.%07d", intPart, decimalPart); +} + +void print_value(int ok, int i, float fa, float fb) +{ + uint32_t *pa = (uint32_t *)&fa; + uint32_t *pb = (uint32_t *)&fb; + char aFloatStrValue[50]; + char bFloatStrValue[50]; + + if(!ok) { + floatToString(fa, aFloatStrValue, sizeof(aFloatStrValue)); + floatToString(fb, bFloatStrValue, sizeof(bFloatStrValue)); + printf("[F] : FPU[%4d]: %08X(%s) => %08X(%s)\n", i, *pa, aFloatStrValue, *pb, bFloatStrValue); + } else { +#ifdef PRINT_SUCCESS_RESULT_DATA + printf("[S] : FPU[%4d]: %08X => %08X\n", i, *pa, *pb); +#endif + } +} + +#ifdef LOAD_STORE_TEST +int loaf_store_test(void) { + + printf("---- FPU Controller Load-Store Test (Element size = %d) \n", ELEMENT_SIZE); + + printf("a: %p, y: %p, y1: %p, y2: %p\n", a, y, y1, y2); + + memset(a, 0, sizeof(a)); + memset(y, 0, sizeof(y)); + memset(y1, 0, sizeof(y1)); + memset(y2, 0, sizeof(y2)); + //---- main test + for(int fpu = 0;fpu < 1;fpu++) + { + // generate kernel data + generate_load_store_kernel(fpu); + + // init data + for(int i = 0;i < ELEMENT_SIZE;i++) + { +#if USED_DATA + a[i] = (float)(i + 1); // a sources +#else + a[i] = (float)rand() / RAND_MAX * 2000.0 - 1000.0; +#endif + } + + // run fpu + for(int core = START_CORE_ID;core < END_CORE_ID;core++) + { + printf("\tCORE: %d\n", core); + + // load kerneal + reg_write(KERNEL_OFFSET, (uint64_t)kbuf); + reg_write(KERNEL_SIZE, (uint64_t)(klen)); + reg_write(KERNEL_LOAD, (uint64_t)(1 << core)); + wait_done(core); + + // get load cycle + load_cycle[fpu][core] = reg_read(8 * (6 + core)); + + // run fpu + reg_write(RUN_FPU, (uint64_t)core); + wait_done(core); + + // get fpu cycles + fpu_cycle[fpu][core] = reg_read(8 * (6 + core)); + + printf("\nY0:\n"); + for(int i = 0;i < ELEMENT_SIZE;i++) + { + int ok = (y[i] >= a[i] ? y[i] - a[i] : a[i] - y[i]) < 0.0000001; + print_value(ok, i, a[i], y[i]); + if(!ok) { + not_ok++; + } + } + printf("\nY1:\n"); + for(int i = 0;i < ELEMENT_SIZE;i++) + { + int ok = (y1[i] >= a[i] ? y1[i] - a[i] : a[i] - y1[i]) < 0.0000001; + print_value(ok, i, a[i], y1[i]); + if(!ok) { + not_ok++; + } + } + printf("\nY2:\n"); + for(int i = 0;i < ELEMENT_SIZE;i++) + { + int ok = (y2[i] >= a[i] ? y2[i] - a[i] : a[i] - y2[i]) < 0.0000001; + print_value(ok, i, a[i], y2[i]); + if(!ok) { + not_ok++; + } + } + } + } + + // print result + printf("[ Result ]\n"); + + printf("---- FPU Controller Test Finished(not_ok: %d)\n", not_ok); + + return 0; +} +#endif + +int main(void) { + +#ifdef LOAD_STORE_TEST + return loaf_store_test(); +#endif + + printf("---- FPU Controller Test (Element size = %d) \n", ELEMENT_SIZE); + printf("a: %p, b: %p, y: %p\n", a, b, y); + + //---- main test + for(int fpu = 0;fpu < MAX_FPU;fpu++) + { + printf("FPU: %s\n", fpu == 0 ? "ADD" : fpu == 1 ? "SUB" : fpu == 2 ? "MUL" : "DIV"); + + // generate kernel data + generate_kernel(fpu); + + // init data + for(int i = 0;i < ELEMENT_SIZE;i++) + { +#if USED_DATA + a[i] = (float)(i + 1); // a sources + b[i] = (float)(i + 2); // b sources +#else + a[i] = (float)rand() / RAND_MAX * 2000.0 - 1000.0; + b[i] = (float)rand() / RAND_MAX * 3000.0 - 2500.0; +#endif + r[i] = fpu == 0 ? a[i] + b[i] : // reference + fpu == 1 ? a[i] - b[i] : + fpu == 2 ? a[i] * b[i] : + a[i] / b[i] ; + } + + // run fpu + for(int core = START_CORE_ID;core < END_CORE_ID;core++) + { + printf("\tCORE: %d\n", core); + + // load kerneal + reg_write(KERNEL_OFFSET, (uint64_t)kbuf); + reg_write(KERNEL_SIZE, (uint64_t)klen); + reg_write(KERNEL_LOAD, (uint64_t)(1 << core)); + wait_done(core); + + // get load cycle + load_cycle[fpu][core] = reg_read(8 * (6 + core)); + + // run fpu + reg_write(RUN_FPU, (uint64_t)core); + wait_done(core); + + // get fpu cycles + fpu_cycle[fpu][core] = reg_read(8 * (6 + core)); + + // check result + for(int i = 0;i < ELEMENT_SIZE;i++) + { + int ok = (y[i] >= r[i] ? y[i] - r[i] : r[i] - y[i]) < 0.0000001; + print_value(ok, i, r[i], y[i]); + if(!ok) { + not_ok++; + } + } + delay_in_usec(1000); + } + } + + // print result + printf("[ Result ]\n"); + for(int fpu = 0;fpu < MAX_FPU;fpu++) + { + for(int core = 0;core < MAX_CORE;core++) + { + char *s = fpu == 0 ? "ADD" : fpu == 1 ? "SUB" : fpu == 2 ? "MUL" : "DIV"; + int lcyc = load_cycle[fpu][core]; + int fcyc = fpu_cycle[fpu][core]; + int tcyc = lcyc + fcyc; + printf("%s#%d:: load: %d cycles, fpu: %d cycles, total: %d cycles, time: %d us\n", s, core, lcyc, fcyc, tcyc, tcyc / FREQ); + } + } + + printf("---- FPU Controller Test Finished(not_ok: %d)\n", not_ok); + + return 0; +} + diff --git a/src/testdriver/fpc.h b/src/testdriver/fpc.h new file mode 100644 index 0000000..9666770 --- /dev/null +++ b/src/testdriver/fpc.h @@ -0,0 +1,44 @@ +/* + * fpc header file + */ + +#ifndef FPC_H +#define FPC_H + +// custom macros +#define STR1(x) #x +#ifndef STR +#define STR(x) STR1(x) +#endif + +#define CAT_(A, B) A##B +#define CAT(A, B) CAT_(A, B) + +#define ROCC_INSTRUCTION_R_R_R(x, rd, rs1, rs2, func7) \ + { \ + asm volatile( \ + ".insn r " STR(CAT(CUSTOM_, x)) ", " STR(0x7) ", " STR(func7) ", %0, %1, %2" \ + : "=r"(rd) \ + : "r"(rs1), "r"(rs2)); \ + } + +#define ROCC_INSTRUCTION_0_R_R(x, rs1, rs2, func7) \ + { \ + asm volatile( \ + ".insn r " STR(CAT(CUSTOM_, x)) ", " STR(0x3) ", " STR(func7) ", x0, %0, %1" \ + : \ + : "r"(rs1), "r"(rs2)); \ + } + +// commands +#define FPC_WRITE 0 +#define FPC_READ 1 + +// custom2 +#define FPC_CUSTOM 2 + +// macros +#define FpcWrite(adr, wd) ROCC_INSTRUCTION_0_R_R(FPC_CUSTOM, adr, wd, FPC_WRITE) +#define FpcRead(adr, rd) { uint64_t _placeholder = 0; ROCC_INSTRUCTION_R_R_R(FPC_CUSTOM, rd, adr, _placeholder, FPC_READ) } + +#endif // FPC_H From 3b8447a8afa4843dba17d6434f7fa0674136cbc6 Mon Sep 17 00:00:00 2001 From: pooky1004 Date: Wed, 6 Dec 2023 07:44:56 +0900 Subject: [PATCH 26/26] cache.. --- src/testdriver/fpc.c | 171 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 156 insertions(+), 15 deletions(-) diff --git a/src/testdriver/fpc.c b/src/testdriver/fpc.c index 5e94c5f..346dd65 100644 --- a/src/testdriver/fpc.c +++ b/src/testdriver/fpc.c @@ -9,17 +9,17 @@ #define FREQ 50 // the number of element to be tested -#define MAX_ELEMENT_SIZE 64 // 2048 -#define ELEMENT_SIZE 64 +#define MAX_ELEMENT_SIZE 2048 // 2048 +#define ELEMENT_SIZE 512 #define VARIABLE_ALIGN 128 #define START_CORE_ID 0 #define END_CORE_ID 2 -#define USED_DATA 0 // 0: random, 1: index +#define USED_DATA 1 // 0: random, 1: index -#define PRINT_SUCCESS_RESULT_DATA +//#define PRINT_SUCCESS_RESULT_DATA //#define LOAD_STORE_TEST @@ -55,21 +55,37 @@ #define SIZE_M 1 +#define _USE_VARIABLES_ 1 + // variables -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float a[MAX_ELEMENT_SIZE]; -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float b[MAX_ELEMENT_SIZE]; -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y[MAX_ELEMENT_SIZE]; +#if _USE_VARIABLES_ +//__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float a[ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float y[ELEMENT_SIZE] __attribute__((section(".nocache"))); +#ifdef LOAD_STORE_TEST +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float y1[ELEMENT_SIZE] __attribute__((section(".nocache"))); +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float y2[ELEMENT_SIZE] __attribute__((section(".nocache"))); +#endif +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float a[ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float b[ELEMENT_SIZE]; +__attribute__ ((aligned (VARIABLE_ALIGN))) volatile static float r[ELEMENT_SIZE]; +#else +float *d; +float *a; +float *b; +float *y; #ifdef LOAD_STORE_TEST -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y1[MAX_ELEMENT_SIZE]; -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float y2[MAX_ELEMENT_SIZE]; +float *y1; +float *y2; +#endif +float *r; #endif -__attribute__ ((aligned (VARIABLE_ALIGN))) volatile float r[MAX_ELEMENT_SIZE]; __attribute__ ((aligned (VARIABLE_ALIGN))) volatile uint32_t kbuf[1024]; __attribute__ ((aligned (VARIABLE_ALIGN))) volatile int load_cycle[MAX_FPU][MAX_CORE]; __attribute__ ((aligned (VARIABLE_ALIGN))) volatile int fpu_cycle[MAX_FPU][MAX_CORE]; volatile uint32_t klen = 0; volatile uint32_t not_ok = 0; +volatile uint32_t not_cok = 0; // functions void reg_write(uint32_t adr, uint64_t wd) { @@ -350,17 +366,124 @@ int loaf_store_test(void) { } #endif +#define BUFFER_ALIGNMENT 0 + +#if !_USE_VARIABLES_ +void release_variables() { + if(d != NULL) { + free(d); + } + if(a != NULL) { + free(a); + } + if(b != NULL) { + free(b); + } + if(y != NULL) { + free(y); + } +#ifdef LOAD_STORE_TEST + if(y1 != NULL) { + free(y1); + } + if(y2 != NULL) { + free(y2); + } +#endif + if(r != NULL) { + free(r); + } +} +#endif + +#if 0 +void non_cacheable() +{ + asm volatile("li t0, 0x80000000"); // Base address of the memory region + asm volatile("li t1, 0x80001000"); // End address of the memory region + asm volatile("li t2, 0x8"); // Set MMU flags to mark the region as non-cacheable + asm volatile("csrw pmpaddr0, t0"); + asm volatile("csrw pmpaddr1, t1"); + asm volatile("csrw pmpcfg0, t2"); +} +#endif + int main(void) { +#if !_USE_VARIABLES_ +// d = malloc(sizeof(float) * ELEMENT_SIZE); +// if(d == NULL) { +// printf("OOM(d) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); +// return -1; +// } + a = malloc(sizeof(float) * ELEMENT_SIZE); + if(a == NULL) { + printf("OOM(a) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } + b = malloc(sizeof(float) * ELEMENT_SIZE); + if(b == NULL) { + printf("OOM(b) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } + y = malloc(sizeof(float) * ELEMENT_SIZE); + if(y == NULL) { + printf("OOM(y) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } +#ifdef LOAD_STORE_TEST + y1 = malloc(sizeof(float) * ELEMENT_SIZE); + if(y1 == NULL) { + printf("OOM(y1) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } + y2 = malloc(sizeof(float) * ELEMENT_SIZE); + if(y2 == NULL) { + printf("OOM(y2) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } +#endif + r = malloc(sizeof(float) * ELEMENT_SIZE); + if(r == NULL) { + printf("OOM(r) %u.\n", sizeof(float) * ELEMENT_SIZE + BUFFER_ALIGNMENT); + release_variables(); + return -1; + } +#endif + + memset(a, 0, sizeof(float) * ELEMENT_SIZE); + memset(b, 0, sizeof(float) * ELEMENT_SIZE); + memset(y, 0, sizeof(float) * ELEMENT_SIZE); #ifdef LOAD_STORE_TEST - return loaf_store_test(); + memset(y1, 0, sizeof(float) * ELEMENT_SIZE); + memset(y2, 0, sizeof(float) * ELEMENT_SIZE); +#endif + memset(r, 0, sizeof(float) * ELEMENT_SIZE); + +#ifdef LOAD_STORE_TEST + int rst; + + rst = loaf_store_test(); + release_variables(); + return rst; #endif printf("---- FPU Controller Test (Element size = %d) \n", ELEMENT_SIZE); - printf("a: %p, b: %p, y: %p\n", a, b, y); + printf("a: %p, b: %p, y: %p, r: %p\n", a, b, y, r); + +// delay_in_usec(1000000); //---- main test + int count = 0; +// for(count = 0;count < 2;count++) + { for(int fpu = 0;fpu < MAX_FPU;fpu++) + //for(int fpu = 3;fpu >= 0;fpu--) { printf("FPU: %s\n", fpu == 0 ? "ADD" : fpu == 1 ? "SUB" : fpu == 2 ? "MUL" : "DIV"); @@ -371,8 +494,8 @@ int main(void) { for(int i = 0;i < ELEMENT_SIZE;i++) { #if USED_DATA - a[i] = (float)(i + 1); // a sources - b[i] = (float)(i + 2); // b sources + a[i] = (float)(i + 1 + count); // a sources + b[i] = (float)(i + 2 + count); // b sources #else a[i] = (float)rand() / RAND_MAX * 2000.0 - 1000.0; b[i] = (float)rand() / RAND_MAX * 3000.0 - 2500.0; @@ -408,6 +531,20 @@ int main(void) { for(int i = 0;i < ELEMENT_SIZE;i++) { int ok = (y[i] >= r[i] ? y[i] - r[i] : r[i] - y[i]) < 0.0000001; + volatile float *y_ptr; + volatile float y_tmp; + uint32_t *ptmp = (uint32_t *)&y_tmp; + + if(!ok) { + not_cok++; + y_ptr = &y[i]; + y_tmp = *y_ptr; + + printf("y_tmp: %08X\n", *ptmp); + ok = (y_tmp >= r[i] ? y_tmp - r[i] : r[i] - y_tmp) < 0.0000001; + // print_value(ok, i, r[i], y_tmp); + } + print_value(ok, i, r[i], y[i]); if(!ok) { not_ok++; @@ -416,6 +553,7 @@ int main(void) { delay_in_usec(1000); } } + } // print result printf("[ Result ]\n"); @@ -431,7 +569,10 @@ int main(void) { } } - printf("---- FPU Controller Test Finished(not_ok: %d)\n", not_ok); +#if !_USE_VARIABLES_ + release_variables(); +#endif + printf("---- FPU Controller Test Finished(not_ok: %d, not_cok: %d)\n", not_ok, not_cok); return 0; }