Compute matmul CRC before result store
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// the matmul local endpoint/control interface.
|
||||
//
|
||||
// AXI-Lite register map, relative to this bridge window:
|
||||
// 0x00 CTRL bit0 start
|
||||
// 0x00 CTRL bit0 start, bit1 skip_result_writeback
|
||||
// 0x04 STATUS bit0 busy, bit1 done (W1C)
|
||||
// 0x08 SRC_BASE physical ExtRAM input base
|
||||
// 0x0C DST_BASE physical ExtRAM result base
|
||||
@@ -102,6 +102,7 @@ module cdma_matmul_bridge #(
|
||||
logic [31:0] seq_load_idx;
|
||||
logic [31:0] seq_store_idx;
|
||||
logic seq_compute_bank;
|
||||
logic seq_skip_writeback;
|
||||
|
||||
wire [7:0] wr_off = s_axil_awaddr[7:0];
|
||||
wire [7:0] rd_off = s_axil_araddr[7:0];
|
||||
@@ -221,6 +222,7 @@ module cdma_matmul_bridge #(
|
||||
seq_load_idx <= 32'd0;
|
||||
seq_store_idx <= 32'd0;
|
||||
seq_compute_bank <= 1'b0;
|
||||
seq_skip_writeback <= 1'b0;
|
||||
cdma_req_valid <= 1'b0;
|
||||
cdma_req_mode <= MODE_MEM2EP;
|
||||
cdma_req_src <= '0;
|
||||
@@ -251,6 +253,7 @@ module cdma_matmul_bridge #(
|
||||
seq_load_idx <= 32'd0;
|
||||
seq_store_idx <= 32'd0;
|
||||
seq_compute_bank <= 1'b0;
|
||||
seq_skip_writeback <= s_axil_wstrb[0] && s_axil_wdata[1];
|
||||
mat_crc_clear <= 1'b1;
|
||||
mat_done_clear <= 1'b1;
|
||||
seq_state <= SQ_CLEAR;
|
||||
@@ -296,9 +299,21 @@ module cdma_matmul_bridge #(
|
||||
SQ_WAIT_DONE: begin
|
||||
if (mat_done) begin
|
||||
mat_done_clear <= 1'b1;
|
||||
if (seq_skip_writeback) begin
|
||||
seq_store_idx <= seq_store_idx + 32'd1;
|
||||
seq_compute_bank <= ~seq_compute_bank;
|
||||
if ((seq_store_idx + 32'd1) >= seq_groups) begin
|
||||
seq_state <= SQ_DONE;
|
||||
end else if (seq_load_idx < seq_groups) begin
|
||||
seq_state <= SQ_LOAD_START;
|
||||
end else begin
|
||||
seq_state <= SQ_WAIT_DONE;
|
||||
end
|
||||
end else begin
|
||||
seq_state <= SQ_STORE_START;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SQ_STORE_START: begin
|
||||
cdma_req_mode <= MODE_EP2MEM;
|
||||
|
||||
@@ -183,22 +183,21 @@ module matmul_axi_slave (
|
||||
reg [31:0] crc32_table [0:255];
|
||||
reg [31:0] crc_reg;
|
||||
|
||||
wire [31:0] crc_stream_data = (ep_rd_valid && ep_rd_ready) ? ep_rd_data : s_axi_rdata;
|
||||
wire crc_axi_valid = (r_state == R_DATA) && s_axi_rvalid && s_axi_rready &&
|
||||
((r_offset >= ADDR_B0_C && r_offset < (ADDR_B0_C + 12'h0C0)) ||
|
||||
(r_offset >= ADDR_B1_C && r_offset < (ADDR_B1_C + 12'h0C0)));
|
||||
wire crc_ep_valid = ep_rd_valid && ep_rd_ready && (ep_rd_word_addr < 8'd48);
|
||||
wire crc_stream_valid = crc_axi_valid || crc_ep_valid;
|
||||
|
||||
wire [31:0] crc_t0, crc_c0, crc_t1, crc_c1, crc_t2, crc_c2, crc_t3, crc_next;
|
||||
assign crc_t0 = crc32_table[(crc_reg[7:0] ^ crc_stream_data[7:0])];
|
||||
assign crc_c0 = crc_t0 ^ {8'h00, crc_reg[31:8]};
|
||||
assign crc_t1 = crc32_table[(crc_c0[7:0] ^ crc_stream_data[15:8])];
|
||||
assign crc_c1 = crc_t1 ^ {8'h00, crc_c0[31:8]};
|
||||
assign crc_t2 = crc32_table[(crc_c1[7:0] ^ crc_stream_data[23:16])];
|
||||
assign crc_c2 = crc_t2 ^ {8'h00, crc_c1[31:8]};
|
||||
assign crc_t3 = crc32_table[(crc_c2[7:0] ^ crc_stream_data[31:24])];
|
||||
assign crc_next = crc_t3 ^ {8'h00, crc_c2[31:8]};
|
||||
function [31:0] crc32_word_next;
|
||||
input [31:0] crc_in;
|
||||
input [31:0] data_in;
|
||||
reg [31:0] t0, c0, t1, c1, t2, c2, t3;
|
||||
begin
|
||||
t0 = crc32_table[(crc_in[7:0] ^ data_in[7:0])];
|
||||
c0 = t0 ^ {8'h00, crc_in[31:8]};
|
||||
t1 = crc32_table[(c0[7:0] ^ data_in[15:8])];
|
||||
c1 = t1 ^ {8'h00, c0[31:8]};
|
||||
t2 = crc32_table[(c1[7:0] ^ data_in[23:16])];
|
||||
c2 = t2 ^ {8'h00, c1[31:8]};
|
||||
t3 = crc32_table[(c2[7:0] ^ data_in[31:24])];
|
||||
crc32_word_next = t3 ^ {8'h00, c2[31:8]};
|
||||
end
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
crc32_table[0 ] = 32'h00000000; crc32_table[1 ] = 32'h77073096;
|
||||
@@ -510,7 +509,7 @@ module matmul_axi_slave (
|
||||
end
|
||||
R_DATA: begin
|
||||
if (s_axi_rvalid && s_axi_rready) begin
|
||||
// 【修改点 3】删掉直接赋值 crc_stream_valid 的逻辑,移至专用 Pipeline 块
|
||||
// CRC is updated from completed compute results, not from C reads.
|
||||
if (r_cnt == r_len) begin
|
||||
s_axi_rvalid <= 1'b0;
|
||||
s_axi_rlast <= 1'b0;
|
||||
@@ -560,17 +559,6 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
// CRC register: update on each C data read beat, clear on write to 0x010
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_clear_pulse) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_stream_valid) begin
|
||||
crc_reg <= crc_next;
|
||||
end
|
||||
end
|
||||
|
||||
// ==========================================
|
||||
// 计算引擎 (Compute FSM)
|
||||
// ==========================================
|
||||
@@ -595,6 +583,23 @@ module matmul_axi_slave (
|
||||
reg [3:0] acc_idx_d1, acc_idx_d2, acc_idx_d3, acc_idx_d4;
|
||||
reg acc_bank_d1, acc_bank_d2, acc_bank_d3, acc_bank_d4;
|
||||
reg [4:0] pipe_cnt;
|
||||
wire [65:0] calc_c_result = ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
wire calc_crc_valid = (state == C_RUN) && (pipe_cnt >= 5'd4) && (pipe_cnt < 5'd20);
|
||||
wire [31:0] crc_calc_0 = crc32_word_next(crc_reg, calc_c_result[31:0]);
|
||||
wire [31:0] crc_calc_1 = crc32_word_next(crc_calc_0, calc_c_result[63:32]);
|
||||
wire [31:0] crc_calc_2 = crc32_word_next(crc_calc_1, {30'b0, calc_c_result[65:64]});
|
||||
|
||||
// CRC tracks completed C elements directly, independent of result writeback.
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (crc_clear_pulse) begin
|
||||
crc_reg <= 32'hFFFFFFFF;
|
||||
end else if (calc_crc_valid) begin
|
||||
crc_reg <= crc_calc_2;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
@@ -659,11 +664,9 @@ module matmul_axi_slave (
|
||||
// Accumulate results from 4 cycles ago (pipe_cnt 4-19)
|
||||
if (pipe_cnt >= 5'd4 && pipe_cnt < 5'd20) begin
|
||||
if (acc_bank_d4 == 1'b0)
|
||||
b0_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
b0_c[acc_idx_d4] <= calc_c_result;
|
||||
else
|
||||
b1_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
b1_c[acc_idx_d4] <= calc_c_result;
|
||||
end
|
||||
|
||||
if (pipe_cnt == 5'd20) begin
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef struct {
|
||||
#define STATUS_DONE_BIT (1 << 1)
|
||||
|
||||
#define SEQ_START_BIT (1 << 0)
|
||||
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||
#define SEQ_BUSY_BIT (1 << 0)
|
||||
#define SEQ_DONE_BIT (1 << 1)
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef struct {
|
||||
#define STATUS_DONE_BIT (1 << 1)
|
||||
|
||||
#define SEQ_START_BIT (1 << 0)
|
||||
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||
#define SEQ_BUSY_BIT (1 << 0)
|
||||
#define SEQ_DONE_BIT (1 << 1)
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ static void uart_puthex(unsigned int val)
|
||||
#define MATMUL_GROUP_NUM 5000
|
||||
#endif
|
||||
|
||||
#ifndef MATMUL_WRITEBACK_RESULTS
|
||||
#define MATMUL_WRITEBACK_RESULTS 1
|
||||
#endif
|
||||
|
||||
unsigned long UART_BASE = 0xbf000000;
|
||||
|
||||
#define EXTRAM_BASE_PHYS 0x1c400000u
|
||||
@@ -55,6 +59,7 @@ unsigned long UART_BASE = 0xbf000000;
|
||||
int main(void)
|
||||
{
|
||||
unsigned int crc;
|
||||
unsigned int seq_ctrl;
|
||||
|
||||
if (MATMUL_GROUP_NUM <= 0) {
|
||||
return 0;
|
||||
@@ -69,7 +74,11 @@ int main(void)
|
||||
DMA_SEQ->MAT_BASE = 0x1f500000u;
|
||||
DMA_SEQ->SRC_STRIDE = 128u;
|
||||
DMA_SEQ->DST_STRIDE = 192u;
|
||||
DMA_SEQ->CTRL = SEQ_START_BIT;
|
||||
seq_ctrl = SEQ_START_BIT;
|
||||
#if MATMUL_WRITEBACK_RESULTS == 0
|
||||
seq_ctrl |= SEQ_SKIP_STORE_BIT;
|
||||
#endif
|
||||
DMA_SEQ->CTRL = seq_ctrl;
|
||||
|
||||
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user