
// // 模块: matrix_dma_axi_bridge // 功能: 将 AXI4 从接口上的突发写数据按 4 拍 64 位拼接为 256 位宽数据 // 输出给加速器。 // 适用于下游加速器需要宽位宽数据而上游 AXI 总线为窄位宽的场景。 // 接口: // 上游: AXI4 从设备接口 (AW/W/B 通道) // 下游: 流式输出valid/ready 握手256 位数据 // module matrix_dma_axi_bridge #( parameter AXI_ADDR_W 64, // AXI 地址位宽 parameter AXI_DATA_W 64, // AXI 数据位宽 parameter ID_W 16, // AXI ID 位宽 parameter MW 256 // 矩阵输出位宽 ) ( input logic clk, input logic rst_n, // ---- AXI4 从设备接口 (AW通道) ---- input logic [AXI_ADDR_W-1:0] aw_a, input logic [ID_W-1:0] aw_id, input logic [7:0] aw_len, input logic [2:0] aw_size, input logic [1:0] aw_burst, input logic aw_v, output logic aw_r, // ---- AXI4 从设备接口 (W通道) ---- input logic [AXI_DATA_W-1:0] w_d, input logic [AXI_DATA_W/8-1:0] w_strb, input logic w_last, input logic w_v, output logic w_r, // ---- AXI4 从设备接口 (B通道) ---- output logic [ID_W-1:0] b_id, output logic [1:0] b_resp, output logic b_v, input logic b_r, // ---- 矩阵加速器接口 (流式输出) ---- output logic [MW-1:0] m_wdata, output logic m_wvalid, input logic m_wready ); typedef enum logic [1:0] { S_IDLE, S_W, S_B } st_t; st_t st, nxt; logic [ID_W-1:0] id_r; // 锁存的 AXI ID logic [7:0] blen; // 突发长度 logic [7:0] bcnt; // 已接收拍计数 logic [MW-1:0] acc; // 拼接累加器 logic [1:0] acnt; // 拼接子拍计数 (0~3) logic m_vreg; // 输出有效寄存器 // ---- 状态转移 ---- always_comb unique case(st) S_IDLE: nxt aw_v ? S_W : S_IDLE; S_W: nxt (w_v w_r w_last) ? S_B : S_W; S_B: nxt b_r ? S_IDLE : S_B; default: nxt S_IDLE; endcase // ---- 时序逻辑 ---- always_ff (posedge clk or negedge rst_n) begin if (~rst_n) begin st S_IDLE; blen 0; bcnt 0; acc 0; acnt 0; id_r 0; m_vreg 1b0; end else begin st nxt; // 捕获突发信息 if (st S_IDLE aw_v) begin blen aw_len; bcnt 0; acnt 0; id_r aw_id; end // 数据拼接每收到一拍写入累加器的对应 64 位段 if (st S_W w_v w_r) begin acc[64*acnt : 64] w_d; acnt (acnt 3) ? 0 : acnt 1; bcnt bcnt 1; // 每凑够 256 位拉起输出有效 if (acnt 3) m_vreg 1b1; end // 输出握手完成清除有效标志 if (m_wready m_vreg) m_vreg 1b0; end end // ---- 矩阵输出 ---- assign m_wvalid m_vreg; assign m_wdata acc; // ---- AXI 反压凑够 4 拍且下游未就绪时暂停接收新数据 ---- assign w_r (st S_W) !(acnt 3 !m_wready); // ---- AXI 握手 ---- assign aw_r (st S_IDLE); assign b_id id_r; assign b_resp 2b00; // 固定 OKAY assign b_v (st S_B); endmodule