Compute matmul CRC before result store
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
// the matmul local endpoint/control interface.
|
// the matmul local endpoint/control interface.
|
||||||
//
|
//
|
||||||
// AXI-Lite register map, relative to this bridge window:
|
// 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)
|
// 0x04 STATUS bit0 busy, bit1 done (W1C)
|
||||||
// 0x08 SRC_BASE physical ExtRAM input base
|
// 0x08 SRC_BASE physical ExtRAM input base
|
||||||
// 0x0C DST_BASE physical ExtRAM result 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_load_idx;
|
||||||
logic [31:0] seq_store_idx;
|
logic [31:0] seq_store_idx;
|
||||||
logic seq_compute_bank;
|
logic seq_compute_bank;
|
||||||
|
logic seq_skip_writeback;
|
||||||
|
|
||||||
wire [7:0] wr_off = s_axil_awaddr[7:0];
|
wire [7:0] wr_off = s_axil_awaddr[7:0];
|
||||||
wire [7:0] rd_off = s_axil_araddr[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_load_idx <= 32'd0;
|
||||||
seq_store_idx <= 32'd0;
|
seq_store_idx <= 32'd0;
|
||||||
seq_compute_bank <= 1'b0;
|
seq_compute_bank <= 1'b0;
|
||||||
|
seq_skip_writeback <= 1'b0;
|
||||||
cdma_req_valid <= 1'b0;
|
cdma_req_valid <= 1'b0;
|
||||||
cdma_req_mode <= MODE_MEM2EP;
|
cdma_req_mode <= MODE_MEM2EP;
|
||||||
cdma_req_src <= '0;
|
cdma_req_src <= '0;
|
||||||
@@ -251,6 +253,7 @@ module cdma_matmul_bridge #(
|
|||||||
seq_load_idx <= 32'd0;
|
seq_load_idx <= 32'd0;
|
||||||
seq_store_idx <= 32'd0;
|
seq_store_idx <= 32'd0;
|
||||||
seq_compute_bank <= 1'b0;
|
seq_compute_bank <= 1'b0;
|
||||||
|
seq_skip_writeback <= s_axil_wstrb[0] && s_axil_wdata[1];
|
||||||
mat_crc_clear <= 1'b1;
|
mat_crc_clear <= 1'b1;
|
||||||
mat_done_clear <= 1'b1;
|
mat_done_clear <= 1'b1;
|
||||||
seq_state <= SQ_CLEAR;
|
seq_state <= SQ_CLEAR;
|
||||||
@@ -296,9 +299,21 @@ module cdma_matmul_bridge #(
|
|||||||
SQ_WAIT_DONE: begin
|
SQ_WAIT_DONE: begin
|
||||||
if (mat_done) begin
|
if (mat_done) begin
|
||||||
mat_done_clear <= 1'b1;
|
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;
|
seq_state <= SQ_STORE_START;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
SQ_STORE_START: begin
|
SQ_STORE_START: begin
|
||||||
cdma_req_mode <= MODE_EP2MEM;
|
cdma_req_mode <= MODE_EP2MEM;
|
||||||
|
|||||||
@@ -183,22 +183,21 @@ module matmul_axi_slave (
|
|||||||
reg [31:0] crc32_table [0:255];
|
reg [31:0] crc32_table [0:255];
|
||||||
reg [31:0] crc_reg;
|
reg [31:0] crc_reg;
|
||||||
|
|
||||||
wire [31:0] crc_stream_data = (ep_rd_valid && ep_rd_ready) ? ep_rd_data : s_axi_rdata;
|
function [31:0] crc32_word_next;
|
||||||
wire crc_axi_valid = (r_state == R_DATA) && s_axi_rvalid && s_axi_rready &&
|
input [31:0] crc_in;
|
||||||
((r_offset >= ADDR_B0_C && r_offset < (ADDR_B0_C + 12'h0C0)) ||
|
input [31:0] data_in;
|
||||||
(r_offset >= ADDR_B1_C && r_offset < (ADDR_B1_C + 12'h0C0)));
|
reg [31:0] t0, c0, t1, c1, t2, c2, t3;
|
||||||
wire crc_ep_valid = ep_rd_valid && ep_rd_ready && (ep_rd_word_addr < 8'd48);
|
begin
|
||||||
wire crc_stream_valid = crc_axi_valid || crc_ep_valid;
|
t0 = crc32_table[(crc_in[7:0] ^ data_in[7:0])];
|
||||||
|
c0 = t0 ^ {8'h00, crc_in[31:8]};
|
||||||
wire [31:0] crc_t0, crc_c0, crc_t1, crc_c1, crc_t2, crc_c2, crc_t3, crc_next;
|
t1 = crc32_table[(c0[7:0] ^ data_in[15:8])];
|
||||||
assign crc_t0 = crc32_table[(crc_reg[7:0] ^ crc_stream_data[7:0])];
|
c1 = t1 ^ {8'h00, c0[31:8]};
|
||||||
assign crc_c0 = crc_t0 ^ {8'h00, crc_reg[31:8]};
|
t2 = crc32_table[(c1[7:0] ^ data_in[23:16])];
|
||||||
assign crc_t1 = crc32_table[(crc_c0[7:0] ^ crc_stream_data[15:8])];
|
c2 = t2 ^ {8'h00, c1[31:8]};
|
||||||
assign crc_c1 = crc_t1 ^ {8'h00, crc_c0[31:8]};
|
t3 = crc32_table[(c2[7:0] ^ data_in[31:24])];
|
||||||
assign crc_t2 = crc32_table[(crc_c1[7:0] ^ crc_stream_data[23:16])];
|
crc32_word_next = t3 ^ {8'h00, c2[31:8]};
|
||||||
assign crc_c2 = crc_t2 ^ {8'h00, crc_c1[31:8]};
|
end
|
||||||
assign crc_t3 = crc32_table[(crc_c2[7:0] ^ crc_stream_data[31:24])];
|
endfunction
|
||||||
assign crc_next = crc_t3 ^ {8'h00, crc_c2[31:8]};
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
crc32_table[0 ] = 32'h00000000; crc32_table[1 ] = 32'h77073096;
|
crc32_table[0 ] = 32'h00000000; crc32_table[1 ] = 32'h77073096;
|
||||||
@@ -510,7 +509,7 @@ module matmul_axi_slave (
|
|||||||
end
|
end
|
||||||
R_DATA: begin
|
R_DATA: begin
|
||||||
if (s_axi_rvalid && s_axi_rready) 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
|
if (r_cnt == r_len) begin
|
||||||
s_axi_rvalid <= 1'b0;
|
s_axi_rvalid <= 1'b0;
|
||||||
s_axi_rlast <= 1'b0;
|
s_axi_rlast <= 1'b0;
|
||||||
@@ -560,17 +559,6 @@ module matmul_axi_slave (
|
|||||||
end
|
end
|
||||||
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)
|
// 计算引擎 (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 [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 acc_bank_d1, acc_bank_d2, acc_bank_d3, acc_bank_d4;
|
||||||
reg [4:0] pipe_cnt;
|
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
|
always @(posedge clk) begin
|
||||||
if (!resetn) begin
|
if (!resetn) begin
|
||||||
@@ -659,11 +664,9 @@ module matmul_axi_slave (
|
|||||||
// Accumulate results from 4 cycles ago (pipe_cnt 4-19)
|
// Accumulate results from 4 cycles ago (pipe_cnt 4-19)
|
||||||
if (pipe_cnt >= 5'd4 && pipe_cnt < 5'd20) begin
|
if (pipe_cnt >= 5'd4 && pipe_cnt < 5'd20) begin
|
||||||
if (acc_bank_d4 == 1'b0)
|
if (acc_bank_d4 == 1'b0)
|
||||||
b0_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
b0_c[acc_idx_d4] <= calc_c_result;
|
||||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
|
||||||
else
|
else
|
||||||
b1_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
b1_c[acc_idx_d4] <= calc_c_result;
|
||||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (pipe_cnt == 5'd20) begin
|
if (pipe_cnt == 5'd20) begin
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ typedef struct {
|
|||||||
#define STATUS_DONE_BIT (1 << 1)
|
#define STATUS_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
#define SEQ_START_BIT (1 << 0)
|
#define SEQ_START_BIT (1 << 0)
|
||||||
|
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||||
#define SEQ_BUSY_BIT (1 << 0)
|
#define SEQ_BUSY_BIT (1 << 0)
|
||||||
#define SEQ_DONE_BIT (1 << 1)
|
#define SEQ_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
#define STATUS_DONE_BIT (1 << 1)
|
#define STATUS_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
#define SEQ_START_BIT (1 << 0)
|
#define SEQ_START_BIT (1 << 0)
|
||||||
|
#define SEQ_SKIP_STORE_BIT (1 << 1)
|
||||||
#define SEQ_BUSY_BIT (1 << 0)
|
#define SEQ_BUSY_BIT (1 << 0)
|
||||||
#define SEQ_DONE_BIT (1 << 1)
|
#define SEQ_DONE_BIT (1 << 1)
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ static void uart_puthex(unsigned int val)
|
|||||||
#define MATMUL_GROUP_NUM 5000
|
#define MATMUL_GROUP_NUM 5000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MATMUL_WRITEBACK_RESULTS
|
||||||
|
#define MATMUL_WRITEBACK_RESULTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long UART_BASE = 0xbf000000;
|
unsigned long UART_BASE = 0xbf000000;
|
||||||
|
|
||||||
#define EXTRAM_BASE_PHYS 0x1c400000u
|
#define EXTRAM_BASE_PHYS 0x1c400000u
|
||||||
@@ -55,6 +59,7 @@ unsigned long UART_BASE = 0xbf000000;
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
|
unsigned int seq_ctrl;
|
||||||
|
|
||||||
if (MATMUL_GROUP_NUM <= 0) {
|
if (MATMUL_GROUP_NUM <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -69,7 +74,11 @@ int main(void)
|
|||||||
DMA_SEQ->MAT_BASE = 0x1f500000u;
|
DMA_SEQ->MAT_BASE = 0x1f500000u;
|
||||||
DMA_SEQ->SRC_STRIDE = 128u;
|
DMA_SEQ->SRC_STRIDE = 128u;
|
||||||
DMA_SEQ->DST_STRIDE = 192u;
|
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) {
|
while ((DMA_SEQ->STATUS & SEQ_DONE_BIT) == 0u) {
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user