轉載 PCIe學習(三):PCIe DMA關鍵模塊分析之二

版權聲明:本文爲CSDN博主「CLGo」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/cllovexyh/article/details/79855813

簡介
    這是學習PCIe DMA傳輸的第二篇博客,在前一篇中敘述了PCIe DMA傳輸的部分基礎知識,並且較爲詳細的分析了接收引擎的各個狀態,這裏接着分析第二個關鍵模塊:發送引擎(BMD_64_TX_ENGINE.v)。
    軟件:VIVADO2017.4
第一步:模塊功能分析
    在分析發送引擎的具體操作之前,需要多這個模塊實現的功能進行簡單的分析。如下是發送引擎中的標頭類型

這裏寫圖片描述

    由圖可知,這個模塊包含5種類型的標頭,這裏先簡單的說明這幾種標頭的應用場景,BMD_64_CPLD_FMT_TYPE 標誌着發送一個帶數據的完成包,這個使用在PC端向FPGA發送一個存儲器讀請求後,FPGA通過這個報文將存儲器信息返回到PC端,這是PIO模式;
    BMD_64_MWR_FMT_TYPE和BMD_64_MWR64_FMT_TYPE標誌着FPGA發送存儲器寫請求TLPs,這個使用在啓動DMA寫時,發送引擎組建存儲器寫請求包將數據發送到PC上;
    BMD_64_MRD_FMT_TYPE和BMD_64_MRD64_FMT_TYPE標誌着FPGA發送存儲讀請求TLPs,這個使用在PC配置啓動DMA讀時,發送引擎組建存儲器讀請求包,PC發送帶數據的完成包到FPGA上,被接收引擎接收(上一篇博客中分析的帶數據的完成包)。
    以上就是幾種標頭的應用場景,瞭解清楚這些對分析發送引擎的結構很有幫助。接下來就開始分析發送引擎。
第二步:具體代碼分析
    觀察狀態機跳轉

這裏寫圖片描述

    首先進入復位狀態BMD_64_TX_RST_STATE,這個狀態中有多個判斷條件,包含發送完成包、DMA讀操作和DMA寫操作,接下來就逐個分析。

這裏寫圖片描述

    1、假設首先發送完成包。設置compl_done_o 爲0,表示完成包未發送完成,這個信號會進入接收引擎來判斷PC發送的存儲器讀請求是否完成。然後是條件判斷,req_compl_q 是從接收引擎引入的信號,其目的是讓發送引擎發送完成包;compl_done_o 是上文說的完成包是否發送完成標誌信號;trn_tdst_rdy_n 是從機是否準備好接收數據標誌信號,此時是FPGA發送數據給PC,所以PC是從機,這個信號表示PC端是否準備好接收數據;trn_tdst_dsc_n 這個信號在FPGA上被置1了。
    設置幀開始信號(trn_tsof_n)有效、幀結束信號(trn_teof_n)無效、主機準備好發送數據(trn_tsrc_rdy_n)之後,就開始組裝完成包頭;組裝的信息來自接收引擎和PCIe IP核,這就完成了發送完成包標頭的前2DW。跳轉到下一狀態。

這裏寫圖片描述

    由於完成包是3DW標頭,所以在這個狀態中發送1DW標頭+1DW數據。
    首先判斷從機是否準備好接收數據,準備好後設置幀起始無效,由於這是PIO模式,因此只有兩幀,所以這是最後一幀,設置幀結束有效,接着設置主機準備好發送數據,然後發送第二幀(1DW標頭+1DW數據),然後設置trn_trem_n 有效,表明這一幀數據都有效,然後compl_done_o 表示完成包發送完成,狀態跳轉到BMD_64_TX_CPLD_WIT 。

這裏寫圖片描述

    這個狀態中設置關鍵的4個信號無效,然後跳轉到復位狀態,準備下一次傳輸。
    2、假設進入DMA寫存儲器操作,

這裏寫圖片描述

    首先判斷是否啓動DMA寫操作、DMA寫操作完成等信號,其中serv_mwr 信號是用輪詢操作控制DMA寫操作的進行。接着和上面完成報文傳輸的格式差不多,trn_trem_n爲0表示這一幀的兩個DW都有效,cur_mwr_dw_count表示這一個TLP中數據的數量(單位DW),拼接發送第一幀數據,即2DW標頭。接着就進入輪詢操作。

這裏寫圖片描述

    輪詢操作的目的是在發送一段時間的存儲器寫TLP之後,停止一次,然後判斷此時是否有DMA讀存儲器開始信號,如果有的話就去執行DMA讀操作,否則就是停止一次傳輸,下一個週期開始又繼續DMA寫操作。其中tmwr_wrr_cnt 信號統計發送TLP的數量,而mwr_wrr_cnt_i 信號則是設定輪詢操作的TLP的量,這個值是在寄存器中配置的,當這兩個值相等時就發生一次輪詢操作。
    通過mwr_64b_en_i 信號判斷髮送的存儲器寫請求的標頭是3DW還是4DW,這和完成包不一樣,因爲完成包只有3DW標頭,而存儲器寫或者讀的TLP有3DW和4DW兩種。
    先分析3DW標頭,此時跳轉到BMD_64_TX_MWR_QW1狀態

這裏寫圖片描述

    這個狀態是發送第二幀數據,包含1DW標頭(地址)+1DW數據,同樣設置主機有效信號,然後通過cur_wr_count判斷這是不是第一個TLP,因爲第幾個TLP決定着需要存入存儲器的地址,mwr_addr是PC端申請的連續內存的首個地址,所以cur_wr_count爲0,則要存入的地址爲連續內存的首地址,之後就按照每個TLP中的數據量改變下一個TLP數據的存儲地址。
    cur_mwr_dw_count信號初值是一個TLP中的數據量(DW),如果當前cur_mwr_dw_count爲1,則表示這是最後一個數據了,那麼這時通過cur_wr_count分析這是否是最後一個包,如果是最後一個包那麼說明這個TLP只有兩幀(3DW標頭+1DW數據),此次DMA傳輸完全結束,mwr_done_o置1;若不是最後一個數據,說明這個TLP不止兩幀數據,則跳轉BMD_64_TX_MWR_QWN 狀態。

這裏寫圖片描述

    一個TLP傳輸到最後有可能還剩下1個或者2個DW數據,所以程序中就設計兩種情況,如果只有1個DW,那麼還需要組裝1DW無用數據,同時使用trn_trem_n 信號來表明最後一個DW無效;如果剛好還剩兩個DW數據,則剛好一次傳輸完,此時設置trn_trem_n 爲0來表示這一幀中兩個DW數據都是有效的。如果還剩的數據大於2DW,則就直接每次傳輸2DW數據,直到出現只剩下1個或者2個DW數據。
    至此,DMA寫操作的流程已經分析完成了,至於DMA讀操作,以及3DW或4DW標頭的分析都與分析類似,就不再分析了。
    此外,BMD_EP_MEM.v 以及BMD_EP_MEM_ACCESS.v兩個模塊可以參照PIO中的分析,BMD_EP_MEM.v中的寄存器可以參照官方資料xapp1052,在這裏就不過多敘述了。
結束
    以上就是PCIe DMA的全部分析,後期會上傳一些參考資料及有詳細註釋的.v文件,有需要的同學可以下載(https://download.csdn.net/download/cllovexyh/10335472)。

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