色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Xilinx RapidIO核例子工程源碼分析

FPGA之家 ? 來源:FPGA之家 ? 作者:FPGA之家 ? 2023-03-03 10:27 ? 次閱讀

一、軟件平臺與硬件平臺

軟件平臺:

操作系統:Windows 8.1 64-bit

開發套件:Vivado2015.4.2

硬件平臺:

評估板:ZYNQ-7 ZC706 Evaluation Board

二、打開例子工程

1、新建工程,并在IP Catalog中找到Serial RapidIO Gen2

74f779de-b93d-11ed-bfe3-dac502259ad0.png

2、雙擊Serial RapidIO Gen2進入核的配置界面,所用參數全部保持默認,然后直接點擊OK

750934bc-b93d-11ed-bfe3-dac502259ad0.jpg

3、在彈出的的對話框中直接點擊Generate

751a9eb4-b93d-11ed-bfe3-dac502259ad0.png

4、在彈出的對話框中點擊OK

75288150-b93d-11ed-bfe3-dac502259ad0.png

5、等待srio_gen2_0核綜合完畢,可能會花幾分鐘的時間

7537f518-b93d-11ed-bfe3-dac502259ad0.jpg

6、IP核綜合完畢以后,單擊srio_gen2_0,并點擊鼠標右鍵,在彈出的菜單欄中單擊Open IP Example Design…

754724c0-b93d-11ed-bfe3-dac502259ad0.jpg

7、在彈出的的對話框中選擇例子工程的存放目錄(這個目錄可任意選擇),然后單擊OK

75581d70-b93d-11ed-bfe3-dac502259ad0.png

8、等一段時間以后例子工程就會自動打開

756b5732-b93d-11ed-bfe3-dac502259ad0.jpg

三、例子工程詳解

3.1 工程概述

RapidIO核的例子工程的仿真頂層代碼里面例化了兩個實體,一個叫做srio_example_top_primary,另外一個叫做srio_example_top_mirror,如下圖所示

757bfad8-b93d-11ed-bfe3-dac502259ad0.jpg

其中每個例化實體都能被配置為發送支持的包類型,檢測接收包失配以及上報鏈路的仿真細節。下表列出了例子工程中各個主要模塊的功能簡介

文件名

功能

srio_example_top.v

例子工程的頂層模塊

srio_request_gen.v

生成請求事務的模塊

instruction_list.vh

這是一個Verilog頭文件,里面定義了120個事務,它被包含在srio_request_gen.v模塊中,srio_request_gen.v模塊會把里面的所有事務依次發出去

srio_response_gen.v

這個模塊用來產生有響應事務的響應包

srio_condensed_gen.v

當IP核的端口配置為Condensed I/O模式時,這個文件才會出現在例子工程中。它用來產生Condensed I/O模式的請求事務。

srio_quick_start.v

這個模塊與IP核的維護端口相連,用來發起維護事務。

maintenance_list.vh

這是一個Verilog頭文件,里面定義了一些維護事務,它被包含在srio_quick_start.v模塊中,srio_quick_start.v模塊會把里面的所有維護事務依次發出去用來配置相關寄存器

srio_report.v

在仿真時,這個模塊用來產生包接收和發送的時間戳,在硬件上運行的時候這個模塊可以刪除

srio_statistics.v

這個模塊用來收集核的統計信息并通過寄存器接口提交一些信息,提交的信息可以通過Vivado的調試特征以及用戶設計來訪問

srio_sim.v

srio_sim.v是仿真頂層文件,它例化了兩個核,分別是primary和mirror,并把它們連接到一起用于仿真。它也包含了上報測試是否成功的機制與超時(timeout)功能。

3.2 工程結構

例子工程的頂層模塊例化了所有核的所有組件和在硬件上執行所需要的例子代碼,整個工程的結構如下圖所示。

758d8bae-b93d-11ed-bfe3-dac502259ad0.jpg

整個結構包括時鐘模塊,復位模塊,配置結構以及產生RapidIO事務的激勵模塊。

srio_quick_start模塊在頂層srio_example_top.v中例化,它與IP核的維護端口相連用來產成維護事務,維護事務在maintenance_list.vh中進行定義,用戶可以根據需要編輯maintenance_list.vh文件來添加,修改和移除維護事務。

srio_request_gen.v模塊也在頂層srio_example_top.v中例化,它用來產生I/O事務與消息事務。這個模塊也存儲了期望的響應并把接收的響應與期望值進行比較。

srio_response_gen.v模塊也在頂層srio_example_top.v中例化,它用來為接收到的請求事務生成對應的響應事務。

通過上圖可以看出,產生I/O事務一共有兩種方式:第一種是通過例子工程中自帶的srio_request_gen.v產生I/O事務;第二種是通過頂層模塊中Initiator和Target的resquest/response接口自己編寫代碼產生I/O事務。同理,產生維護事務也有兩種方式:第一種是通過例子工程中自帶的srio_quick_start.v模塊產生維護事務;第二種是通過頂層模塊中的維護接口自己編寫代碼產生維護事務。I/O事務的端口類型是AXI4-Stream類型,維護事務的端口類型是AXI4-Lite類型。

默認情況下,由于例子工程的頂層srio_example_top.v模塊中,VALIDATION_FEATURES與QUICK_STARTUP兩個參數均被設置為1,如下圖所示

75a2aa48-b93d-11ed-bfe3-dac502259ad0.png

所以,例子工程是采用自帶的srio_request_gen.v和srio_quick_start.v分別產生I/O事務與維護事務,另外,推薦注釋掉外部接口以節省管腳和改善時序。

如果要使用外部接口產生I/O事務,那么需要設置參數VALIDATION_FEATURES=0,并且取消頂層模塊srio_example_top.v中外部接口(axis_ireq_*,axis_tresp_*, axis_iresp_*, axis_treq_*, axis_iotx_*, axis_iorx_*)的注釋。如果要使用外部接口產生維護事務,那些需要設置參數QUICK_STARTUP=0,并且取消頂層模塊srio_example_top.v中外部接口(axis_maintr_*)的注釋。使用外部接口的工程結構如下圖所示

75b38732-b93d-11ed-bfe3-dac502259ad0.jpg

3.3 工程分析

I/O事務與維護事務

默認情況下,例子工程會使用srio_request_gen.v模塊和srio_quick_start.v模塊來產生I/O事務與維護事務。其中instruction_list.vh頭文件定義了待發送的I/O事務,maintenance_list.vh頭文件定義了待發送的維護事務。

當核被復位以后,maintenance_list.vh中的維護事務可以對核進行配置,維護事務可以在maintenance_list.vh進行添加、修改或移除。當沒有處理器時,srio_quick_start.v模塊可以用來管理公共的維護事務。當核復位以后,這是一種比較好的配置核的方法。

srio_request_gen.v模塊和srio_response_gen.v模塊可以用來產生I/O事務,srio_request_gen.v模塊可以用來產生定義在instruction_list.vh中的I/O請求事務。instruction_list.vh中的I/O事務可以被添加、修改或移除,I/O事務的順序是隨機的,但是每次重新仿真時都是按照相同的順序產生的。而且,只有IP核端口支持的事務才能被產生。srio_request_gen.v模塊還可以追蹤期望的響應并且比較接收的響應與期望值,這在仿真的時候可以很方便的確定事務的收發情況。

srio_response_gen.v模塊用來產生接收到的請求所對應的目標響應I/O事務。如果寫事務目標地址的第23位到16位為8’h12(address[23:16]=8’h12),那么數據負載會被存儲在本地存儲器。不需要響應的寫事務會被丟棄,并且srio_response_gen.v模塊不會響應SWRITE事務。如果讀事務目標地址的第23位到16位為8’h12(address[23:16]=8’h12),那么數據將會從實際地址讀出。對于那些地址不滿足第23位到16位為8’h12(address[23:16]=8’h12)的事務,srio_response_gen.v模塊將以地址遞增的方式寫入I/O事務攜帶的數據。響應會根據接收到的請求的順序依次產生,所以不會有無序的事務產生。在所有的情況中,響應事務的優先級等于請求事務的優先級加1。

注意:每個srio_request_gen.v模塊會消耗一個塊RAM(Block RAM),每個srio_response_gen.v模塊會消耗兩個塊RAM(Block RAM)。

配置結構

配置空間分布在RapidIO核的所有塊中,配置結構的參考設計在例子設計的cfg_fabric模塊中,用來管理每個塊配置空間的訪問情況。塊(Block)的配置模塊在配置總線(AXI4-Lite)上是作為從機存在的,cfg_fabric模塊是作為主機存在的。維護事務的讀寫操作是從本地或者遠程被發起,它是通過邏輯層的配置主端口接入配置模塊,配置模塊會把讀寫事務送入對應的塊中,但如果地址不在各自配置寄存器的有效范圍內,配置模塊不會移交任何讀寫事務。往非法的空間寫事務會被丟棄,讀非法的空間將返回0。

時鐘模塊

例子設計的時鐘模塊與IP核的時鐘模塊是相同的。srio_clk模塊有1個MMCM_ADV,1個IBUFDS和3個或4個BUFGs組成,在2x或4x模式,其中一個BUFGs將被轉化為BUFGMUX。srio_clk模塊會根據配置的不同產生合適的參考頻率與用戶時鐘。

復位模塊

srio_rst模塊會把每個時鐘域里面的異步復位信號轉化為一個脈沖擴展的同步復位信號。當被用戶設計調用的時候,srio_rst模塊會用一個狀態機強制對核重新初始化。

四、工程源碼分析

3.1 頂層模塊srio_example_top.v源碼分析

頂層模塊srio_example_top.v源碼的端口定義如下

75c678ce-b93d-11ed-bfe3-dac502259ad0.jpg

頂層模塊包含5個參數:SIM_VERBOSE,VALIDATION_FEATURES,QUICK_STARTUP,STATISTICS_GATHERING和C_LINK_WIDTH。

SIM_VERBOSE設為1時,可以利用srio_report.v模塊生成不可綜合的報告。為0時,此功能被屏蔽。

VALIDATION_FEATURES設為1時,選擇例子工程中的srio_request_gen.v和srio_response_gen.v產生相應的請求事務與響應事務對IP核的功能進行測試。為0時,選擇外部的用戶接口由用戶自己編寫請求事務與響應事務的代碼對IP進行測試。

QUICK_STARTUP設為1時,選擇例子工程中的srio_quick_start.v產生相應的維護事務對IP核的配置空間進行訪問。為0時,選擇外部的維護接口由用戶自己編寫維護事務的代碼對IP核的配置空間進行訪問。

STATISTICS_GATHERING設為1時,可以利用srio_statistics.v模塊搜集IP的性能細節,這個模塊是可綜合的,可以通過Chipscope或ILA進行訪問。為0時,此功能被屏蔽。

頂層模塊的差分時鐘sys_clkp和sys_clkn就是IP核配置界面第一頁的參考時鐘,由于例子工程中采用的全部是默認參數,所以這里這個時鐘為125MHz,這個時鐘可以由FPGA外部的有源晶振或鎖相環芯片輸出。

sys_rst為IP核的復位信號,高電平有效。

差分信號srio_rxn0和srio_rxp0為串行接收數據信號,srio_txn0和srio_txp0為串行發送數據信號。

sim_train_en信號是一個用來減少仿真時間的控制信號,仿真時把這個信號置1可以加快仿真速度,但是代碼在硬件上運行時這個信號必須賦值為0。

led0是led指示信號,可以把port_initialized和link_initialized兩個信號接到led0中,這樣在硬件上執行時可以方便觀察鏈路狀態。

頂層模塊srio_example_top.v中的第466行到第590行例化了RapidIO核,部分源碼如下圖所示

75e31344-b93d-11ed-bfe3-dac502259ad0.png

第612行到631行是例化了srio_report.v模塊用來收集ireq接口的統計信息。除此以外,還例化了3個srio_report.v模塊用來收集iresp,treq,tresp接口的統計信息。下圖是收集ireq統計信息的源代碼。源碼如下圖所示

75f4b392-b93d-11ed-bfe3-dac502259ad0.png

第637行到684行srio_request_gen.v模塊用來生成請求事務。這個模塊有7個參數,分別為SEND_SWRITE,SEND_NWRITER,SEND_NWRITE,SEND_NREAD,SEND_FTYPE9,SEND_DB和SEND_MSG。當他們設置為1時,srio_request_gen.v模塊將會把instruction_list.vh模塊中對應的事務發送給SRIO IP核。部分源碼如下圖所示

76051cfa-b93d-11ed-bfe3-dac502259ad0.png

第779行到804行例化了srio_response_gen.v模塊,這個模塊用來產生響應事務。部分源碼如下圖所示

761a85e0-b93d-11ed-bfe3-dac502259ad0.png

第890行到937行例化了srio_quick_start.v模塊,這個模塊產生維護事務來訪問配置空間。部分源碼如下圖所示

762bea74-b93d-11ed-bfe3-dac502259ad0.png

第944行到988行例化了srio_statistics.v模塊,這個模塊用來收集統計信息,它是一個可綜合的模塊。部分源碼如下圖所示

763c8000-b93d-11ed-bfe3-dac502259ad0.png

3.2 模塊srio_request_gen.v源碼分析

模塊srio_request_gen.v的作用是產生RapidIO請求事務,上篇文章《Xilinx RapidIO核詳解》(鏈接:https://www.cnblogs.com/liujinggang/p/10072115.html)已經提到過,RapidIO核為了簡化包的構建過程,設計了一種精簡的包格式——HELLO格式來完成包的構建,然后按照HELLO格式的時序把數據發送給RapidIO核,RapidIO核會把HELLO格式的包轉化為標準的RapidIO串行物理層的包。這樣,用戶在設計請求事務的Verilog代碼時只需要對HELLO格式的包與時序有所了解,而不需要過多的關注RapidIO的協議與RapidIO包格式。這里重新復習一下HELLO格式的包結構與HELLO格式的時序。

HELLO格式的包結構如下圖所示:

764c1cae-b93d-11ed-bfe3-dac502259ad0.jpg

HELLO格式的時序圖如下圖所示:

765ba214-b93d-11ed-bfe3-dac502259ad0.png

事實上,整個srio_request_gen.v源代碼的核心就是先構建HELLO格式的包,然后把包頭(Header)和數據按照HELLO格式的時序傳給RapidIO核就可以了。下面詳細分析一下。

分析instruction_list.vh頭文件

在分析srio_request_gen.v源代碼之前先來分析一下instruction_list.vh頭文件。因為srio_request_gen.v文件中包含了instruction_list.vh頭文件,instruction_list.vh頭文件中定義了srio_request_gen.v將要發送的所有事務。

instruction_list.vh頭文件的第1行到第9行定義了事務的個數以及所有事務的總個數,每種事務的個數由一個控制變量進行選擇,源碼如下:

767f7afe-b93d-11ed-bfe3-dac502259ad0.jpg

第11行到50行是37個SWRITE事務(流寫事務),其中第1列的12位數據是由8-bit的保留位(SWRITE事務沒有srcTID字段),1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是保留字段(SWRITE事務沒有TTYPE字段),第4列的36-bit數據是由最高2-bit的保留位和34-bit的address字段組成,第5列是8-bit保留字段(SWRITE事務沒有size字段),不管這個字段的值為多少,目標設備都會把這個值當做0來處理。源代碼如下圖所示

7691b836-b93d-11ed-bfe3-dac502259ad0.jpg

第52行到72行是19個NWRITE_R事務(帶響應的寫事務),其中第1列的12位數據是由8-bit的srcTID,1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是TTYPE字段,第4列的36-bit數據是由最高2-bit的保留位和34-bit的address字段組成,第5列是size字段,這個字段的值為實際的數據量減1。比如size=0,表示實際傳輸的數據量為1。源代碼如下圖所示

76aaa580-b93d-11ed-bfe3-dac502259ad0.png

第74行到94行是19個NWRITE事務(寫事務),其中第1列的12位數據是由8-bit的srcTID,1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是TTYPE字段,第4列的36-bit數據是由最高2-bit的保留位和34-bit的address字段組成,第5列是size字段,這個字段的值為實際的數據量減1。比如size=0,表示實際傳輸的數據量為1。源代碼如下圖所示

76bc317e-b93d-11ed-bfe3-dac502259ad0.png

第96行到123行是26個NREAD事務(讀事務),其中第1列的12位數據是由8-bit的srcTID,1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是TTYPE字段,第4列的36-bit數據是由最高2-bit的保留位和34-bit的address字段組成,第5列是size字段,這個字段的值為實際的數據量減1。比如size=0,表示實際傳輸的數據量為1。源代碼如下圖所示

76cf056a-b93d-11ed-bfe3-dac502259ad0.jpg

第125行到128行是兩個DOORBELL事務(門鈴事務),其中第1列的12位數據是由8-bit的srcTID,1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是保留字段(DOORBELL事務沒有TTYPE字段),第4列的36-bit數據是由最高4-bit的保留位,8-bit的信息高8位,8-bit的信息低8位以及最后的16-bit保留位組成。第5列是8-bit保留字段(DOORBELL事務沒有size字段)。源代碼如下圖所示

76e23dc4-b93d-11ed-bfe3-dac502259ad0.png

第130行到148行是17個MESSAGE事務(消息事務),其中第1列的12位數據是由4-bit的msglen,4-bit的msgseg,1-bit的保留位,2-bit的prio和1-bit的CRF組成,第2列是FTYPE字段,第3列是保留字段(MESSAGE事務沒有TTYPE字段),第4列的36-bit數據是由最高26-bit的保留位,6-bit的mailbox字段,2-bit的保留位以及2-bit的ltr組成。第5列是8-bit的size字段。源代碼如下圖所示

76f0079c-b93d-11ed-bfe3-dac502259ad0.png

第150行到152行是1個Data Streaming事務,這是Xilinx定義的第9類事務,由于這種事務用的不多,我自己也不太了解,所以這里就不進行分析了。源代碼如下圖所示

76ffb886-b93d-11ed-bfe3-dac502259ad0.png

分析srio_request_gen.v源碼

在分析完畢instruction_list.vh頭文件以后接下來開始著手分析srio_request_gen.v源碼。分析過程中始終要記住的一點是:srio_request_gen.v的核心功能就是組裝HELLO包頭并把包頭和數據按照HELLO格式的時序發送出去。

srio_request_gen.v源碼的第50行到92行是參數與接口的定義。它包含7個參數,分別為SEND_SWRITE、SEND_NWRITER、SEND_NWRITE、SEND_NREAD、SEND_DB、SEND_FTYPE9和SEND_MSG,它們的默認值被設置為0,但是在頂層模塊中例化的時候,它們的值分別被設置為1、1、1、1、0、1、1。如下圖所示

77115aaa-b93d-11ed-bfe3-dac502259ad0.png

根據上面分析instruction_list.vh頭文件可知,如果上面的7個參數為1的話,各個事務的個數應該由instruction_list.vh頭文件中NUM_SWRITES、NUM_NWRITERS、NUM_NWRITES、NUM_NREADS、NUM_DBS、NUM_MSGS和NUM_FTYPE9決定。

接下來就是端口的定義,其中log_clk與log_rst均由IP輸出,log_clk的頻率與鏈路線速率和鏈路寬度有關,具體的對應關系在上篇文章中能找到。接下來就是設備ID,目的ID以及源ID的定義。然后定義了ireq與iresp,它們都采用了AXI4-Stream協議。link_initialized信號由IP核輸出,當它為高時表明鏈路成功初始化。以user_*開頭的幾個變量可以方便用戶自定義HELLO格式包頭中的各個字段。

772cb5d4-b93d-11ed-bfe3-dac502259ad0.png

第96到110行定義了HELLO格式包頭中的FTYPE字段與TTYPE字段的值,這兩個字段的值與事務的類型有關,源碼如下圖所示

773e0eec-b93d-11ed-bfe3-dac502259ad0.jpg

第120行定義了一個memory類型變量,綜合的時候ram的類型為分布式ram,121行導入了instruction_list.vh頭文件,126行定義的變量可以看做AXI4-Stream總線上數據有效的標志位,當這個信號為高時,AXI4-Stream總線上tdata上的數據為有效數據。源代碼如下圖所示

774f842e-b93d-11ed-bfe3-dac502259ad0.jpg

第178行到205行用來初始化事務列表,instruction[ii]存放的是instruction_list.vh頭文件中定義的各個事務的相關字段值,源代碼如下圖所示

7760667c-b93d-11ed-bfe3-dac502259ad0.jpg

第208到第219行是一些簡單的賦值操作。其中第208行的val_ireq_tkeep和val_ireq_tuser是根據HELLO格式的時序要求賦值的,HELLO格式的時序要求tkeep為8’hFF,tuser在第一個有效的時鐘(log_clk)周期內由src_id與dest_id拼接而成。第213行和第217行的go變量用來選擇HELLO格式包頭各個字段由用戶定義還是由instruction_list.vh定義。第219行的header_beat變量就是HELLO格式的包頭,在第一個有效時鐘(log_clk)周期,tdata上的數據必須為header_beat。源代碼如下圖所示

77752a08-b93d-11ed-bfe3-dac502259ad0.jpg

第266行到288行主要用來產生有效時鐘計數器current_beat_cnt與有效時鐘計數總數number_of_data_beats。當AXI4_Stream總線的tvalid和tready信號同時為高時,時鐘為有效時鐘,current_beat_cnt加1,當檢測到tlast信號為高時表明最后一個數據已發送完畢,所以把current_beat_cnt清0。由于tdata的寬度為64-bit,也就是8個字節,所以有效時鐘計數總數number_of_data_beats為current_size右移3位。源代碼如下圖所示

77864342-b93d-11ed-bfe3-dac502259ad0.jpg

第294行到306行用來產生AXI4_Stream總線中tlast信號,tlast為高時表明發送的是最后一個數據,所以tlast信號相當于一幀數據的邊界。

77a15b0a-b93d-11ed-bfe3-dac502259ad0.jpg

第307行到328行用來產生AXI4_Stream總線中的tdata信號,當有效時鐘計數器current_beat_cnt為0時,tdata為包頭header_beat,包頭header_beat后面是待發送的數據data_beat,例子工程為了簡單起見,發送的數據是累加數,每個累加數為8-bit,然后把每個累加數拼接8次作為待發送的數據,也就是說,待發送的數據為64’h0000000000000000,64’h0101010101010101,64’h0202020202020202,……..,后面以此類推。

77c62d0e-b93d-11ed-bfe3-dac502259ad0.jpg

第330行到345行主要用來產生AXI4_Stream總線中的tvalid信號,同時也產生了一些其他的標志信號。至此,整個AXI4_Stream總線中的所有信號的邏輯都編寫完畢,并且整個邏輯都是完全符合HELLO格式的時序。代碼的核心部分全部分析完畢。

77e28fb2-b93d-11ed-bfe3-dac502259ad0.jpg

第351行到第371行與數據的存儲相關。每當current_beat_cnt的值為0時,request_address變量加1, request_address也被賦給了tid,也就是說request_address也是事務ID值,同時request_address也是instruction的索引值。源代碼如下圖所示

77fa1cc2-b93d-11ed-bfe3-dac502259ad0.jpg

第382行到第406行例化了一個RAMB36SDP原語,RAMB36SDP是一個大小為36Kb的簡單雙口Block RAM(SDP=Simple Dual Port)。它的作用是把請求事務的tid,current_ftype和current_size寫入RAM中存起來,對于有響應的事務,RapidIO會收到一個響應事務,收到響應事務事務以后可以把存放在RAMB36SDP中的數據讀出來與響應事務中對應的字段進行對比從而對整個事務的交互過程的正確性進行一個初步判斷。關于RAMB36SDP原語的詳細解釋請閱讀下一小節。源代碼如下圖所示

781c31e0-b93d-11ed-bfe3-dac502259ad0.jpg

第458行到482行就是把存儲在RAM中請求事務的tid,current_ftype和current_size與響應事務對應的字段進行對比,在仿真時給出對應的提示信息。

784084a0-b93d-11ed-bfe3-dac502259ad0.jpg

至此,整個產生請求事務的代碼全部分析完畢,其他未分析到的代碼大家自己嘗試分析。

3.3 RAMB36SDP原語分析

RAMB36SDP是一個大小為36Kb的簡單雙口Block RAM(SDP=Simple Dual-Port),它其實是Virtex-5系列FPGA的一個原語,Vivado里面并沒有RAMB36SDP的語法模板,ISE中才有它的語法模板,如下圖所示

7867b85e-b93d-11ed-bfe3-dac502259ad0.jpg

RAMB36SDP原語的完整代碼如下所示

78840a22-b93d-11ed-bfe3-dac502259ad0.jpg

//   RAMB36SDP   : In order to incorporate this function into the design,
//    Verilog    : the forllowing instance declaration needs to be placed
//   instance    : in the body of the design code.  The instance name
//  declaration  : (RAMB36SDP_inst) and/or the port declarations within the
//     code      : parenthesis may be changed to properly reference and
//               : connect this function to the design.  All inputs
//               : and outputs must be connected.

//  <-----Cut code below this line---->

   // RAMB36SDP: 72x512 Simple Dual-Port BlockRAM w/ ECC
   //            Virtex-5
   // Xilinx HDL Language Template, version 14.7

   RAMB36SDP #(
      .SIM_MODE("SAFE"),  // Simulation: "SAFE" vs. "FAST", see "Synthesis and Simulation Design Guide" for details
      .DO_REG(0),  // Optional output register (0 or 1)
      .EN_ECC_READ("FALSE"),  // Enable ECC decoder, "TRUE" or "FALSE"
      .EN_ECC_WRITE("FALSE"), // Enable ECC encoder, "TRUE" or "FALSE"
      .INIT(72'h000000000000000000),  // Initial values on output port
      .SIM_COLLISION_CHECK("ALL"),  // Collision check enable "ALL", "WARNING_ONLY",
                                    //   "GENERATE_X_ONLY" or "NONE"
      .SRVAL(72'h000000000000000000), // Set/Reset value for port output

      // The forllowing INIT_xx declarations specify the initial contents of the RAM
      .INIT_00(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_01(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_02(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_03(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_04(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_05(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_06(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_07(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_08(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_09(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_0F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_10(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_11(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_12(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_13(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_14(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_15(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_16(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_17(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_18(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_19(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_1F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_20(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_21(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_22(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_23(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_24(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_25(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_26(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_27(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_28(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_29(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_2F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_30(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_31(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_32(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_33(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_34(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_35(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_36(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_37(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_38(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_39(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_3F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_40(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_41(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_42(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_43(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_44(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_45(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_46(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_47(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_48(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_49(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_4F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_50(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_51(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_52(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_53(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_54(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_55(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_56(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_57(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_58(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_59(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_5F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_60(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_61(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_62(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_63(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_64(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_65(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_66(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_67(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_68(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_69(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_6F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_70(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_71(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_72(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_73(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_74(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_75(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_76(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_77(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_78(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_79(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7A(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7B(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7C(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7D(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7E(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),
      .INIT_7F(256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000),

      // The next set of INITP_xx are for the parity bits
      .INITP_00(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_01(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_02(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_03(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_04(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_05(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_06(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_07(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_08(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_09(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0A(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0B(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0C(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0D(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0E(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00),
      .INITP_0F(256'h00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00)
   ) RAMB36SDP_inst (
      .DBITERR(DBITERR), // 1-bit double bit error status output
      .SBITERR(SBITERR), // 1-bit single bit error status output
      .DO(DO),        // 64-bit data output
      .DOP(DOP),      // 8-bit parity data output
      .ECCPARITY(ECCPARITY), // 8-bit generated error correction parity
      .RDCLK(RDCLK),    // 1-bit read port clock
      .RDEN(RDEN),      // 1-bit read port enable
      .REGCE(REGCE),    // 1-bit register enable input
      .SSR(SSR),        // 1-bit synchronous output set/reset input
      .WRCLK(WRCLK),    // 1-bit write port clock
      .WREN(WREN),      // 1-bit write port enable
      .WRADDR(WRADDR),  // 9-bit write port address input
      .RDADDR(RDADDR), // 9-bit read port address input
      .DI(DI),          // 64-bit data input
      .DIP(DIP),        // 8-bit parity data input
      .WE(WE)           // 8-bit write enable input
   );

   // End of RAMB36SDP_inst instantiation
                    

78840a22-b93d-11ed-bfe3-dac502259ad0.jpg

每個36Kb簡單雙口塊RAM(Simple dual-port block RAM)都能被配置為512x64(32Kb)大小的RAM和一個內置的漢明糾錯編碼(Hamming Error Correction)塊,由于要用到漢明糾錯編碼,所以數據位寬需要多用到8-bit,這樣數據位寬就被擴展到72-bit,當數據位寬為72-bit,深度為512時,RAM的大小剛好為36Kb(512 * 72 / 1024 = 36),其中漢明糾錯編碼操作對用戶是不可見的。每次寫操作都會產生8-bit的保護位(原語中的ECCPARITY信號),這個8-bit的保護位在每次讀操作的過程中可以用來糾正任何單比特的錯誤,或者檢測(但不能糾正)任何雙比特的錯誤。ECCPARITY輸出信號沒有可選的輸出寄存器。原語中兩個狀態輸出信號(SBITERR和DBITERR)的組合指示了三種可能的讀操作結果:無錯誤(No Error),糾正了單比特錯誤(Signal Error Corrected)和檢測到了雙比特錯誤(Double Error Detected)。在讀寫操作的ECC(Error Correcting Code)模式均開啟時(EN_ECC_READ = TRUE 并且 EN_ECC_WRITE = TRUE,EN_ECC_READ和EN_ECC_WRITE為原語的兩個參數),讀操作不能再存儲器陣列中直接糾正錯誤,而只能把已經糾正完畢的數據輸出給原語中的DO信號。ECC配置選項只有RAMB36SDP原語或FIFO36原語才支持。(此部分內容參考ug190的107頁到155頁)

Block RAM的ECC(Error Correcting Code)結構如下圖所示

789fdd1a-b93d-11ed-bfe3-dac502259ad0.png

RAMB36SDP各個端口的定義如下表所示

端口名

方向

信號描述

DI[63:0]

Input

數據輸入總線

DIP[7:0]

Input

數據輸入奇偶校驗總線

WRADDR[8:0]

Input

寫地址總線

RDADDR[8:0]

Input

讀地址總線

WREN

Input

寫使能。當WREN=1時,數據將被寫入存儲器,當WREN=0,寫操作不使能。

RDEN

Input

讀使能。當RDEN=1時,數據將被從存儲器讀出,當RDEN=0,讀操作不使能。

SSR

Input

同步設置/復位(Synchronous Set/Reset),這個信號用來復位輸出寄存器的值為SRVAL,SRVAL是RAMB36SDP原語的一個參數。這個信號不會影響存儲器存儲單元的內容。

REGCE

Input

寄存器使能(Register Enable),端口輸出寄存器使能信號。

WE[7:0]

Input

8位的字節寫使能輸入,由于輸出數據總線為64-bit,一共為8個字節,所以字節寫使能輸入為8位,詳細解釋見表后的內容。

WRCLK

Input

寫操作的時鐘

RDCLK

Input

讀操作的時鐘

DO[63:0]

Output

數據輸出總線

DOP[7:0]

Output

數據輸出奇偶校驗總線

SBITERR

Output

單比特錯誤(Signal Bit Error)狀態

DBITERR

Output

雙比特錯誤(Double Bit Error)狀態

ECCPARITY

Output

ECC編碼器輸出數據總線

字節寫使能(Byte-Writes):(此部分內容參考pg058的第50頁到51頁)

當字節寫使能功能打開時,WE總線的寬度為輸入數據總線DI中包含的字節個數。例如,輸入數據總線DI為64位,包含8個字節,所以WE總線的寬度為8。其中WE總線的最高位對于輸入數據總線DI的最高位的字節,WE總線的最低位對于輸入數據總線DI的最低位的字節,在寫操作過程中,只有WE總線中為1的位對應的字節才能被寫入存儲器中,為0的位保持原來的值不變。

假設輸入數據總線的寬度為24位,它包含3個字節,所以WE的寬度為3,下圖是一個字節寫使能開啟時往RAM的0地址寫入數據的時序圖(假設RAM的初始值全部為0)

78d0a008-b93d-11ed-bfe3-dac502259ad0.jpg

由上圖可知,當WEA(也就是上文的WE)為3’b011時,DINA數據24’hFF EE DD的后兩個字節會寫入存儲器的0地址,而存儲器0地址的最高字節保持00不變,所以第一次寫操作完畢以后存儲器0地址的數據為24’h00 EE DD;當WEA(也就是上文的WE)為3’b010時,DINA數據24’hCC BB AA的中間那個字節BB會寫入存儲器的0地址,而存儲器0地址的最高字節和最低字節則保持前一次的00和DD值不變,所以第二次寫操作完畢以后存儲器0地址的數據為24’h00 BB DD。后面幾次操作依次類推即可。

3.4 模塊srio_response_gen.v源碼分析

模塊srio_response_gen.v的作用是產生RapidIO響應事務。RapidIO協議中只有NREAD、DOORBELL、MESSAGE以及NWRITE_R這幾種事務有響應事務。

srio_response_gen.v源碼的第51行到72行定義了模塊的端口。log_clk和log_rst分別為邏輯層時鐘與復位,tresp和treq為兩個AXI4-Stream通道,tresp是響應事務傳輸通道,treq是請求事務傳輸通道。源碼如下圖所示

78f43fc2-b93d-11ed-bfe3-dac502259ad0.jpg

第77行到90行定義了HELLO格式包頭中的FTYPE字段與TTYPE字段的值,這兩個字段的值與事務的類型有關,源碼如下圖所示

79183512-b93d-11ed-bfe3-dac502259ad0.jpg

第99行到100行定義了AXI4-Stream總線上有效數據的標志,當tvalid和tready同時為高時,tdata上的數據為有效數據。源代碼如下圖所示

79354bc0-b93d-11ed-bfe3-dac502259ad0.png

第161行到163行按照HELLO格式的時序要求,把tkeep信號賦值為8’hFF,把tuser信號由src_id和dest_id拼接而成,并在第一個有效時鐘發出去。源代碼如下圖所示

79536ea2-b93d-11ed-bfe3-dac502259ad0.png

第193行到203行用來產生HELLO時序中的tready。源代碼如下圖所示

796f9e42-b93d-11ed-bfe3-dac502259ad0.jpg

第205行到220行用來產生treq通道第一拍的標志信號,并把tdata中的數據按照HELLO格式的定義把對應的關鍵字段剝離出來,值得注意的是第218行優先級字段prio為tdata重對應的字段加1,原因是響應事務的優先級為請求事務的優先級加1,上篇博客也提到過這一點。這部分源代碼如下圖所示

7990b9f6-b93d-11ed-bfe3-dac502259ad0.jpg

第224行到第235行用來生成有響應事務的標志,其中RapidiO協議中只有NREAD、DOORBELL、MESSAGE和NWRITE_R這幾種事務有對應的響應事務。這部分源代碼如下圖所示

79b03bc8-b93d-11ed-bfe3-dac502259ad0.jpg

第240行到274行與本地數據的存儲有關。其中第240行到250行的邏輯用來產生數據存取使能位data_store_wen,本文第3.3節提到過,只有地址字段的第23位到第16位為8’h12時,寫事務的數據才能被存放到本地存儲器,原因就是第243行的判斷語句加上了這個判斷。第252行到260行的邏輯用來產生數據存儲的寫地址信號data_store_waddr。第262行到274行的邏輯用來產生數據存儲的讀地址信號data_store_raddr。源代碼如下圖所示79d0b290-b93d-11ed-bfe3-dac502259ad0.jpg

第276行到302行主要例化了一個RAMB36SDP用來存儲寫事務發送過來的數據。其中第276行用來產生數據存儲的讀使能標志。源代碼如下圖所示

79fb04f0-b93d-11ed-bfe3-dac502259ad0.jpg

第307行到第335行是把請求事務的包頭(Header)信息存儲在RAM中。其中第307行到308行把請求事務中HELLO格式定義的各個字段進行拼接作為RAM的輸入,第325行到第335行用來產生RAM的讀地址與寫地址。

7a23e94c-b93d-11ed-bfe3-dac502259ad0.jpg

第337行例化了第二個Block RAM,它用來存儲請求事務的HELLO格式信息。

7a42d0e6-b93d-11ed-bfe3-dac502259ad0.jpg

第363行到第372行把從RAM中讀出來的數據對應的字段剝離出來從而得到響應事務HELLO格式對應的字段。

7a602100-b93d-11ed-bfe3-dac502259ad0.jpg

第378行到第388行用來產生有效時鐘的總數number_of_data_beats以及有效時鐘計數器current_beat_cnt。這段邏輯與srio_request_gen.v中對應的邏輯完全一致。源代碼如下圖所示

7a785c52-b93d-11ed-bfe3-dac502259ad0.jpg

第390行到400行用來產生tlast信號,發送最后一個數據時,tlast信號拉高。

7a90812e-b93d-11ed-bfe3-dac502259ad0.jpg

第402行和第403行用來產生響應事務的包頭(Header),第404行到414行用來產生響應事務的數據,其中響應事務的第一個有效時鐘用來發送包頭(Header),后面的有效時鐘用來發送數據,這段邏輯也與srio_request_gen.v中對應的邏輯類似。源代碼如下圖所示

7aa82dd8-b93d-11ed-bfe3-dac502259ad0.jpg

第459行到第469行用來產生AXI4-Stream中的tvalid信號,源代碼如下

7ace4216-b93d-11ed-bfe3-dac502259ad0.jpg

至此,整個響應事務的源代碼分析完畢,其余未分析到的代碼請自行分析。

3.5 模塊srio_quick_start.v源碼分析

模塊srio_quick_start.v的作用是產生維護事務(Maintenance Transaction)訪問本地設備和遠程設備的配置空間。維護事務采用的接口協議為AXI4-Lite,它是一種輕量級的AXI4協議,有地址總線與數據總線,常用來實現單個寄存器的讀寫。在分析srio_quick_start.v源碼之前首先分析一下maintenance_list.vh頭文件。

分析maintenance_list.vh頭文件

maintenance_list.vh頭文件主要定義了維護事務相關的字段,其中第1列為2-bit的保留位,第2列為1-bit的遠程/本地控制位,第3列為24-bit的地址,第4列為讀/寫控制位,第5列為32-bit的數據,第6列為4-bit的數據掩碼(DATA MASK),部分源代碼如下圖所示

7aeaafe6-b93d-11ed-bfe3-dac502259ad0.jpg

分析srio_quick_start.v源文件

srio_quick_start.v源文件的第68行到第101行是接口定義。log_clk和log_rst分別為邏輯層的時鐘和復位。以maintr_*開頭的信號為AXI4-Lite通道的信號,以user_*開頭的信號是用戶自定義的維護事務的相關字段,go變量用來在用戶定義和maintenance_list.vh頭文件定義的字段中進行選擇

7b08825a-b93d-11ed-bfe3-dac502259ad0.jpg

第105行到122行對maintenance_list.vh頭文件中的參數進行了賦值,并引入了頭文件,源代碼如下圖所示。

7b3103e2-b93d-11ed-bfe3-dac502259ad0.jpg

第192行到229行主要用來構建請求包,其本質就是產生AXI4-Lite的協議把數據發出去。部分源代碼如下圖所示

7b4e1694-b93d-11ed-bfe3-dac502259ad0.jpg

第233行到386行例化了一個RAMB36SDP原語,并用maintenance_list.vh頭文件中定義的數據進行初始化。部分源代碼如下圖所示

7b710b2c-b93d-11ed-bfe3-dac502259ad0.jpg

第397行到416行主要負責響應側的檢測,通過maint_autocheck_error和maint_done指示檢測狀態。源代碼如下圖所示

7b94634c-b93d-11ed-bfe3-dac502259ad0.jpg

至此,維護事務的代碼分析完畢,它的代碼邏輯相對來說比較簡單。

另外,例子工程中還有兩個模塊srio_report.v和srio_statistics.v,它們只在仿真有用,在硬件上實現時最好刪掉。這里不再作過多分析。只要理解了srio_request_gen.v與srio_response_gen.v,用RapidIO完成相關應用就足夠了。

五、仿真

工程源碼分析完畢以后,接下來就可以開始仿真了。例子工程中的代碼一行都不要改,直接左鍵單擊Run Simulation,在彈出的菜單中點擊Run Behavioral Simulation,如下圖所示

7bb67a40-b93d-11ed-bfe3-dac502259ad0.jpg

接著會出現下面的滾動框,在這個界面需要等待一會,如下圖所示

7bd927b6-b93d-11ed-bfe3-dac502259ad0.png

上面的滾動框運行完畢以后就出現了波形界面,如下圖所示

7bf60cc8-b93d-11ed-bfe3-dac502259ad0.jpg

然后再點擊下圖中圈出的小圖標把波形復位一下,如下圖所示

7c1f75c2-b93d-11ed-bfe3-dac502259ad0.jpg

復位波形以后在Tcl Console中輸入指令:log_wave –r /* 。輸入完畢以后按回車。這條指令的作用是記錄所有中間變量的波形,這樣后面要觀察任何變量的波形只需要把它拖到波形界面中它的波形就會自動顯示出來而不需要重新仿真,大大節約了時間。如下圖所示

7c4e3542-b93d-11ed-bfe3-dac502259ad0.jpg

最后設置一個比較大的時間,我設置為10ms,然后點擊它左邊的按鈕開始仿真,大約20分鐘以后仿真會自動結束,如下圖所示

7c6884b0-b93d-11ed-bfe3-dac502259ad0.jpg

仿真的過程中,在相應的時間點上,Tcl Console中會打印出包的收發情況

7c92dba2-b93d-11ed-bfe3-dac502259ad0.jpg

最后仿真結束以后,重新回到波形界面可以看到波形都正常產生了。這里最重要的兩個信號就是link_initialized與port_initialized,當他們為高表示整個鏈路初始化完畢。至此,整個仿真過程全部結束,下篇文章會詳細介紹每種事務的時序圖以及需要注意的一些細節。

7cb3268c-b93d-11ed-bfe3-dac502259ad0.jpg

六、總結

本節主要分析了一下請求事務與響應事務的Verilog源碼,事實上,它們的源碼就是按照pg007_srio_gen2.pdf把HELLO格式與HELLO時序描述出來而已。當然官方的這套源碼為了盡可能保證測試到核的所有功能,寫的比較混亂,但在實際項目中可以充分借鑒它的設計思想,然后根據你自己的需求對不需要的地方進行修改來達到你的目標。除此以外,HELLO格式的時序其通過一個狀態機來實現可能更加簡潔易懂。總而言之,這套代碼具有很大的參考價值,但是要想把這個核玩透還是得自己多在項目中理解。

下篇文章將會教大家如何在Vivado抓出每種事務的時序來對各種RapidIO的交互過程有一個更加清晰的理解。

?

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1629

    文章

    21754

    瀏覽量

    604203
  • 模塊
    +關注

    關注

    7

    文章

    2717

    瀏覽量

    47555
  • Xilinx
    +關注

    關注

    71

    文章

    2168

    瀏覽量

    121662
  • Verilog
    +關注

    關注

    28

    文章

    1351

    瀏覽量

    110148
  • 源碼
    +關注

    關注

    8

    文章

    645

    瀏覽量

    29273

原文標題:【高速接口-RapidIO】5、Xilinx RapidIO核例子工程源碼分析

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    TMS320C645x DSP串行RapidIO用戶指南

    電子發燒友網站提供《TMS320C645x DSP串行RapidIO用戶指南.pdf》資料免費下載
    發表于 12-16 10:16 ?0次下載
    TMS320C645x DSP串行<b class='flag-5'>RapidIO</b>用戶指南

    如何在Petalinux下Patch u-boot源碼

    在軟件開發過程中我們經常遇到用 Patch 來傳遞和更新代碼的場景。本文以一個端到端的例子來演示在 Petalinux 使用過程中,如何給 u-boot 的源碼生成 Patch 并在 Petalinux 中編譯。
    的頭像 發表于 12-04 16:26 ?1074次閱讀
    如何在Petalinux下Patch u-boot<b class='flag-5'>源碼</b>

    Xilinx DDS IP的使用和參數配置

    用RAM實現一個DDS,從原理上來說很簡單,在實際使用的時候,可能沒有直接使用官方提供的IP來的方便。這個博客就記錄一下,最近使用到的這個DDS IP。
    的頭像 發表于 10-25 16:54 ?1107次閱讀
    <b class='flag-5'>Xilinx</b> DDS IP<b class='flag-5'>核</b>的使用和參數配置

    如何申請xilinx IP的license

    在使用FPGA的時候,有些IP是需要申請后才能使用的,本文介紹如何申請xilinx IP的license。
    的頭像 發表于 10-25 16:48 ?402次閱讀
    如何申請<b class='flag-5'>xilinx</b> IP<b class='flag-5'>核</b>的license

    [XILINX] 正點原子ZYNQ7035/7045/7100開發板發布、ZYNQ 7000系列、雙ARM、PCIe2.0、SFPX2!

    正點原子FPGA新品ZYNQ7035/7045/7100開發板,ZYNQ 7000系列、雙ARM、PCIe2.0、SFPX2! 正點原子Z100 ZYNQ開發板,搭載Xilinx Zynq7000
    發表于 09-02 17:18

    【正點原子i.MX93開發板試用連載體驗】02 - 異通訊測試

    串口,一個是M的Debug串口,簡單跑個板載的Hello world。 工程 SDK里面提供了一些常規的demo,比如串口通訊、CAN通訊、SPI通訊等,我們可以根據文檔學習如何使用上手。 本來
    發表于 07-13 14:00

    UCGUI單片機源碼

    UCGUI單片機源碼
    發表于 07-04 17:11 ?1次下載

    如何在ModelSim中添加Xilinx仿真庫

    。 9、再次打開ModelSim,即可以看到Xilinx的庫已經默認出現在了庫列表里。以后仿真Xilinx的IP時,就不用每次都添加庫了。
    發表于 07-03 18:16

    FPGA的IP軟使用技巧

    ,可以嘗試對IP軟進行優化。例如,可以調整參數配置、優化布局布線、修改代碼等。 在調試過程中,可以利用FPGA開發工具提供的調試功能,如邏輯分析儀、波形查看器等,幫助定位問題和解決問題。 知識產權保護
    發表于 05-27 16:13

    什么是源碼源碼有什么作用?源碼組件是什么?源碼可二次開發嗎?

    源碼,也稱為源程序,是指未編譯的按照一定的程序設計語言規范書寫的文本文件,是一系列人類可讀的計算機語言指令。
    的頭像 發表于 05-25 14:55 ?1.6w次閱讀
    什么是<b class='flag-5'>源碼</b>?<b class='flag-5'>源碼</b>有什么作用?<b class='flag-5'>源碼</b>組件是什么?<b class='flag-5'>源碼</b>可二次開發嗎?

    便攜式手提設備設計方案:475-便攜式手提RapidIO協議光纖發包測試儀

    便攜式手提RapidIO 協議光纖發包儀,以RapidIO收發卡和X86主板為基礎,構建便攜式的手提設備。
    的頭像 發表于 05-20 15:33 ?407次閱讀
    便攜式手提設備設計方案:475-便攜式手提<b class='flag-5'>RapidIO</b>協議光纖發包測試儀

    鴻蒙OpenHarmony【創建工程并獲取源碼

    在通過DevEco Device Tool創建OpenHarmony工程時,可自動下載相應版本的OpenHarmony源碼
    的頭像 發表于 04-19 21:40 ?385次閱讀
    鴻蒙OpenHarmony【創建<b class='flag-5'>工程</b>并獲取<b class='flag-5'>源碼</b>】

    rapidio交換芯片是什么

    RapidIO交換芯片是一種基于RapidIO協議的專用交換芯片,它能夠實現高速、低延遲的數據傳輸和交換,廣泛應用于嵌入式系統、數據中心、網絡通信等領域。RapidIO協議本身是一種基于包交換的互連技術,具有高速、高效、可靠等特
    的頭像 發表于 03-16 16:40 ?2489次閱讀

    Xilinx fpga芯片系列有哪些

    Xilinx FPGA芯片擁有多個系列和型號,以滿足不同應用領域的需求。以下是一些主要的Xilinx FPGA芯片系列及其特點。
    的頭像 發表于 03-14 16:24 ?3369次閱讀

    求助,在TASKING軟件里如何建立多核工程并能實現3個運行?

    論壇里看到有基于BaseFramework框架的多核工程,但是怎么在TASKING里直接創建工程?我在TASKING里新建多核工程,并通過SoftwarePlatform插件代碼生成來生成完整的各種
    發表于 02-05 09:09
    主站蜘蛛池模板: 岛国片在线免费观看| 最新国产在线视频| 翘臀少妇被扒开屁股日出水爆乳| 免费看a视频| 欧美残忍xxxx极端| 欧美性XXXXX极品娇小| 日本无修肉动漫在线观看| 色婷婷AV99XX| 午夜在线观看免费完整直播网页| 双性将军粗壮H灌满怀孕| 亚洲国产精品一区二区第一页| 一二三四在线视频社区| 手机国产视频福利| 新版孕妇bbwbbwbbw| 一个人免费播放高清在线观看| 777EY_卡通动漫_1页| 成人五级毛片免费播放| 国产亚洲精品免费视频| 久久深夜视频| 日本人吃奶玩奶虐乳| 亚洲国产成人久久一区www妖精| 无码国产伦一区二区三区视频| 亚洲免费黄色| 99久久国产综合精品国| 国产成人久久AV免费看澳门| 国内精品久久久久久西瓜色吧 | 秋霞网韩国理伦片免费看| 色综合久久久久久| 一本道的mv中文字幕| 亚洲最大成人| 99日精品欧美国产| 国产精品一区二区三区四区五区| 国产97视频在线观看| 精品爽爽久久久久久蜜臀| 欧美乱码伦视频免费66网 | 果冻传媒在线观看视频| 女子叉开腿让男子桶免费软件| 亚州笫一色惰网站| 亚洲精品久久久午夜福利电影网 | 色多多污版app下载网站| 亚洲色欲啪啪久久WWW综合网|