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即可,我们接下来便可搭配产生的波形文件去学习整个工程了!
Corundum:100G NIC学习(二)——仿真的更多相关文章
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- SpringCloud学习(二):微服务入门实战项目搭建
一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...
- DjangoRestFramework学习二之序列化组件、视图组件 serializer modelserializer
DjangoRestFramework学习二之序列化组件.视图组件 本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组 ...
- SpringMVC入门学习(二)
SpringMVC入门学习(二) ssm框架 springMVC 在上一篇博客中,我简单介绍了一下SpringMVC的环境配置,和简单的使用,今天我们将进一步的学习下Springmvc的操作. mo ...
随机推荐
- 五年经验的前端社招被问:CPU 和 GPU 到底有啥区别?
首先来看 CPU 和 GPU 的百科解释: CPU(Central ProcessingUnit,中央处理器):功能主要是解释计算机指令以及处理计算机软件中的数据 GPU(Graphics Proce ...
- Python函数用法和底层分析
目录 Python函数用法和底层分析 函数的基本概念 Python 函数的分类 核心要点 形参和实参 文档字符串(函数的注释) 返回值 函数也是对象,内存底层分析 变量的作用域(全局变量和局部变量) ...
- 【世界杯黑技术专题】「原理探索专题」一文解读一下“卡塔尔世界杯”的先进技术之半自动越位技术SAOT+比赛用球Al Rihla
盘点卡塔尔世界杯的先进黑科技 归纳总结一下目前世界杯的先进的黑科技有哪些?大致可以划分为以下几点. 半自动化越位技术 比赛用球Al Rihla 球场智能空调 可持续利用的体育场 便利的数字设施和App ...
- P1162填涂颜色——题解
题目描述 由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向.现要求把闭合圈内的所有空间都填写成2.例如:6×6的方阵(n=6),涂色前和涂色后的方阵如下: 0 ...
- Array.from() ------来自❀ 前端宇宙 ❀公众号。
JavaScript 中有一个这样的函数: Array.from:允许在 JavaScript 集合(如: 数组.类数组对象.或者是字符串.map .set 等可迭代对象) 上进行有用的转换. 1. ...
- 半个前端新手入门Electron的过程
前言 先说几句废话,本人是一名 web 后端开发,主语言是 java,在学 Electron 之前,只会一点点 HTML和 JavaScript.本文讲的也是我学习 Electron 的过程,而非教程 ...
- Node.js学习笔记----day03
认真学习,认真记录,每天都要有进步呀!!! 加油叭!!! 一.Node中的模块系统 使用Node编写应用程序主要就是在使用 EcmaScript 和浏览器不一样的是,在Node中没有BOM.DOM 核 ...
- day04-视图和视图解析器
视图和视图解析器 1.基本介绍 在SpringMVC中的目标方法,最终返回的都是一个视图(有各种视图) 注意,这里的视图是一个类对象,不是一个页面!! 返回的视图都会由一个视图解析器来处理(视图解析器 ...
- (转载)Python中关键词yield怎么用?
原文: https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do 译文: https://zhuanlan.z ...
- Vue 24 props
1 简介 props主要用于组件的传值,他的工作就是为了接收外面传过来的数据,与data.el.ref是一个级别的配置项 2 一个简单示例 1)StudentComp.vue <template ...