P4->NetFPGA 工作流程概述


P4->NetFPGA 工作流程概述

前言

Workflow Overview的翻譯

結構

本頁面介紹了P4-> NetFPGA工作流程的以下幾個方面:

SimpleSumeSwitch Architecture

SimpleSumeSwitch是目前為NetFPGA SUME定義的P4架構。 體系結構描述可以在/opt/Xilinx/SDNet/<version_number>/data/p4include/sume_switch.p4中找到,或者您已經安裝了Xilinx SDNet的地方。 該體系結構由單個解析器,單個匹配操作管道和單個解析器組成。 如下所示:

SimpleSumeSwitch_arch

  • sume_metadata: 對應於SUME reference_switch設計中的tuser總線,定義如下:
struct sume_metadata_t {
    bit<16> dma_q_size; // measured in 32-byte words
    bit<16> nf3_q_size; // measured in 32-byte words
    bit<16> nf2_q_size; // measured in 32-byte words
    bit<16> nf1_q_size; // measured in 32-byte words
    bit<16> nf0_q_size; // measured in 32-byte words
    bit<8> send_dig_to_cpu; // send digest_data to CPU
    bit<8> drop;
    port_t dst_port; // one-hot encoded: {DMA, NF3, DMA, NF2, DMA, NF1, DMA, NF0}
    port_t src_port; // one-hot encoded: {DMA, NF3, DMA, NF2, DMA, NF1, DMA, NF0}
    bit<16> pkt_len; // (bytes) unsigned int
}

其中:

  • pkt_len - 數據包的大小(不包括FCS的以太網前綴),單位為字節。
  • src_port - 數據包到達的端口。 例如,如果數據包到達端口nf1,則該字段將被設置為0b00000100。
  • dst_port - 應由用戶的P4程序設置,以指示哪個或哪些端口(如果有的話)數據包應該被發送出去。 例如,要從端口nf0和nf2發送數據包,該字段應設置為0b00010001。
  • drop - 如果該字段的最低有效位被設置為1,則該分組將被丟棄。
  • send_dig_to_cpu - 如果該字段的最低有效位設置為1,則摘要數據將通過DMA發送到CPU。
  • _q_size - 每個輸出隊列的大小,以32字節的單詞來衡量(向上舍入)。 這是P4程序開始處理數據包時輸出隊列的大小。
  • digest_data: 這個總線的格式是由P4程序員定義的。 唯一的限制是它必須被定義為80位寬。 例如,要實現一個L2學習開關,可以將digest_data總線配置如下:
struct digest_data_t {
    bit<8> src_port;
    bit<48> eth_src_addr;
    bit<24> unused;
}
  • user_metadata: 這個總線的格式也由P4程序員定義。 它可以用來將解析器的任何附加信息傳遞給M / A流水線,並從M / A流水線傳遞給解析器。
  • in/out control: 這些信號用於添加/刪除表和讀/寫控制寄存器的條目。

Xilinx P4-SDNet工具鏈創建一個HDL模塊,然后將其封裝在一個小封裝中,並插入到NetFPGA SUME參考交換機架構中,如下圖所示。

switch_diagram

Xilinx P4-SDNet

賽靈思P4-SDNet編譯器是P4-> NetFPGA工作流程的核心。 它將面向SimpleSumeSwitch體系結構的P4程序編譯成一個具有標准AXI-Stream數據包接口和AXI-Lite控制接口的HDL模塊。 SDNet輸出設計為100G速率,因此能夠輕松處理SUME參考開關設計中的總計40G速率。 有關賽靈思SDNet工具的更多信息,請參見此處

Workflow Steps

1)修改$ SUME_FOLDER / tools / settings.sh以確保將P4_PROJECT_NAME環境變量設置為您想要處理的項目的名稱。 運行$ source settings.sh

2)編寫P4程序和commands.txt - commands.txt文件允許你添加條目到你在P4程序中定義的表中。

3)寫 gen_testdata.py

4)運行P4-SDNet編譯器生成最終的HDL和初始仿真框架:

$ cd $P4_PROJECT_DIR && make

5)運行SDNet模擬:

$ cd $P4_PROJECT_DIR/nf_sume_sdnet_ip/SimpleSumeSwitch

$ ./vivado_sim.bash

注意:如果您想啟動Vivado GUI並查看HDL波形(這是一個非常有用的調試工具),您也可以運行vivado_sim_waveform.bash。

如果這個模擬通過很好! 如果沒有,你將需要修改你的P4程序或你的gen_testdata.py腳本。

6)生成可在NetFPGA SUME模擬中使用的腳本來配置表條目。

$ cd $P4_PROJECT_DIR

$ make config_writes

7)在包裝模塊中包裝SDNet輸出並作為SUME庫核心進行安裝:

$ cd $P4_PROJECT_DIR

$ make uninstall_sdnet && make install_sdnet

8)設置SUME模擬。 $ NF_DESIGN_DIR / test / sim_switch_default目錄包含負責運行SUME模擬的run.py腳本,請檢查一下。 您將看到它讀取由步驟3中的gen_testdata.py腳本生成的測試數據包,並將數據包應用於SUME接口。 我們所需要做的就是將步驟6中生成的config_writes.py腳本復制到這個目錄中。

$ cd $NF_DESIGN_DIR/test/sim_switch_default && make

9)運行SUME模擬:

$ cd $SUME_FOLDER

$ ./tools/scripts/nf_test.py sim --major switch --minor default

注意:您也可以使用--gui選項運行上述命令來啟動Vivado GUI並查看HDL波形。 再次,一個非常有用的調試工具。

10)編譯比特流:

$ cd $NF_DESIGN_DIR && make

11)檢查以確保設計符合時間要求。 看到這個this FAQ,看看如何做到這一點。

12)編程FPGA。 將比特流文件config_writes.sh腳本復制到$ NF_DESIGN_DIR / bitfiles目錄中。

$ cd $NF_DESIGN_DIR/bitfiles

$ cp ../hw/project/simple_sume_switch.runs/impl_1/top.bit ./ && mv top.bit ${P4_PROJECT_NAME}.bit

$ cp $P4_PROJECT_DIR/testdata/config_writes.sh ./

$ sudo bash

# bash program_switch.sh

注意:確保配置寫入全部成功。 如果這是自上次斷電以來首次對FPGA進行編程,則可能需要重新啟動。

13)在真實硬件上測試設計! 轉到$ P4_PROJECT_DIR / sw / CLI目錄並運行P4_SWITCH_CLI.py腳本。 這啟動了一個交互式命令行界面,您可以使用該界面與您的交換機進行交互(例如,讀取/寫入寄存器,添加/刪除表條目等)。 輸入help以查看可用命令的列表。

Writing P4 Programs

該庫目前支持Xilinx P4 _ 16前端編譯器請參閱此處以獲取有關P4_16語言當前標准的鏈接。 有關開源P4語言聯盟的更多信息,請訪問P4.org

賽靈思P4-SDNet指定了一些可用於P4程序的附加注釋:

  • @Xilinx_MaxPacketRegion() - for parser/deparser; 聲明解析器/解析器需要支持的最大數據包大小(以位為單位)。
  • @Xilinx_MaxLatency() - 對於extern; 外部函數需要完成的最大時鍾周期數。
  • @Xilinx_ControlWidth() - 為extern; 地址空間的大小分配給一個extern函數。
  • @Xilinx_ExternallyConnected() - 表格; 將表的請求和響應元組拉到設計的頂層

有關使用和編寫extern函數的更多信息,請參見“P4-> NetFPGA Extern庫”一節。

Table Types:在P4程序中可以使用3種表格類型:

  • exact - 完全匹配指定的標題或元數據字段,然后執行所需的操作。 可以指定多個鍵匹配。
  • ternary - 完全匹配指定鍵的一些所需子集。
  • lpm - 匹配與指定key共享最長前綴匹配的表中的條目。 只能指定一個鍵。

Commands.txt: 這是$ P4_PROJECT_DIR / src /目錄中的文件,其中包含用於填充表條目的命令。 以下是用於填充每種類型的表中的表項的命令的格式:

Table Type Command
exact table_cam_add_entry <table_name> <action_name> <keys (space separated)> => <action_data (space separated)>
ternary table_tcam_add_entry <table_name> <entry_address> <action_name> <key1/mask1 ... keyN/maskN> => <action_data (space separated)>
lpm table_lpm_add_entry <table_name> <action_name> <key>/<prefix_length> => <action_data (space separated)>

上面列出的命令是commands.txt文件中唯一支持的命令。

注意:使用lpm表時,SDNet編譯器將生成一個bash腳本(即create_ip_forward.bash),在啟動SDNet仿真之前必須運行它。

Testing P4 Programs

通過在$ P4_PROJECT_DIR / testdata目錄中寫入一個gen_testdata.py腳本來測試你的P4程序。 gen_testdata.py腳本大量使用python scapy模塊。 Scapy是一個非常方便和易於使用的數據包操作庫。 它允許你定義任意數據包,甚至定義你自己的頭類型(例如switch_calc_headers.py)。 gen_testdata.py腳本必須生成:

  • src.pcap - 數據包通過P4交換機
  • dst.pcap - 數據包在P4交換機的輸出處預期
  • Tuples_in.txt - 與src.pcap中的每個數據包關聯的metadata
  • Tuples_expect.txt - 與dst.pcap中的每個數據包關聯的metadata

上面列出的文件用於初始SDNet模擬。 文件$ P4_PROJECT_DIR / testdata / sss_sdnet_tuples.py可以用於為針對SimpleSumeSwitch體系結構的項目創建Tuples_in.txtTuples_expect.txt文件。 對於每個數據包,更新sume_tuple_indig_tuple_insume_tuple_expectdig_tuple_expect,隨后調用write_tuples()Tuples _ *.txt文件添加一行。

建議gen_testdata.py腳本也會生成:

  • nf0_applied.pcap ... nf3_applied.pcap
  • nf0_expected.pcap ... nf3_expected.pcap

這些是可以在SUME模擬中使用的文件。 該腳本還應該為每個應用數據包設置時間字段,以便可以按正確的順序應用SUME模擬。

$ {NF_DESIGN_DIR} /test/sim_switch_default/run.py腳本運行一個SUME模擬。 它可以使用由gen_tesdata.py腳本生成的數據包追蹤,或者可以創建新數據包並使用它們。 有關編寫run.py腳本的更多詳細信息,請參閱此處

Debugging P4 Programs

如果你做了足夠的P4開發,你可能需要在某個時候進行調試。 本節旨在為您提供一些調試技巧。

SDNet產生你的P4程序的兩個實現:一個HDL實現和一個C ++模型。 為了將C ++模型的輸出與HDL實現的輸出進行比較,請執行以下操作:

$ cd $P4_PROJECT_DIR && make_cpp_test

$ cd nf_sume_sdnet_ip/SimpleSumeSwitch/

$ ./vivado_sim.bash

這對於測試SDNet編譯器的功能非常有用,因為C ++模型的輸出應該始終與HDL實現的輸出相匹配。 所以如果運行上面的模擬失敗這可能表明SDNet編譯器的問題,但它也可能表明另一個問題。 例如,也許你正在試圖添加更多的條目比你的表可以容納? 要解決這個問題,你需要在你的P4程序中增加你的表的大小。 或者,也許你正在使用的任何外部函數的C ++模型是不正確的實現?

SDNet C ++模型有用的另一個原因是因為它產生了經過處理的數據包的PCAP文件Packet_expect.pcap。 要生成C ++模型輸出PCAP文件,請執行以下操作:

$ cd $P4_PROJECT_DIR && make

$ cd nf_sume_sdnet_ip/SimpleSumeSwitch/SimpleSumeSwitch.TB/

$ ./compile

$ ./SimpleSumeSwitch

生成的PCAP文件被稱為Packet_expect.pcap,可以與gen_testdata.py腳本生成的dst.pcap文件進行比較。 運行C ++模型產生非常詳細的輸出,描述如何處理數據包。 例如,您可以看到整個設計中元數據字段的修改方式,以及您定義的表中是否存在命中或未命中。

一旦確定Packet_expect.pcap文件與dst.pcap文件相匹配,您可以運行SDNet模擬,將HDL實現輸出與dst.pcap中的數據包以及Tuple_expect.txt中的預期元數據進行比較:

$ cd $P4_PROJECT_DIR && make

$ cd nf_sume_sdnet_ip/SimpleSumeSwitch/

$ ./vivado_sim.bash

如果運行此模擬會導致元數據錯誤(即期望元組與實際元組之間不匹配),則可以輕松地檢查哪些字段不匹配:

$ ./vivado_sim.bash
...
expected < tuple_out_sume_metadata > = < 00000000000000000000000100040041 >
actual   < tuple_out_sume_metadata > = < 00000000000000000000000100040040 >
...

$ $P4_PROJECT_DIR/testdata/sss_sdnet_tuples.py --parse 00000000000000000000000100040041 sume
Parsed Tuple:
-----------------------
dma_q_size  =  0
nf3_q_size  =  0
nf2_q_size  =  0
nf1_q_size  =  0
nf0_q_size  =  0
send_dig_to_cpu  =  0
drop  =  1
dst_port  = 00000000
src_port  = 00000100
pkt_len  =  65

如果SDNet模擬通過但SUME模擬失敗,該怎么辦?

如果你遇到這個問題,我會建議檢查幾件事情:

1)確保你已經運行:

  • $ cd $P4_PROJECT_DIR && make config_writes
  • $ cd $NF_DESIGN_DIR/test/sim_major_minor && make
  • $ cd $P4_PROJECT_DIR && make install_sdnet

2)請注意,數據包的接收順序很重要。 如果您的nf _ * _ expected.pcap文件中的數據包包含的數據包順序與實際收到的數據包不同,則會導致模擬失敗。

3)運行SUME模擬更長時間 - 如果您看到所有預期的數據包尚未到達,則可能是問題所在。

4)確保所有配置寫入在應用測試數據包之前已經完成。

5)要檢查SUME模擬的實際和預期數據包,請檢查$ NF_DESIGN_DIR / test / nf _ * _ expected.axi和​$ NF_DESIGN_DIR / test / nf _ * _ logged.axi

6)通過在$ NF_DESIGN_DIR / hw / tcl / simple_sume_switch_sim.tcland的底部添加--gui選項來運行SUME仿真,將信號添加到仿真波形。

P4->NetFPGA Extern Library

外部功能旨在讓P4程序員在其P4程序中使用自定義邏輯。 對於NetFPGA平台,這些外部函數必須用HDL(或者可能是一些生成HDL的高級語言)來實現。 為了從P4開發者中抽象出HDL細節,P4-> NetFPGA工作流提供了一個可用於P4程序的外部函數庫。 有狀態的原子實驗是受Domino原子的啟發。 下表介紹了當前支持的外部函數:

Stateful Atomic Extern Functions

Name Description
RW 讀寫狀態
RAW Read, add to, or overwrite state
PRAW Either perform RAW or don't perform RAW based on predicate
ifElseRAW Two RAWs, one each for when a predicate is true or false
Sub IfElseRAW with stateful subtraction capability

IMPORTANT:每個有狀態原子(即寄存器)只能在P4代碼中被訪問一次。 多次調用extern函數會生成原子的多個實例,您可能會得到意想不到的結果。

注:Vivado將寄存器的大小限制為1百萬個條目。 所以這些有狀態原子的索引寬度必須小於20位。

Stateless Extern Functions

Name Description
IP Checksum Given an IP header, compute the IP checksum
LRC longitudinal redundancy check, simple hash function
timestamp generate timestamp (measure in clock cycles, granularity of 5ns)

Adding new extern functions:

為工作流添加新的外部函數是非常容易的。 實現extern函數,只需將條目添加到$ {SUME_SDNET} /bin/extern_data.py文件中即可。 每個條目是一個有兩個鍵的Python字典:

  • “template_file” - 指定相對於$ {SUME_SDNET} / templates目錄的extern函數模板的路徑。
  • “replacements” - 一個python字典,指定要在模板文件中替換的模式,以及替換模式的模式。 支持的命令是:
Command Description
"module_name" The name of the module. This is determined by the P4-SDNet compiler and so must be replaced in the template file.
"extern_name" The full name of the extern function. This is also determined by the P4-SDNet compiler and so must be replaced in the template file.
"prefix_name" The name given to the extern function by the P4 programmer. For example, for an extern function called pktCnt_reg_raw the "prefix_name" would be called pktCnt.
"addr_width" The size (in bits) of the address space allocated to the extern function. Specified by the P4 programmer using the @Xilinx_ControlWidthannotation.
"input_width(field)" The width (in bits) of a particular input field.
"output_width(field)" The width (in bits) of a particular output field.

如果一個P4程序實例化一個控制寬度大於0的外部函數,P4-> NetFPGA工具將自動生成一個可以在外部模塊中使用的<prefix_name> _cpu_regs模塊。 它的目的是使用AXI-Lite接口輕松暴露控制寄存器。

強烈建議實現新的外部函數的用戶將其貢獻給P4-> NetFPGA項目,以便其他人也可以使用它們。

API / CLI

python和C API都是由工作流生成的,而且可以用來操作P4程序中實例化的寄存器和表。 C API由P4-SDNet直接生成,文件被復制到$ {P4_PROJECT_DIR} / sw / API目錄中。 python API只是這些C API函數的一個包裝,使開發人員可以很容易地編寫python程序來控制它們的開關設計。 python API文件名為p4_tables_api.pyp4_regs_api.py,位於​$ {P4_PROJECT_DIR} / sw / CLI目錄中。

這些工具生成一個交互式命令行環境,可用於查詢有關生成的P4設計的編譯時間信息,以及在物理交換機加載到FPGA時與交換機進行交互。 運行:$ ./P4_SWITCH_CLI.py進入環境,輸入help查看命令列表及其文檔。

Limitations

  • lpm和三元表只有輕微的測試。 為這些表類型開發項目和測試用例需要社區支持。

  • 從控制面訪問的寄存器必須限制在32位寬。 因為這是SUME控制數據總線的寬度。

  • 所有的P4設計必須至少有一個表或外部功能與控制界面。 這是因為HDL包裝模塊目前假定SimpleSumeSwitch模塊將具有AXI-Lite控制接口。

  • 有關更多問題,請參閱github issue頁面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM