电子说
EETOP 论坛验证分论坛网友 似水如烟 提问:
在开发流程中,设计和验证人员关注的点肯定是不一样的,尤其在spec的理解上,验证人员往往需要有自己独立的理解。在拿到spec时,作为验证人员,应该如何提炼其中的功能从而转化为对应的inference model以实现和详细设计的交叉验证。大家有什么经验能讨论一下。
以下是网友解答:
jimbo1006:
我觉得验证人员看spec中的功能点的时候,需要关注输入,输出以及从输入到输出所需要的时间。首先,“从输入到输出所需要的时间”,也就是RTL内部的延迟,我觉得这是设计reference model的最大的难点。因为你即使问写spec的人,他也很有可能不知道。这个时候我们会去问设计人员或者看RTL代码,但是这样我们就很有可能被设计人员的思路影响,搭出来的ref model就有可能和RTL一起错了,这样你的验证环境有可能永远也查不到那个BUG。然后就是从输入到输出,这就好比一个真值表,我们需要做的就是按照随机策略设计并约束激励。但是随着逻辑的复杂度的增加,这个真值表会越来越大,大到我们很难写全。这个时候我们可以像设计一个很大的模块一样,把这个大的真值表分成若干小的真值表。说起来简单,但是这里的工作量是随着逻辑复杂度指数上升的。如果要做所谓的交叉验证的话,不如再找一个设计人员,也设计这样一个模块,然后他们比一比结果,再磨合一下延迟,根本不需要验证人员。最后再说下题外话,我在大学做设计的时候,是先设计reference model(用C++写好,用软件跑一下看看效果),然后再根据这个reference model去设计模块,最后设计完模块上FPGA跑一跑就结束了。这里如果加上验证一步骤的话,就可以直接拿这个reference model去验证了。所以我觉得应该是先有reference model, 再有需要被验证的RTL,这才是最合理的流程。但是我在实际工作的时候,是先有RTL再有ref model, 楼主所在公司应该也是这样,不然也不会问这个问题。我们分析一下,ref model虽然是根据spec写的,但是却要获取RTL的内部延迟,然后我们再用这个部分逻辑来源于RTL的ref model 去验证RTL。这里面稍有不慎,就会放过BUG, 因为一般情况下我们的scoreboard里面的auto_check是直接拿ref model的输出用的,不会去验它内部的逻辑的。
zxm92:
1.题主对于reference model的过度关注,侧面反映了题主更多还是站在设计者的角度来做验证,一开始我也执迷于reference model,自动对比给初做验证的人很大的快感。2.楼上说的输入到输出的时间的验证,我认为reference model更侧重于数据流的对比,时序上面的checker可以使用assertion。个人认为设计人员和验证人员看spec的角度是不同的:1.设计人员通常是站在功能实现的角度,而验证人员应该更多站在使用者的角度,也就是说如何使用做出来的芯片2.如何使用芯片,决定了你的激励,你的激励决定了芯片所面临的状况,芯片在所有可能的状况下都能保持正确,那这个芯片的quality就得到了保证,所以如何设计你的激励是验证的核心。
jimbo1006 回复zxm92:
我工作时间也不长,我现在对reference model也特别迷茫,感觉上如果写了这个就把一部分逻辑交给ref model判断去了,如果这部分逻辑和DUT错成一样可能会造成很糟糕的情况。 reference model更侧重于数据流的对比这个我很赞同,因为我验证过UART模块,像这类验证功能点的时候结果的时候主要关注寄存器里面的值,ref model搭起来得心应手。而且后来通过阅读UVM_COOKBOOK发现,像这类数据流的对比连ref model都可以不要。只要在slave agent里设计好transaction,然后和master agent的transaction传递给scoreboard直接比对就够了。 用assertion去验证timing的做法我也尝试过,但是后来我放弃了。因为写assertion我需要知道2个事件发生间的时间。因为逻辑很复杂的时候,DUT有很多内部信号,对于某个功能点的验证来说,整个信号的传递可以看做“输入->内部信号a->内部信号b->...输出”。输入和输出我们可以通过sepc看出来,但是输入到输出花的时间即使我们问写spec的人,他很可能也不知道。这里我开始选择写assertion, 因为我不能信任内部信号,我只能直接去找从输入到输出的时间,结果我问设计人员的时候,发现他也是按照这些内部信号去推出来的,所以我只能选择仿波形去确认。但是这么大的量,不能全靠看波形啊,所以我按照自己的理解设计了输出波形,把这个波形去和dut实际的输出波形去作比较,只要uvm报错了,就去找系统工程师和设计人员确认。这个时候发现即使是SV的assertion,根本满足不了我的要求,只能自己用SV甚至C++去搭自动check的逻辑。 验证中激励很重要我也赞同,但是我不觉得它是核心。对于UVM验证方法学来说,我觉得核心应该是如何去判断激励输入以后的结果是不是对的以及覆盖率的设计。覆盖率设计就像一个大纲,激励只不过按照那个大纲一步一步写(这里分成2个人去做效果应该更好),而且SV真的很合适干这事。
似水如烟:
大家感触都很深啊,也能看出来,都在验证的这条路上摸索。比较同意楼上的说法,黑盒验证无疑是相对比较省工作量的,只需要关注输入输出,更多精力放在如何判断对错以及根据覆盖率构建激励。但这些问题的根其实还是在对spec的理解上,这个我估计除了好的方法外,还是注重积累,就这方面大家没有好的经验传授。
jimbo1006:
1. 在阅读spec的时候,每句话看完都要仔细推敲下,把自己当做客户,想想客户在看到这句话时会怎么想。会怎么用。
2. 仔细推敲每个功能点,要多个角度去想想。例如,当某个enable信号打开时,某个输出为1。但是当这个enable信号关闭时,这个输出是多少,0,1还是donot care。如果spec没有明确表示,我们需要找系统工程师(写spec的人)确认。
3. 系统工程师和设计人员在设计模块的阶段,因为长时间合作,很有可能会有一些默契。比如说,某个开关打开以后,dut需要几个时钟采一下这个信号。而spec里面却是按照理想的情况描述的。这个默契可能会提高设计模块的效率,但是对于我们验证人员来说却是一个大麻烦。
因为spec每句话都有可能藏这么一个默契。而这个默契不仅会影响验证的效率,还有可能影响验证的可靠性。比如我按照理想的spec为了某个功能点写了自动比对代码,仿真以后发现结果不对,结果系统工程师告诉我有这么个默契在,我只能自动比对代码里面慢慢去找哪里涉及到了这个点,然后改回来。
但是这里其实有个风险,假设我的自动比对代码某个地方漏了这几个时钟,导致某个配置下的输出一直在输出默认值0(正确的输出应该是1),而DUT这个配置下正好也出错输出为0,这样我为认为自动比对和DUT都是对的,导致漏掉BUG。
zxm92:
1.写assertion我需要知道2个事件发生间的时间-->我觉得这句话应该换成spec没有定义2个事件发生的时间,如果没有定义时间的标准,又要去check,并不是assertion办不到,而是别的都办不到。假设我担心输入到输出的响应时间太长,又没有spec,我会记录下来输入的时间,记录输出的时间,拿对应的输入输出时间去计算两者的时间,得到最大值,再去考量这个最大值是否过大。
2.按照自己的理解设计了输出波形,把这个波形去和dut实际的输出波形去作比较,只要uvm报错了,就去找系统工程师和设计人员确认-->不理解怎么设计输出波形,如果输入到输出的时间在3us~5us这样一个范围都是正确的,你要怎么设计输出波形。
3.覆盖率设计就像一个大纲,激励只不过按照那个大纲一步一步写-->如果你说的是function coverage,我认为覆盖率和激励不应该同一个人来写,出考题和参加考试不应该是同一个人。激励和覆盖率是scenario的两种表现形式,并不是先有了覆盖率,才去做激励覆盖它,也不是有了激励,才去写覆盖率。假设dut有十种function,这十个function是必须串行去做,还是可以并行去做?串行去做的话有没有顺序的限制?并行去做的话哪些需要sync?往往error会出现在那些没有想到的scenario下。
4.核心应该是如何去判断激励输入以后的结果是不是对的-->判断激励输入以后的结果,先有激励输入,才有结果,才有判断。激励都不够完善,判断正确不代表dut正确
5.在阅读spec的时候,每句话看完都要仔细推敲下,把自己当做客户,想想客户在看到这句话时会怎么想。会怎么用。
-->这句话和我之前回复的这句是一个意思吧"设计人员通常是站在功能实现的角度,而验证人员应该更多站在使用者的角度,也就是说如何使用做出来的芯片"
jimbo1006 回复 7# zxm92 :
我很高兴我们的观点大部分都相同或者类似,因为我来论坛讨论的主要目的就是希望检验自己的方法和一些想法。而我们观点不相同的地方,我认为主要原因是“自动比对”上面。像你3L所说的一样,作为初做验证的我来说,“自动比对”对我的诱惑实在是太大,我现在的想法是“自动比对”就是当前,至少是未来验证人员的主要价值所在,也是我们验证人员的浪漫。我现在只验证过几个模块,每个模块的大部分都是通过自动比对验证的。而且我也找到很多设计人员和系统工程师很惊叹的BUG,在review的会议上,当他们问我怎么验证到这么特殊的case的时候,产生的成就感与满足感让我无法自拔。你尝试把我的验证环境都是自动比对的,我的一些观点你可能就会接受。
下面几个point和你7楼的点对应
1. 需要知道2个事件发生的时间是因为我在设计自动比对的代码,我发现如果不借助DUT的内部信号或者我自己设计的中间信号,已经很难去统计所有配置下DUT的输出的情况。这就相当于设计人员在设计一个大的模块时,他会划分成一个一个小的模块。而我在设计自动比对时,也需要这么做。我会设计一个一个中间点,因为有很多组输入和对应的输出,所以输入到中间再到输出并不是单纯的线性结构,而是网状的。网状的结构会导致我必须要知道每种配置下,到这些中间点的时间,至少是大致的时间。当然,如果系统工程师能给我一个表格,上面列出了所有的输入的组合和对应的输出以及他们之间的时间,也就没这个事了。但是他们肯定做不到,即使做到了,几种配置以不同的组合线性输入到DUT,对应的输出时间也可能有变。
2. 输出波形的自动比对是我在验证动机控制模块(很多PWM功能相关的模块组成的)设计的做法。我设计了一个collect模块与slave agent的monitor的相连,以DUT的输出信号和对应的输出oe信号为依据,设计了一个transaction, transaction会反应输出波形的值(0或者1),这个值的持续时间(以系统时钟/2+1的采样频率去采样确认输出信号),输出波形是否为高阻态(输出oe信号为0)等。然后我将这个transaction传递给scoreborad,另外输入的组合我也会通过master agent的monitor传递给socreborad。然后我就在scoreborad进行所谓的理想波形和输出波形的自动比对。利用fork join函数,设计3段并发路径,第一条随机一个时间,第二条将输入配置下的理想波形和实际输出波形实时比对,第三条根据需要修改一些参数,例如采样频率。你所说的3us~5us这个范围都是对的,在我这种结构下有很多种解法,为了规范结构提高重用性,我可以在第二路径下再插入2个fork join,每个2条并发路径,第一条的时间分别是3us和5us(5us下面发一个flag1),第二条都是去比对波形,但是对应3us的那个最后放另外一个flag2,在最后我再设计一段代码会对设计的所有falg进行确认。
3. 覆盖率和激励确实不该一个人来写,我也是这个观点。但是目前我们公司就我一个人在研究UVM验证,我去哪找一个人写激励。就算今后招了个人,暂时也不可能让2个人去做一个模块的验证,毕竟对spec的理解都要花很多时间。然后你想想,如果我真的把覆盖率和自动比对的代码设计好了,我完全可以找几个本科的应届生,让他们用尽一切办法,只有能够达到覆盖率要求并且通过我的自动比对,就OK。这样会节约很多时间与人力的成本。写激励的人和写覆盖率的人互相check自然很美好,仔细分析下,真正的决定权其实还在写覆盖率的人的手里。你所说的10个function并行和串行的问题,我正好在验证MCM模块也遇到,解决方法参照point2.
4. 正如我第3点提到的,只要我设计好覆盖率,你仿真完,随时可以查覆盖率的情况(我用的是VCS+verdi),里面你可以直接找到哪些点你没有覆盖到,写激励的人可以按照那个重新设计或者添加新的激励。当然我不是说写激励不重要,激励不完善可以通过覆盖率的百分比去反馈,但是覆盖率设计不完善谁能去反馈(代码覆盖率和功能覆盖率可以互相检测,但是这个的可靠性真不高)?
5. 我很高新我们这个观点是一致的。
全部0条评论
快来发表一下你的评论吧 !