吹拉弹唱


  • Home
  • Archive
  • Categories
  • Tags
  • Books
  •  

© 2022 Kleon

Theme Typography by Makito

Proudly published with Hexo

机器学习系统 1-4 - 后端硬件验证

Posted at 2021-01-15Updated at 2021-01-15 机器学习  机器学习 FPGA 

仿真不是真,只不过是现实世界的一个有限切面。但仿真又是在进入现实世界前的必经试炼。

仿真(Emulation)用来从底层机制层面模拟硬件运行性能,测试功能正确性,评估性能是否达到设计标准。

# 层级

项目启动阶段重心放在硬件功能开发上,而验证流程可能处于刀耕火种阶段:

  • C++写Test Case,dump输入数据文件和输出结果文件,要求转化成Verilog-friendly 16进制字符串
  • 手写Verilog读取文件,围绕仿真激励逻辑,dump波形文件和输出结果文件
  • diff比对Test Case和Verilog的输出结果文件,匹配不上需要看波形定位问题

实际生产中需要完善的仿真测试来保证达到设计目标,尤其是芯片,毕竟比较贵。如果流片回来变砖就很尴尬了,赶在流片前,尽力而为。

和软件测试类似,硬件验证也分为不同层级。根据粒度可以将仿真分为:

  • 单元仿真

测试基础功能模块是否达到设计目标,通常设计一些测试用例(Testbench)来验证,基本作用与软件单元测试(Unit Test)类似。

软件测试的基础单元是函数(Function),硬件测试的基础单元是模块(Module),需要选择合适的测试粒度大小。

TDD1(Test Driven Development)适合拆解开发工作量,也可以用于硬件开发。

由于HDL及其周边工具的迭代速度缓慢,语言编程接口与仿真调试工具的易用性与软件相比,并没有显著性提升。因此在以开发速度远超ASIC闻名的FPGA开发流程中,单元仿真可以是不存在的。

至少在一个项目进度很紧的早期团队中是不存在的。

  • 系统仿真

这里基本实现了较独立的完整功能。为了提高仿真速度,一般去除比较独立的寄存器逻辑,仿真非常耗时的存储器(如DDR仿真模型)逻辑等。

即便去除了一些耗时的逻辑,硬件仿真的耗时相比软件高出不少,并且还没有测试Cache机制,每运行一次可能需要数个小时,导出的波形文件也非常大。

除了一些用来跑通控制流和数据流的Case之外,一般也会采用遍历(case较少)或者随机测试,最终看代码覆盖率。
如果要做比较完善的测试,靠刀耕火种的流程肯定是不够的,自动化(Automation)是必须的。

  • 后仿真

后仿真,是指可以在每个后端流程(综合,布局布线)后抽取HDL仿真。用于检查流程是否出错,以及时序验证。前端也可以手动加入一个delay(不会被综合,但可以指导仿真),模拟信号固定延迟,波形上好看一些。

FPGA几乎从不后仿,非常费时,不如可以直接上板,通常一些只有上板才出现的问题也仿不出来。

  • 上板调试

通常使用FPGA开发板,因此称为上板调试。在芯片验证流程中,FPGA被用来做原型验证,一般降频运行,测试功能时序正确性。

容易遇到的问题是,测试模型需要用软件重写,导致引入额外bug。

如果真的遇到了和预期不符的地方,调试起来就比较费力。需要使用FPGA IDE的信号抓取功能添加信号线作为debug逻辑,再重新跑后端流程。

当FPGA项目比较大时,一次可以抓取的信号数量有限,需要同时编很多版本。在FPGA资源已经比较吃紧的情况下,拥塞程度较高,添加过多信号线,会让时序优化更有压力。

实际测试下来发现,很多bug都是因为Test Case不够全。因此要尽可能在之前的仿真中测出bug啊!

如果遇到了抓信号也不好复现的bug:

  • 有可能是跨时钟问题,这个在仿真中不太好复现。
  • 有极小可能(真的碰到过)是定制板卡的PCB版设计有问题。
  • 几乎没有可能是因为宇宙射线引起的单粒子反转效应。😃

# 应用

测试框架可以使用System Verilog的UVM2(常用的芯片工业的验证框架)或者基于Python的Cocotb3。

深度学习的FPGA后端的核心功能是offload计算密集型算子,并且与标准框架(Tensorflow,PyTorch)实现比对数据,对验证的覆盖性要求不高。可以使用基于Python的Cocotb,使用Python编写测试逻辑的好处是有大量可用包,写数据处理逻辑比较方便。

基于COCOTB的协同仿真框架

Cocotb只提供了核心组件和System Verilog的VPI4连接,需要编写硬件激励的Driver,把Python数据转换成硬件信号,比如AXI/AXI-lite Driver;编写信号采样Probe,把硬件信号转换成Python数据。

向上封装类DMA的驱动接口,包括DMA数据读写以及寄存器读写。这样在这个层面可以做到和驱动接口统一,便于在上板测试时保持上层激励逻辑不变。

再向上封装硬件相关的运行时(Runtime)模型,直接配置硬件指令,运行时模型负责模拟内存分配,数据和指令读写等功能。使用者只需要指令遍历指令的集合验证即可。

由于Verilog仿真速度很慢,在指令遍历选项过多的情况下会非常耗时,一般选择直接上板遍历,并记录对应失败配置,有针对性地对失败的case仿真调试,查看波形。

收获的一个经验是:

  • 测试越早写,收获越大,可以有效减少系统调试时一些花了很久定位的“显而易见”的bug。但目前还不知道怎么能提高写测试的积极性,降低写测试的overhead。
  • 绝大多数代码只会被用一次。

  • [1] Test-driven development
  • [2] Universal Verification Methodology
  • [3] cocotb/cocotb
  • [4] Verilog Procedural Interface

Share 

 Previous post: 机器学习系统 3-3 - 实验 Next post: 机器学习系统 1-3 - 后端硬件描述语言 

© 2022 Kleon

Theme Typography by Makito

Proudly published with Hexo