介绍
现场可编程门阵列(fpga)越来越多地用于金融和贸易领域. 它们允许用户创建定制硬件,而不会产生与定制芯片相关的许多成本和延迟. fpga可以用来减少延迟, 更有效地处理突发数据, 并降低系统复杂性(在其他方面).
构建FPGA系统需要多种学科的应用. 一般来说, 这些可以分为设计和验证, 也就是说, FPGA设计的构建和测试. 虽然测试系统的所有功能很重要, 对于硬件来说更是如此, 哪一种具有在软件世界中通常不会遇到的规模上的并行性的额外复杂性. 这使得它容易受到时间问题(内部和外部)的影响。, 哪些必须经过测试才能获得对设备的信心.
这篇文章将描述我们的验证环境以及CQ9如何到达今天的位置的. 我们将从制定我们的环境目标开始. 下一个, 我们将讨论解决这个问题的不同方法, 并描述CQ9如何建立我们的环境来实现我们的目标.
环境目标
在构建验证环境时,有很多选择, 所以我们有必要考虑一下我们想要什么样的性质. 建立函数的正确性显然是最重要的. 我们构建的硬件是公司众多交易系统的一部分,并在任何一天的过程中与许多不同的交易所和市场进行交互. 这意味着验证不仅确定设备是否按预期运行, 还要遵守CQ9的风险检查, 并遵守所有的规章制度.
我们不仅需要构建测试来验证正确的行为, 我们还希望创造一个环境,使其更容易做到这一点. 当然,每个人都希望最大化开发人员的生产力, 但这对我们来说尤其重要,因为交易对上市时间特别敏感. 这也是一种良好的感觉. 谁不想在一个更容易表达自己想法的系统中工作呢?
我们希望使验证开发人员更有效的方法之一是尽可能重用代码. CQ9使用c++和Python开发代码,这些代码与我们的fpga一样与所有相同的市场进行交互. 如果我们能把代码用在验证的上下文中, 我们不仅节省时间, 我们将避免在第二次实现中引入错误.
我们还希望能够在问题出现时快速发现问题. 当然, 这必须在部署用于交易的新硬件之前进行, 但是,当bug被引入到代码库中时,及时发现它们也是一件好事. 潜在的和/或未解决的bug只会使我们的问题更加复杂,因为新代码是建立在损坏的代码之上的.
最后,我们想利用CQ9的计算资源. 如果不经常执行这些测试,那么世界上所有的测试都不会帮助我们.
不同的方法
给定我们的目标,我们就可以将它们应用到各种验证方法中. 也许最简单的方法是使用测试向量. 测试向量提供了一个主要输入值和随时间变化的预期主要输出值的列表. 它们本质上是时间序列真值表. 作为一个简单的例子,JK触发器可以测试如下:
今天,在芯片制造的某些阶段仍然使用测试向量, 然而, 对于我们的目的来说,这种方法太脆弱了. 并行接口很难处理,因为整个设备被视为一个整体. 在删除所有上下文后,调试尤其痛苦. 我们可能会看到输出与预期不同, 但为什么会有这样的结果,它的不同又意味着什么呢? 最后,这种方法不允许多个正确结果的可能性. 虽然有可能完全预测设备的行为给出足够的底层实现细节信息, 要求这种水平的知识将极大地限制我们在构建测试时可以使用的抽象.
另一种更广泛使用的方法是HDL(硬件描述语言)测试台. 我们在CQ9上使用Verilog(或者更确切地说是SystemVerilog), 因此,如果有一个可以模拟Verilog的工具,就可以编写更多的Verilog来模拟和检查设计. 例如,我们可以验证JK触发器是这样的:
因为Verilog是作为硬件设计和验证语言构建的, 这似乎是一条潜在的合理路径. 然而, 我们更愿意使用在CQ9上已经建立的语言,如c++或Python进行测试. 这样做可以让我们实现代码重用的目标. 但除此之外,这些语言比Verilog更具表现力和受支持程度. SystemVerilog的加入带来了许多语言特性,比如关联数组和类, 很难打败现代的c++或Python. 而且由于软件语言的使用远远超过了HDLs, 毫无疑问,像调试器和分析器这样的工具, 以及社区支持(e.g. 堆栈溢出),对于c++和Python比Verilog要好得多.
通用核查方法(UVM)是目前特别流行的方法. 这是SystemVerilog的一个类库,它实现了常见的验证概念,如驱动程序和监视器,用于将事务编组到硬件接口上或从硬件接口上取下. 由于它是建立在Verilog之上的,所以我们对Verilog测试平台的所有反对意见仍然适用. 虽然我们不使用UVM, 我们确实大量借鉴了它的概念,因为它们没有理由不能在其他语言中实现.
出于我们的目的,我们使用联合模拟,它利用了外部函数接口(ffi)在HDL模拟器和用其他语言编写的代码之间进行通信. 通常是C, 但是从那里构建到c++是相当简单的, Python, 或者其他语言. Verilog有两个ffi:验证过程接口(VPI)和直接编程接口(DPI)。. DPI更加精简, 而VPI提供了设计自省的能力, 与模拟器内部的交互, 还有很多其他特点. 但是,两者都支持与非verilog代码进行交互. 这符合我们的很多要求, 因为我们现在可以灵活地选择最适合这项工作的语言,并从其他CQ9开发人员和开源社区回收尽可能多的代码. 我们认为这很有意义,因为它只使用模拟器来模拟Verilog,而将测试设计的业务留给通常配备更好的系统来做.
我们使用的工具
在确定联合模拟是可行的方法后,我们仍然需要构建环境. 我们使用了开源和本土技术的结合.
Cocotb 是一个开源的Python包,可以从Python访问模拟器内部的信号. 它与模拟器无关,所以如果需要不同的工具,测试是可移植的. 它还支持Verilog和VHDL,尽管我们只使用前者. 它还提供了一个协程调度器来处理硬件设计中固有的并行性. 协程通过维护单一的执行路径来简化代码, 而不是真正独立的线程.
cocotb不仅支持用我们认为比Verilog强大得多的语言编写测试, 它还将我们连接到Python模块的世界中,这些模块现在导入到我们的测试中是微不足道的.
我们使用 Verilator 尽可能多地满足我们的模拟需求. Verilator是一个开源工具,它可以将Verilog设计转换为c++类,然后可以与其他代码一起编译,以提供给定设计的进程内模拟.
Verilator有一些目前不支持的语言特性, 例如延迟控制和加密Verilog. 对于需要这种代码的环境,我们使用专有的模拟器. 但对于我们的大多数测试来说,这是可以避免的. 与专有模拟器相比,Verilator提供了非常高性能的模拟. 而且由于经过验证的代码没有大多数专有EDA工具附带的许可问题, 我们能够利用我们的计算资源,这样每个开发人员都能够在任何给定的时间点运行数千个模拟, 而不是每个人都为几个许可证而角力.
我们还致力于确保我们针对全芯片模拟运行的测试可移植到我们的实验室环境中. 这需要一些额外的抽象, 但好处是一个测试现在可以在模拟和实际的FPGA上运行. 这有几个好处. 当然, 我们希望我们的模拟是Verilog将生产的实际fpga的忠实代表. 不幸的是,情况并非总是如此, 因为我们的时间限制, 脚本, 或者只是简单的工具错误会导致分歧. 在实验室中再次运行测试绝对是应对此类问题的一个很好的后盾. 另外, 因为模拟比实际硬件慢, 我们能够在模拟中实际无法实现的时间尺度上运行测试.
最后,我们喜欢在任何有意义的地方使用持续集成. 我们使用 詹金斯 还有其他的平台. 我们用它来求回归, 尝试新的伪随机种子, 自动化的构建, 去实验室做测试, 简化部署. 虽然我们的基本原理与大多数用户相似, 在主要用于软件流的平台上运行EDA工具确实存在一些挑战. 然而, 我们认为这些都是值得的,这样我们就可以让机器人做繁琐的工作,我们自己专注于更有趣的挑战.
结论
硬件验证环境不是一刀切的. 在从零开始构建或在这个领域进行改进之前,绝对值得考虑更广泛的组织环境和手头的权衡. 在荷尔蒙替代疗法, 我们对开放源代码的使用以及我们自己的开发提供了一个验证环境,使我们能够以高速度创建硬件设计.