new启动新建项目 给新建的工程命名(默认名字好像是project_1),并指定工程存放路径,默认选择为工程创建子目录: 由于是第一次学习vivado,新建工程类型,选择“Example Project”: 快速创建一个基于Microblaze的工程,所以选择的工程模板是“Base Microblaze”: 进入下一步,要为工程选择一个板卡,随便弄一个: 完成一步步后,点击finish开始创建新工程,之后得到新工程框图如下: 下面再为这个软核添加其它IP或外围: 首先,我们 手动添加 axi_memory_maped_to_pcie,如上图所示,点击+号,在弹出的IP列表中找到AXI MM to PCIe : 双击上图列表中的AXI MM to PCIe组建后,一个AXI MM to PCIe模块自动添加到了工程的Diagram里: 用同样的方法,再添加另外一个组件- AXI BRAM CONTROLLER。然后选择执行自动连接: 自动连接后的地址编辑器如下所示: 添加组件的时候没有显示出参数配置的界面,也就是说之前添加的两个组件目前是默认配置,为了按照自己的要求对组件进行配置,研究了一个下午,一直没有找到入口,囧!其实最终发现和Altera的原理图编辑一样,在Diagram页对目标组件双击就可以进入组件参数设置窗口(Xilinx叫重定制 IP(即:Re-customize IP)窗口),下面将加入到系统的pcie(应该算Root端吧?!)核进行配置,具体配置如下: 链路采用 4x, 5G; 参考时钟 100M; Bar0空间 64K 地址宽度 32位, 数据宽度 128位, C_AXIBAR2PCIEBAR_0=0xFFFF0000( EP端的 bar0地址), C_PCIEBAR2AXIBAR_0=0x06000000( RP端的 BRAM基地址) 记得上图中的“Device/Port Type”要选择“Root Port of PCI Express Root Complex”。 研究了半天,才终于找到怎么设置 C_AXIBAR2PCIEBAR_0=0xFFFF0000( EP端的 bar0地址)和 C_PCIEBAR2AXIBAR_0=0x06000000( RP端的 BRAM基地址),如下图所示: 设置 gpio为 output, 32bit。设置 bram为 128位。 ------------------------------------------------ 以上创建Microblaze工程是参考这篇文章https://www.cnblogs.com/yuzeren48/p/6680062.html进行的;此时有个流程问题,该文章说接下来就可以将系统设计导入硬件到SDK了,但是我这边的结果是导出硬件到SDK之前必须“Generate Block Design”。仔细阅读这篇文章,确实提到了有此一步,但是是在导出硬件到SDK之后。我猜测该博主是先做项目,后写博文,所以在参考其博文进行设计的时候,应该会有些许不一样的地方。下面按照步骤继续完成SDK里的任务。 生成系统框架设计之后,导出硬件到SDK,这样就为该系统框架设计生成了一个hdf文件,从Vivado的file菜单里可以直接切换到SDK工具。进入SDK之后从SDK的file菜单里 file-new-board support packet,在该硬件平台上生成 BSP。 生成bsp之后的SDK如下图所示: 继续跟着前人步伐,在 BSP的基础上搭建一个 C-project,这里就不新建工程了,而是使用 pcie的 example来举例,点开下图中红框 import example,选择 RC枚举的例子。 如上图所示点击导入例程,弹出下图所示窗口,选择RC枚举例子,然后点击“OK” 样例成功导入后,直接右击工程,从弹出的下拉菜单里选择“Build Project”: Build project后就可以在 debug目录下看到相应的 elf文件了,如下图所示。需要注意的是,对于像我这样的新手来说,下图中的目录结构也是需要留意的,由于一路创建硬件、软件工程都是按照默认设置,所以下图中看到SDK目录位于硬件工程目录下,导入的BSP样例则位于SDK目录下,在BSP样例目录下就能找到Debug目录了: 到此似乎RP端已经圆满结束了,但是原文里是在上述样例基础上进行了修改;有点疑问的是修改是直接在样例上修改,还是另建工程进行修改呢?看行问后面出现了“ build project,在 project_2.sdk\helloword_bsp_xaxipcie_rc_enumerate_example_1\Debug目录下生成 elf文件。 ”也就是有了新的“project_2.sdk”,我的理解是不是新建了一个bsp?如果想要新建工程,可以在SDK里从file菜单的new下新建了一个工程: 这里由于还不太确定,所以还是在样例的基础上试着按照原文进行如下修改: 修改 rc_enmuerate_example.c文件(注:样例工程的src目录下只有xaxipcie_rc_enumerate_example.c文件)。需要修改以下几个地方: 1,去掉所有打印,使用 gpio输出替代 printf;( 此处暂不修改 ) 2,参考 xgpio_example.c ,在 rc_enmuerate_example.c中增加 gpio初始化,输出方向等设置; ( 此处暂不修改 ) 3,将 PCIE_CFG_BAR_0_ADDR改为 0xFFFF0000,确保在枚举的时候写入 EP端配置空间的 bar0基地址是 PCIE_CFG_BAR_0_ADDR; 4,修改 PcieInitRootComplex函数中关于 link_up的部分,使用 do while语句来确保 RP和 EP能 link_up; ( 此处该如何修改? ) 5,从 SDK安装目录 E:\Xilinx\SDK\2015.4\data\embeddedsw\XilinxProcessorIPLib\drivers\axidma_v9_0\src中把所有 .h文件 copy到 SDK工程所在的 bsp\microblaze_0\include下,把所有 .c文件 copy到 src目录下,参考 xaxidma_example_simple_intr.c文件配置 dma,特别注意我们要根据自己 ep端的设计来修 xaxidma_g.c中的 XAxiDma_ConfigTable。 DMA这一块需要修改的东西比较多,主要是 DMA收发数据时的几个 Rxbuffer和 Txbuffer地址要搞清楚,因为 microblaze在 RP端而 DMA在 EP端。本例中,我们一开始通过 micro blaze往 Txbuffer填数时, Txbuffer地址用的是 RP端看过去的 EP端 BRAM地址。而 DMA发送数据时, Txbuffer地址用的是 EP端看过去的 BRAM地址。 6,修改部分定义,代码里有很多 for循环,次数太多影响仿真。 上面第4步,我试着修改如下: /* Status = XAxiPcie_IsLinkUp(AxiPciePtr); if (Status != TRUE ) { xil_printf("Link is not up\r\n"); return XST_FAILURE; } xil_printf("Link is up\r\n");*/ /*Above was commented by Jerry, and which was changed to do-while statements*/ do { Status = XAxiPcie_IsLinkUp(AxiPciePtr); if (Status != TRUE ) { xil_printf("Link is not up\r\n"); return XST_FAILURE; } } while(Status != TRUE); xil_printf("Link is up\r\n"); 而第5步,从EDK安装目录下拷贝文件,由于版本不同,我安装目录下没有axidma_v9_0,但是有好几个不同的版本,最小版本是v9_3,还有v9_4到v9_8,那么就从最小的版本号里拷贝。 关于第6步的问题有: xaxidma_example_simple_intr.c文件在哪儿? 如何根据自己 ep端的设计来修 xaxidma_g.c中的 XAxiDma_ConfigTable? 上面第一个问题的答案,应该是在v9_3目录下的examples目录里能找到 xaxidma_example_simple_intr.c文件。 接下来完成RP端最后一步(注意上面对于软件的修改并未完成,先放一放),原文的描述是“ 打开 vivado,右键 board design,把 elf文件关联到我们的 RP端 board design里, RP端的软硬件设计就算完成了。 ”,所谓的“ 右键 board design ”应该是回到vivado之前RP的系统框图设计,右击框图里的microblaze,如下图所示,选择“Associate ELF Files...”: 之后弹出对话框,点击浏览按钮,搜索并找到之前刚刚生产的ELF文件,建立软硬件之间的关联: 到此,按照原文,RP端已经建立,下面开始第二部分,即EP端。 ------------------------------------------------------------------------------分割线--------------------------------------------------------- 在上面的基础上,使用 ip integrator – create block design,命名为 IP Integrator 可能是版本的问题,上述操作或者描述有误,具体操作应该是 Create Block Design,打开创建设计框图, 在弹出的对话框里对设计进行命名,设计存放地址保持默认即可: 点击OK给工程添加一个空的框图设计架构,如下图所示: 添加 ip核: axi_memory_maped_to_pcie, axi_abram_ctrl, axi_direct_memory_access, axi_interconnect。这些IP核可以在IP Catalog里找到,可能名字在不同版本里不太一样,在2018.3里,没有下划线,直接是空格代替,这也导致我在IP Catalog里搜索了半天没有找到对应IP: 设置 EP端 pcie核,本设计中链路采用 4x, 5G,参考时钟 100M, Bar0空间 64K,地址宽度 32位,数据宽度 128位, C_AXIBAR2PCIEBAR_0=0xEEEE0000( RP端的 bar0地址), C_PCIEBAR2AXIBAR_0=0x08000000( EP端的 BRAM基地址)。设置 bram数据位宽 128bit。其余连线如下。 连线搞了半天,发现DMA自动使能了SG,需要将其禁止,这样才能和原文一致: 在配置地址空间的发现居然还存在未连接的slave: 上述问题通过比较RP添加的pcie核,不同的地方在AXI:System页面里的S AXI ID WIDTH,RP里是4,而EP是2,而且还不能修改;只能删除后重新添加,发现变成了4. 重新添加pcie核后,完成各个端口连接,运行“Validate Design”的时候提示下面的错误,该错误似乎很多人遇到过,有人说是版本问题,解决的方案,有人换版本,有人是删组件重新添加: 删除该元件,然后重新添加并按照要求连接各个端口后,EP系统框架如下图所示: 执行Validate Design命令后不再出现之前的错误了,但是所有地址都提示unmapped slaves 我不知道这是怎么发生的,但是试着找到一个方法来解决:即将每个unmapped slave先转入exlcude(右击目标组件,选择exlude segment命令): 这样在Address Editor里会出现一个Exluded Address Segments,之前操作的组件就位于这里了,而且可以进行地址映射: 然而,再鼠标右击这个位于Excluded里的组件,选择Include Segment命令,这样该组件就map好了: 依次方法,将所有组件map好,完整的地址映射如下图所示,唯一的问题是,为何原文要将Data_S2MM以及Data_MM2S里的S_AXI_LITE接口要Exluded? Validate Design终于没有错误和Critical Warning了: 为何刚刚建立的RP和EP框图设计创建HDL Wrapper文件: 完毕后,分别对 EP和 RP两个 block design进行 generate output product(如上图所示,选择“Generate Output Products”)。选 global综合。