基于Partition Compile技术来提高VCS编译整体效率


王凤海wangfenghai@vimicro.com

李树杰lishujie@vimicro.com

常 岩changyan@vimicro.com

中星微电子有限公司

Vimicro

摘要

随着芯片规模的增大,验证工作所占用的时间越来越成为项目的瓶颈之一。在仿真验证中,任何一点设计代码或测试平台的改动都要求对代码进行重新编译仿真,特别是对于全芯片级验证工作来讲,大量的重复编译消耗了很多的资源并且降低了工作的效率。业界迫切希望能够显著地缩短重复编译的时间。本文通过一个中星微电子的实际项目,介绍如何基于Synopsys公司的VCS数字仿真器的Partition Compile来提高重复编译的效率。结果表明,VCS的Partition Compile能明显地减少重复编译所需时间和资源,从而提高整体验证工作的效率。

Abstract

As the design size is growing exponentially, the verifi cation bottleneck is increasing accordingly. Full chip compile time is too long to do a lot of iterations. Industry is deeply in need of the improvement of compile turn-around-time. This paper discusses the Partition Compile feature of VCS and its adoption into a ViMicro real project. The result shows that, Partition Compile can signifi cantly improve the effi ciency of re-compile, and thus shorten the verifi cation cycle.

1. 引言

验证工作在芯片设计周期中所占据的比重越来越大,而随着芯片规模的持续增大,仿真验证所需要的时间也随之增加。设计或测试代码中的任何一点改动都要求重新编译与仿真,从而导致验证时间的延长。特别是对于全芯片级验证工作来讲,大量的重复编译消耗了很多的软硬件资源并且降低了工作的效率。
为了提高编译的效率,芯片设计公司与EDA公司合作提出了各种方法来减少重复编译的工作量。在工具流程方面有增量式编译(Incremental Compile)、分离编译(Separate Compile)以及在代码中加入“$test$plusargs”来提供仿真时的控制;在验证方法学方面也引入了vmm_test这个基类来提供对特定测试激励的选择;这些方法都可在某些方面减少重复编译的工作量,并在以往的项目中获得了很好的效果。然而以上的各种方法也都有其各自的局限性,例如,VCS的分离编译技术对于测试代码的划分和测试用例的灵活选择可以提供很好的支持,然而对于设计代码的微小改动却无能为力。
为了能够对设计代码进行划分从而提高再次编译时的针对性和效率,Synopsys公司最新版的VCS(VCS-2011.03)引入了一个全新的功能:分割编译技术(Partition Compile)。使用该技术可以对设计和验证代码进行划分(Partition),当任何一个设计代码的partition或验证代码的partition有改动的情况,可以仅对该partition进行重新编译,对未作改动的partition可以重复利用以前的编译结果。由于Partition Compile减少了无必要的重复工作,从而明显地提高了再次编译时的效率。

2. Partition Compile介绍

Partition Compile是2011.03版VCS新引入的feature,其思想是对设计和验证代码进行划分,如图1所示。通常,一个芯片的设计和验证工作都是高度模块化的。对于设计工作,可以根据功能划分成多个部分,每一部分由专门的工程师负责,而且通常一个项目中,有很多模块是复用以前的设计或外部采购的IP。这样,每一个工程师所负责的代码,在整个芯片中只占很小的一部分。当某工程师需要对其所负责的模块(例如图1中的inst 1模块)做调整时,如能避免重复编译未改动的其他部分代码,而只对其负责的那部分代码重新编译,则可以显著地提高再次编译时的效率。

图 1 – Possible Partitions of a Design and its Testbench

当前的Partition Compile功能需要采用VCS的UUM(Unifi ed Use Model)方式,即首先使用vlogan 命令对代码进行分析,然后使用vcs命令对分析结果进行处理(compile、elab等)。而且在编译前需要编辑一个confi g文件来描述partition的信息。如图2所示:

图 2 – An Example of Design Partition and Confi g fi le

图中,将代码中的TEST,BLOCK1,BLOCK2划分成3个partition,在一个名为“topcfg.v”的文件中通过“partition”关键字(verilog2001标准关键字)将划分意图描述出来,之后在调用vlogan 时将config文件作为源代码的一部分,就可以将划分意图输入VCS了。 然后,在调用VCS编译时,要加上“-partcomp”选项。所以,对于如图2所示的划分,使用Partition Compile做初次编译时的命令如下:
$>vlogan test.v –sverilog –work testlib
$>vlogan block1.v block2.v block3.v –sverilog
–work dutlib
$>vlogan dut.v top.v –sverilog –work dutlib
$>vlogan topcfg.v
$>vcs dutlib.topcfg –partcomp
如果在后续的工作中,对某一partition中的代码进行了改动,则仅需对相应的partition做重新编译。例如,如果验证工程师对验证代码有所调整,则可以通过以下2个命令来实现对验证部分代码的重新编译:
$>vlogan test.v –sverilog –work testlib ??
$>vcs dutlib.topcfg –partcomp
在对代码进行partition时,可以使用两种方式来描述各partition所包含的代码部分,一种是如上例所示的基于instance的划分,还有一种是基于module的划分,其示例性的语法如下。
在使用中,可以根据实际代码的情况灵活选择。作为一般性的原则,如果某些module在项目中有多个例化,则使用modulebased的partition,其再次编译所需的时间会更短一些。
confi g topcfg;
design top;
partition cell TEST_BLOCK;
partition cell BLOCK1;
partition cell BLOCK2;
endconfi g
在实际的项目使用中,我们认为Partition Compile可以有2种典型的应用场景。一种是针对验证工作中需要开发大量regression test case的场景,另一种是针对设计中有IP复用的场景。

2.1 Compiling for regression tests

验证工作中要针对芯片的各功能特性开发很多的测试用例(test case),对每一用例都要进行编译仿真。举例来说,对于如图2中所示的划分,会有很多不同的测试用例文件来实现不同目的的TEST_BLOCK。然而对于所有的这些测试用例,它们所对应的dut代码都是同样的。如果可以在众多的测试用例中复用对dut的编译结果,则可以显著的降低总的编译时间。为了达到此目的,需要在初始编译时通过“-partcomp_dir=

”来将共享的目录加入到各用例中,如图3所示。

图 3– Example of Compiling for regression tests

2.2 Compiling for IP reuse

复杂的芯片项目通常由多个工程师共同承担设计任务,而且芯片内往往有来源于以往项目或第三方的IP模块。对于每个设计工程师来说,如果能够将自己承担部分之外的模块预编译成某种类似于库文件的形式,在日常的工作中可以通过调用该预编译的结果而非每次都重复编译所有的代码,则其工作的效率可以得到显著地提升。仍以图2所示为例,如希望将BLOCK1作为IP进行复用,则可以用如下的方法实现:
1.IP generation
vlogan block1.v –sverilog –work dutlib vcs –partcomp=precompileip dutlib.dummy_block1_cfg产生的整个目录作为将来复用的数据库。
2.IP reuse
将第一步产生的目录拷贝到目标路径< path_to_block1_ip>在 synopsys_sim.setup文件中添加一行block1:/path_to_
block1_ip vlogan test.v –sverilog –work testlib
vlogan block2.v block3.v dut.v top.v –sverilog –work dutlib
vcs dutlib.topcfg –partcomp
可以看出在复用block时,不需要再对其进行编译了。

3. Partition Compile在ViMicro项目中的使用

我们在最近的一款大规模SOC芯片中采用了Partition Compile技术,以减少编译时间,并增加编译的复用性。下面介绍在该项目中的编译流程。
在我们的项目中,我们使用IP预编译技术将ARM CORTEX-A8作为一个单独的IP进行预编译,然后在各个test case之间共享编译库,一方面减少了编译时间,另一方面节省了硬 盘。同时,我们对自己验证的模块单独做了一个partition。这里以gpu为例,在验证过程中,gpu的代码可能会不断变化,但多数情况下不会修改跟其它模块的接口,因此把它作为一个partition,可以减少重新编译所需要的时间。同样,test环境可能需要不断地进行调试修改,所以我们将test也单独做了一个partition,以减少迭代编译所需要的时间。
首先我们需要一个cfg文件topcfg.v,如下所示:
confi g topcfg;
design vc07xx_tb_top;
default liblist DEFAULT dutlib testlib ip_work_
a8
partition instance vc07xx_tb_top.u_vc07xx.u_
shutdown.u_av_subs.u_gpu_top;
partition instance vc07xx_tb_top.test;
partition instance vc07xx_tb_top.u_vc07xx.u_
在上面的config文件中指定了编译时搜索的library库,包括DEFAULT, dutlib, testlib, ip_work_a8等,我们需要在synopsys_sim.setup中指定这些library库所对应的physical库,如下所示:
WORK > DEFAULT
DEFAULT : ./work
dutlib: ./dut_dir
testlib: ./$test_dir
ip_work_a8: ./ip_work_a8
另外,我们还需要对IP写一个confi g文件,这里以CORTEX-A8为例,创建一个a8_confi g.v文件,如下所示:
confi g a8_confi g;
design a8_wrapper;
partition instance a8_wrapper;
endconfi g
在进行整个项目的编译之前,我们需要对CORTEX-A8进行预编译,编译的脚本如下所示:
vlogan -f a8.f +v2k -work ip_work_a8 -l ip_a8.log
vlogan ./a8_confi g.v -work ip_work_a8 +v2k -l a8_confi g.log
vcs -lca -partcomp -partcomp=precompileip -partcomp_dir=ip_lib ip_work_a8.a8_confi g …
在该脚本中,首先对CORTEXT-A8的verilog代码进行vlogan分析,然后对a8_config进行vlogan分析,最后进行vcs编译。注意此时需要通过-partcomp来表明现在使用的是partition compile技术,通过-partcomp=precompileip选项表明这里是进行IP预编译,通过-partcomp_dir=ip_lib来指定该IP用来共享的physical library(在当前目录下会生成ip_lib目录,整个项目编译时通过指定该library进行共享)。
执行该编译脚本后,即完成对IP的预编译,并产生所需的编译库。
下面是整个项目的编译脚本,在第一次编译或者设计的修改不仅涉及指定的partition,还涉及其它模块时,需要运行此脚本:
vlogan -f fi le_test.f +v2k -sverilog -ntb_opts rvm -work testlib -l test.log
vlogan -f fi le_gpu.f +v2k -work dutlib -l gpu.log
vlogan -f fi le.f +v2k -sverilog -ntb_opts rvm -l dut.log
vlogan topcfg.v +v2k -l cfg.log
vcs -lca topcfg -partcomp -partcomp_sharedlib=ip_lib …
在该脚本中,首先对test partition, gpu partition进行vlogan分析,然后对其它部分进行vlogan分析,最后用vcs进行编译。通过-partcomp_sharedlib=ip_lib来指定CORTEXT-A8预编译时产生的共享库。
第一次编译完成后,当gpu或test的代码有更改时,我们不需要对整个设计进行重新编译,只需对更改的部分进行编译即可,因此我们需要单独的脚本来指定编译的范围。这里以gpu为例,假设gpu的代码做了个性,进行迭代编译时所需要执行的脚本如下所示:
vlogan -f fi le_gpu.f +v2k -work dutlib -l gpu.log
vcs -lca topcfg -partcomp -partcomp_sharedlib=ip_lib …
在该脚本中,首先对gpu的代码进行vlogan分析,然后即可用vcs进行编译。此时只会编译gpu代码,不会对其它部分进行重新编译。请注意,这里vcs的命令选项必须跟上面第一次编译脚本中的vcs选项完全一致。如有不一致,会导致vcs对整个设计进行编译,这样就无法达到节省编译时间的目标。
下表比较了在我们项目中典型的编译时间:

由上表可以看出,使用partition compile技术最主要的优势是节省重复编译的时间,可节省69%的编译时间,但第一次编译时所需的时间会稍稍增加,不过同时使用IP预编译技术即可以节省第一次编译的时间并可在多个测试中共享编译库,减少硬盘空间的占用。

4. 结论及建议

我们在一款SoC芯片中成功地采用了VCS的Partition Compile 技术。结果表明,无论是对于regression test还是IP reuse,该技术都能明显地减少重复编译所需时间和软硬件资源,从而显著地提高整体验证工作的效率。
Partition Compile在VCS-2011.03版本中还是LCA的feature,因此在某些方面,还有进一步完善的地方,例如,在目前的版本中,还是要使用UUM三步式的fl ow,而且partition compile目前还不支持SDF反标的编译。相信随着工具流程的进一步成熟,在VCS以后的版本中,这些地方可以得到完善。

5. 致谢

在采用VCS Partition Compile 提高编译效率的过程中,得到了中星微同事的大力支持,在此感谢刘子熹、侯华敏及其他同事的热情帮助。同时,我们要特别感谢Synopsys工程师时昕在我们项目过程以及本文的写作中提出的很多宝贵建议与周到细致的现场支持。

6. 参考文献

[1] VCS®/VCSi™ User GuideSynopsys

[2] VCS_Partition_Compile_User_GuideSynopsys