Corundum:100G NIC學習(二)——仿真


前情提要:搭建corundum仿真環境(一)https://www.cnblogs.com/shroud404/articles/15364812.html

三、Running test

接上文,梳理了一下具體的仿真流程,現對整個項目的仿真作以介紹:

總的來講,兩種方式:pytest 和 makefile

pytest方式調用python庫cocotb-test的cocotb-test.simulator.run方法,該方法定義了使用何種仿真器的方法;makefile方式是調用python庫cocotb中的makefile.sim,該Makefile會根據運行cocotb的命令行中仿真器的類別來調用不同仿真器的makefile,從而執行相關仿真器的編譯和仿真操作。

殊途同歸,兩種方式最終都是在cocotb-test的框架下去啟動編譯器仿真器(iverilog)對RTL代碼進行編譯和仿真

擴展知識:python庫介紹,感興趣的可以去了解cocotb的使用,功能強大並且高效,cocotb是一個基於CO routine的CO simulation TestBench環境,使用Python驗證VHDL和SystemVerilog RTL。

cocotb介紹:https://docs.cocotb.org/en/stable/

cocotb git:https://github.com/cocotb/cocotb

cocotb-test:https://github.com/themperek/cocotb-test

1、成功安裝tox——更方便快捷的使用pytest

  tox是通用的虛擬環境管理和測試命令行工具。tox能夠讓我們在同一個Host上自定義出多套相互獨立且隔離的python環境(tox是openstack社區最基本的測試工具,比如python程序的兼容性、UT等)。它的目標是提供最先進的自動化打包、測試和發布功能。

  • 作為持續集成服務器的前端,大大減少測試工作所需時間;
  • 檢查軟件包能否在不同的python版本或解釋器下正常安裝;
  • 在不同的環境中運行測試代碼

  個人思考總結:tox方便仿真環境的搭建和移植,它能夠維護項目使用多個版本的python,具體按照個人開發環境進行配置,可以修改項目根目錄下tox.ini文件指定python版本,便於維護和移植。更為強大的功能還不理解。。。

  成功安裝tox的開發者:可以使用命令

$ cd /path/to/corundum-master
$ tox

  運行仿真。

  在tox環境下,所有的測試都可以通過在根目錄下運行 tox 來進行。在這種情況下,tox會建立一個python虛擬環境,並在虛擬環境中安裝所有的python依賴項。此外,tox將以pytest -n auto的方式運行pytest,因此它將在多個CPU上並行運行測試。

  該命令可以一次性仿真項目內部的所有測試例,會在各個測試例的位置生成仿真文件夾sim_build,該文件夾下包含了編譯完成的文件xx.vpp(iverilog編譯器對代碼編譯后生成的文件,類似於questasim的compile后生成的文件)和仿真日志。

 2、tox未成功,直接使用pytest

  所有測試都可以通過在 repo 根目錄下運行 pytest 來運行。建議以pytest -n auto的方式運行,在多個CPU上並行運行多個測試。

$ cd /path/to/corundum-master
$ pytest -n auto (多核)
$ pytest (單核)

  此種方法使用的時間會比tox多出不少,但效果是一樣的。都是使用pytest方式,最終效果和1、成功安裝tox——更方便快捷的使用pytest 中一致,也是運行了所有的測試例。

3、運行單個測試組(單模塊測試)

  剛玉這個項目的開發者對於每個模塊都提供了測試文件,如果我們對某個模塊功能不理解可以仿真配合學習。

  可以通過在子目錄下運行pytest來運行測試組。建議以pytest -n auto的方式運行,在多個CPU上並行運行多個測試。

$ cd /path/to/corundum/fpga/common/tb/rx_hash
$ pytest -n 4
Test session starts (platform: linux, Python 3.9.2, pytest 6.2.2, pytest-sugar 0.9.4)
rootdir: /path/to/corundum, configfile: tox.ini
plugins: parallel-0.1.0, cocotb-test-0.2.0, split-0.1.6.dev1+g97d96c2, sugar-0.9.4, xdist-2.2.1, forked-1.3.0, metadata-1.11.0, html-3.1.1, flake8-1.0.7, cov-2.11.1
gw0 [2] / gw1 [2] / gw2 [2] / gw3 [2]

 fpga/common/tb/rx_hash/test_rx_hash.py ✓✓                       100% ██████████

Results (27.68s):
       2 passed

  如果想要查看仿真波形文件,請在對應模塊目錄下使用命令

$ WAVES=1 pytest

  

運行仿真,仿真結束后會在sim_build文件夾下生成對應測試例的波形文件 xx.fst,使用gtkwave即可觀察波形。

 

 

4、makefile方式

  最后,可以通過運行make來運行單個測試。這個方法提供了覆蓋參數和啟用FST格式的波形轉儲的能力,可以在gtkwave中查看。

  效果會和4中pytest的方式一樣,生成波形文件 xx.fst。終端中的打印日志信息也可以保存下來以供查閱。

$ cd /path/to/corundum/fpga/common/tb/rx_hash
$ make WAVES=1
make results.xml
make[1]: Entering directory '/path/to/corundum/fpga/common/tb/rx_hash'
/usr/bin/iverilog -o sim_build/sim.vvp -D COCOTB_SIM=1 -s rx_hash -P rx_hash.DATA_WIDTH=64 -P rx_hash.KEEP_WIDTH=8 -s iverilog_dump -f sim_build/cmds.f -g2012   ../../rtl/rx_hash.v iverilog_dump.v
MODULE=test_rx_hash TESTCASE= TOPLEVEL=rx_hash TOPLEVEL_LANG=verilog \
        /usr/bin/vvp -M /home/alex/.local/lib/python3.9/site-packages/cocotb/libs -m libcocotbvpi_icarus   sim_build/sim.vvp -fst
     -.--ns INFO     cocotb.gpi                         ..mbed/gpi_embed.cpp:76   in set_program_name_in_venv        Did not detect Python virtual environment. Using system-wide Python interpreter
     -.--ns INFO     cocotb.gpi                         ../gpi/GpiCommon.cpp:99   in gpi_print_registered_impl       VPI registered
     -.--ns INFO     cocotb.gpi                         ..mbed/gpi_embed.cpp:247  in _embed_sim_init                 Python interpreter initialized and cocotb loaded!
     0.00ns INFO     cocotb                                      __init__.py:247  in _initialise_testbench_          Running on Icarus Verilog version 11.0 (stable)
     0.00ns INFO     cocotb                                      __init__.py:253  in _initialise_testbench_          Running tests with cocotb v1.6.0.dev0 from /home/alex/.local/lib/python3.9/site-packages/cocotb
     0.00ns INFO     cocotb                                      __init__.py:274  in _initialise_testbench_          Seeding Python random module with 1622183492
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_001
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_002
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_003
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_004
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_005
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_006
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_007
     0.00ns INFO     cocotb.regression                         regression.py:127  in __init__                        Found test test_rx_hash.run_test_008
     0.00ns INFO     cocotb.regression                         regression.py:477  in _start_test                     Running test 1/8: run_test_001
     0.00ns INFO     ...test.run_test_001.0x7f85f23398e0       decorators.py:312  in _advance                        Starting test: "run_test_001"
                                                                                                                     Description: Automatically generated test
                                                                                                                 
                                                                                                                         pkt_type: Ether (No docstring supplied)
                                                                                                                         payload_lengths: size_list (No docstring supplied)
                                                                                                                         payload_data: incrementing_payload (No docstring supplied)
                                                                                                                         idle_inserter: None
                                                                                                                 
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:271  in __init__                        AXI stream source
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:272  in __init__                        cocotbext-axi version 0.1.13
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:273  in __init__                        Copyright (c) 2020 Alex Forencich
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:274  in __init__                        https://github.com/alexforencich/cocotbext-axi
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:319  in __init__                        AXI stream source configuration:
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:320  in __init__                          Byte size: 8 bits
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:321  in __init__                          Data width: 64 bits (8 bytes)
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:323  in __init__                        AXI stream source signals:
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:326  in __init__                          tdata width: 64 bits
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:328  in __init__                          tdest: not present
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:328  in __init__                          tid: not present
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:326  in __init__                          tkeep width: 8 bits
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:326  in __init__                          tlast width: 1 bits
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:328  in __init__                          tready: not present
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:328  in __init__                          tuser: not present
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:326  in __init__                          tvalid width: 1 bits
     0.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:367  in _handle_reset                   Reset de-asserted
     0.00ns INFO     cocotb.rx_hash.m_axis                         stream.py:154  in _handle_reset                   Reset de-asserted
FST info: dumpfile rx_hash.fst opened for output.
     4.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:357  in _handle_reset                   Reset asserted
     4.00ns INFO     cocotb.rx_hash.m_axis                         stream.py:144  in _handle_reset                   Reset asserted
    12.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:367  in _handle_reset                   Reset de-asserted
    12.00ns INFO     cocotb.rx_hash.m_axis                         stream.py:154  in _handle_reset                   Reset de-asserted
    20.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:502  in _run                            TX frame: AxiStreamFrame(tdata=bytearray(b'\xda\xd1\xd2\xd3\xd4\xd5ZQRSTU\x90\x00\x00'), tkeep=None, tid=None, tdest=None, tuser=None, sim_time_start=20000, sim_time_end=None)
    28.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:502  in _run                            TX frame: AxiStreamFrame(tdata=bytearray(b'\xda\xd1\xd2\xd3\xd4\xd5ZQRSTU\x90\x00\x00\x01'), tkeep=None, tid=None, tdest=None, tuser=None, sim_time_start=28000, sim_time_end=None)
    36.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:502  in _run                            TX frame: AxiStreamFrame(tdata=bytearray(b'\xda\xd1\xd2\xd3\xd4\xd5ZQRSTU\x90\x00\x00\x01\x02'), tkeep=None, tid=None, tdest=None, tuser=None, sim_time_start=36000, sim_time_end=None)
    40.00ns INFO     cocotb.tb                               test_rx_hash.py:191  in run_test                        RX hash: 0x00000000 (expected: 0x00000000) type: HashType.0 (expected: HashType.0)
    48.00ns INFO     cocotb.rx_hash.s_axis                           axis.py:502  in _run                            TX frame: AxiStreamFrame(tdata=bytearray(b'\xda\xd1\xd2\xd3\xd4\xd5ZQRSTU\x90\x00\x00\x01\x02\x03'), tkeep=None, tid=None, tdest=None, tuser=None, sim_time_start=48000, sim_time_end=None)
    48.00ns INFO     cocotb.tb                               test_rx_hash.py:191  in run_test                        RX hash: 0x00000000 (expected: 0x00000000) type: HashType.0 (expected: HashType.0)
    56.00ns INFO     cocotb.tb                               test_rx_hash.py:191  in run_test                        RX hash: 0x00000000 (expected: 0x00000000) type: HashType.0 (expected: HashType.0)


################    skip a very large number of lines    ################


252908.01ns INFO     cocotb.rx_hash.s_axis                           axis.py:502  in _run                            TX frame: AxiStreamFrame(tdata=bytearray(b'\xda\xd1\xd2\xd3\xd4\xd5ZQRSTU\x08\x00E\x00\x00V\x00\x8c\x00\x00@\x06d\xfc\n\x01\x00\x8c\n\x02\x00\x8c\x00\x8c\x10\x8c\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00mo\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-'), tkeep=None, tid=None, tdest=None, tuser=None, sim_time_start=252908007, sim_time_end=None)
253000.01ns INFO     cocotb.tb                               test_rx_hash.py:191  in run_test                        RX hash: 0x6308c813 (expected: 0x6308c813) type: HashType.TCP|IPV4 (expected: HashType.TCP|IPV4)
253008.01ns INFO     cocotb.regression                         regression.py:373  in _score_test                     Test Passed: run_test_008
253008.01ns INFO     cocotb.regression                         regression.py:496  in _log_test_summary               Passed 8 tests (0 skipped)
253008.01ns INFO     cocotb.regression                         regression.py:569  in _log_test_summary               ***********************************************************************************
                                                                                                                     ** TEST                       PASS/FAIL  SIM TIME(NS)  REAL TIME(S)  RATIO(NS/S) **
                                                                                                                     ***********************************************************************************
                                                                                                                     ** test_rx_hash.run_test_001    PASS        11144.00          1.16      9569.44  **
                                                                                                                     ** test_rx_hash.run_test_002    PASS        44460.00          3.90     11409.70  **
                                                                                                                     ** test_rx_hash.run_test_003    PASS        12532.00          1.41      8908.08  **
                                                                                                                     ** test_rx_hash.run_test_004    PASS        49996.00          4.53     11047.04  **
                                                                                                                     ** test_rx_hash.run_test_005    PASS        13088.00          1.54      8513.81  **
                                                                                                                     ** test_rx_hash.run_test_006    PASS        52220.00          4.79     10905.96  **
                                                                                                                     ** test_rx_hash.run_test_007    PASS        13940.00          9.79      1423.57  **
                                                                                                                     ** test_rx_hash.run_test_008    PASS        55628.00         16.83      3305.63  **
                                                                                                                     ***********************************************************************************
                                                                                                                     
253008.01ns INFO     cocotb.regression                         regression.py:586  in _log_sim_summary                *************************************************************************************
                                                                                                                     **                                 ERRORS : 0                                      **
                                                                                                                     *************************************************************************************
                                                                                                                     **                               SIM TIME : 253008.01 NS                           **
                                                                                                                     **                              REAL TIME : 45.14 S                                **
                                                                                                                     **                        SIM / REAL TIME : 5604.98 NS/S                           **
                                                                                                                     *************************************************************************************
                                                                                                                    
253008.01ns INFO     cocotb.regression                         regression.py:268  in tear_down                       Shutting down...
make[1]: Leaving directory '/home/alex/UCSD/Projects/corundum-clean-build/fpga/common/tb/rx_hash'

5、總結

  包含了一個廣泛的基於Python的開源仿真框架,以評估完整設計。該框架使用Python庫MyHDL構建,並包括PCI Express系統基礎架構,PCI Express硬IP內核,NIC驅動程序和以太網接口的仿真模型。該仿真框架通過提供整個系統狀態的可視性,有助於調試完整的NIC設計。

  PCIe仿真框架的核心由大約4,500行Python組成,並包括PCIe基礎結構組件的事務層模型,其中包括根聯合體,功能,端點和交換機以及高級功能,包括配置空間,功能,總線枚舉,根聯合體 內存分配,中斷和其他功能。其他模塊由另外4,000行Python組成,提供FPGA PCIe硬IP核的模型,與模擬的PCIe基礎設施交換事務層流量,並驅動可連接至共同仿真的Verilog設計的信號。

  模擬Corundum需要幾行代碼來實例化和連接所有組件。清單1顯示了使用模擬框架發送和接收各種大小的數據包的簡化測試台,在Icarus Verilog中共同模擬了Verilog設計。該測試平台實例化了以太網接口端點,PCIe根聯合體和驅動程序的仿真模型,並將它們連接到協同仿真的設計。然后,它初始化PCIe基礎結構,初始化驅動程序模型,並發送,接收和驗證幾個不同長度的測試數據包。

 

清單1. NIC測試台的縮寫。包括設置PCIe,以太網接口和驅動程序模型,初始化模擬的PCIe總線和驅動程序以及發送和接收測試數據包。為簡潔起見,大多數信號已刪除。

  無論使用何種方式,只要能成功調用編譯器iverilog即可,我們接下來便可搭配產生的波形文件去學習整個工程了!


免責聲明!

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



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