This repository has been archived on 2026-08-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ciciec2026/.trellis/tasks/06-25-hardware-crc32-engine-in-matmul-ip/prd.md

3.4 KiB
Raw Blame History

Hardware CRC32 Engine in Matmul IP

Goal

Replace software CRC32 (80.8% of total time, ~396ms for 5000 groups) with a hardware CRC32 engine embedded in the matmul IP. The CRC32 streams through during DMA reads of C result data, near-zero overhead.

Expected: total time drops from 490ms → ~94ms, score from 51.66 → ~69.

Requirements

  1. CRC32 table: 256×32 LUTRAM, IEEE 802.3 polynomial 0xEDB88320, identical to software table
  2. Engine: 4-byte/cycle combinational CRC32, triggered only when AXI R_CH reads C memory (B0_C/B1_C)
  3. Register at offset 0x010:
    • Read: returns crc_reg ^ 0xFFFFFFFF (final CRC32)
    • Write any value: resets CRC to 0xFFFFFFFF
  4. Software: remove crc32_table[], compute_crc32(), and CRC32 printf call
    • Replace with REG_RD(MATMUL_CRC) after all groups complete
  5. No regressions: existing AXI read/write, compute engine, DMA, interrupts unchanged
  6. Lint clean, Vivado synthesis passes at 33MHz

Acceptance Criteria

  • CRC match: hardware CRC32 matches software CRC32 for 10-group and 5000-group tests
  • Correct output: MATMUL_CRC32=d53cd879 (5000 groups, unchanged since matmul compute is identical)
  • Timing improvement: CRC32 component drops from ~396ms to <1ms
  • No timing violations in Vivado (WNS passes)
  • No DSP used (DSP utilization = 0)
  • Lint clean

Definition of Done

  • matmul_axi_slave.v: CRC engine added, register at 0x010
  • user-sample.c: software CRC removed, hardware CRC read
  • Simulation verifies CRC match (10 groups)
  • Lint + compile pass
  • Synced to regional-submit

Technical Approach

Hardware

CRC32 engine in matmul_axi_slave.v:

  • LUTRAM table: 256 entries × 32 bits, initialized via initial block
  • 4-byte combinational datapath: t0→c0→t1→c1→t2→c2→t3→crc_next
  • Triggered when AXI read address hits B0_C or B1_C ranges
  • Registered on posedge clk when s_axi_rvalid && s_axi_rready
  • Reset on write to 0x010 (CRC register)
// Simplified combinational chain:
t0 = TABLE[(crc_reg[7:0] ^ rdata[7:0])];
c0 = t0 ^ {8'h00, crc_reg[31:8]};
t1 = TABLE[(c0[7:0] ^ rdata[15:8])];
c1 = t1 ^ {8'h00, c0[31:8]};
t2 = TABLE[(c1[7:0] ^ rdata[23:16])];
c2 = t2 ^ {8'h00, c1[31:8]};
t3 = TABLE[(c2[7:0] ^ rdata[31:24])];
crc_next = t3 ^ {8'h00, c2[31:8]};

Register map:

  • 0x010: CRC_VAL (RO returns final CRC; WO resets CRC to 0xFFFFFFFF)

Software

// Before main loop: reset CRC
REG_WR(MATMUL_CRC_CTRL, 1);  // 0xbf500010

// After all DMA + compute:
crc = REG_RD(MATMUL_CRC_CTRL);
printf("MATMUL_CRC32=%08lx\n", (unsigned long)crc);

Delete: crc32_table[256], compute_crc32(), t_crc32 timing variables.

Out of Scope

  • Pipelined CRC (combinational at 33MHz is sufficient; pipeline only if timing fails)
  • CRC32 for FFT data
  • Other polynomial CRC variants

Technical Notes

Files to modify

  • rtl/ip/matmul/matmul_axi_slave.v — add CRC engine + register
  • sdk/software/examples/asm/user-sample.c — remove software CRC, add hardware CRC read

Timing expectations

  • CRC datapath: 4 LUTRAM reads + 4 XORs in combinational chain
  • At 33MHz (30ns cycle), critical path ~15-20ns on LS FPGA → should meet timing
  • If Vivado reports WNS violation, fall back to 2-stage pipeline (2 bytes per stage)

CRC32 byte order verification

The software processes: byte0 (LSB), byte1, byte2, byte3 (MSB). The hardware must match this order.