PCIE-XPDMA-SGDMA調試筆記

聲明:所有文章屬於個人在工作中所記下和蒐集的筆記,不得轉載

參考的手冊地址:
a). Xilinx PCIe axi memory mapped手冊地址鏈接:https://china.xilinx.com/support/documentation/ip_documentation/axi_pcie/v2_8/pg055-axi-bridge-pcie.pdf
b). xapp1171文檔PCI Express Endpoint-DMA Initiator Subsystem手冊地址鏈接: https://www.xilinx.com/support/documentation/application_notes/xapp1171-pcie-central-dma-subsystem.pdf
c)AXI Central Direct Memory Access (CDMA) 手冊地址鏈接: https://china.xilinx.com/support/documentation/ip_documentation/axi_cdma/v4_1/pg034-axi-cdma.pdf
d)關於CDMA可以參考我的這篇博客:
https://blog.csdn.net/Real003/article/details/90054993
e)關於PCIE Memory Mapped可以參考我的這篇博客:
https://blog.csdn.net/Real003/article/details/90045800
f)關於xapp1171源碼工程恢復的方法可以參考我的這篇博客:
https://blog.csdn.net/Real003/article/details/90186337

最近剛剛調試完PCIE memory mapped IP,從接到任務到完成這個驅動的編寫,花了差不多兩週,不容易啊,這兩週都是天天加班在調試,趁熱打鐵,趕緊記錄一下調試筆記,不然過幾個月估計就忘得一乾二淨了。。。。

從設計思路開始講起吧,首先肯定是先去下載Xilinx PCIe axi memory mapped手冊,把手冊看一遍,提煉出來重點,以及網上搜索一些與PCIe axi memory mapped相關的資料,網上資料真的不多啊,看到網上有說需要與CDMA IP配合一起使用,Xilinx官網也給了一個測試例子xapp1171,按照xapp1171文檔裏的步驟創建好工程後,數據始終都沒收到啊,只能進行PIO操作,DMA怎麼也沒有工作起來,也真的是琢磨了好幾天。後來得到了大神的指點,才最終解決了這些問題,我覺得好的東西還是可以寫出來分享一下的,這樣可以幫助別人減少很多的調試時間,下面開始我的設計步驟:

  1. 首先參照xapp1171用Block模塊搭建好工程,或者用xapp1171工程腳本恢復工程,這一步可以參考我上面中提到的博客,搭建開的Block框圖如下:
    在這裏插入圖片描述
    去掉DDR3模塊,引入了兩個AXI_M接口:pcie_data_m_axi用來讀寫DMA數據,pcie_pio_m_axi用來讀寫驅動外部寄存器。
    axi_cma模塊勾選上Enable Scatter Gather,讀寫數據位寬64,地址位寬32
    AXI Interconnect模塊選擇3個Slave和6個Master,需要注意的是:M01_AXI是用來配置PCIE CTL的,所以它的M01_ACLK時鐘必須連PCIE的axi_ctl_aclk_out,其它時鐘可以全部連axi_aclk_out;
    AXI Memory Mapped To PCI Express模塊:
    PCIEBAR2AXIBAR勾選BAR0,映射基地址爲:0x8100_0000,128kilobytes夠用了(0x8102_0000);
    AXIBAR2PCIEBAR勾選BAR0,BAR1,映射基地址BAR0爲:0xa000_0000,用來存放描述符,BAR1爲:0xc000_0000,用來存放數據;
    bram數據位寬64bit,4k地址深度就可以了。
    在添加AXI總線接口的時候Frequency填:125000000,CLK Domain填:design_1_axi_pcie_1_0_axi_aclk_out

  2. 關於地址分配:
    地址分配可以參考XAPP1171文檔的P7頁的配置,我這裏是根據它的配置做了適當的修改:
    在這裏插入圖片描述
    從上面的地址配置表可以分析出:
    1).PCIE的Master端只做寄存器配置的工作,完成往bram中存儲BAR1數據對應的RC端的物理地址;完成對PCIE的BAR0對應的RC端的物理地址配置;完成CDMA的寄存器配置;完成通過PIO_M_AXI接口讀寫外部寄存器;
    2)CDMA的M_AXI端即axi_cdma->data端根據SG端口讀取的描述符完成數據搬移;將bram存儲的BAR1地址搬移到pcie的控制寄存器中;將BAR1中的數據與pcie_data_m_axi中的數據來回搬動以實現讀寫功能;
    3)CDMA的M_AXI_SG端即axi_cdma->data_sg端在PCIE的Master端配置完CDMA寄存器後開始從BAR0讀取描述符;

Excluded Address Segment中的地址可以Include Segment進去,沒有什麼影響,我這樣分開只是爲了更加明確在interconnect中每個Master真正需要控制哪些slave。

  1. 關於描述符
    在這裏插入圖片描述
    上圖是描述符的格式由8個32bit字對其,由SA和DA的數據地址決定DMA從哪裏把數據搬運到哪裏,如果SA對應的是AXI interconnet模塊的BAR1地址,DA對應的是用戶端M_AXI地址,則實現PCIE的寫操作;如果SA對應的是AXI interconnet模塊用戶端M_AXI地址,DA對應的是BAR1地址,則實現PCIE的讀操作;具體詳細的可以參考:https://blog.csdn.net/Real003/article/details/90054993

  2. 工作流程:
    工作流程與xapp1171的15頁中提到的一樣:
    首先配置寄存器:關於詳細的寄存器描述請參考pg055和pg034;
    PCIEBAR2AXIBAR0=0x8100_0000

1).PCIEBAR2AXIBAR0+0X0000_C000 數據:0x0000_0004;配置CDMA的寄存器,對CDMA復位
2).PCIEBAR2AXIBAR0+0X0000_C000 數據:0x0000_7008;配置CDMA的寄存器,開啓DMA傳輸完成中斷,錯誤中斷,啓用SG模式
3).RC端創建描述符,獲得描述的偏移物理地址,將描述符的物理地址通過下面兩個寄存器告訴PCIE,Bar0用於存描述符;
4).PCIEBAR2AXIBAR0+0X0000_8208 數據:0x0000_0001;配置PCIE的寄存器,bar0映射的RC端的高32位物理地址(該值根據實際情況修改)
5).PCIEBAR2AXIBAR0+0X0000_820c 數據:0x0000_0000;配置PCIE的寄存器,bar0映射的RC端的低32位物理地址(該值根據實際情況修改)
6).PCIEBAR2AXIBAR0+0X0000_0000~ 0X0000_7fff 數據:往bram中寫入數據,表示每一個描述符的起始地址在BAR1中映射到RC端所對應的物理地址;
7).PCIEBAR2AXIBAR0+0X0000_c008 數據:0x8080_0000;配置CDMA的寄存器,寫入CDMA開始工作後從SG端口向BAR0開始讀取的描述符的起始地址指針
8).PCIEBAR2AXIBAR0+0X0000_c010 數據:0x8080_0040;配置CDMA的寄存器,寫入CDMA開始工作後從SG端口向BAR0開始讀取的描述符的最後一個地址指針。(該值根據實際情況修改)
9).寫入第八步的寄存器後CDMA工作開始,直到讀取到上面設置的最後描述符指針,完成數據搬移動作後,停止。
10).PCIEBAR2AXIBAR0+0X0000_C004 數據:0x0000_7000;如果啓用了中斷,中斷髮生後需要清除中斷。
在這裏插入圖片描述
上圖是下app1171中工作流程的例子,我也是看了好多遍纔看懂這個圖,我這裏稍微解釋一下:
上面第9步開始工作後,CDMA的SG端口根據第7步設置的寄存器數據,從AXI地址0x8080_0000開始讀取八個數據,AXI地址0x8080_0000映射到RC端的物理地址是0x00000001_00000000;這個物理地址映射我們在第四第五步進行了配置,有可能你的RC端並不是這個地址,那麼你只需要配置成你的地址就可以了。讀出來的描述符如上圖中的描述符,這些描述符都是在第三步中由RC端寫入它的物理地址中的,我們這裏使用SG端口通過BAR0的地址映射,讀取過來進行使用。
讀出來的第一個描述符SA爲0x8100_0000,DA爲0x8100_8210,表示下一步會通過CDMA的M_AXI端讀取bram中的數據,寫入地址爲0x8100_8210,對應BAR1高位映射的物理地址。
第二個描述符表示從BAR1中讀取64k字節的數據寫入DDR;
第三個描述符表示從bram中讀取一個BAR1的物理映射地址,下發給PCIE的控制寄存器;
第四個描述符表示從DDR中讀取64K字節的數據,送入BAR1。
下圖這個引入了完成狀態標誌,一般用在最後一個描述符。
在這裏插入圖片描述

  1. 封裝後的Block生成HDL Wrapper後如下:
    注意reset_logic_mmcm_locked_in作爲連接PCIE的復位引腳要做同步輸入處理,這個在pg055的p41頁中有講到,具體可以參考我的另一篇博客:https://blog.csdn.net/Real003/article/details/90045800
    在這裏插入圖片描述
    如果與PCIE驅動對接的不是AXI接口,可以將AXI_M總線時序轉換爲其它的,比如視頻時序、標準的FIFO時序等,這個還是比較容易的。
    我的系統是G2X2經過測試PIO寄存器讀速率爲12.806Mbps,寫速率爲306.223Mbps,當然這個測試速率並不可靠,因爲還參雜了其它用戶邏輯,由於項目時間吹得緊原因DMA讀寫數據速率沒測。

  2. 這個PCIE驅動的開發整個調試過程還是不算太難的,主要是在幾個地方卡了一些時間:
    a).一是地址的分配,之前一直沒搞懂爲什麼要這麼分配,導致我完全照搬XAPP1171的配置,無法正確讀取出BAR0、BAR1中的數據,手冊反覆看了好幾遍才明白,所以你們在使用的時候,地址分配和寄存器配置數據下發需要根據實際情況做修改才能跑起來,當然整個Block的框架是沒有問題;
    b).二是我調試的系統RC端存在字對其的問題,往地址尾數[3:0]是0x4或者0xc寫數據的時候EP端收到的數據跑到高32bit去了,之前一直沒發現,而CDMA和PCIE的寄存器配置的總線數據位寬是32位的,導致了高32bit數據的失效;
    c).三是CDMA設置了中斷打開,在中斷觸發後,一定要進行對應位的寫1清零,不然會導致下一個DMA數據沒法傳輸;

7.疑問:
a).另外就是一直沒搞明白 在PCIE IP中設置的AXIBAR2PCIEBAR 的BAR1、BAR2設置的偏移地址與通過PCIE CTL端口配置的寄存器0x18、0x1c、0x24、0x28有何聯繫,是不是BAR1、BAR2設置的偏移地址可以隨便設置,只要正確配置0x18、0x1c、0x24、0x28就可以了 ?
b).該工程只使用了兩個BAR和一個CDMA,一個BAR用來作爲描述符通道,另外一個BAR用來作爲DM數據通道,只能實現半雙工通信,是否可以再開啓多個BAR和增加多個CDMA來實現更高速率的傳輸 ?

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