fix samples ntt bugs & set PLL & optimize matmul

This commit is contained in:
2026-07-15 10:36:38 +08:00
parent fc91511950
commit c4d36515cc
7 changed files with 274 additions and 120 deletions

View File

@@ -64,6 +64,7 @@ module cdma_matmul_bridge #(
output logic mat_done_clear,
output logic mat_crc_clear,
input logic mat_done,
input logic mat_crc_idle,
output logic seq_done_irq
);
@@ -102,10 +103,10 @@ module cdma_matmul_bridge #(
logic [31:0] load_next_dst_addr;
logic [31:0] bank_dst_addr [2];
logic rd_busy;
logic wr_busy;
logic rd_active_bank;
logic wr_active_bank;
logic [1:0] rd_outstanding_count;
logic [1:0] rd_bank_fifo;
logic [1:0] compute_q;
logic [1:0] compute_q_count;
logic mat_done_seen;
@@ -136,6 +137,7 @@ module cdma_matmul_bridge #(
wire retire_from_store = seq_busy && cdma_wr_req_done;
wire retire_from_compute = seq_busy && seq_skip_writeback && mat_done_event && (compute_q_count != 2'd0);
wire [31:0] retire_inc = {31'd0, retire_from_store} + {31'd0, retire_from_compute};
wire rd_req_fire = cdma_rd_req_valid && cdma_rd_req_ready;
function automatic logic [31:0] apply_wstrb(
input logic [31:0] old_val,
@@ -257,10 +259,10 @@ module cdma_matmul_bridge #(
load_next_dst_addr <= 32'd0;
bank_dst_addr[0] <= 32'd0;
bank_dst_addr[1] <= 32'd0;
rd_busy <= 1'b0;
wr_busy <= 1'b0;
rd_active_bank <= 1'b0;
wr_active_bank <= 1'b0;
rd_outstanding_count <= 2'd0;
rd_bank_fifo <= 2'b00;
compute_q <= 2'b00;
compute_q_count <= 2'd0;
mat_done_seen <= 1'b0;
@@ -290,7 +292,7 @@ module cdma_matmul_bridge #(
if (done_clear_req)
seq_done_flag <= 1'b0;
if (cdma_rd_req_valid && cdma_rd_req_ready)
if (rd_req_fire)
cdma_rd_req_valid <= 1'b0;
if (cdma_wr_req_valid && cdma_wr_req_ready)
@@ -313,8 +315,9 @@ module cdma_matmul_bridge #(
load_next_dst_addr <= seq_dst_base;
bank_dst_addr[0] <= 32'd0;
bank_dst_addr[1] <= 32'd0;
rd_busy <= 1'b0;
wr_busy <= 1'b0;
rd_outstanding_count <= 2'd0;
rd_bank_fifo <= 2'b00;
compute_q <= 2'b00;
compute_q_count <= 2'd0;
mat_done_seen <= 1'b1;
@@ -325,18 +328,50 @@ module cdma_matmul_bridge #(
end else if (seq_busy) begin
if (retire_inc != 32'd0) begin
groups_retired <= groups_retired + retire_inc;
if ((groups_retired + retire_inc) >= seq_groups) begin
seq_busy <= 1'b0;
seq_done_flag <= 1'b1;
end
end
if (cdma_rd_req_done) begin
rd_busy <= 1'b0;
bank_load_active[rd_active_bank] <= 1'b0;
bank_ab_valid[rd_active_bank] <= 1'b1;
// The final compute completion can precede the recursive CRC
// consumer. Do not expose sequence completion until it drains.
if ((groups_retired >= seq_groups) && mat_crc_idle) begin
seq_busy <= 1'b0;
seq_done_flag <= 1'b1;
end
if (cdma_rd_req_done && (rd_outstanding_count != 2'd0)) begin
bank_load_active[rd_bank_fifo[0]] <= 1'b0;
bank_ab_valid[rd_bank_fifo[0]] <= 1'b1;
end
// Track the active read and one prefetched read. Completion
// pulses are in request order, so a two-entry bank FIFO is
// sufficient to associate each RLAST with its destination.
case ({rd_req_fire, cdma_rd_req_done})
2'b10: begin
if (rd_outstanding_count == 2'd0)
rd_bank_fifo[0] <= cdma_rd_req_ep_bank[0];
else
rd_bank_fifo[1] <= cdma_rd_req_ep_bank[0];
rd_outstanding_count <= rd_outstanding_count + 2'd1;
end
2'b01: begin
if (rd_outstanding_count == 2'd2)
rd_bank_fifo[0] <= rd_bank_fifo[1];
if (rd_outstanding_count != 2'd0)
rd_outstanding_count <= rd_outstanding_count - 2'd1;
end
2'b11: begin
if (rd_outstanding_count == 2'd1) begin
rd_bank_fifo[0] <= cdma_rd_req_ep_bank[0];
end else begin
rd_bank_fifo[0] <= rd_bank_fifo[1];
rd_bank_fifo[1] <= cdma_rd_req_ep_bank[0];
end
end
default: begin
end
endcase
if (cdma_wr_req_done) begin
wr_busy <= 1'b0;
bank_store_active[wr_active_bank] <= 1'b0;
@@ -354,15 +389,14 @@ module cdma_matmul_bridge #(
compute_q_count <= compute_q_count - 2'd1;
end
if (!rd_busy && !cdma_rd_req_valid && (load_next_idx < seq_groups) && load_target_free) begin
if ((rd_outstanding_count < 2'd2) && !cdma_rd_req_valid &&
(load_next_idx < seq_groups) && load_target_free) begin
cdma_rd_req_src <= load_next_src_addr;
cdma_rd_req_bytes <= MAT_AB_BYTES;
cdma_rd_req_ep_id <= 4'd0;
cdma_rd_req_ep_bank <= {3'b000, load_target_bank};
cdma_rd_req_ep_word_off <= 8'd0;
cdma_rd_req_valid <= 1'b1;
rd_busy <= 1'b1;
rd_active_bank <= load_target_bank;
bank_load_active[load_target_bank] <= 1'b1;
bank_group_idx[load_target_bank] <= load_next_idx;
bank_dst_addr[load_target_bank] <= load_next_dst_addr;

View File

@@ -423,6 +423,13 @@ module snix_axil_cdma_mux #(
logic [7:0] ext_rd_word_addr_r;
logic [3:0] ext_rd_ep_id_r;
logic [3:0] ext_rd_ep_bank_r;
logic ext_rd_queue_valid;
logic ext_rd_queue_ar_sent;
logic [ADDR_WIDTH-1:0] ext_rd_queue_addr;
logic [31:0] ext_rd_queue_bytes;
logic [7:0] ext_rd_queue_word_addr;
logic [3:0] ext_rd_queue_ep_id;
logic [3:0] ext_rd_queue_ep_bank;
logic [ADDR_WIDTH-1:0] ext_wr_addr_r;
logic [31:0] ext_wr_bytes_left;
@@ -434,7 +441,10 @@ module snix_axil_cdma_mux #(
wire ext_wr_active = (ext_wr_state != EXT_WR_IDLE);
wire ext_rd_accept = ext_rd_req_valid && ext_rd_req_ready;
wire ext_wr_accept = ext_wr_req_valid && ext_wr_req_ready;
wire ext_any_busy_or_req = ext_rd_active || ext_wr_active || ext_rd_req_valid || ext_wr_req_valid;
wire ext_rd_prefetch_ar = (ext_rd_state == EXT_RD_READ) &&
ext_rd_queue_valid && !ext_rd_queue_ar_sent;
wire ext_any_busy_or_req = ext_rd_active || ext_rd_queue_valid || ext_wr_active ||
ext_rd_req_valid || ext_wr_req_valid;
wire use_ep_engine = ((state == RUN) && (engine_mode != MODE_MEM2MEM));
// Dynamic routing to the engine based on current active channel
@@ -478,8 +488,12 @@ module snix_axil_cdma_mux #(
assign mm2mm_bready = ext_wr_active ? (ext_wr_state == EXT_WR_BRESP) : (use_ep_engine ? ep_bready : core_bready);
assign mm2mm_arid = ext_rd_active ? '0 : (use_ep_engine ? ep_arid : core_arid);
assign mm2mm_araddr = ext_rd_active ? ext_rd_addr_r : (use_ep_engine ? ep_araddr : core_araddr);
assign mm2mm_arlen = ext_rd_active ? (((ext_rd_bytes_left[31:2] == 30'd0) ? 8'd1 : ext_rd_bytes_left[9:2]) - 8'd1) : (use_ep_engine ? ep_arlen : core_arlen);
assign mm2mm_araddr = ext_rd_prefetch_ar ? ext_rd_queue_addr :
(ext_rd_active ? ext_rd_addr_r : (use_ep_engine ? ep_araddr : core_araddr));
assign mm2mm_arlen = ext_rd_prefetch_ar ?
(((ext_rd_queue_bytes[31:2] == 30'd0) ? 8'd1 : ext_rd_queue_bytes[9:2]) - 8'd1) :
(ext_rd_active ? (((ext_rd_bytes_left[31:2] == 30'd0) ? 8'd1 : ext_rd_bytes_left[9:2]) - 8'd1) :
(use_ep_engine ? ep_arlen : core_arlen));
assign mm2mm_arsize = ext_rd_active ? 3'd2 : (use_ep_engine ? ep_arsize : core_arsize);
assign mm2mm_arburst = ext_rd_active ? 2'b01 : (use_ep_engine ? ep_arburst : core_arburst);
assign mm2mm_arlock = ext_rd_active ? 1'b0 : (use_ep_engine ? ep_arlock : core_arlock);
@@ -487,7 +501,8 @@ module snix_axil_cdma_mux #(
assign mm2mm_arprot = ext_rd_active ? 3'b0 : (use_ep_engine ? ep_arprot : core_arprot);
assign mm2mm_arqos = ext_rd_active ? 4'b0 : (use_ep_engine ? ep_arqos : core_arqos);
assign mm2mm_aruser = ext_rd_active ? '0 : (use_ep_engine ? ep_aruser : core_aruser);
assign mm2mm_arvalid = ext_rd_active ? (ext_rd_state == EXT_RD_AR) : (use_ep_engine ? ep_arvalid : core_arvalid);
assign mm2mm_arvalid = ext_rd_active ? ((ext_rd_state == EXT_RD_AR) || ext_rd_prefetch_ar) :
(use_ep_engine ? ep_arvalid : core_arvalid);
assign mm2mm_rready = ext_rd_active ? ((ext_rd_state == EXT_RD_READ) && ep_wr_ready) : (use_ep_engine ? ep_rready : core_rready);
always_ff @(posedge clk) begin
@@ -597,7 +612,10 @@ module snix_axil_cdma_mux #(
// ==========================================
// Generic external endpoint requester
// ==========================================
assign ext_rd_req_ready = (state == IDLE) && (ep_state == EP_IDLE) && !ext_rd_active;
assign ext_rd_req_ready = (state == IDLE) && (ep_state == EP_IDLE) && !ext_wr_active &&
((ext_rd_state == EXT_RD_IDLE) ||
((ext_rd_state == EXT_RD_READ) && !ext_rd_queue_valid &&
!ext_rd_done_fire));
assign ext_wr_req_ready = (state == IDLE) && (ep_state == EP_IDLE) && !ext_wr_active;
assign ext_rd_req_done = ext_rd_done_fire;
assign ext_wr_req_done = ext_wr_done_fire;
@@ -610,7 +628,17 @@ module snix_axil_cdma_mux #(
ext_rd_word_addr_r <= '0;
ext_rd_ep_id_r <= '0;
ext_rd_ep_bank_r <= '0;
ext_rd_queue_valid <= 1'b0;
ext_rd_queue_ar_sent <= 1'b0;
ext_rd_queue_addr <= '0;
ext_rd_queue_bytes <= '0;
ext_rd_queue_word_addr <= '0;
ext_rd_queue_ep_id <= '0;
ext_rd_queue_ep_bank <= '0;
end else begin
if (ext_rd_prefetch_ar && mm2mm_arvalid && mm2mm_arready)
ext_rd_queue_ar_sent <= 1'b1;
case (ext_rd_state)
EXT_RD_IDLE: begin
if (ext_rd_accept) begin
@@ -629,11 +657,37 @@ module snix_axil_cdma_mux #(
end
EXT_RD_READ: begin
if (ext_rd_accept) begin
ext_rd_queue_valid <= 1'b1;
ext_rd_queue_ar_sent <= 1'b0;
ext_rd_queue_addr <= ext_rd_req_src;
ext_rd_queue_bytes <= ext_rd_req_bytes;
ext_rd_queue_word_addr <= ext_rd_req_ep_word_off;
ext_rd_queue_ep_id <= ext_rd_req_ep_id;
ext_rd_queue_ep_bank <= ext_rd_req_ep_bank;
end
if (mm2mm_rvalid && mm2mm_rready) begin
ext_rd_word_addr_r <= ext_rd_word_addr_r + 8'd1;
ext_rd_bytes_left <= (ext_rd_bytes_left > 32'd4) ? (ext_rd_bytes_left - 32'd4) : 32'd0;
if (mm2mm_rlast)
ext_rd_state <= EXT_RD_IDLE;
if (mm2mm_rlast) begin
if (ext_rd_queue_valid) begin
ext_rd_addr_r <= ext_rd_queue_addr;
ext_rd_bytes_left <= ext_rd_queue_bytes;
ext_rd_word_addr_r <= ext_rd_queue_word_addr;
ext_rd_ep_id_r <= ext_rd_queue_ep_id;
ext_rd_ep_bank_r <= ext_rd_queue_ep_bank;
ext_rd_queue_valid <= 1'b0;
ext_rd_queue_ar_sent <= 1'b0;
if (ext_rd_queue_ar_sent ||
(ext_rd_prefetch_ar && mm2mm_arvalid && mm2mm_arready))
ext_rd_state <= EXT_RD_READ;
else
ext_rd_state <= EXT_RD_AR;
end else begin
ext_rd_state <= EXT_RD_IDLE;
end
end
end
end