访问内部 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深度不深。

altera和xilinx的fpga区别

Xilinx Virtex-7 FPGA 中的 Block RAM是DRAM还是SRAM啊?

我做的FPGA项目,要用到256块ram,其中128块深度只有20,另外128块深度60。这样做行吗?

Xilinx FPGA中block RAM是做啥用的?在XPS中生成的MSS文件中也有地址,这是啥地址呢?

关于Xilinx的FPGA中双口RAM使用的若干问题