访问内部 Xilinx FPGA 块 RAM
Posted
技术标签:
【中文标题】访问内部 Xilinx FPGA 块 RAM【英文标题】:Access to internal Xilinx FPGA block RAM 【发布时间】:2011-05-21 16:45:01 【问题描述】:我正在为 Xilinx Virtex-6 X8 PCI Express Gen 2 评估/开发套件 SX315T FPGA 编写设备驱动程序。我的操作系统是 openSUSE 11.3 64 位。 在此设备的文档中(Virtex-6 FPGA Integrated Block form PCI Express User Guide UG517 (v5.0) April 19, 2010, page 219)说:
PIO 设计是一个简单的纯目标应用程序,它与 Endpoint 接口 PCIe 内核的事务 (TRN) 接口,作为客户构建自己设计的起点。包括以下功能:
• 使用内部 Xilinx FPGA 模块的四个特定于事务的 2 KB 目标区域 RAM,提供 8192 字节的总目标空间
• 支持单个 DWORD 有效负载读取和写入 PCI Express 事务以 支持完成 TLP 的 32 位/64 位地址内存空间和 I/O 空间
• 利用内核的 trn_rbar_hit_n[6:0] 信号来区分 TLP 目标 基地址寄存器
• 提供针对 32 位、64 位和 128 位 TRN 优化的单独实现 接口
在设备中可用的 BAR0 和 BAR2 长度为 128 字节。 我正在尝试,因为我将 BAR0 映射到虚拟空间内核中。
struct pcie_dev
struct pci_dev* dev;
struct cdev chr_dev;
atomic_t dev_available;
u32 IOBaseAddress;
u32 IOLastAddress;
void* __iomem bar;
void *virt_addr;
u32 length;
unsigned long sirqNum;
void *private_data; ;
struct pcie_dev cur_pcie_dev;
cur_pcie_dev.IOBaseAddress = pci_resource_start(dev, 0);
cur_pcie_dev.IOLastAddress = pci_resource_end(dev, 0);
cur_pcie_dev.length=pci_resource_len(dev,0);
cur_pcie_dev.bar=pci_iomap(dev, 0,cur_pcie_dev.length);
IOBaseAddress 为 0xfbbfe000 IOLastAddress 为 0xfbbfe07f 长度=128;
我尝试使用 IOCTL,写入/读取数据。
case IOCTL_INFO_DEVICE:
u32 *rcslave_mem = (u32 *)pCur_dev->bar;
u32 result = 0;
u32 value = 0;
int i;
for (i = 0; i <2048 ; i++)
printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n",
(u32)value, (void *)rcslave_mem + i);
iowrite32(value, rcslave_mem + i);
value++;
/* read-back loop */
value = 0;
for (i = 0; i < 2048; i++)
result = ioread32(rcslave_mem + i);
printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n",
(u32)value, (void *)rcslave_mem + i, (u32)result);
value++;
但事实证明只能写入和读取 32 个值。据我了解,录制发生在 BAR0(4 字节 * 32 个值 = 128 字节)中,而不是在内部 Xilinx 内存中。我试图走另一条路。
cur_pcie_dev.IOBaseAddress = pci_resource_start(dev, 0);
cur_pcie_dev.IOLastAddress = pci_resource_end(dev, 0);
cur_pcie_dev.length=pci_resource_len(dev,0);
flags = pci_resource_flags(dev,0);
if (flags & IORESOURCE_MEM)
if (request_mem_region(cur_pcie_dev.IOBaseAddress,cur_pcie_dev.length, DEVICE_NAME)== NULL)
return -EBUSY;
cur_pcie_dev.virt_addr=ioremap_nocache(cur_pcie_dev.IOBaseAddress,cur_pcie_dev.length);
if (cur_pcie_dev.virt_addr == NULL)
printk(KERN_ERR "ERROR: BAR%u remapping FAILED\n",0);
return -ENOMEM;
printk(KERN_INFO " Allocated I/O memory range %#lx-%#lx\n", cur_pcie_dev.IOBaseAddress,(cur_pcie_dev.IOBaseAddress+cur_pcie_dev.length-1));
else
printk(KERN_ERR "ERROR: Invalid PCI region flags\n");
return -EIO;
然后
address = ((unsigned int)pCur_dev->virt_addr+pd.Address);
iowrite32(pd.Value,(unsigned int*) address);
address = ((unsigned int)pCur_dev->virt_addr+pd.Address);
pd.Value = ioread32((unsigned int *)address);
我使用求和的虚拟地址和指定用户的地址。但结果是读/写操作也不是真的。告诉我我做错了什么。
P.S.对不起我的英语不好
【问题讨论】:
【参考方案1】:您尝试访问电路板内部块 RAM 的原因是什么?如果您在 FPGA 上使用 Programmed I/O (PIO),我认为设备驱动程序(您的设备在这里是 PCI Express 接口)的正常行为就足够了。当您写入设备驱动程序时,数据将通过 FPGA 端下载的 IP 内核传输到块 RAM(也可以反向传输)。
查看 Xilinx 的 xapp1022(内存端点测试)包中的 Linux 驱动程序。
P.S.:我知道这是一个老问题,您可能会更快找到答案:)
【讨论】:
以上是关于访问内部 Xilinx FPGA 块 RAM的主要内容,如果未能解决你的问题,请参考以下文章
我做的FPGA课题要用到大量的数据,我用的xilinx的板子,大概会用到100块ram,但每块ram深度不深。
Xilinx Virtex-7 FPGA 中的 Block RAM是DRAM还是SRAM啊?
我做的FPGA项目,要用到256块ram,其中128块深度只有20,另外128块深度60。这样做行吗?