Add direct CDMA matmul path
This commit is contained in:
@@ -80,6 +80,28 @@ module matmul_axi_slave (
|
||||
output reg s_axi_rvalid,
|
||||
input s_axi_rready,
|
||||
|
||||
// CDMA local endpoint port
|
||||
input ep_wr_valid,
|
||||
input [3:0] ep_wr_id,
|
||||
input [3:0] ep_wr_bank,
|
||||
input [7:0] ep_wr_word_addr,
|
||||
input [31:0] ep_wr_data,
|
||||
output ep_wr_ready,
|
||||
|
||||
input ep_rd_valid,
|
||||
input [3:0] ep_rd_id,
|
||||
input [3:0] ep_rd_bank,
|
||||
input [7:0] ep_rd_word_addr,
|
||||
output reg [31:0] ep_rd_data,
|
||||
output ep_rd_ready,
|
||||
|
||||
// Direct control from the CDMA/matmul bridge
|
||||
input mat_start_valid,
|
||||
input mat_start_bank,
|
||||
input mat_done_clear,
|
||||
input mat_crc_clear,
|
||||
output mat_done,
|
||||
|
||||
// Interrupt output (active high level, pulsed by calc_done)
|
||||
output intr
|
||||
);
|
||||
@@ -115,6 +137,33 @@ module matmul_axi_slave (
|
||||
reg [31:0] b1_b [0:15];
|
||||
reg [65:0] b1_c [0:15];
|
||||
|
||||
assign ep_wr_ready = 1'b1;
|
||||
assign ep_rd_ready = 1'b1;
|
||||
assign mat_done = done;
|
||||
|
||||
wire [3:0] ep_wr_idx = ep_wr_word_addr[3:0];
|
||||
wire [7:0] ep_rd_elem_raw = ep_rd_word_addr / 8'd3;
|
||||
wire [7:0] ep_rd_part_raw = ep_rd_word_addr % 8'd3;
|
||||
wire [3:0] ep_rd_elem = ep_rd_elem_raw[3:0];
|
||||
wire [1:0] ep_rd_part = ep_rd_part_raw[1:0];
|
||||
wire [65:0] ep_rd_c0 = b0_c[ep_rd_elem];
|
||||
wire [65:0] ep_rd_c1 = b1_c[ep_rd_elem];
|
||||
|
||||
always @(*) begin
|
||||
ep_rd_data = 32'b0;
|
||||
if (ep_rd_word_addr < 8'd48) begin
|
||||
if (ep_rd_bank[0] == 1'b0) begin
|
||||
if (ep_rd_part == 2'd0) ep_rd_data = ep_rd_c0[31:0];
|
||||
else if (ep_rd_part == 2'd1) ep_rd_data = ep_rd_c0[63:32];
|
||||
else ep_rd_data = {30'b0, ep_rd_c0[65:64]};
|
||||
end else begin
|
||||
if (ep_rd_part == 2'd0) ep_rd_data = ep_rd_c1[31:0];
|
||||
else if (ep_rd_part == 2'd1) ep_rd_data = ep_rd_c1[63:32];
|
||||
else ep_rd_data = {30'b0, ep_rd_c1[65:64]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function [31:0] apply_wstrb;
|
||||
input [31:0] old_value;
|
||||
input [31:0] new_value;
|
||||
@@ -134,10 +183,12 @@ module matmul_axi_slave (
|
||||
reg [31:0] crc32_table [0:255];
|
||||
reg [31:0] crc_reg;
|
||||
|
||||
wire [31:0] crc_stream_data = s_axi_rdata;
|
||||
wire crc_stream_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 [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])];
|
||||
@@ -305,7 +356,8 @@ module matmul_axi_slave (
|
||||
reg calc_done_pulse;
|
||||
|
||||
// 【修改点 1】单独引出一个写脉冲信号给 CRC 清零用
|
||||
wire crc_clear_pulse = (w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC);
|
||||
wire crc_clear_pulse = ((w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC)) ||
|
||||
mat_crc_clear;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
@@ -320,10 +372,34 @@ module matmul_axi_slave (
|
||||
end else begin
|
||||
if (req_0 && state == C_RUN && cur_bank == 1'b0) req_0 <= 1'b0;
|
||||
if (req_1 && state == C_RUN && cur_bank == 1'b1) req_1 <= 1'b0;
|
||||
|
||||
if (mat_start_valid) begin
|
||||
if (mat_start_bank) req_1 <= 1'b1;
|
||||
else req_0 <= 1'b1;
|
||||
end
|
||||
|
||||
if (calc_done_pulse) begin
|
||||
done <= 1'b1;
|
||||
end
|
||||
|
||||
if (mat_done_clear) begin
|
||||
done <= 1'b0;
|
||||
error <= 1'b0;
|
||||
end
|
||||
|
||||
if (ep_wr_valid && ep_wr_ready) begin
|
||||
if (ep_wr_word_addr < 8'd16) begin
|
||||
if (ep_wr_bank[0] == 1'b0)
|
||||
b0_a[ep_wr_idx] <= ep_wr_data;
|
||||
else
|
||||
b1_a[ep_wr_idx] <= ep_wr_data;
|
||||
end else if (ep_wr_word_addr < 8'd32) begin
|
||||
if (ep_wr_bank[0] == 1'b0)
|
||||
b0_b[ep_wr_idx] <= ep_wr_data;
|
||||
else
|
||||
b1_b[ep_wr_idx] <= ep_wr_data;
|
||||
end
|
||||
end
|
||||
|
||||
case (w_state)
|
||||
W_IDLE: begin
|
||||
@@ -604,4 +680,4 @@ module matmul_axi_slave (
|
||||
|
||||
assign intr = done;
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user