芯片验证系列之:验证的管理篇(良心大作,验证必看)

本篇为作者验证系列之验证的管理篇,之前我们陆续发过验证系列还包括一下几篇,可以点击查看:

复杂信号处理模块的验证方案

芯片验证全视

芯片验证的方法篇(上篇)

芯片验证的方法篇(下篇)

验证的计划篇

芯片验证的管理篇
本文分七个部分:
验证的管理篇之一:验证周期的检查清单
验证的管理篇之二:验证管理的三要素
验证的管理篇之三:验证的收敛
验证的管理篇之四:让漏洞无处可逃
验证的管理篇之五:团队建设
验证的管理篇之六:验证师的培养
验证的管理篇之七:验证的专业化

验证的管理篇之一:验证周期的检查清单

从这一篇开始我们进入到了《验证的管理篇》,也许不少读者会有疑问,验证管理不是验证经理关心的事情吗?和验证人员有什么关系呢?在我们进入本篇的正题之前,我想讲讲自己刚进入第一家公司作为一个验证菜鸟,在头一个月的经历。

刚进公司的时候,我只知道自己要验证的模块是什么,花时间了解它的功能,跟设计人员交流,进行模块验证,可以说是完全专注在一个点,那一个模块上面。验证经理给我安排的验证时间也很紧张,我脑海里只知道一件事情,就是尽可能又快又多地发现漏洞,在截止时间前完成验证,而对模块验证完成之后我要做什么,我知道的几乎很少,所以我感觉挺被动的。那个时候,我就在想,如果我能很清晰地知道一份验证周期的检查清单,那么对于每一个项目节点我需要做什么,跟下一个节点的联系以及在整个周期的作用,我会首先有一个全面的认识。在这样的条件下,作为验证的新手,会更好地扮演他的角色。

到了后来,随着经验的增长,项目赋予了我更多的责任,从负责一个模块、到一个子系统、再到整个芯片的验证。每当接到更有挑战性的任务,或者芯片的功能更复杂的时候,肩负的压力自然会更大,这种压力来源不单单是面对更多的技术问题、更大的验证团队,也来源于对于未知部分的焦虑。在这里,未知的部分包括验证流程的执行和每天出现的新的风险。风险虽然是不可避免的,但是也是可以尽可能降低的。如果,不单单是验证经理,包括每一位验证人员都能够充分了解各个验证环节,那么就可以在已知的范围内将各项验证任务贯彻下来,从项目的整体风险来看毫无疑问降低了,而且其中的动力来源于整个团队,验证经理背负的压力也由所有验证人员共同分担了。

所以,无论你担任着什么样的验证角色,在执行日常事务的时候如果心中已经有一副通往流片大门的地图,那么整个团队的目标会更加清晰、验证人员同验证经理之间的沟通也会更顺畅。

接下来,我们一起看一看,验证周期各个关键节点的划分和每个节点需要完成的事情有哪些。

从项目的启动阶段开始,历经RTL验证、门级验证到最终的流片,我们将各个环节可以分为:

  • RTL0:芯片框架和模块功能定义完成,制定验证的策略。

  • RTL1:模块和子系统的功能信号定义完成,定制完成需要的存储模型。

  • RTL2:完成所有模块的设计,以及80%以上的模块和子系统的验证,核心功能全部完成验证。

  • RTL3:完成芯片系统的连线集成和验证,覆盖所有的功能验证点。

  • GLS:完成门级网表的验证。

  • TO:回顾验证的各项检查清单,最终流片。

在这里,我们需要指出几个需要注意的前提:

  1. 实际的芯片项目周期跨度要超过上面提到的验证周期长度,因为它往往会包含RTL0之前的产品可行性调查、项目立项、项目启动的过程,同时在TO之后,我们仍然需要对硅后测试阶段提供支持、也需要对客户的集成使用提供支持,并且也需要准备可能的下一次功能改进之后的流片(新的周期)。

  2. 尽管不同公司的芯片项目对于验证周期的划分和定义会存在差别,但是就芯片验证的一般意义来看,我们上面提到的各个环节是有普适性的。所有通过进一步详细列举出上面各个环节需要完成的事项,我们会对于验证的生命周期有一个全局的认识。

  3. 在上面列出的各个环节中,我们主要将注意力放在验证方面,对于设计、系统定义和后端的事项我们并没有详细列出。

RTL0

RTL1

RTL2

RTL3

GLS

TO

也许上面的这一列验证清单对你而言,还不是那么迫切,但你要相信伴随着你的经验和责任的增加,你会越来越意识到一幅验证周期的全视野地图对你而言有多么重要,如果你需要管理一个验证项目,那么这些任务清单放在枕边,那么就可以让你在新的挑战开始可以睡得好一点。正所谓不打无准备之仗,懂得一点点套路,对于一个新人而言,不是什么坏事。

我们至此将这份验证清单梳理完毕,下一节我们将进入管理的三个核心要素:时间、人力和任务

验证的管理篇之二:验证管理的三要素

有一句关于项目成功或者失败的话,比较受用,在这里与君分享:“每个项目的失败都各有各的问题,而成功项目之间却有共同之处”。对于一名验证经理和一个验证团队,如果可以将验证的三要素:时间、人力资源和任务做好恰当安排,那么项目的成功已经完成了一半。

我们接下来会结合项目的实际经验,介绍如何规划时间、安排人力和做好任务的优先级划分和分派。

时间管理

早行动

在项目还在备案策划的时候,先进入项目的是什么角色?系统工程师。因为他们需要定义系统和各个模块的性能参数、功能描述。此外,验证人员也需要尽早参与进来。这其中的原因在于,继承性的项目一方面在系统结构上面有相似性,另一方面在新项目的验证环境(无论是模块还是系统层面)都有可继承性。所以,各个模块和系统验证人员尽早参与到项目的前期定义环节,可以尽早知道设计的改动从而考虑如何对原有的环境做出更新。同时,在选用IP和定义新模块的过程中,验证人员也可以更早地考虑选用什么验证IP、验证方法和相应的工具。

在实际项目中,验证人员可能会等待设计实施或者IP的功能选择,这种等待是有缩短的空间的。例如,如果设计是在原有设计的基础上更新,那么验证环境可以先行(通过复用)来首先验证原有的功能部分;又例如,如果是新的设计,那么验证人员可以协助系统工程师在早期功能定义时,实现虚拟模型(virtual prototype),并创建验证环境来实现基本测试,待后期设计实现以后,将虚拟模型替换为真实设计,并将虚拟模型作为可参考模型来进行数据比对;再当确定IP的特性参数之前,可以提前阅读完善的IP验证套件文档和环境,可以通过早期认识环境,在IP参数确定下来之后实现快速配置环境,开展验证工作。

有经验的验证团队,在项目伊始甚至开始之前就考虑更新验证环境、流程、工具选择、方法学、技能训练、自主工具开发等等。因为只有将这些可以提前的工作提前了,才能在项目运行的时候投入更多的时间进行功能相关的验证。类似的有效资源利用方式还包括,将验证环境搭建工作和测试用例创建工作划分开,也就是让少数人搭建维护验证环境(本身需要全面的系统知识和验证经验),让剩下的绝大部分专心创建测试用例,通过这种让资源更专注地进行功能验证来提高产出效率。

少依赖

一旦有了充分的意识,懂得验证过程并非是在设计的功能完备之后开始的道理,那么验证人员就应该想出各种办法来减轻或者消除对于设计进度的依赖性。尤其对于验证经理而言,让团队因为依赖一些未完成的事情而白白浪费时间,这对于项目执行来讲是大忌。

同时,考虑到验证团队往往需要在两个以上的项目中同时开展新项目以及维护老项目,更需要做好实现的进度安排,避免出现项目之间人力冲突的情况

所以,目前用来降低依赖性的方法譬如有在一些IP模块没有准备好之前,可以通过原有的设计或者创建行为模型来暂时替代,又譬如软件开发无法在低速的仿真环境下进行前期软件开发,但他们可以利用硬件加速器来提前在芯片上进行软件开发。

大局观

在实际项目中,往往我们会将不同的模块分派给相应的设计人员和验证人员。对于每个小组而言,他们首要照顾的是分给他们的“一亩三分地”,但同时我们还要求所有的验证人员都清楚共同的关键节点,以及各个模块彼此之间的依赖性。

如果模块A依赖于模块B,那么假定关键节点在4周之后,模块B的验证人员需要考虑的不单单是在4周之内完成验证任务,更需要有大局观,将模块B在2周或者3周左右完成验证交付给模块A,或者才可以采取分阶段提供的手段,尽可能减少模块A对模块B的依赖性。

而在面临选择验证工具、方法学的时候,需要考虑的不单单是该方法或者工具本身可以提高多少仿真速度或者覆盖率,而同时也要考虑人员的技能培训投入、学习曲线、新工具的整合、新环境的维护等等与项目进度密切相关的因素。    

人力资源安排

团队建设

由于验证技术的趋势变化加快,新的方法、工具层出不穷,验证团队的成员组成往往需要有不同技术背景。对于这种整体的需要,我们在招聘或者培养人员的时候,会考虑所需要具备的基本技能,和在某些技术领域较深入的人选,例如软件编程、脚本、验证环境搭建、形式验证、硬件加速等等。

一个经验丰富的验证团队成员之间的技能一般会有重叠和不同的部分,这种方式可以保证在人员任务选派的时候会有多种选择,同时团队在共同工作时,也可以实现技能互补。

有不同经验层次的梯队即可以保证技术的传承,梯队的培养,同时在任务分派的时候,也可以考虑将新的任务交给老员工,将老的任务交给新员工,满足老员工新技能培养和接受新的挑战,也使得新员工快速适应项目环境。

技术和管理

关于技术和管理之间孰轻孰重的争论恐怕会长期延续下去,尤其在研发团队中,这一分歧也更加明显。我们通常见到的情景是,技术功底深厚的人少有管理同样出色的,而善于在不同部门、技术组之间沟通的人善于沟通、计划、监督和衡量却又无法很好地兼顾技术层面。目前在多数公司的研发团队中,技术优秀的人才会被委以团队和项目管理的责任,但这种选择不见得是最合适的。

伴随着验证项目的要求越来越复杂,芯片公司都明确要求有经验的项目管理的合适管理者,因为这样一位管理者会对整个项目组起到组织和推动作用。所以好的验证组织既需要有技术良好的梯队,也有着丰富的管理经验。一个验证团队需要不同技术侧重背景的验证人员,也需要可以统观全局的验证经理。

任务拆分和重组

在项目立项和启动初期,往往摆在眼前的是一团迷雾,这是因为系统结构和设计功能描述可能还未完全确定下来,同时相邻模块的不确定性也会影响到自身模块。在这种时候往往考验一名验证经理的经验,因为他需要在不确定环境当中找到确定因素,来安排验证进度、估算所需要的验证资源,而对于一名验证人员,他也需要开展已经可以实施的行动。

任务拆分指的是可以将一件用时较长或者较复杂的任务拆分为不同完成阶段以及所对应的时间段。拆分任务的好处表现在:

  • 更容易清楚要做的任务的技术难易度、时间长短

  • 帮助分辨不同小的任务之间的依赖性

  • 发现哪些部分是核心,哪些部分存在风险

  • 在有多人参与的情况下,可以帮助更合理的分配任务

  • 细分的任务有助于进度跟踪和工作量化

任务重组指的是验证经理在统筹各个模块、不同验证周期之间的任务时,可以化整为零、合理地对不同任务进行合并、转接、排序等,它的目的是为了更有效地利用整体的验证资源,常见的任务重组场景包括:

  • 发现各个模块验证中共同的可利用资源,指派专人维护这些资源(验证IP、递归工具、环境、脚本、仿真工具等)

  • 当模块A和模块B都需要创建一个类似组件或者环境时,考虑两个组之间共同规划同一个环境或者参数化的组件,以便减少整体工作量,提高模块复用性

  • 在发现不同模块之间有依赖性的时候,就需要安排优先级,消除依赖路径,尽可能使全员都转动起来

上述的验证管理三要素,无论对于验证经理还是普通的验证人员都有参考意义,因为在日常工作中,我们需要将如何提高验证效率(工作效率)记挂在心上,尽早地为验证做安排,早行动,才会在愈加迅速的芯片开发中有着团队整体的节奏感。下一节我们将会重点讨论验证的收敛过程.

验证的管理篇之三:验证的收敛

伴随着随机验证的方式,递归(regression)验证的方式变得更加有意义。一般来讲,我们基于两种目的来提交递归测试表

  • 由于随机验证环境每次仿真产生的激励序列不同,这就使得每次仿真均会对覆盖率产生贡献,变得有意义

  • 设计缺陷被发现以后,递归测试序列需要再次提交,用来确保之前的功能点测试无误,同时设计缺陷也被修复

通常而言的递归测试指的是每次将所有测试用例提交到服务器上,检查测试结果。对于模块级的递归测试,这种方法在时间和计算资源上也许是可行的,然而对于芯片级,这种方式每次要消耗的时间和资源恐怕需要重新考虑。在实际项目中,采取何种方式使用递归测试,需要考虑的是下面几个因素:

  • 递归流程

  • 递归质量

  • 递归效率

递归流程

我们在验证周期中,通常都是从模块级到子系统级再到芯片级,对于设计、集成和验证都是这样的步骤。那么,采取瀑布集成的方式是否可以满足目前快速的SoC芯片周期呢?恐怕会很难。虽然我们之前将不同项目节点的内容列举出来,但是实际的窘境是,由于紧张的节点安排,往往是“一波未平,一波又起”。例如我们本应该在RTL2之前完成模块级验证工作,在RTL3完成芯片级验证,但实际情况却往往是在RTL2节点上,我们可能只完成了80%以上的验证工作,而剩下的模块验证工作需要和芯片验证工作一同完成。一方面,作为验证经理,需要顶着压力,在RTL2结束以后,开展芯片验证工作,另外一方面,他也需要同时追踪各个模块的验证进度。

所以,递归流程没有一致的标准,更多的是去符合实际的项目情况,但同时又需要在节节落后的情况下要保证最终流片的按时完成。这看起来可能是一种同项目进度的妥协,但更多地需要验证经理详细清楚哪些任务是必要在节点前完成,哪些任务可以适当延迟,总体控制风险,这同走钢丝一样,平衡一词始终需要牢记心间。

那么,单独拿出递归流程举例,让我们看看如何在快速的项目周期下,做出合理的递归流程吧。

  • 首先在模块设计阶段,除了需要需要准备验证环境之外,需要在验证的基本功能完备之时就创建一些基本测试用例,并形成一份基本功能递归列表。该列表在RTL2(模块周期)前必须全部通过。

  • 同时,在保证基本功能递归列表时,一些高级、附加功能仍然需要尽可能多地在RTL2前完成验证,但这些功能可能有部分需要在RTL2和RTL3之间完成验证,所以按照优先级划分的高级功能递归列表也需要作为最终模块验证完成的检查项

  • 由于在RTL2节点时可以保证基本功能的正常工作,这一份递归测试表单也使得在RTL3开始时进行的芯片集成工作可以得到保证,在完成集成之后,各个模块之间的互动也能初步得到测试。此时,各个模块同其它模块的通话就依赖于这些基本功能的测试表单。

  • 同时,在RTL2与RTL3之间,我们需要在完成模块级的高级功能验证之后,进行反复提交递归测试列表,通过大规模的随机测试用来测试设计的稳定性,并且完成覆盖率收集

  • 模块功能验证必须在RTL3之前完成,而芯片级验证则需要在门级仿真之前完成,并且尽可能减小落后于节点的差距,只有这样才会留给后端小组稳定的设计(出现更少新的缺陷)来做物理实现,为门级仿真提供合理的物理实现时间

那么当以上流程中一旦出现了缺陷该怎么办呢?我们应该遵循的原则是:

  • 选择更小的验证环境、给出更少的变量,实现更容易调试的环境。具体而言,就是在芯片级遇到缺陷,如果可以在模块级验证,那么首先在模块级验证;通过,如果可以固定其它变量,例如配置设计的功能为一些基本功能,减少负责功能配置,来重现错误场景,那么这种方式也会更有利于错误定位、设计分析和缺陷修正。在缺陷完成修复以后,也可以在更小的验证环境中,重复之前的测试,来确保出错的场景通过。

  • 在对缺陷完成修复之后,我们仍然需要先后进行模块级验证和芯片级验证的递归测试表,确保除了缺陷修复之后,还不会引入新的缺陷,所有之前测试通过的功能仍然可以保证正常工作

递归质量

在软件的迭代开发中,除了保证测试质量之外,也需要通过单元测试来保证设计在每次提交之后(版本更新或者缺陷修复)保证设计的自检,使得在提交给测试人员之前可以保证基本功能通过,减少由于明显设计错误带来的设计与测试人员之间的沟通和时间消耗。而这种有效的方式,也被越来越广泛地运用到芯片验证过程中。

尽管芯片设计在每次完成后,无法通过集成开发环境简单地通过一个敲键就完成设计模块的单元测试,但是,我们仍然可以通过有效的递归测试工具将设计、验证环境的编译、仿真、结果检查集成为一体,使得设计在完成以后,也可以通过一些简单的命令由设计者首先查看是否设计的基本功能是否正常工作,只有在保证这项基本功能递归列表完成以后,我们的版本管理工具才会允许设计文本的签入,同时通知验证人员设计的更新,由验证人员直接展开其它高级功能或者更高层次的验证工作。

在之前提到的如果验证人员发现缺陷之后,设计人员首先完成缺陷修复并且通过基本功能测试之后再次递交给验证人员。那么验证人员需要做的是,检查之前错误的场景是否可以通过,同时创建专门针对该缺陷的基本测试来更有目的地完成测试。在这些激励确定性较明显的测试完成之后,我们也会给出更宽松的激励,产生更复杂的可能场景来对设计产生更丰富的测试场景。

通过随机递归测试,我们可以在每次递归测试完成之后收集覆盖率,分析一些功能点覆盖漏洞,在下一次递归测试开始之前,有意地调整随机约束,使得产生的激励更有可能填补那些功能点漏洞

除了随机测试以外,我们也会通过形式验证的方式来完成验证。对此,我们提供的多种属性检查也可以分为基本功能属性和高级功能属性,这种简单的分类也可以保证设计每次提交以后保证基本功能属性,而高级功能属性的验证可以由验证人员完成。同时,覆盖率的收集,也可以从形式验证中得到,并且和其它动态仿真的覆盖率数据实现合并和分析。

随机测试的递归序列如果要实现更高的覆盖率,就需要运行多次,这种方式使得覆盖率收敛曲线随着递归往复的次数而提高,同时该方式也非常消耗运算资源和时间。所以关于通过递归方式来完善功能覆盖率和检查设计功能,我们建议将它们区别开来,比较合理的方式应该是:

  • 前期设计不稳定的情况下,主要定向提交一些测试用例来快速检查功能是否通过

  • 设计较稳定以后,可以规划用时较短,测试场景较简单的用例,来较快检查核心功能点是否通过

  • 设计后期,应该一方面设计复杂场景,另外一方面大量提交递归测试表来完善功能覆盖率

递归效率

递归测试虽然是一种确保设计功能通过的稳妥手段,而且由于它方便管理操作,也可以用来提升覆盖率,但同时,追求验证完备性的同时,递归测试的效率问题也变得越来越引起重视。递归效率的重要性基于以下几个方面:

  • 模块验证阶段,随机测试的方式使得倾向于反复提交测试表用来产生各种可能场景,而到了后期,覆盖率难以得到更多提升,那么如何精细控制随机约束,使得每次递归测试总有新增覆盖率的收获,这是要深入的问题。

  • 设计缺陷得到修复以后,如何快速检查设计基本功能,保证设计版本提交的质量,进而转移到验证人员一侧,提升沟通效率,这也需要设计合适的递归表

  • 芯片级验证阶段,由于测试用例时间明显加长,那么每次递归整个测试表( 数以千计)耗时极长,且由于芯片级测试更多基于C的验证,在项目后期集成改动较少的情况下,反复递归的收益就明显降低,但同时验证管理又需要这样的数据,这种矛盾也需要化解。

通过上面的考虑,我们在日常工作中,建议采取以下的办法来提升递归效率:

  • 在可实现的情况下,可以考虑切分测试场景将一个长的测试序列切分为多个序列并为之创建多个测试用例。这么做的好处是避免过于冗长复杂的测试,划分为多个用例可以实现并行提交测试,用计算空间来换取时间。

  • 对于一些较难切分测试向量的场景,例如芯片级仿真需要首先完成上电、复位、时钟使能的流程,同时芯片处理器需要完成初始化、搬运执行代码的过程,我们可以考虑通过快速跳转到该状态来实现缩短测试时间的要求。

  • 对于一些需要通过长时间运行来跳转到某一状态的测试,我们建议可以分为两个阶段。第一阶段来检查,跳转到该状态的条件是否满足,进而检查状态跳转。一旦第一阶段被验证过,我们可以在第二阶段后的用例,通过直接初始化到该特定状态来节省时间,例如强行置位硬件寄存器、状态位等方式,来使得设计可以快速条状到某一状态,进而缩短验证时间。

  • 尽可能给予充分的计算资源,目前用于仿真的普遍方式是,中心集群化的服务器来提供计算和数据存储资源,通过资源分配管理办法来实现尽可能足够的并行运算资源,使得递归测试表可以尽快执行完毕。

至此,关于通过递归测试来合理收敛验证进程的讨论已完毕,智慧合理的递归测试方式有利于设计的发布质量和快速稳定。下一节课,我们将带大家一起看看,如果发现了漏洞,我们应该做哪些事情。

验证的管理篇之四:让漏洞无处可逃

在上一节我们提到如何快速有效地进行验证收敛,即利用递归测试表来产生更多复杂场景和提高验证的覆盖率。在验证收敛的过程中,每一个人,无论你是验证人员、设计人员还是系统人员,都不可避免地会遇到一个问题,那就是检测出了漏洞,应该怎么办?

对于设计漏洞而言,较容易理解,因为一旦验证环境的参考模型与硬件设计的结构产出不一致,且最终得出设计并未完全遵循硬件功能描述时,那么设计漏洞便被发现了;而在验证的过程中,如果发现了硬件的问题,且最终回溯到系统设计有遗漏并不全面的时候,那么系统设计描述便产生了一个漏洞;容易被人忽视的是,验证环境的漏洞往往在被发现以后,经常是由发现者提交问题邮件、由环境构建者予以检查并最终确认和修改,这种局部的方式可能造成了更多不知情的验证人员被该问题阻碍,或者新的项目仍然需要重复之前的陷阱,所以验证环境的漏洞(一般是芯片级验证环境的),也需要被记录;而在后期门级仿真,因为综合时序不满足采样条件导致的门级验证失败,也需要将时序问题予以追踪,这带来的方式会提醒后期项目着重关注一些较长的时序路径,进行有针对性的优化;在验证过程中,我们还会遇到别的问题,例如仿真工具问题标准单元设计库问题、第三方IP问题等等。

由以上的例子我们可以总结出,发现了问题以后,进行跟踪的基本依据是:

  • 如果该问题会明显影响项目进度、或者影响大范围的群体、或者对后续项目造成影响的话,我们需要将这些问题记录并且跟踪它们的解决情况。

  • 项目中实施的各个环节中(我们这里专注在硅前验证阶段),如果符合上述情况的话,我们需要记录下各种环节的问题。

所以,我们可以将问题追踪的类型分为以下几类:

  • 系统功能定义问题

  • 硬件设计漏洞问题

  • 芯片验证环境问题

  • 综合时序问题

  • 硅前工具问题

  • 引用库和IP问题

在对硅前问题进行分类以后,我们接下来需要将它们记录到一个合适的数据库中,该数据库不但需要记录问题、还需要有分类派发、查找、追溯、报告的作用。芯片设计项目除了在执行过程中,会参考软件项目的构建、分块、依赖路径、决策的方法,也在问题追踪上借鉴了软件开发的方式。软件开发更早地使用标准化的问题追踪工具来进行执行项目,伴随着芯片开发的进度逐渐加快,一些商业或者免费的问题跟踪工具也进入了芯片开发的视野。例如以下这些问题追踪工具:

  • 商业工具:Team Foundation Server (Microsoft),JIRA,Rational ClearQuest (IBM),HP Quality Center (Hewlett-Packard)

  • 开源工具:Bugzilla (Mozilla),Redmine,Trac (Edgewall),Mantis

这些问题追踪工具一般也都会具备如下的功能:

  • 记录:需要记录的内容有问题标题、内容、出错场景、背景描述、发布版本、测试用例和相关文件等。

  • 分类:归属于哪一个项目、哪一个环节(系统、设计、验证还是其它)、哪一个模块、问题严重性(致命、重要、中级、完善)。

  • 派发:在跟踪系统中,问题一旦提交,即它的生命周期开始,接下来由管理层指定问题回顾和修复的人员,再转而由下一位问题持有者完成他所需要做的环节,并且继续指定问题的下一位持有者,这部分我们会在后面的问题跟踪流程中详细介绍。

  • 查找:当遇到漏洞之后,除了可以同漏洞相关人员沟通之外,在确定提交问题之前,我们还需要利用问题追踪工具数据库提供的查询功能快速判断,该问题以前是否发生过、有无解决方法;另外一方面,我们也可以很方便地利用问题独一无二的ID编码在工具搜索栏中快速调出该问题的背景和进度。

  • 追溯:问题从被提出到被派发、解决、验证和最终的关闭,在一个项目中可能走完它的生命周期,而不排除它可能会在下一个项目中“复活”,可能造成问题复活的因素有许多譬如问题重新发现、原来解决方案不再满足、新项目继承上一个项目时一些问题修复没有被集成进来仍然需要再次修复等等。所以,问题追溯的好处就可以看到同一个“顽固”的问题是如何在不同的项目之间(尤其是多个并行项目中)产生的。

  • 报告:谁最喜欢看报告?当然是管理层了!他们时间有限,如果不能深入前线听到枪响嗅到火药味,对于他们而言,看到一份数据健全有内容的报告是必不可少的了。问题追踪工具可以统计出从项目周期开始,多个视角的数据,例如常见的设计问题提交、修复、验证和关闭趋势图,从这张图可以看出项目执行的健康状况,又比如系统设计缺陷提交曲线,曲线如果到了项目后期仍然居高不下,那么很有可能意味着结构性的严重错误会进一步导致项目延期从而调整芯片结构。

问题追踪流程

在了解了问题追踪工具一般具备功能之后,我们还需要了解在日常工作中,如果发现了一个问题,我们应该如何使用工具来提交、跟踪、修改、验证这个问题的状态,还有状态之间的跳转通常是在什么情况下发生的。上面这幅问题追踪状态流程图是针对硅前芯片开发流程的,实际上的问题跟踪周期要比这个状态更长,还包括了硅后测试周期。在这里,我们先集中在硅前芯片开发阶段,来依次解释各个状态的表征以及状态之间的跳转条件。

新的问题:当在项目执行中,发现了一个新的问题,而且这个问题的影响满足之前问题提交的基本依据时,我们就需要在问题追踪工具中提交这个问题,填写相应的内容,这对应着步骤1。接下来,提交者会将问题派发给需要解决问题的所有者。如果所有者发现该问题不属于他的模块,那么他应该再次将该问题派发给真正的问题所有者,即步骤2。问题所有者会进行研究,确定是否属于系统结构、设计或者验证问题,然后他可能会进行

  • 进入开始状态,修复问题,即步骤3。

  • 如果问题所有者进过分析,发现他的模块并不会导致该问题,而是由其它模块引起的,那么他可以将状态重新修改为新的问题,即步骤4。

  • 该问题之前已经被发现过,则将状态修改为重复状态,即步骤5,同时需要备注已经提交相同问题的ID号,用来追溯该问题。

  • 该问题的修复如果会严重影响项目进度而且不使致命问题的情况下,需要同管理层商讨。假如最终确定有软件方法或者其它补正方法时,可修改为延后状态,即步骤6,待后期项目可以重启该问题。

  • 如果问题所有者发现该问题实际上已经在新的发布版本中修正以后,他可以将状态修改为解决状态,即步骤7

开始:当问题开始进入修复过程时,问题所有者在经过研究之后,做出了修正,则他会将问题修改了解决状态,即步骤8。在这一状态中,问题所有者仍然有可能会将状态修改为重复或者延后的状态,即步骤9步骤10

解决:当问题修复以后,问题所有者会将该问题再派发给验证人员,例如设计人员会派发给验证人员要求测试漏洞修复是否完成,系统人员派发给设计人员要求检查功能描述是否与设计相符且漏洞得到修复等,这一过程即是上图的步骤11。

验证:当问题得到修复和验证之后,问题会再次派发给当初的问题提交者或者管理人员,由他们将状态修改为关闭状态,即步骤12

关闭:在问题关闭之后,问题的提交者如果在回顾问题、或者再次遇到此问题发现没有得到完全解决时,他可以重启问题,即步骤13

重启:问题得到重启后,问题所有者又需要再次进入问题,检查新的问题场景,经过研究后

  • 如果问题仍然需要再次修复,则进入开始状态,即步骤14

  • 如果问题的场景需要另外配置设置,或者已经修复,则可转入解决状态,即步骤15

  • 如果问题受限于实际,暂时无法修复需要延迟,则需要步骤16

上述的各个状态以及状态之间的跳转,符合一般芯片开发中的问题追踪流程,从该流程的细节我们可以发现,问题追踪管理的特点是:

  • 符合实际工程应用,状态之间的跳转合理。

  • 问题一旦提交即有两方,提交者和所有者,且这种状态会一直持续到问题的生命周期结束为止,即关闭状态。

  • 追踪工具的可以满足工程师和管理者的需求,让双方共同参与,深入了解第一线的资料(问题描述、解决方法、验证方案),同时也提供了整个项目的执行状态。

  • 管理者并不需要在问题的生命周期内完全参与,他可以随时介入,但更多的状态跳转只需要由工程师执行,这样减轻了管理负担,留出时间统揽全局

至此,我们将问题追踪需求、分类、工具和流程介绍完毕。有了团队间协作的工作,那接下来我们将进入“人”的环节,来看一看如何在长、中、短期建设验证团队,使团队成为最宝贵的公司财富。

验证的管理篇之五:团队建设

可能在工程技术领域要找出比芯片验证更考验团队合作的项目类型会很难,之所以这样讲,是因为验证质量只有在流片之后经过测试、用户反馈才能得到最终的结果,而且,验证非常依赖于团队的整体协作,一百个人的验证协作如果其中有一个人疏忽了,那么我们只能心里默默祈祷,他疏漏的模块功能作用没有那么广。

我们在验证工作中,面临紧张的进度,除了可以加班加点赶任务,也还需要有时候停下来回顾一下我们走过的路是否有弯路和没有寻访的地方。因为我们不但需要下力气去尽量实现验证的完备性,也需要考虑如何利用现有的人力资源实现最大化的验证收益。

除了越来越完备的各种验证方法、工具和流程,我们还需要注意,人始终是对项目能否顺利进行的至关重要的因素。招聘到合适的人,融入一个优秀的验证团队,使我们个人和公司都要关注的地方。我们这一节将“以人为本”,来讲一讲如何建设一个验证团队的文化。

验证团队的7个好习惯

无论哪一家公司,我们在加入那家公司前了解他们的企业文化,而一旦加入之后,团队文化的影响要更胜一筹,因为每个人日常工作中都会在自己的团队或者接触其它团队。接下来我们介绍的7个好习惯有的是广泛意义上的团队习惯,有的则是专门针对验证团队的建议。这些习惯尽管并不会列在我们执行项目的检查清单中,但是它对于保持整个团队的健康和活力有着积极的作用。

习惯1:从全局入手

在处理同一件日常事务时,专家的考量角度总会比新手更高、更广、更丰富,也因此解决问题时的方案也因此产生了高下的区别。无论你目前是什么专家水平还是新手入行,都会有更高、更新颖的视角等待你去挖掘。对于一个团队而言,在项目启动开始的时候,如果团队负责人就能够对项目的周期、难点、人力估计、环境建设作出响应,与团队分享他的视野,保证团队清楚接下来大家要如何作战、清晰每个阶段的作战目标时,团队中的每一个人也因此会在思考问题时多保持一份全局观。实际上,从全局入手解决问题,往往解决方式更有利于项目的中长期运行,也只需要更少的代价去修改和维护。

习惯2:追求百分百

如果一个问题从硅前RTL隐藏到门级仿真,那么代价是数倍的,如果被隐藏到了硅后测试,那么代价是数十倍的。如果已经发现了问题,那么你预见到该问题带来的影响会随着项目执行而不断放大,所以我们建议如果你遇到了问题,就解决它。不要再说什么这个问题下周处理、这个节点结束以后再做的谎话,要知道下周还有下周的问题,这个节点结束了还有下一个节点。这里我们要着重强调的是,如果你发现了一个会影响大家的问题,更应该主动去修复它,避免一个问题影响到更多的人。也许的确由于节点,你放缓了一些问题的处理进度,但请一直讲它们记录到你的待处理事项清单上,直到你真得做完了它。

习惯3:保持面向对象的开发习惯

对于硬件设计者而言,面向对象的开发方式不一定需要熟悉,而对于验证工程师而言,它的重要性尤为明显。无论你是使用SV、SC、C++还是Python,如果你需要开发一个长期维护的工具,请首先考虑面向对象的方式。作者曾经参与过一些芯片验证工具的开发,在早期功能简单的阶段,由于未对日后软件的结构有一个充分的认识(缺少习惯1),以至于用了过程语言的方式去构建了软件工具的框架。待需要大幅扩容软件的功能时,我们在后续的开发中面临了诸多痛苦,而首当其冲的就是当时缺少面向对象构建的思想。

习惯4:合理复用

复用一词是高效验证的核心理念之一,无论是方法学的推陈出新还是验证环境的搭建维护,都需要始终考虑复用。复用所涉及的范围也很广,除了设计模块复用、验证环境复用、测试用例复用之外,也包括项目环境建设复用、脚本复用等。验证目前占到了整个芯片前端开发的60%以上的工作量,提高复用性就可以加快验证速度,同时也减少维护成本(对于一些需要专门知识的IP模块尤甚)。所以,我们验证工作中,可以考虑将验证环境参数化、脚本自动化、提交文档使得验证环境便于维护和使用。

习惯5:保持创新

除了书本上的知识,更多的磨练来自于项目执行。在从新手逐渐转变为老手以后,往往会有一段倦怠期或者自满期,因为验证人员可能觉得他所属的模块已经足够了解,验证环境也熟练了,似乎没有那么多再需要埋头深挖的地方了。这个时候,不妨建议你争取新的模块和任务,我们看重的是熟练的“新人”在接手新任务以后提出的问题和改善措施。我们相信验证总有需要不断完善的地方,在新的领域你的思想还会保持一段活跃时间,从而提出一些新的改善方法。同时,如果你要考虑如何让大脑保持不断创新的状态呢?除了不断学习、不断交流之外,那就是永远对验证效率的不满足。而实际工作中的创新一旦被证明它对整个团队的价值,那么不单单是它的作用会逐渐放大,而且你也可以感染吸引更多的人一同加入到你们的创新队伍中去。

习惯6:高效沟通

随着验证团队的扩大,如果人员一旦超出10个人,那么整体的沟通效率会随着人员增多而下降,对此我们提出几种建议来有效提高团队的沟通效率。首先,可以进一步考虑拆分为5人以内的小组,平行执行任务,保持各组之间的独立;其次,在可行的情况下首先考虑面对面谈话,次而打电话,再次者写邮件,我们相信口头表达是最高效的方式;再者,尽量少开会,开短会,只邀请必要的人参加,节省他人时间,也节省自己的时间;最后,如果有条件,可以将团队在一些关键项目节点附近聚集在一起办公,团体作战,减少沟通成本。

习惯7:突破责任边界

在设计的边界划分上,我们可以通过定义模块层次和结构来实现,而在验证工作中,我们则无法清晰划分出边界,因为模块之间往往有互动功能。一般,我们会遵循主从、上下行数据和功能实现工作量大小的方式来确定互动功能谁哪一方来验证。例如,如果模块A是主端,模块B是从端,在集成验证中模块A的验证人员也需要验证从模块A发起的访问经过模块B,再回到模块A的数据通路;又例如,如果模块A实现了互动功能更多的逻辑部分,那么也会由模块A的验证人员来发起集成验证。尽管我们希望以一种合理的方式来划分验证边界,但仍然难免有一些边界不清晰的功能交互部分,这时候如果模块A、B双方可以突破责任边界,积极承担各自的部分,或者从项目整体出发,定义验证的完整方案,再考虑工作的承担问题,那么这毫无疑问对于验证团队的整体验证质量是有益的。

通过上述的验证团队的7个好习惯,我们不难看出,一个优秀的验证团队需要从职业技能和工作态度两方面入手来培养。于公司和团队如何着眼于个人培养他们的职业技能,以及个人如何不断炼化自己的工作态度,我们将在管理篇的最后一节《验证师的进阶》中展开讨论。

验证的管理篇之六:验证师的培养

验证的管理篇之七(终):验证的专业化

来源:路科验证(微信订阅号ROCKER-IC) 及 EETOP BLOG

(0)

相关推荐