添加一些补充说明

main
阳光少年 8 months ago
parent 487f58971b
commit eaa3f793fd

@ -2,15 +2,15 @@
module axi_bram #(
parameter AXI_IDWIDTH = 4, // AXI的id宽度
parameter AXI_AWIDTH = 64, // AXI的 地址总线宽度
parameter AXI_DWIDTH = 256, // AXI的数据总线宽度 一次读取的数据位数
parameter MEM_AWIDTH = 12 // BRAM size = MEM_AWIDTH*C_M_AXI_DATA_WIDTH (bits) = MEM_AWIDTH*C_M_AXI_DATA_WIDTH/8 (bytes)
parameter AXI_DWIDTH = 256, // AXI的数据总线宽度 一次读取的数据位数, 每次数据传输的bit位宽
parameter MEM_AWIDTH = 12 // 内存二维数组的长度len的宽度 也就是索引一共 1<<12个, BRAM size = MEM_AWIDTH*C_M_AXI_DATA_WIDTH (bits) = MEM_AWIDTH*C_M_AXI_DATA_WIDTH/8 (bytes)
) (
input wire rstn,
input wire clk,
// AXI-MM AW interface ----------------------------------------------------
output wire s_axi_awready, // 从写地址准备好
output wire s_axi_awready, // 从S 写地址准备好接收了
input wire s_axi_awvalid, // 主准备好
input wire [ AXI_AWIDTH-1:0] s_axi_awaddr,
input wire [ AXI_AWIDTH-1:0] s_axi_awaddr, // 传入的地址, 注意这个地址是bit, 后面计算出来通过右移得到二维数组中的索引
input wire [ 7:0] s_axi_awlen,
input wire [ AXI_IDWIDTH-1:0] s_axi_awid,
// AXI-MM W interface ----------------------------------------------------
@ -25,9 +25,9 @@ module axi_bram #(
output wire [ AXI_IDWIDTH-1:0] s_axi_bid,
output wire [ 1:0] s_axi_bresp,
// AXI-MM AR interface ----------------------------------------------------
output wire s_axi_arready, // 表示S 已经可以接受 读地址信号
output wire s_axi_arready, // 表示S 已经可以接受 M读地址信号
input wire s_axi_arvalid, // 表示M 地址已经准备就绪
input wire [ AXI_AWIDTH-1:0] s_axi_araddr, // M 发送的地址
input wire [ AXI_AWIDTH-1:0] s_axi_araddr, // M 发送的地址, 这是个bit的地址, 后面通过右移计算得到索引
input wire [ 7:0] s_axi_arlen, // 突发长度
input wire [ AXI_IDWIDTH-1:0] s_axi_arid,
// AXI-MM R interface ----------------------------------------------------
@ -92,13 +92,13 @@ always @ (posedge clk or negedge rstn)
// 组合逻辑块,根据当前状态计算内存读地址
always_comb
if (rstate == R_IDLE && s_axi_arvalid) // 如果空闲状态 且 M已经准备好地址
mem_raddr = (MEM_AWIDTH)'(s_axi_araddr >> log2(AXI_DWIDTH/8)); // 计算地址,
if (rstate == R_IDLE && s_axi_arvalid) // 如果空闲状态 且 M已经准备好地址
mem_raddr = (MEM_AWIDTH)'(s_axi_araddr >> log2(AXI_DWIDTH/8)); // 计算地址, 字节对齐 //不太懂这个为啥除以8
// 因为每次数据都会 传256位数据, 这里除以8, 得到需要传的次数, 每次1字节传输, 256/8就是32次
// 看能整除多少次2, 然后 s_axi_araddr 进行右移, 移动到传过来的地址的 AXI_DWIDTH的字节边界 start起始的位置
// 将AXI_DWIDTH除以8的原因是为了从字节byte粒度转换到数据宽度的粒度。在很多基于AXI协议的系统中地址通常是按字节对齐的而数据宽度AXI_DWIDTH可能不是8的整数倍比如可能是16位、32位、64位等
else if (rstate == R_BUSY && s_axi_rready) // 如果繁忙, 且 M 已经准备好 接收 S发来的数据
else if (rstate == R_BUSY && s_axi_rready) // 如果当前正在传输数据, 且 M 已经准备好 接收 S发来的数据
mem_raddr = mem_raddr_last + (MEM_AWIDTH)'(1); // 计算下一个内存地址, 加一即可, 这是一个二维数组
else
mem_raddr = mem_raddr_last; // 保持地址不变
@ -161,16 +161,16 @@ always @ (posedge clk or negedge rstn)
// a block RAM
// ---------------------------------------------------------------------------------------
reg [AXI_DWIDTH-1:0] mem [ 1<<MEM_AWIDTH ]; // 这是一个二维数组
reg [AXI_DWIDTH-1:0] mem [ 1<<MEM_AWIDTH ]; // 这是一个二维数组, 数组中每个元素为 AXI_DWIDTH 宽, 数组长度为 MEM_AWIDTH
always @ (posedge clk)
s_axi_rdata <= mem[mem_raddr]; // 一次读出 AXI_DWIDTH 位的数据
s_axi_rdata <= mem[mem_raddr]; // 一次读出索引mem_raddr 处 AXI_DWIDTH 位的数据
always @ (posedge clk)
if (s_axi_wvalid & s_axi_wready)
for (int i=0; i<(AXI_DWIDTH/8); i++)
if (s_axi_wstrb[i])
mem[mem_waddr][i*8+:8] <= s_axi_wdata[i*8+:8];
mem[mem_waddr][i*8+:8] <= s_axi_wdata[i*8+:8]; // 每次根据地址写入8bit
endmodule

@ -216,5 +216,4 @@ axi_bram #(
);
endmodule
// 1000_0000_0000_0000_0000
endmodule
Loading…
Cancel
Save