xapp1052是xilinx官方給出的一個有關(guān)DMA數(shù)據(jù)傳輸?shù)臉永糜赑C端和FPGA端之間的DMA數(shù)據(jù)傳輸。首先需要說的是,xapp1052并不是一個完整的DMA數(shù)據(jù)傳輸?shù)慕K端硬件設(shè)計,這在下面會有詳細解釋。
首先說一下xapp1052模塊的組成結(jié)構(gòu):頂層模塊是xilinx_pci_exp_ep,在頂層模塊中包含pci_exp_64b_app和bmd_design兩個模塊,其中pci_exp_64b_app就是我們要介紹的重點,而bmd_design則是實現(xiàn)PCIE協(xié)議的底層模塊。
下面就詳細說一下pci_exp_64b_app的模塊結(jié)構(gòu):
pci_exp_64b_app
|
|__BMD
|
|__BMD_EP
| |
| |__BMD_EP_MEM_ACCESS
| | |_BMD_EP_MEM
| |
| |__BMD_RX_ENGINE
| |__BMD_TX_ENGINE
| |__BMD_INTR_CTRL
|
| |__BMD_GEN2
| |__BMD_RD_THROTTLE
|
|__BMD_TO_CTRL
|__BMD_CFG_CTRL
1,BMD_RX_ENGINE的設(shè)計:這個模塊的作用就是接受來自PC的TLP包(trn_rd[63:0]),并根據(jù)不同的情況對包進行拆解,首先根據(jù)trn_rd[62:56]位判斷包的類型,如果是32位地址讀請求(BMD_MEM_RD32_FMT_TYPE),那么就轉(zhuǎn)到32位讀對應(yīng)的狀態(tài)(BMD_64_RX_MEM_RD32_QW1);如果是32位地址寫請求(BMD_MEM_WR32_FMT_TYPE),那么久轉(zhuǎn)到32位寫對應(yīng)的狀態(tài)(BMD_64_RX_MEM_WR32_QW1);如果是不帶數(shù)據(jù)的完成類型(BMD_CPL_FMT_TYPE),那么就轉(zhuǎn)到完成請求對應(yīng)的狀態(tài)(BMD_64_RX_CPL_QW1);如果是帶數(shù)據(jù)的完成類型(BMD_CPLD_FMT_TYPE),那么就轉(zhuǎn)到帶數(shù)據(jù)完成對應(yīng)的狀態(tài)(BMD_64_RX_CPLD_QW1)。
上面是狀態(tài)機的第一次過渡,下面看狀態(tài)的第二次過渡,在狀態(tài)是BMD_MEM_RD32_FMT_QW1時,這個時候TLP包的第二個DWORD已經(jīng)傳來,從第二個DWORD中可以得到讀請求的地址addr_o,這個地址時輸入到memory模塊下用于讀出對應(yīng)地址下的數(shù)據(jù)的;然后過渡到下一個狀態(tài)(BMD_64_RX_MEM_32_WT),在這個狀態(tài)下,RX模塊會一直檢測從TX返回的compl_done_i信號,當(dāng)讀請求申請的對應(yīng)地址下的數(shù)據(jù)由TX發(fā)送出去時,compl_done_i信號就為1,這個時候RX就會返回到RST狀態(tài)。當(dāng)狀態(tài)是BMD_MEM_WR32_FMT_QW1時,這個時候RX也接受到了TLP包的第二個DWORD,從這個DWORD中可以拆分出地址(addr_o)和要寫的數(shù)據(jù)(wr_data_o),同時在這個狀態(tài)寫使能值為有效(we_en_o),然后過渡到下一個狀態(tài)(BMD_64_RX_MEM_WR32_WT),在這一個狀態(tài),RX會一直檢測從memory模塊出來的信號(wr_busy_i)是不是為0,如果為0,說明寫操作完成,RX回到RST狀態(tài)。當(dāng)狀態(tài)是BMD_64_RX_CPL_QW1的時候,說明這是一個不帶數(shù)據(jù)的完成,其他并沒有什么操作。當(dāng)狀態(tài)是BMD_64_RX_CPLD_QW1時,說明這是一個帶數(shù)據(jù)的完成,為什么完成信號要攜帶數(shù)據(jù)呢,原因就是為了檢驗傳輸?shù)臄?shù)據(jù)是否正確,在這個狀態(tài)下以及它的過渡狀態(tài)中,RX會一次檢測傳輸?shù)絇C端的數(shù)據(jù)和設(shè)備內(nèi)存的數(shù)據(jù)是否相同,如果不相同,說明數(shù)據(jù)傳輸失敗,返回失敗傳輸信號(cpld_malformed)。
從上面的描述可以看出,BMD中的RX是不支持連續(xù)的寫數(shù)據(jù)的(往設(shè)備內(nèi)存寫數(shù)據(jù)),所以往設(shè)備內(nèi)存寫數(shù)據(jù)的DMA操作,xapp1052是不支持的,那么這里發(fā)送和接收的數(shù)據(jù)到底是什么呢,其實這里RX并不是要發(fā)送和接收存儲數(shù)據(jù),而是發(fā)送和接收配置數(shù)據(jù),即DMA的配置數(shù)據(jù)。
2,BMD_TX_ENGINE的設(shè)計:這個模塊是往PC端發(fā)送TLP包(trn_td[63:0]),這個模塊是xapp1052DMA的核心模塊,它包含DMA控制器的所有操作,當(dāng)然這里只是發(fā)送端的DMA控制器。TX要解決的問題就是要在不同的情況下發(fā)送對應(yīng)的TLP包。
第一種情況:發(fā)送帶數(shù)據(jù)的完成TLP,這是TX最優(yōu)先處理的(這一點不是很確定,個人感覺xapp1052寫的有點問題)。首先在RST狀態(tài)會產(chǎn)生一個帶數(shù)據(jù)類型的包頭。然后過渡到下一個狀態(tài):BMD_64_TX_CPLD_QW1。在這個狀態(tài)里要發(fā)送TLP的第二個DWORD,主要包含地址和數(shù)據(jù),然后進入下一個狀態(tài)(BMD_64_TX_CPLD_QW1)。
第二種情況:開啟DMA發(fā)送操作,在mwr_start_i和cfg_bm_en有效的情況下,開始發(fā)送TLP的包頭,DMA的包頭也只是一個普通的寫數(shù)據(jù)請求;在DMA發(fā)送模式下,有幾個參數(shù)是特別重要的:要發(fā)送的TLP數(shù)目、每個TLP中包含的數(shù)據(jù)長度、每個TLP對應(yīng)PC端的起始寫入地址。進入下一個狀態(tài)(BMD_64_TX_MWR_QW1)的時候,TX首先會根據(jù)已經(jīng)發(fā)送的TLP包的個數(shù)來計算PC端寫入的起始地址(tmwr_addr),根據(jù)計算出的起始地址發(fā)送TLP的第二個DWORD,然后進入下一個狀態(tài):BMD_64_TX_MWR_QWN。在這個狀態(tài)中,TX首先會判斷一個TLP包中的數(shù)據(jù)長度是多少,如果是1,則在發(fā)送下一個DWORD之后,TX會進入RST狀態(tài);如果是2,則下一個DWORD會包含兩個數(shù)據(jù),但是同樣在發(fā)送完下一個DWORD之后,TX會進入RST狀態(tài),在進入RST狀態(tài)之前,TX又會判斷當(dāng)前發(fā)送的TLP數(shù)目是否已經(jīng)等于預(yù)先設(shè)定的數(shù),如果相等,則會返回mwr_done_o信號;如果當(dāng)前數(shù)據(jù)長度大于2,那么在發(fā)完下一個DWORD的時候,TX還會繼續(xù)發(fā)送數(shù)據(jù),知道余下的數(shù)據(jù)長度小于2。這就是TX的發(fā)送DMA操作,但是現(xiàn)在有一個問題就是在每個TLP中的數(shù)據(jù)長度大于2的時候,發(fā)向PC端的地址該由誰控制累加呢,這在TX模塊中并沒有體現(xiàn),這里我猜測是在PC端地址會由相應(yīng)的模塊控制自動累加。還有這里的TX的DMA其實也是有一定問題的,DMA發(fā)送的數(shù)據(jù)不是由內(nèi)存讀取出來的,而是一個始終不變的數(shù),雖然表面上看是由內(nèi)存中讀取出來的,說明xapp1052的TX的DMA設(shè)計也只是存粹驗證一下DMA控制器的正確性,數(shù)據(jù)的來源xapp1052卻并沒有涉及。
評論