Clean production code: -O2, read CRC32 from ExtRAM, remove all debug
This commit is contained in:
@@ -1,43 +1,29 @@
|
||||
/**
|
||||
* user-sample - CIC-IEC 2026 Stage 3 Evaluation Program
|
||||
*
|
||||
* Reads N groups of 4x4 unsigned matrix multiplications from ExtRAM,
|
||||
* computes C = A x B via the hardware matmul IP, writes results back,
|
||||
* computes CRC32 over the result region, and outputs the required identifiers.
|
||||
*
|
||||
* N is controlled by MATMUL_GROUP_NUM (Makefile / CI passes -DMATMUL_GROUP_NUM=5000).
|
||||
* Local default: 10 (fast testing). For full eval: make MATMUL_GROUP_NUM=5000
|
||||
*
|
||||
* Data layout (word offsets in ExtRAM):
|
||||
* Input: SRC_BASE = 0, N * 32 words
|
||||
* Result: DST_BASE = SRC_BASE + N * 32, N * 48 words
|
||||
* CRC32 over result region byte stream (N * 192 bytes, little-endian words)
|
||||
* user-sample — CIC-IEC 2026 Stage 3
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* ─── Configurable group count (default 10 for fast local testing) ─── */
|
||||
#ifndef MATMUL_GROUP_NUM
|
||||
#define MATMUL_GROUP_NUM 5000
|
||||
#endif
|
||||
|
||||
/* ─── BSP globals ─────────────────────────────────────────────────── */
|
||||
/* ─── BSP globals ──────────────────────────────────────────────────── */
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
|
||||
/* ─── Memory layout ────────────────────────────────────────────────── */
|
||||
/* ─── Memory layout ─────────────────────────────────────────────────── */
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000
|
||||
#define EXTRAM_BASE (0xA0000000 | (EXTRAM_BASE_PHYS & 0x1FFFFFFF))
|
||||
|
||||
#define SRC_BASE 0
|
||||
#define DST_BASE (SRC_BASE + MATMUL_GROUP_NUM * 32)
|
||||
#define RESULT_WORDS (MATMUL_GROUP_NUM * 48)
|
||||
#define RESULT_BYTES (RESULT_WORDS * 4)
|
||||
|
||||
/* ─── MATMUL IP registers ─────────────────────────────────────────── */
|
||||
/* ─── MATMUL IP registers ──────────────────────────────────────────── */
|
||||
#define MATMUL_BASE 0xbf500000
|
||||
#define MATMUL_CTRL (MATMUL_BASE + 0x000)
|
||||
#define MATMUL_STATUS (MATMUL_BASE + 0x004)
|
||||
@@ -50,11 +36,11 @@ unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
#define STATUS_DONE 0x2
|
||||
#define STATUS_ERROR 0x4
|
||||
|
||||
/* ─── Convenience macros ──────────────────────────────────────────── */
|
||||
/* ─── Convenience ──────────────────────────────────────────────────── */
|
||||
#define REG_WR(addr, val) (*(volatile uint32_t *)(addr) = (uint32_t)(val))
|
||||
#define REG_RD(addr) (*(volatile uint32_t *)(addr))
|
||||
|
||||
/* ─── CRC32 table (IEEE 802.3, polynomial 0xEDB88320) ─────────────── */
|
||||
/* ─── CRC32 table ──────────────────────────────────────────────────── */
|
||||
static const uint32_t crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
@@ -122,46 +108,25 @@ static const uint32_t crc32_table[256] = {
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
/* ─── Read N words from IP register space ─────────────────────────── */
|
||||
static void read_ip(uint32_t base, volatile uint32_t *dst, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
dst[i] = REG_RD(base + i * 4);
|
||||
}
|
||||
|
||||
/* ─── Write N words to IP register space ──────────────────────────── */
|
||||
static void write_ip(uint32_t base, const volatile uint32_t *src, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
REG_WR(base + i * 4, src[i]);
|
||||
}
|
||||
|
||||
/* ─── Poll IP STATUS until done or error ──────────────────────────── */
|
||||
static void wait_done(void)
|
||||
{
|
||||
uint32_t status;
|
||||
do {
|
||||
status = REG_RD(MATMUL_STATUS);
|
||||
} while (!(status & (STATUS_DONE | STATUS_ERROR)));
|
||||
do { status = REG_RD(MATMUL_STATUS); }
|
||||
while (!(status & (STATUS_DONE | STATUS_ERROR)));
|
||||
}
|
||||
|
||||
/* ─── CRC32 over ExtRAM result region (little-endian word → byte stream) ─ */
|
||||
static uint32_t compute_crc32(volatile uint32_t *extram)
|
||||
{
|
||||
uint32_t crc = 0xFFFFFFFF;
|
||||
uint32_t i, w;
|
||||
|
||||
for (i = 0; i < RESULT_WORDS; i++) {
|
||||
w = extram[DST_BASE + i];
|
||||
crc = crc32_table[(crc ^ (w & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 8) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 16) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ (w >> 24) ) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════ */
|
||||
int main(void)
|
||||
{
|
||||
volatile uint32_t *extram = (volatile uint32_t *)EXTRAM_BASE;
|
||||
@@ -169,18 +134,8 @@ int main(void)
|
||||
uint32_t crc;
|
||||
int g, i;
|
||||
|
||||
/* ── Start marker (must be first output) ──────────────────── */
|
||||
printf("MATMUL_START\n");
|
||||
|
||||
/* ── CRC32 self-test (printed inline later) ───────────────── */
|
||||
const char *test = "123456789";
|
||||
uint32_t tcrc = 0xFFFFFFFF;
|
||||
for (int ti = 0; test[ti]; ti++)
|
||||
tcrc = crc32_table[(tcrc ^ test[ti]) & 0xFF] ^ (tcrc >> 8);
|
||||
tcrc ^= 0xFFFFFFFF;
|
||||
|
||||
/* ── Process all groups and compute CRC32 on-the-fly ──────── */
|
||||
crc = 0xFFFFFFFF;
|
||||
for (g = 0; g < MATMUL_GROUP_NUM; g++) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
a_buf[i] = extram[SRC_BASE + g * 32 + i];
|
||||
@@ -192,34 +147,21 @@ int main(void)
|
||||
REG_WR(MATMUL_CTRL, CTRL_START);
|
||||
wait_done();
|
||||
read_ip(MATMUL_C_BASE, c_buf, 48);
|
||||
for (i = 0; i < 48; i++) {
|
||||
uint32_t w = c_buf[i];
|
||||
crc = crc32_table[(crc ^ (w & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 8) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 16) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ (w >> 24) ) & 0xFF] ^ (crc >> 8);
|
||||
extram[DST_BASE + g * 48 + i] = w;
|
||||
}
|
||||
if (g == 0) {
|
||||
extram[DST_BASE + 1] = 0xDEADBEEF;
|
||||
printf("DBG CRCtest=0x%08lx g=0 rdback=%08lx BEEF=%08lx\n",
|
||||
(unsigned long)tcrc,
|
||||
(unsigned long)extram[DST_BASE],
|
||||
(unsigned long)extram[DST_BASE + 1]);
|
||||
}
|
||||
if (g <= 3 || g >= (MATMUL_GROUP_NUM-2)) {
|
||||
printf("DBG g=%d A0=%08lx B0=%08lx C0=%08lx\n",
|
||||
g, (unsigned long)a_buf[0], (unsigned long)b_buf[0],
|
||||
(unsigned long)c_buf[0]);
|
||||
}
|
||||
for (i = 0; i < 48; i++)
|
||||
extram[DST_BASE + g * 48 + i] = c_buf[i];
|
||||
}
|
||||
|
||||
crc = 0xFFFFFFFF;
|
||||
for (i = 0; i < RESULT_WORDS; i++) {
|
||||
uint32_t w = extram[DST_BASE + i];
|
||||
crc = crc32_table[(crc ^ (w & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 8) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ ((w >> 16) & 0xFF)) & 0xFF] ^ (crc >> 8);
|
||||
crc = crc32_table[(crc ^ (w >> 24) ) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
crc ^= 0xFFFFFFFF;
|
||||
printf("DBG CRC32 loop: i=%d RESULT_WORDS=%d\n", i, RESULT_WORDS);
|
||||
|
||||
/* ── Final markers ────────────────────────────────────────── */
|
||||
printf("MATMUL_CRC32=%08lx\n", (unsigned long)crc);
|
||||
printf("MATMUL_DONE\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user