Nvme控制器设计笔记

小结

1.axi
2.Nvme控制器的设计

简介

1.axi总线有五大接口,其中读写通道是独立的,写地址、写数据、写读地址、读数据、写响应。
2.axi总线分为axi-lite axi-full和axi-stream,其中axi-lite是传输一些控制信号、axi-stream传输数据流,没有地址映射,因此只能点对点、axi-full可以支持突发传输,其中突发传输的数量可以配置XXlen接口


2.Nvme控制器外部与ddr、ps端、xdma连接

  • 其中ps端通过s-axi-lite接口对nvme进行指令寄存器的配置,对xdma进行初始化(BAR空间?)的配置
  • Nvme随后进行指令的组装,确定工作模式是否为数据流;
  • 假如为数据流模式,则要先判断指令为读还是写,读指令需要先组装指令再等待数据读入DDR,进行数据流的转换;写指令需要先将数据流转换为DDR中的缓存,再组装指令,模块通过M-axi-DDR控制DDR的读和写;
  • 组装后的指令根据指令的类别存入fifo缓存中,等待进入SQ,其中SQ又分为admin SQ和若干个IO SQ,当指令的数量到达一定阈值或指令计数器到达一个数时,仲裁模块就会将指令根据一定的策略存入队列中,此外由于SSD处理指令可能会乱序,因此要给每个指令分配单独的ID,等到处理完毕再释放ID号,在此文献中队列存储在BRAM中(速度快),在其他文献中也有存放至DDR中的;
  • 当队列的指令到达一定数量时,会发送门铃信息,此时队列暂停仲裁判断,等待门铃信息发送完毕的标志再进行后续的指令处理,门铃信息也使用axi-lite进行传输;
  • 在发送门铃信息之后,模块会等待SSD的读指令命令,再将命令发送出去,这里SSD作为主机;最后接收完成指令,存入完成队列。
  • 当然这篇文献中也有困惑的地方,比如给出的Block design图和实现方案并不能很好的对应
    (设计参考文献:基于Zynq的Nvme控制器设计与实现)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Zynq NVMe控制器访问DDR的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <xil_types.h> #include <xil_printf.h> #include <xparameters.h> #include <xscugic.h> #include <xil_exception.h> #include "xil_cache.h" // NVMe 命令缓冲区地址 #define NVME_CMD_BUF_ADDR 0x10000000 // NVMe 数据缓冲区地址 #define NVME_DATA_BUF_ADDR 0x20000000 // DDR 起始地址 #define DDR_BASE_ADDR 0x80000000 // DDR 大小 #define DDR_SIZE 0x40000000 // 初始化 NVMe 控制器 void nvme_init() { // TODO: 初始化 NVMe 控制器 } // 向 NVMe 控制器发送命令 void nvme_send_cmd(u32 cmd_addr) { // TODO: 向 NVMe 控制器发送命令 } // 从 NVMe 控制器读取数据 void nvme_read_data(u32 data_addr, u32 size) { // TODO: 从 NVMe 控制器读取数据 } // 将数据写入 DDR void write_to_ddr(u32 ddr_addr, u32 data_addr, u32 size) { // 使能 L1 和 L2 缓存 Xil_DCacheFlushRange(data_addr, size); // 写入 DDR memcpy((void*)ddr_addr, (void*)data_addr, size); } // 从 DDR 读取数据 void read_from_ddr(u32 ddr_addr, u32 data_addr, u32 size) { // 从 DDR 读取数据 memcpy((void*)data_addr, (void*)ddr_addr, size); // 使能 L1 和 L2 缓存 Xil_DCacheInvalidateRange(data_addr, size); } int main() { // 初始化 NVMe 控制器 nvme_init(); // 在 NVMe 命令缓冲区中写入命令 u32 nvme_cmd = 0x12345678; memcpy((void*)NVME_CMD_BUF_ADDR, &nvme_cmd, sizeof(nvme_cmd)); // 向 NVMe 控制器发送命令 nvme_send_cmd(NVME_CMD_BUF_ADDR); // 从 NVMe 控制器读取数据 nvme_read_data(NVME_DATA_BUF_ADDR, sizeof(u32)); // 将数据写入 DDR write_to_ddr(DDR_BASE_ADDR, NVME_DATA_BUF_ADDR, sizeof(u32)); // 从 DDR 读取数据 u32 data_from_ddr; read_from_ddr(DDR_BASE_ADDR, (u32)&data_from_ddr, sizeof(data_from_ddr)); // 打印数据 xil_printf("Data from NVMe: 0x%08x\r\n", nvme_cmd); xil_printf("Data from DDR: 0x%08x\r\n", data_from_ddr); return 0; } ``` 这是一个简单的示例,实际情况可能更加复杂。在实际开发中,需要根据具体的硬件平台和NVMe控制器的实现进行适当的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值