/** * user-sample - CIC-IEC 2026 Stage 3 Evaluation Program * * Matmul AXI-master CRC-only path with fast startup and low-overhead UART output. */ #include #define UART_THR (*(volatile unsigned char *)0xbf000000) #define UART_LSR (*(volatile unsigned char *)0xbf000005) #define LSR_THRE 0x20 static inline void uart_tx(unsigned char c) { while ((UART_LSR & LSR_THRE) == 0) { } UART_THR = c; } static void uart_put_matmul_start_fifo(void) { UART_THR = 'M'; UART_THR = 'A'; UART_THR = 'T'; UART_THR = 'M'; UART_THR = 'U'; UART_THR = 'L'; UART_THR = '_'; UART_THR = 'S'; UART_THR = 'T'; UART_THR = 'A'; UART_THR = 'R'; UART_THR = 'T'; } static inline void uart_wait_tx_empty(void) { while ((UART_LSR & LSR_THRE) == 0) { } } static inline unsigned char hex_digit(unsigned int val, int shift) { unsigned char nibble = (unsigned char)((val >> shift) & 0xf); return (unsigned char)(nibble < 10 ? ('0' + nibble) : ('a' + nibble - 10)); } static void uart_put_result_fifo(unsigned int crc) { uart_wait_tx_empty(); UART_THR = 'M'; UART_THR = 'A'; UART_THR = 'T'; UART_THR = 'M'; UART_THR = 'U'; UART_THR = 'L'; UART_THR = '_'; UART_THR = 'C'; UART_THR = 'R'; UART_THR = 'C'; UART_THR = '3'; UART_THR = '2'; UART_THR = '='; UART_THR = hex_digit(crc, 28); UART_THR = hex_digit(crc, 24); UART_THR = hex_digit(crc, 20); uart_wait_tx_empty(); UART_THR = hex_digit(crc, 16); UART_THR = hex_digit(crc, 12); UART_THR = hex_digit(crc, 8); UART_THR = hex_digit(crc, 4); UART_THR = hex_digit(crc, 0); UART_THR = 'M'; UART_THR = 'A'; UART_THR = 'T'; UART_THR = 'M'; UART_THR = 'U'; UART_THR = 'L'; UART_THR = '_'; UART_THR = 'D'; UART_THR = 'O'; UART_THR = 'N'; UART_THR = 'E'; } #ifndef MATMUL_GROUP_NUM #define MATMUL_GROUP_NUM 5000 #endif #if MATMUL_FAST_START == 0 unsigned long UART_BASE = 0xbf000000; #endif #define EXTRAM_BASE_PHYS 0x1c400000 #define EXTRAM_BASE_UNCACHED (0xA0000000 | (EXTRAM_BASE_PHYS & 0x1FFFFFFF)) #define SRC_BASE_WORDS 0 #define EXTRAM_PHYS_AB(g) (EXTRAM_BASE_PHYS + (SRC_BASE_WORDS * 4) + (g) * 128) #define MATMUL_BASE_PHYS 0x1f500000 #define MATMUL_BASE_UNCACHED 0xbf500000 #define MATMUL_CTRL (MATMUL_BASE_UNCACHED + 0x000) #define MATMUL_STATUS (MATMUL_BASE_UNCACHED + 0x004) #define MATMUL_DMA_SRC_BASE (MATMUL_BASE_UNCACHED + 0x020) #define MATMUL_DMA_GROUPS (MATMUL_BASE_UNCACHED + 0x028) #define MATMUL_DMA_SRC_STRIDE (MATMUL_BASE_UNCACHED + 0x02C) #define CTRL_START_B0 0x1 #define CTRL_START_B1 0x2 #define CTRL_DMA_START (1 << 8) #define STATUS_DONE 0x2 #define STATUS_ERROR 0x4 #define STATUS_DMA_BUSY (1 << 3) #define STATUS_DMA_DONE (1 << 4) #define MATMUL_CRC (MATMUL_BASE_UNCACHED + 0x010) #define DMA_CTRL_VAL (CTRL_BURST_SIZE(2) | CTRL_BURST_LEN(63) | CTRL_START_BIT) #define MATMUL_EP_ID 0 int main(void) { if (MATMUL_GROUP_NUM <= 0) { return 0; } volatile unsigned int *mat_ctrl = (volatile unsigned int *)MATMUL_CTRL; volatile unsigned int *mat_status = (volatile unsigned int *)MATMUL_STATUS; volatile unsigned int *mat_crc = (volatile unsigned int *)MATMUL_CRC; unsigned int crc; uart_put_matmul_start_fifo(); *(volatile unsigned int *)MATMUL_CRC = 0; *mat_status = STATUS_DMA_DONE | STATUS_DONE | STATUS_ERROR; *(volatile unsigned int *)MATMUL_DMA_SRC_BASE = EXTRAM_PHYS_AB(0); *(volatile unsigned int *)MATMUL_DMA_GROUPS = MATMUL_GROUP_NUM; *(volatile unsigned int *)MATMUL_DMA_SRC_STRIDE = 128; *mat_ctrl = CTRL_DMA_START; while (!(*mat_status & STATUS_DMA_DONE)) {} *mat_status = STATUS_DMA_DONE; crc = *mat_crc; uart_put_result_fifo(crc); return 0; }