芯片验证

关于芯片验证的基本概念

本页简单介绍什么是芯片验证,以及示例里面用到的概念,如 DUT (Design Under Test) 和 RM (Reference Model) 。

芯片验证过程需要和企业、团队的实际情况契合,没有符合所有要求,必须参考的绝对标准。

什么是芯片验证


芯片从设计到成品的过程主要包括芯片设计、芯片制造、芯片封测试三大阶段。在芯片设计中,又分前端设计和后端设计,前端设计也称之为逻辑设计,目标是让电路逻辑达到预期功能要求。后端设计也称为物理设计,主要工作是优化布局布线,减小芯片面积,降低功耗,提高频率等。芯片验证(Chip Verification)是芯片设计流程中的一个重要环节。它的目标是确保设计的芯片在功能、性能和功耗等方面都满足预定的规格。验证过程通常包括功能验证、时序验证和功耗验证等多个步骤,使用的方法和工具包括仿真、形式验证、硬件加速和原型制作等。针对本文,芯片验证仅包含对芯片前端设计的验证,验证设计的电路逻辑是否满足既定需求(“Does this proposed design do what is intended?"),通常也称为功能验证(Functional verification),不包含功耗、频率等后端设计

对于芯片产品,一旦设计错误被制造出来修改成本将会非常高昂,因为可能需要召回产品,并重新制造芯片,无论是经济成本还是时间成本都十分昂贵。经典由于芯片验证不足导致失败的典型案例如下:

Intel Pentium FDIV Bug:在1994年,Intel的Pentium处理器被发现存在一个严重的除法错误,这个错误被称为FDIV bug。这个错误是由于在芯片的浮点单元中,一个查找表中的几个条目错误导致的。这个错误在大多数应用中不会出现,但在一些特定的计算中会导致结果错误。由于这个错误,Intel不得不召回了大量的处理器,造成了巨大的经济损失。

Ariane 5 Rocket Failure:虽然这不是一个芯片的例子,但它展示了硬件验证的重要性。在1996年,欧洲空间局的Ariane 5火箭在发射后不久就爆炸了。原因是火箭的导航系统中的一个64位浮点数被转换为16位整数时溢出,导致系统崩溃。这个错误在设计阶段没有被发现,导致了火箭的失败。

AMD Barcelona Bug:在2007年,AMD的Barcelona处理器被发现存在一个严重的转译查找缓冲(TLB)错误。这个错误会导致系统崩溃或者重启。AMD不得不通过降低处理器的频率和发布BIOS更新来解决这个问题,这对AMD的声誉和财务状况造成了重大影响。

这些案例都强调了芯片验证的重要性。如果在设计阶段就能发现并修复这些错误,那么就可以避免这些昂贵的失败。验证不足的案例不仅发生在过去,也发生在现在,例如某新入局 ASIC 芯片市场的互联网企业打造一款 55 纳米芯片,极力追求面积缩减并跳过验证环节,最终导致算法失败,三次流片皆未通过测试,平均每次流片失败导致企业损失约 50 万美元。

芯片验证流程


验证在芯片设计中的位置

芯片设计和验证的耦合关系如上图所示,设计和验证有同样的输入,即规范文档(specification)。参考规范,设计与验证人员双方按照各自的理解,以及各自的需求进行独立编码实现。设计方需要满足的前提是编码的RTL代码“可综合”,需要考虑电路特性,而验证方一般只要考虑功能是否满足要求,编码限制少。双方完成模块开发后,需要进行健全性对比测试(Sanity Test),判定功能是否表现一致,若不一致需要进行协同排查,确定问题所在并进行修复,再进行对比测试,直到所有功能点都满足预期。由于芯片设计和芯片验证耦合度很高,因此有些企业在研发队伍上也进行了直接耦合,为每个子模块的设计团队都配置了对应的验证团队(DV)。上图中的设计与验证的耦合流程为粗粒度的关系,具体到具体芯片(例如Soc、DDR)、具体企业等都有其适合自身的合作模式。

在上述对比测试中,设计方的产出的模块通常称为DUT(Design Under Test),验证方开发的模型通常称为RM(Reference Model)。针对图中的验证工作,按照流程可以有:编写验证计划、创建验证平台、整理功能点、构建测试用例、运行调试、收集Bug/覆盖率、回归测试、编写测试报告等多个阶段。

验证计划: 验证计划描述了如何进行验证,以及如何保证验证质量,达到功能验证要求。在文档结构上通常包含验证目标,验证策略、验证环境、验证项、验证过程、风险防范、资源及时间表、结果和报告等部分。验证目标明确需要验证的功能或性能指标,这些目标应该直接从芯片的规范文档中提取。验证策略描述如何进行验证,包括可能使用的验证方法,例如仿真、形式化、FPGA加速等,以及如何组织验证任务。验证环境用于描述具体的测试环境,例如验证工具类型,版本号等。验证项包含了需要验证的具体项以及预期结果。验证计划可以有总计划,也可以针对具体验证的子任务进行编写。

平台搭建: 验证平台是具体验证任务的执行环境,同一类验证任务可以使用相同的验证平台。验证平台的搭建是验证流程中的关键步骤、具体包含验证工具选择(例如是采用软件仿真,还是采用形式化验证,或者硬件加速)、环境配置(例如配置服务器环境,FPGA环境)、创建测试环境、基本测试案例等。创建好基本测试平台,跑通基本测试案例,也通常称为“冒烟测试”。后继具体的测试代码,都将基于该测试平台进行,因此测试平台需要具有可重用性。验证平台通常包含测试框架和被测试代码,以及对应的基本信号激励。

功能点整理: 根据规范手册(spec)列出DUT的基本功能,并对其进行明确的描述,以及如何对该功能点进行测试。功能点整理过程中,需要根据重要性、风险、复杂性等因数对其进行优先级排序。功能点整理还需要对各个功能点进行追踪和状态,如果发现原始功能点有更新需要及时进行对应计划的同步。

测试用例: 测试用例是指一组条件或变量,用于确定DUT是否满足特定需求并能正确运行。每个测试用例通常包含测试条件,输入数据,预期结果,实际结果和测试结果。通过运行测试用例并比较预期结果和实际结果,可以确定系统或应用是否正确实现了特定的功能或需求。在芯片验证中,测试用例是用来验证芯片设计是否满足规格要求的重要工具。

编码实现: 编码实现即测试用例的具体执行过程,包括测试数据生成、测试框架选择、编程语言选择、参考模型编写等。编码实现是对功能点和测试用例充分理解后工作,如果理解不到位,可能导致DUT无法驱动,不能发现潜在bug等问题。

收集bug/覆盖率: 验证的目标就是提前发现设计中存在的bug,因此需要对发现的bug进行收集和管理。每发现一个新缺陷,需要给定唯一标号,并同设计工程师进行bug定级,然后进行状态追踪。能发现bug最好,但在实际验证中不是每次测试都能发现bug,因此需要另外一个指标评价验证是否到位。该指标通常采用覆盖率,当覆盖率超过一点阈值(例如代码覆盖率大于90%)后方可任务进行了充分验证。

回归测试: 验证和设计是一个相互迭代的过程,因此当验证出bug后,需要设计进行修正,且需要保证修正后的DUT仍然能正常工作。这种测试的目的是捕获可能由于修改而引入的新错误,或者重新激活旧错误。回归测试可以是全面的,也就是说,它涵盖了所有的功能,或者可以是选择性的,只针对某些特定的功能或系统部分。

测试报告: 测试报告是对整个验证过程的总结,它提供了关于测试活动的全面视图,包括测试的目标、执行的测试用例、发现的问题和缺陷、测试覆盖率和测试效率等。

芯片验证层次


按照验证对象的大小,芯片验证通常包含UT、BT、IT、ST四个层次。

单元测试(Unit Testing, UT): 这是最低的验证层次,主要针对单个模块或组件进行。目标是验证每个模块或组件的功能是否正确。

块测试(Block Testing,BT): 很多时候,单个模块和其他模块存在紧耦合,如果进行单独UT测试,可能存在信号处理复杂,功能验证不准确等问题,这时候可以把多个有耦合关系的模块合并成一个DUT块进行测试。

集成测试(Integration Testing): 在单元测试的基础上,将多个模块或组件组合在一起,验证它们能否正确地协同工作,通常用于测试子系统功能是否正常。

系统测试(System Testing): ST通常也称为Top验证,在集成测试的基础上,将所有的模块或组件组合在一起,形成一个完整的系统,验证系统的功能是否正确,以及系统的性能是否满足要求。

理论上,这些层次的验证通常按照从低到高的顺序进行,每个层次的验证都建立在前一个层次的验证的基础上。但实际验证活动中,需要根据企业验证人员的规模、熟练度,功能需求等进行选择,不一定所有层次的验证都需要涉及。在每个层次,都需要编写相应的测试用例,运行测试,收集和分析结果,以确保芯片设计的正确性和质量。

芯片验证指标


芯片验证的指标,通常包含功能正确性、测试覆盖率、缺陷密度、验证效率、验证成本等多个方面。功能正确性是最基本的验证指标,即芯片是否能够正确地执行其设计的功能。这通常通过运行一系列的功能测试用例来验证,包括正常情况下的功能测试,以及异常情况下的鲁棒性测试。测试覆盖率是指测试用例覆盖了多少设计的功能点,以及覆盖的程度如何。高的测试覆盖率通常意味着更高的验证质量。测试覆盖率可以进一步细分为代码覆盖率、功能覆盖率、条件覆盖率等。缺陷密度是指在一定的设计规模或代码量中,发现的缺陷的数量。低的缺陷密度通常意味着更高的设计质量。验证效率是指在一定的时间和资源下,能够完成的验证工作量。高的验证效率通常意味着更高的验证生产力。验证成本是指进行验证所需要的总体资源,包括人力、设备、时间等。低的验证成本通常意味着更高的验证经济性。

功能正确性是验证的绝对指标,但在实践中,很多时候无法确定测试方案是否完备,所有测试空间是否全部测试到位,因此需要一个可量化的指标来指导验证是否足够充分,是否可以结束验证。该指标通常采用“测试覆盖率”。测试覆盖率通常有代码覆盖率(行,函数,分支)、功能覆盖率。

代码行覆盖率: 即在测试过程中,DUT的设计代码中有多少行被执行;

函数覆盖率: 即在测试过程中,DUT的设计代码中有多少函数被执行;

分支覆盖率: 即在测试过程中,DUT的设计代码中有多少分支被执行(if else);

功能覆盖率: 即在测试过程中,有多少预定义功能被触发。

高的代码覆盖率可以提高验证的质量和可靠性,但并不能保证验证的完全正确性,因为它不能覆盖所有的输入和状态组合。因此,除了追求高的代码覆盖率,还需要结合其他测试方法和指标,如功能测试、性能测试、缺陷密度等。

芯片验证管理


芯片验证管理是一个涵盖了芯片验证过程中所有活动的管理过程,包括之前提到的验证策略的制定、验证环境的搭建、测试用例的编写和执行、结果的收集和分析、以及问题和缺陷的跟踪和修复等。芯片验证管理的目标是确保芯片设计满足所有的功能和性能要求,以及规格和标准。

在芯片验证管理中,首先需要制定一个详细的验证策略,包括验证的目标、范围、方法、时间表等。然后,需要搭建一个适合的验证环境,包括硬件设备、软件工具、测试数据等。接下来,需要编写一系列的测试用例,覆盖所有的功能和性能点,然后执行这些测试用例,收集和分析结果,找出问题和缺陷。最后,需要跟踪和修复这些问题和缺陷,直到所有的测试用例都能通过。

芯片验证管理是一个复杂的过程,需要多种技能和知识,包括芯片设计、测试方法、项目管理等。它需要与芯片设计、生产、销售等其他活动紧密协作,以确保芯片的质量和性能。芯片验证管理的效果直接影响到芯片的成功和公司的竞争力。因此,芯片验证管理是芯片开发过程中的一个重要环节。

芯片验证管理过程可以基于“项目管理平台”和“bug管理平台”进行,基于平台的管理效率通常情况下明显高于基于人工的管理模式。

芯片验证现状


当前,芯片验证通常是在芯片设计公司内部完成的,这一过程不仅技术上复杂,而且具有巨大的成本。从验收与设计的紧密关系来看,芯片验证不可避免地涉及芯片设计的源代码。然而,芯片设计公司通常将芯片设计源代码视为商业机密,这使得必须由公司内部人员来执行芯片验证,难以将验证工作外包。

验证工作量占比

芯片验证的重要性在于确保设计的芯片在各种条件下能够可靠运行。验证工作不仅仅是为了满足技术规格,还需要应对不断增长的复杂性和新兴技术的要求。随着半导体行业的发展,芯片验证的工作量不断增加,尤其是对于复杂的芯片而言,验证工作已经超过了设计工作,占比超过70%。这使得在工程师人员配比上,验证工程师人数通常是设计工程师人数的2倍或以上(例如zeku的三千人规模团队中,大约有一千人的设计工程师,两千人的验证工程师。其他大型芯片设计公司的验证人员占比类似或更高)。

由于验证工作的特殊性,需要对芯片设计源代码进行访问,这在很大程度上限制了芯片验证的外包可能性。芯片设计源代码被视为公司的核心商业机密,涉及到技术细节和创新,因此在安全和法律层面上不太可能与外部方共享。这也导致了公司内部人员必须承担验证工作的重任,增加了公司内部的工作负担和成本。

在当前情况下,芯片验证工程师的需求持续增加。他们需要具备深厚的技术背景,熟悉各种验证工具和方法,并且对新兴技术有敏锐的洞察力。由于验证工作的复杂性,验证团队通常需要庞大的规模,这与设计团队规模形成鲜明对比。

为了应对这一挑战,行业可能需要不断探索创新的验证方法和工具,以提高验证效率,降低成本。

小结:复杂芯片验证成本昂贵,表现在如下几个方面

验证工作量大: 对于复杂芯片,验证工作在整个芯片设计工作中,占比超过 70%。

人力成本高: 验证工程师人数是设计工程师人数的2倍,对于复杂业务,工程师数量在千人以上。

内部验证: 芯片设计公司为了保证商业秘密(芯片设计代码)不被泄露,只能选择招聘大量验证工程师,在公司内部进行验证工作。

芯片验证众包


相比与硬件,软件领域为了减少软件测试成本,测试外包(分包)已经成为常态,该领域的分包业务非常成熟,市场规模已经是千亿人民币级别,并朝万亿级别规模进发。从工作内容上看,软件测试和硬件验证,有非常大的共同特征(系统的目的不同的对象),如果以软件的方式对硬件验证进行分包是否可行?

软件外包市场

把芯片验证工作进行外包(分包)面临诸多挑战,例如:

从业人员基数少: 相比软件领域,硬件开发者数量少了几个数量级。例如在github的统计上(https://madnight.github.io/githut/#/pull_requests/2023/2),传统软件编程语言占(Python、Java、C++,Go)比接近 50%, 而硬件描述语言,verilog占比仅 0.076%,这能从侧面反应出各自领域的开发者数量。

验证工具商业化: 企业中使用的验证工具(仿真器、形式化、数据分析)几乎都是商业工具,这类工具对于普通人来说几乎不可见,自学难度高。

开放学习资料少: 芯片验证涉及到访问芯片设计的源代码,而这些源代码通常被视为公司的商业机密和专有技术。芯片设计公司可能不愿意公开详细的验证过程和技术,限制了学习材料的可用性。

可行性分析

虽然芯片验证领域一直以来相对封闭,但从技术角度而言,采用分包的方式进行验证是一种可行的选择。这主要得益于以下几个因素:

首先,随着开源芯片项目的逐渐增多,验证过程中所涉及的源代码已经变得更加开放和透明。这些开源项目在设计和验证过程中没有商业机密的顾虑,为学习和研究提供了更多的可能性。即使某些项目涉及商业机密,也可以通过采用加密等方式来隐藏设计代码,从而在一定程度上解决了商业机密的问题,使验证更容易实现。

其次,芯片验证领域已经涌现出大量的基础验证工具,如verilator和systemc等。这些工具为验证工程师提供了强大的支持,帮助他们更高效地进行验证工作。通过这些工具,验证过程的复杂性和难度得到了一定程度的缓解,为采用分包的验证方法提供了更为可行的技术基础。

在开源软件领域,已经有一些成功的案例可供参考。例如,Linux内核的验证过程采用了分包的方式,不同的开发者和团队分别负责不同的模块验证,最终形成一个整体完备的系统。类似地,机器学习领域的ImageNet项目也采用了分包标注的策略,通过众包的方式完成大规模的图像标注任务。这些案例为芯片验证领域提供了成功的经验,证明了分包验证在提高效率、降低成本方面的潜力。

因此,尽管芯片验证领域相对于其他技术领域而言仍显得封闭,但技术的进步和开源项目的增多为采用分包验证提供了新的可能性。通过借鉴其他领域的成功经验和利用现有的验证工具,我们有望在芯片验证中推动更加开放、高效的验证方法的应用,进一步促进行业的发展。这种技术的开放性和灵活性将为验证工程师提供更多的选择,推动芯片验证领域迎来更为创新和多样化的发展。

技术路线

为了克服挑战,让更多的人参与到芯片验证,本项目从如下几个技术方向进行持续尝试

提供多语言验证工具: 传统芯片验证是基于System Verilog编程语言进行,但是该语言用户基数少,为了让其他软件开发/测试的技术人员参与到芯片验证,本项目提供多语言验证转换工具Picker,它可以让验证者使用自己熟悉的编程语言(例如C++/Python/Java/Go)基于开源验证工具参与验证工作。

提供验证学习材料: 芯片验证学习材料少,主要原因由于商业公司几乎不可能公开其内部资料,为此本项目会持续更新学习材料,让验证人员可在线,免费学习所需要的技能。

提供真实芯片验证案例: 为了让学习材料更具使用性,本项目以“香山昆明湖(工业级高性能risc-v处理器)IP核”作为基础,从中摘取模块持续更新验证案例。

组织芯片设计分包验证: 学以致用是每个人学习的期望目标,为此本项目定期组织芯片设计的验证分包,让所有人(无论你是大学生、验证专家、软件开发测试者、还是中学生)都可以参与到真实芯片的设计工作中去。

本项目的目标是达到如下愿景,“打开传统验证模式的黑盒,让所有感兴趣的人可以随时随地的,用自己擅长的编程语言参与芯片验证”。

愿景
最后修改 September 12, 2024: Fix typo (4b0984f)