Add matmul AXI master path
This commit is contained in:
@@ -95,6 +95,47 @@ module matmul_axi_slave (
|
||||
output reg [31:0] ep_rd_data,
|
||||
output ep_rd_ready,
|
||||
|
||||
// AXI master port for autonomous matrix stream load/store
|
||||
output reg [3:0] m_axi_awid,
|
||||
output reg [31:0] m_axi_awaddr,
|
||||
output reg [7:0] m_axi_awlen,
|
||||
output reg [2:0] m_axi_awsize,
|
||||
output reg [1:0] m_axi_awburst,
|
||||
output reg m_axi_awlock,
|
||||
output reg [3:0] m_axi_awcache,
|
||||
output reg [2:0] m_axi_awprot,
|
||||
output reg m_axi_awvalid,
|
||||
input m_axi_awready,
|
||||
|
||||
output reg [31:0] m_axi_wdata,
|
||||
output reg [3:0] m_axi_wstrb,
|
||||
output reg m_axi_wlast,
|
||||
output reg m_axi_wvalid,
|
||||
input m_axi_wready,
|
||||
|
||||
input [3:0] m_axi_bid,
|
||||
input [1:0] m_axi_bresp,
|
||||
input m_axi_bvalid,
|
||||
output reg m_axi_bready,
|
||||
|
||||
output reg [3:0] m_axi_arid,
|
||||
output reg [31:0] m_axi_araddr,
|
||||
output reg [7:0] m_axi_arlen,
|
||||
output reg [2:0] m_axi_arsize,
|
||||
output reg [1:0] m_axi_arburst,
|
||||
output reg m_axi_arlock,
|
||||
output reg [3:0] m_axi_arcache,
|
||||
output reg [2:0] m_axi_arprot,
|
||||
output reg m_axi_arvalid,
|
||||
input m_axi_arready,
|
||||
|
||||
input [3:0] m_axi_rid,
|
||||
input [31:0] m_axi_rdata,
|
||||
input [1:0] m_axi_rresp,
|
||||
input m_axi_rlast,
|
||||
input m_axi_rvalid,
|
||||
output reg m_axi_rready,
|
||||
|
||||
// Interrupt output (active high level, pulsed by calc_done)
|
||||
output intr
|
||||
);
|
||||
@@ -105,6 +146,11 @@ module matmul_axi_slave (
|
||||
localparam ADDR_CTRL = 12'h000;
|
||||
localparam ADDR_STATUS = 12'h004;
|
||||
localparam ADDR_CRC = 12'h010;
|
||||
localparam ADDR_DMA_SRC_BASE = 12'h020;
|
||||
localparam ADDR_DMA_DST_BASE = 12'h024;
|
||||
localparam ADDR_DMA_GROUPS = 12'h028;
|
||||
localparam ADDR_DMA_SRC_STRIDE = 12'h02C;
|
||||
localparam ADDR_DMA_DST_STRIDE = 12'h030;
|
||||
|
||||
localparam ADDR_B0_A = 12'h100;
|
||||
localparam ADDR_B0_B = 12'h140;
|
||||
@@ -131,6 +177,28 @@ module matmul_axi_slave (
|
||||
reg [31:0] b1_b [0:15];
|
||||
reg [65:0] b1_c [0:15];
|
||||
|
||||
reg [31:0] dma_src_base;
|
||||
reg [31:0] dma_dst_base;
|
||||
reg [31:0] dma_groups;
|
||||
reg [31:0] dma_src_stride;
|
||||
reg [31:0] dma_dst_stride;
|
||||
reg dma_busy;
|
||||
reg dma_done;
|
||||
reg [31:0] load_group;
|
||||
reg [31:0] store_group;
|
||||
reg [31:0] completed_groups;
|
||||
reg [1:0] bank_loaded;
|
||||
reg [1:0] bank_store_pending;
|
||||
reg [1:0] bank_storing;
|
||||
reg [1:0] bank_compute_pending;
|
||||
reg dma_compute_bank;
|
||||
reg dma_load_bank;
|
||||
reg dma_store_bank;
|
||||
reg dma_start_pulse;
|
||||
reg dma_done_clear_pulse;
|
||||
reg dma_req0_pulse;
|
||||
reg dma_req1_pulse;
|
||||
|
||||
assign ep_wr_ready = 1'b1;
|
||||
assign ep_rd_ready = 1'b1;
|
||||
|
||||
@@ -177,12 +245,15 @@ 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_data : s_axi_rdata;
|
||||
wire crc_dma_valid;
|
||||
wire [31:0] crc_dma_data;
|
||||
wire [31:0] crc_stream_data = crc_dma_valid ? crc_dma_data :
|
||||
(ep_rd_valid ? 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 crc_stream_valid = crc_axi_valid || crc_ep_valid || crc_dma_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])];
|
||||
@@ -348,6 +419,46 @@ module matmul_axi_slave (
|
||||
reg [1:0] state;
|
||||
reg cur_bank;
|
||||
reg calc_done_pulse;
|
||||
|
||||
localparam DMA_RD_IDLE = 2'd0;
|
||||
localparam DMA_RD_ADDR = 2'd1;
|
||||
localparam DMA_RD_DATA = 2'd2;
|
||||
reg [1:0] dma_rd_state;
|
||||
reg [4:0] dma_rd_count;
|
||||
reg dma_rd_bank;
|
||||
wire [3:0] dma_rd_word_idx = dma_rd_count[3:0];
|
||||
wire dma_rd_commit = (dma_rd_state == DMA_RD_DATA) && m_axi_rvalid && m_axi_rready;
|
||||
|
||||
localparam DMA_WR_IDLE = 2'd0;
|
||||
localparam DMA_WR_ADDR = 2'd1;
|
||||
localparam DMA_WR_DATA = 2'd2;
|
||||
localparam DMA_WR_RESP = 2'd3;
|
||||
reg [1:0] dma_wr_state;
|
||||
reg [5:0] dma_wr_count;
|
||||
|
||||
wire [7:0] dma_wr_elem_raw = dma_wr_count / 6'd3;
|
||||
wire [7:0] dma_wr_part_raw = dma_wr_count % 6'd3;
|
||||
wire [3:0] dma_wr_elem = dma_wr_elem_raw[3:0];
|
||||
wire [1:0] dma_wr_part = dma_wr_part_raw[1:0];
|
||||
wire [65:0] dma_wr_c0 = b0_c[dma_wr_elem];
|
||||
wire [65:0] dma_wr_c1 = b1_c[dma_wr_elem];
|
||||
wire [65:0] dma_wr_c = dma_store_bank ? dma_wr_c1 : dma_wr_c0;
|
||||
wire [31:0] dma_wr_word =
|
||||
(dma_wr_part == 2'd0) ? dma_wr_c[31:0] :
|
||||
(dma_wr_part == 2'd1) ? dma_wr_c[63:32] :
|
||||
{30'b0, dma_wr_c[65:64]};
|
||||
wire [5:0] dma_wr_next_count = dma_wr_count + 6'd1;
|
||||
wire [7:0] dma_wr_next_elem_raw = dma_wr_next_count / 6'd3;
|
||||
wire [7:0] dma_wr_next_part_raw = dma_wr_next_count % 6'd3;
|
||||
wire [3:0] dma_wr_next_elem = dma_wr_next_elem_raw[3:0];
|
||||
wire [1:0] dma_wr_next_part = dma_wr_next_part_raw[1:0];
|
||||
wire [65:0] dma_wr_next_c0 = b0_c[dma_wr_next_elem];
|
||||
wire [65:0] dma_wr_next_c1 = b1_c[dma_wr_next_elem];
|
||||
wire [65:0] dma_wr_next_c = dma_store_bank ? dma_wr_next_c1 : dma_wr_next_c0;
|
||||
wire [31:0] dma_wr_word_next =
|
||||
(dma_wr_next_part == 2'd0) ? dma_wr_next_c[31:0] :
|
||||
(dma_wr_next_part == 2'd1) ? dma_wr_next_c[63:32] :
|
||||
{30'b0, dma_wr_next_c[65:64]};
|
||||
|
||||
// 【修改点 1】单独引出一个写脉冲信号给 CRC 清零用
|
||||
wire crc_clear_pulse = (w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC);
|
||||
@@ -364,7 +475,17 @@ module matmul_axi_slave (
|
||||
req_1 <= 1'b0;
|
||||
done_count <= 2'd0;
|
||||
error <= 1'b0;
|
||||
dma_src_base <= 32'd0;
|
||||
dma_dst_base <= 32'd0;
|
||||
dma_groups <= 32'd0;
|
||||
dma_src_stride <= 32'd128;
|
||||
dma_dst_stride <= 32'd192;
|
||||
dma_start_pulse <= 1'b0;
|
||||
dma_done_clear_pulse <= 1'b0;
|
||||
end else begin
|
||||
dma_start_pulse <= 1'b0;
|
||||
dma_done_clear_pulse <= 1'b0;
|
||||
|
||||
if (ep_wr_valid && ep_wr_ready) begin
|
||||
if (ep_wr_bank[0] == 1'b0) begin
|
||||
if (ep_wr_word_addr < 8'd16)
|
||||
@@ -383,8 +504,24 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
if (dma_rd_commit) begin
|
||||
if (dma_rd_bank == 1'b0) begin
|
||||
if (dma_rd_count < 5'd16)
|
||||
b0_a[dma_rd_word_idx] <= m_axi_rdata;
|
||||
else
|
||||
b0_b[dma_rd_word_idx] <= m_axi_rdata;
|
||||
end else begin
|
||||
if (dma_rd_count < 5'd16)
|
||||
b1_a[dma_rd_word_idx] <= m_axi_rdata;
|
||||
else
|
||||
b1_b[dma_rd_word_idx] <= m_axi_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
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 (dma_req0_pulse) req_0 <= 1'b1;
|
||||
if (dma_req1_pulse) req_1 <= 1'b1;
|
||||
|
||||
case (w_state)
|
||||
W_IDLE: begin
|
||||
@@ -403,10 +540,22 @@ module matmul_axi_slave (
|
||||
if (w_offset == ADDR_CTRL) begin
|
||||
if (s_axi_wdata[0]) req_0 <= 1'b1;
|
||||
if (s_axi_wdata[1]) req_1 <= 1'b1;
|
||||
if (s_axi_wdata[8]) dma_start_pulse <= 1'b1;
|
||||
end
|
||||
else if (w_offset == ADDR_STATUS) begin
|
||||
if (s_axi_wdata[2]) error <= 1'b0;
|
||||
if (s_axi_wdata[4]) dma_done_clear_pulse <= 1'b1;
|
||||
end
|
||||
else if (w_offset == ADDR_DMA_SRC_BASE)
|
||||
dma_src_base <= apply_wstrb(dma_src_base, s_axi_wdata, s_axi_wstrb);
|
||||
else if (w_offset == ADDR_DMA_DST_BASE)
|
||||
dma_dst_base <= apply_wstrb(dma_dst_base, s_axi_wdata, s_axi_wstrb);
|
||||
else if (w_offset == ADDR_DMA_GROUPS)
|
||||
dma_groups <= apply_wstrb(dma_groups, s_axi_wdata, s_axi_wstrb);
|
||||
else if (w_offset == ADDR_DMA_SRC_STRIDE)
|
||||
dma_src_stride <= apply_wstrb(dma_src_stride, s_axi_wdata, s_axi_wstrb);
|
||||
else if (w_offset == ADDR_DMA_DST_STRIDE)
|
||||
dma_dst_stride <= apply_wstrb(dma_dst_stride, s_axi_wdata, s_axi_wstrb);
|
||||
// 【修改点 2】删除 else if (w_offset == ADDR_CRC) { crc_reg <= ... } 防止多重驱动
|
||||
else if (w_offset >= ADDR_B0_A && w_offset < ADDR_B0_B)
|
||||
b0_a[(w_offset - ADDR_B0_A) >> 2] <= apply_wstrb(b0_a[(w_offset - ADDR_B0_A) >> 2], s_axi_wdata, s_axi_wstrb);
|
||||
@@ -528,7 +677,17 @@ module matmul_axi_slave (
|
||||
else if (current_r_offset == ADDR_CRC)
|
||||
s_axi_rdata = crc_reg ^ 32'hFFFFFFFF;
|
||||
else if (current_r_offset == ADDR_STATUS)
|
||||
s_axi_rdata = {29'b0, error, done, busy};
|
||||
s_axi_rdata = {27'b0, dma_done, dma_busy, error, done, busy};
|
||||
else if (current_r_offset == ADDR_DMA_SRC_BASE)
|
||||
s_axi_rdata = dma_src_base;
|
||||
else if (current_r_offset == ADDR_DMA_DST_BASE)
|
||||
s_axi_rdata = dma_dst_base;
|
||||
else if (current_r_offset == ADDR_DMA_GROUPS)
|
||||
s_axi_rdata = dma_groups;
|
||||
else if (current_r_offset == ADDR_DMA_SRC_STRIDE)
|
||||
s_axi_rdata = dma_src_stride;
|
||||
else if (current_r_offset == ADDR_DMA_DST_STRIDE)
|
||||
s_axi_rdata = dma_dst_stride;
|
||||
else if (current_r_offset >= ADDR_B0_A && current_r_offset < ADDR_B0_B)
|
||||
s_axi_rdata = b0_a[(current_r_offset - ADDR_B0_A) >> 2];
|
||||
else if (current_r_offset >= ADDR_B0_B && current_r_offset < ADDR_B0_C)
|
||||
@@ -709,6 +868,206 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
// ==========================================
|
||||
// Autonomous AXI master loader/storer
|
||||
// ==========================================
|
||||
assign crc_dma_valid = (dma_wr_state == DMA_WR_DATA) && m_axi_wvalid && m_axi_wready;
|
||||
assign crc_dma_data = m_axi_wdata;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
dma_busy <= 1'b0;
|
||||
dma_done <= 1'b0;
|
||||
load_group <= 32'd0;
|
||||
store_group <= 32'd0;
|
||||
completed_groups <= 32'd0;
|
||||
bank_loaded <= 2'b00;
|
||||
bank_store_pending <= 2'b00;
|
||||
bank_storing <= 2'b00;
|
||||
bank_compute_pending <= 2'b00;
|
||||
dma_compute_bank <= 1'b0;
|
||||
dma_load_bank <= 1'b0;
|
||||
dma_store_bank <= 1'b0;
|
||||
dma_rd_state <= DMA_RD_IDLE;
|
||||
dma_rd_count <= 5'd0;
|
||||
dma_rd_bank <= 1'b0;
|
||||
dma_wr_state <= DMA_WR_IDLE;
|
||||
dma_wr_count <= 6'd0;
|
||||
|
||||
m_axi_arid <= 4'd0;
|
||||
m_axi_araddr <= 32'd0;
|
||||
m_axi_arlen <= 8'd31;
|
||||
m_axi_arsize <= 3'd2;
|
||||
m_axi_arburst <= 2'b01;
|
||||
m_axi_arlock <= 1'b0;
|
||||
m_axi_arcache <= 4'b0;
|
||||
m_axi_arprot <= 3'b0;
|
||||
m_axi_arvalid <= 1'b0;
|
||||
m_axi_rready <= 1'b0;
|
||||
|
||||
m_axi_awid <= 4'd0;
|
||||
m_axi_awaddr <= 32'd0;
|
||||
m_axi_awlen <= 8'd47;
|
||||
m_axi_awsize <= 3'd2;
|
||||
m_axi_awburst <= 2'b01;
|
||||
m_axi_awlock <= 1'b0;
|
||||
m_axi_awcache <= 4'b0;
|
||||
m_axi_awprot <= 3'b0;
|
||||
m_axi_awvalid <= 1'b0;
|
||||
m_axi_wdata <= 32'd0;
|
||||
m_axi_wstrb <= 4'hF;
|
||||
m_axi_wlast <= 1'b0;
|
||||
m_axi_wvalid <= 1'b0;
|
||||
m_axi_bready <= 1'b0;
|
||||
dma_req0_pulse <= 1'b0;
|
||||
dma_req1_pulse <= 1'b0;
|
||||
end else begin
|
||||
dma_req0_pulse <= 1'b0;
|
||||
dma_req1_pulse <= 1'b0;
|
||||
|
||||
if (dma_done_clear_pulse)
|
||||
dma_done <= 1'b0;
|
||||
|
||||
if (dma_start_pulse && !dma_busy && dma_groups != 32'd0) begin
|
||||
dma_busy <= 1'b1;
|
||||
dma_done <= 1'b0;
|
||||
load_group <= 32'd0;
|
||||
store_group <= 32'd0;
|
||||
completed_groups <= 32'd0;
|
||||
bank_loaded <= 2'b00;
|
||||
bank_store_pending <= 2'b00;
|
||||
bank_storing <= 2'b00;
|
||||
bank_compute_pending <= 2'b00;
|
||||
dma_compute_bank <= 1'b0;
|
||||
dma_load_bank <= 1'b0;
|
||||
dma_store_bank <= 1'b0;
|
||||
dma_rd_state <= DMA_RD_IDLE;
|
||||
dma_wr_state <= DMA_WR_IDLE;
|
||||
end
|
||||
|
||||
if (dma_busy) begin
|
||||
if (state == C_RUN)
|
||||
bank_compute_pending[cur_bank] <= 1'b0;
|
||||
|
||||
if (bank_loaded[0] && !req_0 && !bank_store_pending[0] && !bank_storing[0] &&
|
||||
!bank_compute_pending[0] && !(state == C_RUN && cur_bank == 1'b0)) begin
|
||||
dma_req0_pulse <= 1'b1;
|
||||
bank_loaded[0] <= 1'b0;
|
||||
bank_compute_pending[0] <= 1'b1;
|
||||
dma_compute_bank <= 1'b0;
|
||||
end else if (bank_loaded[1] && !req_1 && !bank_store_pending[1] && !bank_storing[1] &&
|
||||
!bank_compute_pending[1] && !(state == C_RUN && cur_bank == 1'b1)) begin
|
||||
dma_req1_pulse <= 1'b1;
|
||||
bank_loaded[1] <= 1'b0;
|
||||
bank_compute_pending[1] <= 1'b1;
|
||||
dma_compute_bank <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (calc_done_pulse && dma_busy) begin
|
||||
bank_store_pending[cur_bank] <= 1'b1;
|
||||
end
|
||||
|
||||
case (dma_rd_state)
|
||||
DMA_RD_IDLE: begin
|
||||
m_axi_arvalid <= 1'b0;
|
||||
m_axi_rready <= 1'b0;
|
||||
if (dma_busy && load_group < dma_groups && !bank_loaded[dma_load_bank] &&
|
||||
!bank_compute_pending[dma_load_bank] &&
|
||||
!((dma_load_bank == 1'b0) ? req_0 : req_1) &&
|
||||
!(state == C_RUN && cur_bank == dma_load_bank)) begin
|
||||
dma_rd_bank <= dma_load_bank;
|
||||
dma_rd_count <= 5'd0;
|
||||
m_axi_araddr <= dma_src_base + (load_group * dma_src_stride);
|
||||
m_axi_arlen <= 8'd31;
|
||||
m_axi_arsize <= 3'd2;
|
||||
m_axi_arburst <= 2'b01;
|
||||
m_axi_arvalid <= 1'b1;
|
||||
dma_rd_state <= DMA_RD_ADDR;
|
||||
end
|
||||
end
|
||||
DMA_RD_ADDR: begin
|
||||
if (m_axi_arvalid && m_axi_arready) begin
|
||||
m_axi_arvalid <= 1'b0;
|
||||
m_axi_rready <= 1'b1;
|
||||
dma_rd_state <= DMA_RD_DATA;
|
||||
end
|
||||
end
|
||||
DMA_RD_DATA: begin
|
||||
if (m_axi_rvalid && m_axi_rready) begin
|
||||
if (m_axi_rlast) begin
|
||||
m_axi_rready <= 1'b0;
|
||||
bank_loaded[dma_rd_bank] <= 1'b1;
|
||||
load_group <= load_group + 32'd1;
|
||||
dma_load_bank <= ~dma_load_bank;
|
||||
dma_rd_state <= DMA_RD_IDLE;
|
||||
end else begin
|
||||
dma_rd_count <= dma_rd_count + 5'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
default: dma_rd_state <= DMA_RD_IDLE;
|
||||
endcase
|
||||
|
||||
case (dma_wr_state)
|
||||
DMA_WR_IDLE: begin
|
||||
m_axi_awvalid <= 1'b0;
|
||||
m_axi_wvalid <= 1'b0;
|
||||
m_axi_bready <= 1'b0;
|
||||
if (dma_busy && bank_store_pending[dma_store_bank]) begin
|
||||
dma_wr_count <= 6'd0;
|
||||
bank_store_pending[dma_store_bank] <= 1'b0;
|
||||
bank_storing[dma_store_bank] <= 1'b1;
|
||||
m_axi_awaddr <= dma_dst_base + (store_group * dma_dst_stride);
|
||||
m_axi_awlen <= 8'd47;
|
||||
m_axi_awsize <= 3'd2;
|
||||
m_axi_awburst <= 2'b01;
|
||||
m_axi_awvalid <= 1'b1;
|
||||
dma_wr_state <= DMA_WR_ADDR;
|
||||
end
|
||||
end
|
||||
DMA_WR_ADDR: begin
|
||||
if (m_axi_awvalid && m_axi_awready) begin
|
||||
m_axi_awvalid <= 1'b0;
|
||||
m_axi_wvalid <= 1'b1;
|
||||
m_axi_wdata <= dma_wr_word;
|
||||
m_axi_wlast <= 1'b0;
|
||||
dma_wr_state <= DMA_WR_DATA;
|
||||
end
|
||||
end
|
||||
DMA_WR_DATA: begin
|
||||
if (m_axi_wvalid && m_axi_wready) begin
|
||||
if (dma_wr_count == 6'd47) begin
|
||||
m_axi_wvalid <= 1'b0;
|
||||
m_axi_wlast <= 1'b0;
|
||||
m_axi_bready <= 1'b1;
|
||||
dma_wr_state <= DMA_WR_RESP;
|
||||
end else begin
|
||||
dma_wr_count <= dma_wr_count + 6'd1;
|
||||
m_axi_wdata <= dma_wr_word_next;
|
||||
m_axi_wlast <= (dma_wr_count == 6'd46);
|
||||
end
|
||||
end
|
||||
end
|
||||
DMA_WR_RESP: begin
|
||||
if (m_axi_bvalid && m_axi_bready) begin
|
||||
m_axi_bready <= 1'b0;
|
||||
bank_storing[dma_store_bank] <= 1'b0;
|
||||
dma_store_bank <= ~dma_store_bank;
|
||||
store_group <= store_group + 32'd1;
|
||||
completed_groups <= completed_groups + 32'd1;
|
||||
if ((completed_groups + 32'd1) >= dma_groups) begin
|
||||
dma_busy <= 1'b0;
|
||||
dma_done <= 1'b1;
|
||||
end
|
||||
dma_wr_state <= DMA_WR_IDLE;
|
||||
end
|
||||
end
|
||||
default: dma_wr_state <= DMA_WR_IDLE;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign intr = done;
|
||||
|
||||
endmodule
|
||||
|
||||
3431
rtl/soc_top.v
3431
rtl/soc_top.v
File diff suppressed because it is too large
Load Diff
108
sdk/axi_ram.mif
108
sdk/axi_ram.mif
@@ -52,7 +52,7 @@
|
||||
00000011100000000110000000001101
|
||||
00000100000000000000000110101100
|
||||
00011100000000000000000000101100
|
||||
00000010101100111111000110001100
|
||||
00000010101101001111000110001100
|
||||
00011100000000000001000000001101
|
||||
00000010101111001001000110101101
|
||||
00011100000000000001000000001110
|
||||
@@ -94,7 +94,7 @@
|
||||
00000000000101010000000000001110
|
||||
00101001000000000001000110101110
|
||||
00011100000000000000000000001100
|
||||
00000010100011000001000110001100
|
||||
00000010100011010001000110001100
|
||||
00000100000000000011000000101100
|
||||
00000011100000000000010000001101
|
||||
00000100000000010001000000101101
|
||||
@@ -146,67 +146,70 @@
|
||||
00010101011111100000000000010000
|
||||
00101001100000000111000001100001
|
||||
00101001100000000110000001110111
|
||||
00101001100000000101000001111000
|
||||
00000010100000010011010000001100
|
||||
00011100000000000001000000001111
|
||||
00000010101101101011000111101111
|
||||
00000010101101101010000111101111
|
||||
00000011100000000001011000001101
|
||||
00101001100000000011000001101100
|
||||
00101010000000000011000001101110
|
||||
00000010100000000000010111101111
|
||||
00000011010000000000000000000000
|
||||
00101010000000000000000110101100
|
||||
00000011010000001000000110001100
|
||||
01011011111111111111100110000000
|
||||
00101001000000000000001000001110
|
||||
00101000000000000000000111101100
|
||||
01011111111111111101110110000000
|
||||
01010100000001100011100000000000
|
||||
00010101011111100110000000001100
|
||||
00000011100010000000000110001100
|
||||
00000010100000000000100000001110
|
||||
00101001100000000001000110001110
|
||||
00010100001110001000000000001101
|
||||
00101001100000000010000110001101
|
||||
00000011100101000000000110110011
|
||||
00000010100000000010100000010010
|
||||
00101001100000000011000110010011
|
||||
00101001100000000100000110010010
|
||||
00010100001111101010000000010001
|
||||
00000010100000100000000000010000
|
||||
00101001100000000101000110010001
|
||||
00101001100000000110000110010000
|
||||
00000010100000110000000000001111
|
||||
00000010100000000000010000001110
|
||||
00101001100000000111000110001111
|
||||
00000000000101010000000010010111
|
||||
00000000000101010000000110001101
|
||||
01011111111111111110000110000000
|
||||
01010100000001100111100000000000
|
||||
00010101011111101010000000001100
|
||||
00000011100000000100000110010001
|
||||
00101001100000000000001000100000
|
||||
00000010100000000101100000010000
|
||||
00000011100000000001000110001101
|
||||
00101001100000000000000110110000
|
||||
00010100001110001000000000001110
|
||||
00000011100000001000000110001111
|
||||
00101001100000000000000111101110
|
||||
00000011100101000000000111000101
|
||||
00000000000101010000000010011000
|
||||
00000011100000001001000110000100
|
||||
00101001100000000000000010000101
|
||||
00000011100000001010000110010011
|
||||
00000010100000000010100000010100
|
||||
00101001100000000000001001110100
|
||||
00000011100000001011000110010001
|
||||
00000010100000100000000000010010
|
||||
00101001100000000000001000110010
|
||||
00000011100000001100000110001111
|
||||
00000010100000110000000000010000
|
||||
00000010100001000000000000001110
|
||||
00101001100000000000000111110000
|
||||
00010101011111101010000000010111
|
||||
00101001100000000000000110001110
|
||||
00000011010000000000000000000000
|
||||
00101000100000000001000110101100
|
||||
00000011010000000000100110001100
|
||||
00101000100000000000000110101100
|
||||
00000011010000000100000110001100
|
||||
01011011111111111111100110000000
|
||||
00000010100000000000100000001100
|
||||
00101001100000000001000110101100
|
||||
01010100000001011100110000000000
|
||||
00011100000000000001000000001110
|
||||
00000010101101011000000111001110
|
||||
00101000100000000000000111010010
|
||||
00010101011111101010000000001101
|
||||
00000010100000000100000000001100
|
||||
00101001100000000000000110101100
|
||||
01010100000001011111110000000000
|
||||
00011100000000000001000000001101
|
||||
00000010101101010100000110101101
|
||||
00000011100000000100001011110111
|
||||
00101000100000000000000110110010
|
||||
00101000100000000000001011110001
|
||||
00010100000000000001111010001100
|
||||
00000011100000000100000110101101
|
||||
00010101011111100000000000010000
|
||||
00000011100010010000000110001110
|
||||
00000000000100010101110010000100
|
||||
00000000000100010110000010000100
|
||||
00000000001000010011101001010011
|
||||
01011100000000000000100111000000
|
||||
00000000001010100000000000000111
|
||||
00101000100000000000000110110001
|
||||
00000010100000010011010000001100
|
||||
00000000001000010100110010010010
|
||||
01011100000000000000101001100000
|
||||
00000000001010100000000000000111
|
||||
00000010100000010011010000001100
|
||||
00011100000000000001000000001111
|
||||
00000010101100110101000111101111
|
||||
00000010101100110010000111101111
|
||||
00000011100000000001011000001101
|
||||
00101001100000000011000001101100
|
||||
00101010000000000011000001101110
|
||||
@@ -222,6 +225,7 @@
|
||||
00000010100000000010010000010100
|
||||
00000010101111111111000000010011
|
||||
00000011100000000001011000001101
|
||||
00000011010000000000000000000000
|
||||
00000000000101111011101000101100
|
||||
00000011010000000011110110001100
|
||||
00000010100000010101110110001111
|
||||
@@ -236,7 +240,7 @@
|
||||
00010101011111100000000000010000
|
||||
00000010100000000011010000001100
|
||||
00011100000000000001000000001111
|
||||
00000010101100011011000111101111
|
||||
00000010101100010111000111101111
|
||||
00000011100000000001011000001101
|
||||
00101001100000000011000001101100
|
||||
00101010000000000011000001101110
|
||||
@@ -248,11 +252,11 @@
|
||||
00101001000000000000001000001110
|
||||
00101000000000000000000111101100
|
||||
01011111111111111101110110000000
|
||||
01010100000000101001100000000000
|
||||
01010100000000101100100000000000
|
||||
00010101011111100000000000010000
|
||||
00000010100000000011010000001100
|
||||
00011100000000000001000000001111
|
||||
00000010101100010000000111101111
|
||||
00000010101100001100000111101111
|
||||
00000011100000000001011000001101
|
||||
00101001100000000011000001101100
|
||||
00101010000000000011000001101110
|
||||
@@ -265,11 +269,11 @@
|
||||
00101000000000000000000111101100
|
||||
01011111111111111101110110000000
|
||||
00000000000101010000001001000100
|
||||
01010100000000100101010000000000
|
||||
01010100000000101000010000000000
|
||||
00010101011111100000000000010000
|
||||
00000010100000000011010000001100
|
||||
00011100000000000001000000001111
|
||||
00000010101100000100000111101111
|
||||
00000010101100000000000111101111
|
||||
00000011100000000001011000001101
|
||||
00101001100000000011000001101100
|
||||
00101010000000000011000001101110
|
||||
@@ -282,10 +286,22 @@
|
||||
01011111111111111110000110000000
|
||||
00101000100000000111000001100001
|
||||
00101000100000000110000001110111
|
||||
00101000100000000101000001111000
|
||||
00000000000101010000000000000100
|
||||
00000010100000001000000001100011
|
||||
01001100000000000000000000100000
|
||||
00000011010000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000000000000000000000000000000
|
||||
00000010101111100001000001100011
|
||||
00101001100000011110000001100001
|
||||
00101001100000011101000001100010
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
/**
|
||||
* user-sample - CIC-IEC 2026 Stage 3 Evaluation Program
|
||||
*
|
||||
* (ULTIMATE PERFORMANCE DMA + PING-PONG BUFFER ARCHITECTURE v2)
|
||||
*
|
||||
* Optimizations over v1:
|
||||
* 1. Pre-fire DMA Ch0 load at loop tail → fully overlaps with IP compute
|
||||
* 2. Inlined wait loops → zero function-call overhead in hot path
|
||||
* 3. Inlined DMA start → skips redundant STATUS_BUSY_BIT check
|
||||
* 4. XOR bank toggle → avoids g%2 recomputation per iteration
|
||||
* Matmul AXI-master path.
|
||||
*/
|
||||
|
||||
#include <dma.h>
|
||||
@@ -82,12 +76,19 @@ unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||
|
||||
#define MATMUL_CTRL (MATMUL_BASE_UNCACHED + 0x000)
|
||||
#define MATMUL_STATUS (MATMUL_BASE_UNCACHED + 0x004)
|
||||
#define MATMUL_BASE_PHYS_FOR_DMA MATMUL_BASE_PHYS
|
||||
#define MATMUL_DMA_SRC_BASE (MATMUL_BASE_UNCACHED + 0x020)
|
||||
#define MATMUL_DMA_DST_BASE (MATMUL_BASE_UNCACHED + 0x024)
|
||||
#define MATMUL_DMA_GROUPS (MATMUL_BASE_UNCACHED + 0x028)
|
||||
#define MATMUL_DMA_SRC_STRIDE (MATMUL_BASE_UNCACHED + 0x02C)
|
||||
#define MATMUL_DMA_DST_STRIDE (MATMUL_BASE_UNCACHED + 0x030)
|
||||
|
||||
#define CTRL_START_B0 0x1
|
||||
#define CTRL_START_B1 0x2
|
||||
#define CTRL_DMA_START (1 << 8)
|
||||
#define STATUS_DONE 0x2
|
||||
#define STATUS_ERROR 0x4
|
||||
#define STATUS_DMA_BUSY (1 << 3)
|
||||
#define STATUS_DMA_DONE (1 << 4)
|
||||
|
||||
#define MATMUL_CRC (MATMUL_BASE_UNCACHED + 0x010)
|
||||
|
||||
@@ -101,8 +102,9 @@ int main(void)
|
||||
if (MATMUL_GROUP_NUM <= 0) return 0;
|
||||
|
||||
/* ── Hot-path local volatile pointers (one-time addr calc) ──────── */
|
||||
volatile unsigned int *mat_crc = (volatile unsigned int *)MATMUL_CRC;
|
||||
volatile dma_seq_regs_t *seq = DMA_SEQ;
|
||||
volatile unsigned int *mat_ctrl = (volatile unsigned int *)MATMUL_CTRL;
|
||||
volatile unsigned int *mat_status = (volatile unsigned int *)MATMUL_STATUS;
|
||||
volatile unsigned int *mat_crc = (volatile unsigned int *)MATMUL_CRC;
|
||||
|
||||
unsigned int crc;
|
||||
unsigned int cycle_start, cycle_end, cycles, time_us;
|
||||
@@ -111,16 +113,16 @@ int main(void)
|
||||
uart_puts("MATMUL_START\r\n");
|
||||
cycle_start = get_clock_count();
|
||||
|
||||
seq->STATUS = SEQ_DONE_BIT;
|
||||
seq->SRC_BASE = EXTRAM_PHYS_AB(0);
|
||||
seq->DST_BASE = EXTRAM_PHYS_C(0);
|
||||
seq->GROUPS = MATMUL_GROUP_NUM;
|
||||
seq->MAT_BASE = MATMUL_BASE_PHYS_FOR_DMA;
|
||||
seq->SRC_STRIDE = 128;
|
||||
seq->DST_STRIDE = 192;
|
||||
seq->CTRL = SEQ_START_BIT;
|
||||
while (!(seq->STATUS & SEQ_DONE_BIT)) {}
|
||||
seq->STATUS = SEQ_DONE_BIT;
|
||||
*(volatile unsigned int *)MATMUL_CRC = 0;
|
||||
*mat_status = STATUS_DMA_DONE | STATUS_DONE | STATUS_ERROR;
|
||||
*(volatile unsigned int *)MATMUL_DMA_SRC_BASE = EXTRAM_PHYS_AB(0);
|
||||
*(volatile unsigned int *)MATMUL_DMA_DST_BASE = EXTRAM_PHYS_C(0);
|
||||
*(volatile unsigned int *)MATMUL_DMA_GROUPS = MATMUL_GROUP_NUM;
|
||||
*(volatile unsigned int *)MATMUL_DMA_SRC_STRIDE = 128;
|
||||
*(volatile unsigned int *)MATMUL_DMA_DST_STRIDE = 192;
|
||||
*mat_ctrl = CTRL_DMA_START;
|
||||
while (!(*mat_status & STATUS_DMA_DONE)) {}
|
||||
*mat_status = STATUS_DMA_DONE;
|
||||
cycle_end = get_clock_count();
|
||||
cycles = cycle_end - cycle_start;
|
||||
time_us = cycles / (CORE_CLOCKS_PER_SEC / 1000000UL);
|
||||
|
||||
Reference in New Issue
Block a user