Avoid DSP in matmul master path

This commit is contained in:
2026-07-01 23:30:11 +08:00
parent fd03aaaaa1
commit baf3f6f696
3 changed files with 76 additions and 287 deletions

View File

@@ -2,7 +2,7 @@
// 3-stage pipelined multiplier (LUT-based, no DSP)
// latency=3, throughput=1 result/cycle
// ═══════════════════════════════════════════════════════
(* use_dsp = "no" *)
(* use_dsp = "no", use_dsp48 = "no", syn_multstyle = "logic" *)
module pipelined_mult_32x32 (
input clk,
input rstn,
@@ -11,7 +11,23 @@ module pipelined_mult_32x32 (
output reg [63:0] p
);
reg [31:0] a_r, b_r;
(* use_dsp = "no", use_dsp48 = "no", syn_multstyle = "logic" *)
reg [63:0] prod;
function automatic [63:0] lut_mul32;
input [31:0] lhs;
input [31:0] rhs;
integer bit_idx;
reg [63:0] acc;
begin
acc = 64'b0;
for (bit_idx = 0; bit_idx < 32; bit_idx = bit_idx + 1) begin
if (rhs[bit_idx])
acc = acc + ({32'b0, lhs} << bit_idx);
end
lut_mul32 = acc;
end
endfunction
always @(posedge clk) begin
if (!rstn) begin
@@ -20,7 +36,7 @@ module pipelined_mult_32x32 (
end else begin
a_r <= a; // Stage 1: register inputs
b_r <= b;
prod <= a_r * b_r; // Stage 2: LUT-based multiply
prod <= lut_mul32(a_r, b_r); // Stage 2: LUT-based multiply
p <= prod; // Stage 3: register output
end
end
@@ -186,6 +202,8 @@ module matmul_axi_slave (
reg dma_done;
reg [31:0] load_group;
reg [31:0] store_group;
reg [31:0] dma_next_rd_addr;
reg [31:0] dma_next_wr_addr;
reg [31:0] completed_groups;
reg [1:0] bank_loaded;
reg [1:0] bank_store_pending;
@@ -880,6 +898,8 @@ module matmul_axi_slave (
dma_done <= 1'b0;
load_group <= 32'd0;
store_group <= 32'd0;
dma_next_rd_addr <= 32'd0;
dma_next_wr_addr <= 32'd0;
completed_groups <= 32'd0;
bank_loaded <= 2'b00;
bank_store_pending <= 2'b00;
@@ -933,6 +953,8 @@ module matmul_axi_slave (
dma_done <= 1'b0;
load_group <= 32'd0;
store_group <= 32'd0;
dma_next_rd_addr <= dma_src_base;
dma_next_wr_addr <= dma_dst_base;
completed_groups <= 32'd0;
bank_loaded <= 2'b00;
bank_store_pending <= 2'b00;
@@ -978,7 +1000,7 @@ module matmul_axi_slave (
!(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_araddr <= dma_next_rd_addr;
m_axi_arlen <= 8'd31;
m_axi_arsize <= 3'd2;
m_axi_arburst <= 2'b01;
@@ -999,6 +1021,7 @@ module matmul_axi_slave (
m_axi_rready <= 1'b0;
bank_loaded[dma_rd_bank] <= 1'b1;
load_group <= load_group + 32'd1;
dma_next_rd_addr <= dma_next_rd_addr + dma_src_stride;
dma_load_bank <= ~dma_load_bank;
dma_rd_state <= DMA_RD_IDLE;
end else begin
@@ -1018,7 +1041,7 @@ module matmul_axi_slave (
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_awaddr <= dma_next_wr_addr;
m_axi_awlen <= 8'd47;
m_axi_awsize <= 3'd2;
m_axi_awburst <= 2'b01;
@@ -1055,6 +1078,7 @@ module matmul_axi_slave (
bank_storing[dma_store_bank] <= 1'b0;
dma_store_bank <= ~dma_store_bank;
store_group <= store_group + 32'd1;
dma_next_wr_addr <= dma_next_wr_addr + dma_dst_stride;
completed_groups <= completed_groups + 32'd1;
if ((completed_groups + 32'd1) >= dma_groups) begin
dma_busy <= 1'b0;