一种利用IC Compiler实现复杂情况下off-track布线的方法


徐君
中国科学院计算技术研究所 微处理器中心

xujun@ict.ac,cn

摘要

随着芯片设计日渐复杂以及设计者对芯片面积最小化、性能最大化的不懈追求, 物理设计面临着越来越大的挑战, 这时候就需要工具具有良好的扩展性,通过提供给用户足够的接口,使用户能够充分利用这些接口满足自己特殊的设计要求。

本文将介绍借助ICC的可编程能力实现项目对布线的特殊需求的一种方法。在龙芯3号二级缓存模块的物理设计阶段,我们面临着宏单元过多、布线资源严重匮乏的局面,为了将宏单元的连线以最有效的方式引出,只能让连线走在非track通道上。我们借助ICC的可编程能力开发脚本完成了连线的非track部分,又利用ICC提供的命令将这些连线巧妙地连接到相应的元器件引脚上,最终很好的达成了我们的设计目标。

1. 引言

我们经常面临一些复杂情况下的布线挑战,既要保证面积够小从而缩减成本,又要保证连线够短从而提高性能。这时候单纯地依靠几个命令或某种流程已无法满足我们的设计需要。我们期望工具可以提供给用户必要的接口,使我们可以从实际项目出发,扩展出我们需要的功能。Synopsys的IC Compiler恰好满足了我们的这一需求,它以TCL语言作为用户界面,通过提供给用户对象属性以及基本命令,展现出强大的可扩展性。较之上一代主要基于Scheme语言的Astro而言,它更加灵活、鲁棒、容易操作和掌握。

本文使用的方法成功地用于龙芯3号二级缓存模块物理设计,具有一定的通用性和启发性。本文组织如下:第一部分提出问题,介绍项目概况,阐述我们面临的设计难点;第二部分介绍我们如何开发点工具,实现off-track布线;第三部分介绍我们如何利用工具提供给我们的命令,将我们所做的off-track连线成功的连到相应标准单元的引脚上,完成整个布线过程;文章的最后是结论。

2. 龙芯3号二级缓存模块概况

该项目采用65nm工艺流片,共有7层走线金属。power strap由垂直方向的M6和水平方向的M7交叉构成。对于宏单元上空的电源、地,我们采用了特殊处理方式。宏单元本身使用了M1-M5共5层金属,其中M5是电源、地的引脚,如图1(a)所示。为保证宏单元供电充足,龙芯3号对所有宏单元都是直接将M6贴到竖向M5引脚上并很紧密地打上通孔。这样,宏单元上空就只能在M6的电源、地之间走少量信号线,而且这些M6布线资源绝大部分都不在track上。图1(b)显示了宏单元的电源、地与标准单元部分的不同。

图1(a): ram内部电源、地引脚,为M5层金属。由图可见,横向、竖向都有。为保证供电充足,M6 strap的中心线完全与竖向的M5引脚中心线重合,这样留给M6的走线空间就非常有限了。

图1(b): ram上空电源、地与标准单元部分采用不同的处理方式。

龙芯3号二级缓存容量是1MB,由32个容量为4096*72的宏单元构成其数据部分,每个宏单元有8位用于ECC检查,因此4096*(72-8)*32/8=1MB。该模块的floorplan如图2所示。因为是4路组相联,所以在图2中我们将数据部分分为4组,每组由8个宏单元面对面构成。通道宽度是89.4um。每个数据宏单元包含72个D端口,72个Q端口,12个A端口以及13个时钟、测试以及读写使能控制端口,也就是说,每个宏单元都将有169条线进出,8个宏单元将有169*8=1352条线通过这个宽为89.4um的通道。在65nm工艺下,竖向的M2、M4最小宽度和最小间距都是0.1um,因此1um宽度最多可以通过10条连线(1/0.2*2=10,乘2是因为可以走两层金属)。如此看来,89.4um最多可以走890条连线,指望所有这1352条线都穿过这个通道是不切实际的。

图2: 二级缓存模块floorplan。最上面和最下面是cache的目录项,中间8块为标志项,其余32块为数据项,分为4组。每组之间的通道宽度为89.4um。我们计划data的Q端输出由ram上空穿过,D端以及其他端口输入和目录项的全部连线均由通道进出。

于是我们设想将宏单元的Q端连线从宏单元上空引出,就利用上面提到的少量M6布线资源。这样,通道内只需穿过(72+12+13)*8=776条连线,这是可以实现的,而且利用工具的自动化流程就可以办到。

唯一的难点在于宏单元上空的走线。图3是一个示意。我们要在M6 strap的间隙内走出自己的Q端输出和从上面的宏单元传来的feedthrough,而这些可以走M6 signal的地方基本都不在track上,这就需要我们自己想办法完成这部分工作。

 

图3: 宏单元上空走线示意图。在对一个macro进行操作时,两侧设置route guide以限制走线区域

3. 在宏单元上空做off_track连线

3.1 插入buffer引导连线

为确保连线能够按照我们设想的方向延伸,我们在通道内和宏单元上、下分别插入buffer用来引导连线。逻辑上,我们在RTL中将这些buffer写定,并对这些buffer和连线做特殊命名,然后在综合过程中设置上dont_touch属性。物理上,在做floorplan阶段用set_cell_location命令将他们摆在合适的位置并设上fixed属性,此时注意一定要放置在row上。这既可以通过计算出精确的坐标实现,也可以全部摆完后稍微move一下让ICC自动调整。插入结果如图4所示。

图4: 在ram块之间添加buffer用于引导连线。图中白色为飞线,表示连接关系。其中延伸到右下角的飞线是指向bist逻辑的,因为在floorplan阶段,bist逻辑还没有被布局。

3.2 宏单元上空连线

在宏单元上空走过的线包括从上面传下来的feedthrough和自己的Q端输出。对feedthrough,只要在能走M6的位置创建一条贯穿宏单元的线即可。对于自己的Q端输出,则要完成三部分工作:1)在竖向PG net间隙找到能走M6的坐标;2)根据Q端引脚和M7 PG net位置,确定能走M7信号线的坐标;3)将M6和M7通过via6通孔连接起来。

我们用Perl开发了一个点工具,用来输出ICC用来创建连线和通孔的命令create_net_shape和create_via。该点工具的输入和输出如图5所示。

 

 

图5: 在ram上空创建m6走线。输出为可直接为ICC所用的tcl脚本和供后面使用的

图6: 在ram上空创建m6走线。输出为可直接为ICC所用的tcl脚本和供后面使用的m6

该点工具的输入可以是具有某种固定格式的文件,也可以是命令行参数。利用该工具可以完成M6的feedthrough和竖直方向Q端输出。

绘制M7的方法与M6非常类似,甚至更简单。因为M7的PG net是顶层划分下来的,所以我们只需知道第一条M7 PG net的位置即可计算所有其他M7 PG net坐标。这样,我们只要在满足DRC的前提下在与Q端最接近的位置绘制M7信号线,算法与route_m6_over_ram.pl相同,唯独输入由Q端引脚位置替代了M6 strap,如图6所示。

图7: Q端引脚与M7的连接。图中,上面部分是ICC自动生成的,下面部分是我们开发程序仿照生成的。

 

图8: 连接Q端引脚与M7 signal的代码片段

 

本设计中ram的Q端引脚为M2和M3,因此还要考虑如何将引脚与M7相连。我们先是在前面两步工作结束的基础上,让ICC自动完成这部分工作,然后我们先选取一条ICC连接得比较好的引脚,如图7所示,记录所用的M3-M7各层金属长度和各通孔位置,以此为基准,考虑电源、地通孔位置,加以调整,开发程序去完成所有引脚连接。程序片段如图8所示。

因为在绘制M6和M7过程中,相应信号的横纵坐标也已输出,因此M6与M7间的通孔位置就很容易确定了。如果M6起始点坐标为(x,y),M7启始点坐标为(a,b),则通孔坐标为(x,b)。

至此,我们就实现了宏单元上空的off-track走线,如图9所示。

图9: ram上空的off-track走线

3.3 将off_tracktrack上

宏单元上空的连线通过M6引出,如3.1介绍,我们在宏单元间隙放置了相应buffer,我们需要这些连线能够连到相应buffer的引脚上。为了让工具来完成这部分工作,我们需要在它们与buffer相连之前,将所有off-track连线纠正到track上。

在我们前面的工作中,每条点工具绘制好的M6连线都有相应坐标输出,而M6的track位置是可以计算出来的。因此根据已有M6位置找到离它最近的M6 track位置不是难事。但问题在于:1)要确保找到M6 track不与电源地连线有DRC规则违背;2)要确保找到的M6 track没有被前面的M6连线占用。

为解决这两个问题,我们采用“单向原则”。一条M6金属,与它最近的track也许在左也许在右,所谓“单向原则”就是放弃“最近”条件,只选择一个方向上的,比如都选右边的。如果右边的track与PG via有DRC违背,则继续向右选择下一条。根据分析,如果两条M6金属选择了同一条track,则这两条M6信号线一定相邻。因此,我们只需记录上一条M6信号线的track坐标即可,如果本条信号线与上一条冲突,则再向右选下一条track。调整后的结果如图10所示。

图10: 将off-track走线调整到track上,图中虚线为M6 track,红色单元为要连接的buffer,绿色是一条完整连接的信号线。

4. 完成布线流程

至此,此模块的所有需要精确完成的布线工作都已结束,接下来就是完成所有与宏单元相关的连线连接工作。这里布线的顺序很重要,因为它直接影响的到布线资源的使用。我们的原则是重要的、需要尽可能短的线先布。这里,调整到track的M6还未与buffer相连。而我们知道,buffer的pin脚是M1的,如何让ICC能够自动连上buffer引脚并遵从我们先前利用点工具生成的部分连线,便成了很重要的一个环节。幸运的是,ICC提供给我们一个非常有用的命令恰好可以满足我们的设计需求。

set_net_routing_layer_constraints [get_nets …] \

-min_layer_name {M6}

-max_layer_name {M6}

该命令限定信号线走哪些层金属。在我们这个设计中,如果我们限定这些信号线走M6金属层,则ICC使用我们的M6连线的几率就会非常之高。实验的结果也证明了这一点,如图10中那条被标志为绿色的信号线所示。

于是我们的设计流程可作如下安排:

for (i=0; i<4; i++) {

turn on Xtalk options;

route signal nets of Q[*] output;

route bist logic;

route other signal nets of ram;

}

利用这种方法,ram部分的布线DRC violation为0,而且时序最优。

5. 结论

随着设计复杂度逐渐升高和开发人员对性能、面积以及功耗的不懈追求,芯片设计逐渐向“精”的方向发展。很多项目为了达到自己的规范要求,不得不用ASIC的设计流程完成“半定制”的设计方法。相比于传统的版图工具,ICC提供给用户丰富的接口,使得用户可以按照自己的设想去扩展工具的潜能,有效地节省了开发时间,提升了开发效率,甚至将很多“不可能”的任务变成了活生生的现实。

本文就是利用ICC的这种能力完成了一种非常复杂的布线方案,具有一定的通用性和启发性。在可以预知的将来,ICC的这种可扩展能力也许会变成物理设计人员手中一笔宝贵的财富和锋锐的利刃。

6. 参考文献

[1] IC Compiler User Guide