仿真與實際應用場景的差別
通常我們都會用Modelsim、Questa等工具對工程進行仿真驗證,在仿真的時候可能關注的點沒有那么的多,檢查到對端收到包沒有問題,一般情況下就認為已經完成調試,可以上板給host、birdge或者switch下的其他PCIE設備進行發包,不過在實際應用的過程中,如果想用FPGA作為Endpoint主動發包去讀寫其他設備,還有一個功能需要打開:Bus Master Enable,下圖1是PCIE協議對此功能的定義。
圖1
這個功能決定了Endpoint能否向遠端設備發起讀寫請求,只有使能了此功能,FPGA作為Endpoint時,才能夠向遠端設備成功發起讀寫訪問。Bus Master Enable在PCIE的配置空間命令寄存器04h中,此功能可以通過setpci指令打開。
如何使用PCIE的RQ接口來產生讀寫請求
在介紹如何控制端口信號產生讀寫請求之前,需要先介紹下描述符(如下圖2所示),描述符類似與包頭的功能,描述符的大小是128bit,這個是固定的,其內包含了地址類型、地址、請求類型、數字數等字段,在傳輸時第一拍先傳輸的是描述符,傳完描述符之后才會傳后面的數據,使用128bit或者大于128Bit數據端口的用戶對這一點可能沒有疑問,但是使用64bit數據端口的用戶會可能會有疑問,128bit的描述符,64bit的數據端口一拍傳不完,如果使用的是64bit的端口,描述符會傳兩拍,在傳輸的前兩拍都是描述符。
圖2
描述符的前兩個字段是address type,這個字段比較簡單,其標志了地址是否經過了轉換,如果用戶要自己產生讀寫請求可以把此字段設置為0,address就是用戶要訪問的地址,在填寫地址之前要確認好此地址是否可讀寫,避免讀到讀清寄存器。Dword Count表示的是描述符后跟的數據的Dword數,一般來講數據的長度都是雙字的整數倍,如果長度不是雙字的整數倍,就需要使用firstbe,或者lastbe,這兩個被放在了tuser字段,下面的篇幅會對其進行介紹。接下來是Request Type,Request Type字段的定義如下圖3所示:
圖3
根據所發送包的類型選擇相應數字填充data字段即可,接下來說一下Requester ID和Completer ID這兩個字段,如果用戶使用的是基于地址的方式對包進行路由,這兩個字段的數值不需要特別關注,重點字段已介紹完,描述符其他字段的含義可參考Xilinx的PG343(Versal ACAP Integrated Block for PCI Express v1.0 LogiCORE IP Product Guide)。
本篇參考的是Xilinx的PG343,接下來會對Versal的 PCIE IP進行介紹,以下提及的端口的data的bit數都是512bit,如果想了解其他bit位數據的接口如何使用,可以參考PG343,與512bit的數據端口區別不大。
產生讀寫請求所使用的接口是PCIE IP的Requester Request Interface,接口的定義如下圖4所示:
圖4
之前的篇幅中提到的描述符就在s_axis_rq_tdata中傳輸,前128bit是描述符,后面跟的是數據,類似與tlast、tkeep和tready等字段,本篇blog不再進行贅述,可以參照AMBA總線,或者上圖的描述,下面重點介紹s_axis_rq_tuser字段,手冊上稱其為邊帶信號,部分字段的定義如下圖5所示:
圖5
首先介紹下first_be和last_be,first_be指的是數據的第一個雙字中有幾個byte是有效的,一個雙字是4byte,所示只用4bit就可以識別出一個雙字中有效的byte數,在IP界面,把straddle模式打開時,可以一拍傳輸兩個TLP,在512bit數據接口,其first_be字段的長度為8bit,前4bit表示的是第一個TLP包中的第一個雙字中有效的byte,后4個bit表示的是第二個TLP包中的第一個雙字中有效的byte。is_sop的值表明了此拍的有或者沒有以及有幾個新的TLP,is_sop表明這一拍有沒有TLP結束或者有幾個TLP結束。
No straddle模式使用注意事項
在使用no straddle模式時,在發送1DW的memory write時,雖然上圖中說的是在使用no straddle模式時,is_eop是可選的,但是在實際使用的時候,特別是有1DW的memory write或者有1DW為結尾的memory write,需要把is_eop的數值設置為1。下圖6是memory write的發包格式,在生成包時可以參考如下圖6格式:
圖6
下下面的兩張圖是發包的仿真圖,圖7為End point的Requester request接口的仿真圖,圖8為root port的Completer Request接口的仿真圖,整體的流程就是End point通過自己的Requester request接口把memory write TLP發送到root port的Completer Request接口。
先看Requester request接口所發送的包的rq_tuser字段,410000f中的f表示第一個TLP的firstbe全有效,10000表示此拍數據沒有第二個TLP且這一拍數據只有1DW,last_be全為0,10000中的1即為圖中的第四行2‘b01, //is SOP,表示這個一拍是一個TLP的開始,4為圖中的2‘01 //is eop? 2’b00sop1 ptr兩行,表示此拍數據只有一個TLP,且此TLP在此拍結束。
接下來對Requester request接口所發送的包的rq_tdata進行說明,rq_tdata的前兩個bit表明了地址有沒有經過轉換,數據的地址為BE7 1CBD 975D 4000,rq_tdata中的801表示此數據位memory寫,且Dword count 為1.
圖7
接下來對RP的Completer Request接口接收到的數據進行簡要分析,可以看到m_axis_cq_tdata與s_axis_rq_tdata的字段完全相同,m_axis_tuser中的firstbe為0F,lastbe為00,這一點與發送端的情況一致,End point此次發送的數據包被Root port成功接收。
圖8
審核編輯:湯梓紅
-
FPGA
+關注
關注
1630文章
21769瀏覽量
604656 -
接口
+關注
關注
33文章
8667瀏覽量
151526 -
Xilinx
+關注
關注
71文章
2168瀏覽量
121777 -
仿真
+關注
關注
50文章
4111瀏覽量
133786 -
PCIe
+關注
關注
15文章
1245瀏覽量
82869
發布評論請先 登錄
相關推薦
評論