cache module

This commit is contained in:
Core_kingdom
2025-08-26 16:53:22 +08:00
commit 79dee10db1
124 changed files with 13283 additions and 0 deletions

View File

@@ -0,0 +1,196 @@
module axi_write_ctrl #(
parameter AXI_ID_W = 8, // AXI ID位宽
parameter AXI_ADDR_W = 32, // AXI地址位宽
parameter AXI_DATA_W = 256, // AXI数据位宽
parameter AXI_STRB_W = AXI_DATA_W / 8 // 字节选通位宽(256bit对应32字节)
) (
input wire clk, // 系统时钟
input wire rst_n, // 异步复位低有效
// 控制与数据输入
input wire start_en, // 写事务启动使能
input wire [AXI_ADDR_W-1:0] sram_base_addr, // SRAM基地址
input wire [AXI_DATA_W-1:0] fifo_rd_data, // FIFO读数据
input wire fifo_empty, // FIFO空标志
output reg fifo_rd_en, // FIFO读使能
// AXI AW通道
output reg [AXI_ID_W-1:0] axi_m_awid, // 写地址ID
output reg [AXI_ADDR_W-1:0] axi_m_awaddr, // 写地址
output reg [3:0] axi_m_awlen, // 突发长度(0表示1个数据)
output reg [2:0] axi_m_awsize, // 数据宽度(5对应32字节)
output reg [1:0] axi_m_awburst, // 突发类型(0表示增量)
output reg axi_m_awlock, // 锁定信号(0表示普通访问)
output reg [4:0] axi_m_awcache, // 缓存属性(0表示非缓存)
output reg [2:0] axi_m_awprot, // 保护属性(0表示普通)
output reg [4:0] axi_m_awqos, // QoS优先级(0表示默认)
output reg axi_m_awvalid, // 写地址有效
input wire axi_m_awready, // 写地址就绪
// AXI W通道
output reg [AXI_ID_W-1:0] axi_m_wid, // 写数据ID
output reg [AXI_DATA_W-1:0] axi_m_wdata, // 写数据
output reg [AXI_STRB_W-1:0] axi_m_wstrb, // 字节选通(全1表示所有字节有效)
output reg axi_m_wlast, // 突发结束标志
output reg axi_m_wvalid, // 写数据有效
input wire axi_m_wready, // 写数据就绪
// AXI B通道
input wire [AXI_ID_W-1:0] axi_m_bid, // 写响应ID
input wire [1:0] axi_m_bresp, // 写响应(0表示OKAY)
input wire axi_m_bvalid, // 写响应有效
output reg axi_m_bready, // 写响应就绪
// 状态输出
output reg axi_busy, // AXI写事务忙
output reg axi_done // AXI写事务完成
);
// 内部信号定义
reg [AXI_ADDR_W-1:0] curr_addr; // 当前写地址(基于基地址递增)
reg [1:0] axi_state; // AXI状态机状态寄存器
// 状态定义
localparam AXI_IDLE = 2'd0; // 空闲状态
localparam AXI_AW = 2'd1; // 地址通道传输状态
localparam AXI_W = 2'd2; // 数据通道传输状态
localparam AXI_B = 2'd3; // 响应通道传输状态
// 1. AXI状态机时序逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_state <= AXI_IDLE;
curr_addr <= {AXI_ADDR_W{1'b0}};
axi_busy <= 1'b0;
axi_done <= 1'b0;
end else begin
axi_done <= 1'b0; // 单周期有效
case (axi_state)
AXI_IDLE: begin
axi_busy <= 1'b0;
// 启动条件: 使能信号有效且FIFO非空
if (start_en && !fifo_empty) begin
axi_state <= AXI_AW;
axi_busy <= 1'b1;
// 初始化当前地址为基地址(首次)或保持上次地址(连续传输)
curr_addr <= (curr_addr == {AXI_ADDR_W{1'b0}}) ? sram_base_addr : curr_addr;
end
end
AXI_AW: begin
// 地址通道握手完成进入数据通道
if (axi_m_awvalid && axi_m_awready) begin
axi_state <= AXI_W;
// 预计算下一次地址(当前地址 + 数据宽度字节数)
curr_addr <= curr_addr + (AXI_DATA_W / 8);
end
end
AXI_W: begin
// 数据通道握手完成进入响应通道
if (axi_m_wvalid && axi_m_wready) begin
axi_state <= AXI_B;
end
end
AXI_B: begin
// 响应通道握手完成事务结束
if (axi_m_bvalid && axi_m_bready) begin
axi_state <= AXI_IDLE;
axi_done <= 1'b1; // 标记事务完成
end
end
endcase
end
end
// 2. AXI AW通道信号生成逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_m_awid <= {AXI_ID_W{1'b0}};
axi_m_awaddr <= {AXI_ADDR_W{1'b0}};
axi_m_awlen <= 4'd0;
axi_m_awsize <= 3'd5; // 5对应32字节(2^5 = 32)
axi_m_awburst <= 2'd0; // 0表示INCR(增量)突发
axi_m_awlock <= 1'b0;
axi_m_awcache <= 5'd0; // 非缓存非缓冲
axi_m_awprot <= 3'd0; // 普通非特权数据访问
axi_m_awqos <= 5'd0; // 默认QoS级别
axi_m_awvalid <= 1'b0;
end else begin
case (axi_state)
AXI_AW: begin
axi_m_awid <= 8'd0; // 固定ID为0
axi_m_awaddr <= curr_addr; // 当前地址
axi_m_awlen <= 4'd0; // 突发长度为1(0+1)
axi_m_awsize <= 3'd5; // 保持32字节宽度
axi_m_awburst <= 2'd0; // 保持增量突发
axi_m_awvalid <= 1'b1; // 地址有效
end
default: begin
axi_m_awvalid <= 1'b0; // 非地址状态时无效
end
endcase
end
end
// 3. AXI W通道信号生成逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_m_wid <= {AXI_ID_W{1'b0}};
axi_m_wdata <= {AXI_DATA_W{1'b0}};
axi_m_wstrb <= {AXI_STRB_W{1'b1}}; // 所有字节有效
axi_m_wlast <= 1'b1; // 单拍突发始终为1
axi_m_wvalid <= 1'b0;
fifo_rd_en <= 1'b0;
end else begin
case (axi_state)
AXI_AW: begin
// 地址握手完成前预读FIFO
if (axi_m_awready) begin
fifo_rd_en <= 1'b1; // 读取FIFO数据
axi_m_wid <= 8'd0; // 与AW通道ID保持一致
axi_m_wdata <= fifo_rd_data; // 锁存FIFO数据
axi_m_wvalid <= 1'b1; // 数据有效
end else begin
fifo_rd_en <= 1'b0;
axi_m_wvalid <= 1'b0;
end
end
AXI_W: begin
fifo_rd_en <= 1'b0; // 停止读FIFO
// 数据握手完成后失效
if (axi_m_wready) begin
axi_m_wvalid <= 1'b0;
end
end
default: begin
fifo_rd_en <= 1'b0;
axi_m_wvalid <= 1'b0;
end
endcase
end
end
// 4. AXI B通道信号生成逻辑
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
axi_m_bready <= 1'b0;
end else begin
case (axi_state)
AXI_B: begin
axi_m_bready <= 1'b1; // 准备接收响应
// 响应握手完成后失效
if (axi_m_bvalid) begin
axi_m_bready <= 1'b0;
end
end
default: begin
axi_m_bready <= 1'b0;
end
endcase
end
end
endmodule