PCIE_DMA實例三:Xilinx 7系列(KC705/VC709)FPGA的EDK仿真

一:前言

好久沒寫博客了,前段時間有個朋友加微信請教關於PCIe的一些學習方法。本人也不是專家,只是略知一些皮毛。對於大家反饋的問題未必能一一解答,但一定知無不言。以後我會常來博客園看看,大家可以把問題直接在評論區提出來。這篇博客是應部分網友的要求寫的,Xilinx升級到7系列後,原來的pcie ip核trn接口統統轉換成了axis接口,這可愁壞了之前用xapp1052的朋友,一下子不好用了,該怎麼辦?對此我的想法是:如果您兩年左右的verilog代碼經驗,建議您直接使用axis接口,如果您覺得使用不方便,大可在外面再包一層您自己覺得好用的接口。博主公司有這方面的技術積累,但涉及到商業利益,我不能在此出售源代碼,如有私下合作,可談。PCIe_to_RapidIO, PCIe_to_FC, PCIe_to_Enet等各類接口轉換都沒問題。如果您剛接觸PCIe,想要更清楚得理解axis接口的PCIe IP核是如何工作的,那麼這篇系統級的博客對您將會非常有用,同時博主也會給出一個用Block_design搭的帶有DMA功能的簡易EP,大家只要自己寫個簡單的控制邏輯就可以操作EP端的DMA,對於沒有經驗的工程師,是一個比較容易的技術遷移。

二:前期準備

1、pcie基礎還是要有,尤其是協議部分。推薦一本電子書,很經典,請耐心讀它(Addison.Wesley.PCI.Express.System.Architecture.eBook-LiB.chm)下載地址:http://download.csdn.net/download/yuzeren48/7723815

2、Vivado2015.4套件

3、Modelsim64_10.5

三:具體步驟

第一部分我們要生成一個PCIe的RP端,具體操作如下:

打開vivado,快速生成一個example design,選擇base microblaze,按默認設置生成。手動添加axi_memory_maped_to_pcie,axi_abram_ctrl; 根據EP端的設計需求,設置RP端pcie核,本設計中鏈路採用4x,5G,參考時鐘100M,Bar0空間64K,地址寬度32位,數據寬度128位,C_AXIBAR2PCIEBAR_0=0xFFFF0000(EP端的bar0地址),C_PCIEBAR2AXIBAR_0=0x06000000(RP端的BRAM基地址)設置gpio爲output,32bit。設置bram爲128位。然後自動連接,最後Generate Block Design,生成RP端系統框架如下:

2、Create HDL Wrapper 外部端口如下:

module pcie_rp_wrapper

output [31:0] gpio_tri_o,

  input [3:0]pcie_7x_mgt_rxn,

  input [3:0]pcie_7x_mgt_rxp,

  output [3:0]pcie_7x_mgt_txn,

  output [3:0]pcie_7x_mgt_txp,

  input reset,

  input rs232_uart_rxd,

  output rs232_uart_txd,

  input sys_diff_clock_clk_n,

  input sys_diff_clock_clk_p

)

 

3、FILE-Export-Export hardware,生成hdf文件,File-Launch SDK;

4、進入SDK,file-new-board support packet,在該硬件平臺上生成BSP。

5、在BSP的基礎上搭建一個C-project,這裏我們不新建工程了,而是使用pcie的example來舉例,點開上圖中紅框import example,選擇RC枚舉的例子。

Build project後就可以在debug目錄下看到相應的elf文件了。

6、修改rc_enmuerate_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循環,次數太多影響仿真。

7、build project,在project_2.sdk\helloword_bsp_xaxipcie_rc_enumerate_example_1\Debug目錄下生成elf文件。

7、打開vivado,右鍵board design,把elf文件關聯到我們的RP端board design裏,RP端的軟硬件設計就算完成了。

 

 

第二部分我們要設計一個自己的PCIe EP端,具體操作如下:

1、  在第一部分的基礎上,使用ip integrator – create block design,命名爲Pcie_ep_dma。添加ip核:axi_memory_maped_to_pcie,axi_abram_ctrl,axi_direct_memory_access,axi_interconnect。設置EP端pcie核,本設計中鏈路採用4x,5G,參考時鐘100M,Bar0空間64K,地址寬度32位,數據寬度128位,C_AXIBAR2PCIEBAR_0=0xEEEE0000(RP端的bar0地址),C_PCIEBAR2AXIBAR_0=0x08000000(EP端的BRAM基地址)。設置bram數據位寬128bit。其餘連線如下。

2、Create HDL Wrapper 外部端口如下:

entity Pcie_ep_dma_wrapper is

  port (

    REFCLK : in STD_LOGIC;

    pcie_7x_mgt_rxn : in STD_LOGIC_VECTOR ( 3 downto 0 );

    pcie_7x_mgt_rxp : in STD_LOGIC_VECTOR ( 3 downto 0 );

    pcie_7x_mgt_txn : out STD_LOGIC_VECTOR ( 3 downto 0 );

    pcie_7x_mgt_txp : out STD_LOGIC_VECTOR ( 3 downto 0 );

    reset : in STD_LOGIC

  );

end Pcie_ep_dma_wrapper;

完畢後,分別對EP和RP兩個block design進行generate output product。選global綜合。

 

第三部分就是將EP端和RP端相連仿真了。Testbench實在太簡單了這裏不多說了,把EP和RP的pcie一連,接上時鐘和復位就可以仿真了。仿真結果如下:

EP->RP:

RP到EP:

AXI_Dma上的波形

因爲發送的length設成了256字節,故一次dma的時間很短。

四:結束語

按照慣例,硬件Block_design博客裏已經公開,SDK軟件主要的幾個關鍵點博客裏也已經點明,基本一年以上經驗的工程師看了這篇博客就可以獨立搞定這個K7的PCIe_DMA_Design了。當然如果你搞不定,歡迎你付費購買此篇博客的全套源代碼(包含全部軟硬件設計),博主會附贈你三個注意事項,以及博主關於PCIe地址映射的理解。此次付費項目如下:1、帶破解的Modelsim64_10.5,xaxipcie 的核必須要用modelsim10.5進行仿真。2、K7_PCIe_DMA_Design,包含軟硬件源代碼以及相關的說明文檔。付費方式:支付寶(賬戶:[email protected]  姓名:俞則人)。費用:50元(其中帶破解的Modelsim64_10.5,價值20元,網上沒有免費的)。另外,博主最近比較忙,QQ基本不上,有需要請微信(330853172)聯繫。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章