1、IC 行业收藏:数字后端面试问题 zz(2013-05-08 13:06:07)转 载 分类: 硬件数字后端面试问题分类: IC 设计 2012-08-31 15:51 2251 人阅读 评论(0) 收藏 举报面试 transitiondelaypathtreefunction目录(?)+1.1 EETOP 版主面试问题001)Why power stripes routed in the top metal layers?为什么电源走线选用最上面的金属层?因为顶层金属通常比较厚,可以通过较大的电流1.高层更适合 globalrouting.低层使用率比较高,用来做 power 的话会占用一些
2、有用的资源,比如 std cell 通常是 m1 Pin 。2. EM 能力不一样,一般顶层是低层的 23 倍。更适合电源布线。3.一般 ip 占用的层次都靠近下几层,如果上层没有被禁止 routing 的话,top layer 可以穿越,低层是不可能的,并且高层对下层的 noise 影响也小很多。002)Why do you use alternate routing approach HVH/VHV(Horizontal-Vertical-Horizontal/ Vertical-Horizontal-Vertical)?为什么要使用横竖交替的走线方式? (感觉这个问题比较弱智,但是号称是
3、 intel 的面试问题,晕!我憧憬和向往的圣地啊!)为了节省布线资源-主要原因横竖的两根线之间的耦合系数最小,信号干扰小003)How to fix x-talk violation?如何解决线间干扰?答案:1)upsize victim net driver, downsize aggressor net driver2)increase wire space, shielding, change layer,change wire width3)insert butter in victim net能答出以上 3 条的,在工作中已经基本够用,但是还有两个不常用到的,是 AMD 的一个大牛
4、告诉我的。4)把与 victim net 相连的输入端改成 Hi-Vth 的单元5)改变信号的 timing window。这个不易做到,但是也是解决方法004)What are several factors to improvepropagation delay of standard cell?哪些因素可以影响标准单元的延迟?答案:1) PVT2)input transition, output load3)Vth005)What would you do in order to not usecertain cells from the library?如何禁止使用库里面的某些单元?禁
5、用就用 set_dont_use 禁止修改就用 set_dont_touch006)During the synthesis, what type of wireload model are often used?做 RTL 综合时,经常使用的 wire load model 有哪几种?答案:1)zero wire load model2)基于 fanout 的传统 WLM3)基于物理位置(距离)的 wire load model,在 Cadence 的 RC 中叫 PLE,Synopsys 叫 DC Ultra Topographical附加问题:What types of delay mo
6、del are used in digital design? (数字 IC 设计中有多少种类型的 delaymodel)答案:NLDMCCSECSM还有一个现在基本不用了的LDM007)How delays are characterized using WLM(Wire Load Model)?使用一般的 WLM (不是 zero WLM,也不是按照物理位置算的 DCT),DC 是如何计算 delay 的?答案:DC 在计算延时的时候,net 的 rc 就要根据所选取的 wrie load model 来计算,计算时和输出的 fanout 决定以 smic13 的 smic13_wl10
7、为例wire_load(“smic13_wl10“) resistance : 8.5e-8;capacitance : 1.5e-4;area : 0.7;slope : 66.667;fanout_length (1,66.667);根据 fanout 值,由 fanout(1,66.667)可以得出互连线长度为 66.667,然后根据 resistance 和capacitance 计算出互连线电容为 1.5e-4*66.667,互连线电阻为 8.5e-8*66.667,当然如果扇出值表中没有,就会用到 slope,例如扇出为 3 时,此时估算的互连线长度为1*66.667+(3-1)*
8、slope ,再计算出 RC 值,然后 DC 由此计算 net 的延时。008)There are source clock clka(create_clock), and generated clock clkb by clka.In pre-CTS netlist, there is network latency in clka, how this latencypropagates to clkb?In post-CTS netlist, What you need to do for this network latency?假设有两个时钟,原始为 clka,生成的时钟为 clkb,
9、在没有时钟树的网表中,clka 的 network latency 会自动传递到 clkb 上吗?clkb 的 latency 如何描述?在生成时钟树的网表中,如何处理 network latency? clkb 的 latency 又如何描述?答案:在 pre-CTS 时, clka 的 network latency 会自动传到 clkb 上在 post-CTS 时,可以把 network latency 去掉,通过 set_propagated_clock 命令,让工具根据clocktree 去计算实际的 clock network latency009)There are source
10、 clock clka (create_clock),and generated clock clkb by clka. how do you specify them in CTS spec file?Assume there is real timing path between clka and clkb.clkb 是 clka 的生成时钟,在 CTS 的 spec 文件中如何定义这两个时钟?假设 clka 和 clkb 之间的FF 有时序收敛的要求。难度:3答案:在 CTS 的 spec 文件中定义 clka 是 root ,clkb 为 throughpin,再加上那些应该有的ske
11、w,transition,insertion delay 等就好了,其它的事 CTS 会给你做010)assume in pre-CTS SDC, clock uncertaintyfor setup contains pll jitter + clock tree skew. How do you set clockuncertainty for hold, and how to modify it to post-CTS sdc?假设在 pre-CTS 的时序约束中, setup 的 clock uncertainty 是由 PLL jitter 和 clock tree skew 两部分
12、组成,那么1)pre-CTS 的时序约束中,hold 的 clock uncertainty 是什么?2)post-CTS 的时序约束中,setup 和 hold 的 clock uncertainty 要做什么样的修改?难度:2答案:1) pre-CTS,setup 的 clock uncertainty = PLL jitter + clock tree skewhold 的 clock uncertainty = clock tree skew2) post-CTS,setup 的 clock uncertainty = PLL jitterhold 的 clock uncertaint
13、y = 0011)What are various techniques to resolverouting congestion?请详细解释解决走线阻塞的问题难度:4提示:1) routing congestion 发生在后端,前端一般不太考虑这个问题,需要后端自己去想办法解决,但是解决的办法不只在后端,也有一些方法需要前端的配合2) 阻塞有多种情形,要分别讨论,没有一个统一的解决办法。能够把大部分的阻塞情况列举出来,就已经够 4 级的水平啦答案:1)阻塞在 RAM(macro)之间:可能 RAM 之间的距离没有计算正确,可以加大 RAM 之间的间距;扭转 RAM 的方向,使得 RAM 的
14、IOpin 朝向更容易走线的那边;如果是多个 RAM 共用地址或者数据线,尽量把 RAM 的地址数据 pin 对齐2)阻塞出现在 RAM 和帮助单元交界的地方:在 RAM 周围加一条 halo(keepout);把 RAM 放在四周,尽量把中间留下的空间变成方形;在有阻塞的地方加一些由小的 placementblockage 组成的矩阵3)阻塞出现在标准单元的某一块:也可以加一些由小的 placement blockage 组成的矩阵;module/instancepadding;利用 placement guide 减少那块地方的标准单元个数;scan chainreordering 也会改
15、善一些阻塞;定义 density 上限;使用 congestion driven 的 placement,并且要求 place 之后做 congestion 优化;在综合是禁止使用那些 pin 太多太密集的标准单元( 多半是那些复杂的组合逻辑单元);请前端使用 RAM 代替触发器矩阵;请前端修改算法4)应该尽量减少 power route 占有的资源,谨慎选择 power mesh 使用的金属层,VIA 的大小等。在 detailroute 完成之后,你如果已经试了各种解决 signal congestion 的方法,还有少量 DRC 无法解决时,可以考虑切掉部分 power mesh012)
16、How do you get better skew/insertiondelays in CTS (Clock Tree Synthesis)?如何得到更好的时钟树 skew 和 insertion delay难度:4答案:clock mesh 是一种方法。如果是用普通的 CTS 的方法,可以从下面几个方面着手。不太可能一次就把 CTS 做得很好,要反复调试各种参数,达到最佳效果。1)合理的 clock root 和 through pin。这个看似 CTS 会从 SDC 自动抓出来,但是并不一定是最好的,特别是多个 clock 相互有重叠的 leafpin 时,要特别注意2)不要用太大或者
17、太小的 clock buf/inv3)选用 RC 最小的金属层。如果上面 RC 最小的金属层已经被占用,比如 RC 最小的 top,top-1已经不够 clocknet 时,而 top-2 到 layer2 都是一样的 RC 时,可以选用 layer3/4。为什么不用更高层哪?因为这样既照顾了 layer2/1 的 pin,有不用太多的 via 到更高层4)如果用 double width clock wire,可以适当增大 clock buf/inv 的 size5)合理的 max fanout。有时 clock buf/inv 的 fanout 可以超过 max_fanout 的限制6)不
18、要把 skew 设得太小7)min_insertion_delay = 0ns8)合理的 transition time,不要太小9)使用 postCTS 的 CTS opt10)做 clock tree 时,就直接把 clock net 走线完成013)If giving total standard cell gate count,all memory macro list including memory type, bit width and depth, all othermacro with real size, and IO type and total number. How
19、do you estimate the diesize?如果告诉你标准单元的门数,所有内存的类型和逻辑大小,其他 IP 的实际大小,以及 IO cell 的种类和数量,你如何估算整个芯片的面积?难度:3答案:IO neck 和 core neck 一般称作 IO limited 和 core limited,IO limited :这个芯片的面积是因为 IO 个数限制(太多),而不得不做得那么大。core 部分其实用不了那么大。这时面积计算就简化为每边 IO 个数的计算了。Core limited:芯片面积是有 core 部分的决定的,IO 没有那么多在 Core limited 情况下,di
20、e size 的估算如下:芯片面积 = core 面积+ power ring 面积 +PAD ring 面积 core 面积 = RAM 面积 + 其他 macro 面积 + 标准单元面积RAM 面积 = RAM 自身的面积 + RAM power ring 面积 + keepout 面积 + mbist 面积RAM 自身的面积可以通过 memory compiler 或者查 datasheet 得到,有些 RAM 可以不要 power ring。如果要的话,按照 power mesh 的宽度 x RAM 的长宽 x 2 = 面积keepout + mbist 的面积一般是 RAM 自身面积
21、的 10%其他 macro 的面积,比如 PLL,ADC ,DAC 等,直接把面积加起来,再留 35% 的 keepout 面积就好了标准单元的面积=(预估的 gate count x 每个 gate 的面积)/ utilizationutilization 与使用的金属层数和设计的用途有关,简单地计算方法是5 层 metal:50%6 层 metal:60%7 层 metal:70%8 层 metal:80%以上不包括 power 专用的金属层如果设计是多媒体芯片,一般可以增加 35% utilizaion,如果是网络芯片,则要减少 35%014)what is pros and cons
22、of using buffer andinvters in CTS?CTS 中使用 buffer 和 inverter 的优缺点是什么?答案:使用 BUF:优点:逻辑简单,便于 post-CTS 对时钟树的修改缺点:面积大,功耗大,insertion delay 大使用 INV:优点:面积小,功耗小,insertion delay 小,对时钟 duty cycle 有利缺点:不易做时钟树的修改015)If giving two physical dies as below, andask you select one of them. How do you pick it up? explai
23、n the reason please.(1) width = 2 x height(2) height = 2 x width如果从下面的两个芯片中选一个给你做后端设计,你选哪个?请说明选择的理由?(1) 宽 = 2 倍的长(2) 长 = 2 倍的宽答案:去除不太好用的 layer(比如 metal1)和 power 专用 layer(比如 RDL)后,比较剩下的 layer 可以提供的 H 和 V 的 routingresource,如果 H 的多,就选宽的,反之,就选高的。016)if the design is IO limited, how to reducethe die size
24、?因为 IO 太多而导致芯片面积过大,有什么方法减小面积?答案:1)stagger IO,2 重 io 可以算一个方法2)IO 可以不全放到四边,只要封装没问题就行啦 - flip chip 算第二个方法3)如果有多套 IOcell 可以选择,尽量选瘦的4)调整芯片的长宽比017)giving the schematic and delay inattached picture, calculate the WC setup slack at D pin of F2, and BC holdslack at D pin of F4如图所示电路,时钟和延迟,计算到 F2 输入端 D 的 setu
25、p slack,到 F4 输入端 D 的 hold slack答案:F2 输入端 D 的 setup slack 是(8+0.5-0.3)-(0.7+7.0)=0.5F4 输入端 D 的 hold slack 是(0.2+0.2)-(0.2+0.2+0.1)=-0.1018)using the same logic as question #17,considering OCV on clock path only, which clock buffer will be used for OCVderating calculation and which clock buffer will n
26、ot (a.k.a. CPPR)?如果考虑 clockpath 的 OCV,在第 17 题的电路里面,哪几个时钟 BUF 要被用来计算 OCV 的derating,哪几个不用(又叫 CPPR)?暂不考虑 X-talk 产生的 incrementaldelay难度:2答案:C1 C2 不用算入 derating(应该是也计算过,但是会通过 CRPR 弥补),C3,C4,C5 要计算 derating附录:以下是几个概念的通俗解释。OCV:因为制造工艺的限制,同一芯片上不同位置的单元会有一点差异,这就是 OCV。现在还有LOCV 和 AOCV,暂且不提。derating:是计算 OCV 的一种简单
27、方法,在某个单一条件下,比如 WC 或者 BC,把指定 path 的延迟放大或者缩小一点,这个比率就是 derating。注意,这里要强调的是某个单一条件,要么是WC,要么是 BC,不能把 WC 和 BC 混在一起,再 OCV,因为那样太悲观,实际上是很难发生的。除了 derating 以外,在使用 incremental SDF 的时候,也会对 OCV 发生作用。这是明天的问题,比较有难度。CPPR:一条 path 的 start flop 和 endflop 的时钟路径,有时会有一部分是重合的,重合的部分不应该算 OCV(注意,这里假设没有使用 incremental SDF),这就叫 C
28、PPR。019)continue from question #18. Because thereis CPPR, the OCV derating on clock path C1 and C2 are canceled. Now givingincremental delay caused by x-talk at net between C1 and C2. Please use thederating to calculate the difference of clock path delay from C1 to C2(including the net between them)
29、 for WC setup and BC hold.接上面#18 的问题继续讨论,因为有 CPPR,在 C1 到 C2 那段 clockpath 上面的 OCV 被抵消掉了。现在我们增加一个由 x-talk 引起的 incremental 延迟在 C1 到 C2 的那段 net 上,具体数字见图。问题:对于 C1 到 C2 那段 clock path,在计算 WC setup 时,因为 OCV 引起的路径延迟的差是多少?在计算 BC hold 时,因为 OCV 引起的路径延迟的差是多少?注意:问题是那段 clock path 因为 OCV 引起的 path delay 的差,不是问 path
30、delay 的绝对值难度:5难度 5 的问题不是盖的吧,好,改为选择题,C1 到 C2 一段的 OCV 延迟的差,1)在计算 WC setup 时,是a) 0b) 0.0005c) 0.00075d) 0.02452)在计算 BC hold 时,是a) 0b) 0.001c) 0.0015d) 0.0265答案:现在从 incremental SDF 的格式说起,(-0.01:0.015)(-0.015 : 0.01)左边括弧里的是 rising timing 延迟,右边的是 falling timing括弧里面的一对数字表示在这个条件下(WC 或者 BC)延迟的最大和最小值因为是 incre
31、mental 延迟,要和基本延迟结合使用,所以,会有负数出现。再讲 OCV 的使用 incremental SDF 的方法,OCV 计算 path delay 时挑选最困难的情况,在 WC setup 时,比如从 F1 到 F2,计算 F1 的 clock path,就选 incremental SDF 里面的最大值 0.015,计算 F2 的 clock path,就选最小值-0.01因为有 0.95 derating 在-clock,-early 上,所以 F2 的 clock path 要按比例缩小-0.01x0.95=-0.0095所以 C1 到 C2 那段的 OCV 的差是 0.01
32、5+0.0095=0.0245 (选项 d)在 BC hold 时,比如 congF3 到 F4,因为 2 个 FF 在同一个时钟沿检测 hold timing,CPPR 可以把 incremental SDF 的延迟也抵消掉,所以 C1 到 C2 那段的 OCV 的差是 0 (选项 a)结论:计算 setup 时,CPPR 不抵消 incremental SDF计算 hold 时,CPPR 连 incremental SDF 都可以抵消掉020)Explain ECO (Engineering Change Order)methodology.说一下 ECO 的流程难度:2答案:ECO 有两
33、种,pre-mask ECO 和 post-mask ECO,它的分界线就是 base layer tape out 之前和之后。pre-mask ECO 的流程是1)后端写出网表,给前端2)前端修改这个网表 (一般不再做综合),可以使用任何标准单元(只要不是 dont_use),交给后端3)后端读入 ECO 网表,和 ECO 之前的 place 和 route4)ECO place if you think its not necessary, write X.如图,一个设计中有 4 个电源,VDD1/2/3 的电压各不相同, VDD1 总是开着,其他会有开和关,并且到模块 B 的 VDD2
34、 和到模块 C 的 VDD2 有各自分别的开关。请判断在连接这 4 个模块的 8 条net 上,哪些需要 levelshifter,哪些需要 ioslation cell,把结果填入右边的表中。填法如下:假如你认为需要在 netAB 上加个 levelshifter,加的位置在模块 B 里面,就在 netAB 的右边的第一列空格里写 B。如果什么都不加,就写 Xhttp:/ from #31 question, thereis isolation cell on netBA with isolate enable pin. When shutdown the block B,will you
35、enable isolate pin first, or shutdown B first? What order it is duringblock B power-on?接着上一题提问,在 netBA 上有一个 isolationcell,isolation cell 都会有一个 isolate enable 端,在模块 B 关断电源时,是先让 isolateenable 端 on 哪,还是先关模块 B?反之,在开模块 B 的电源时,谁先谁后?难度:2答案:先 isolate on,再 power off,反之先 poweron,再 isolate off33)There are 1000
36、 clocks in a design.You guess the constraint cross the clocks is incomplete, and want to have alist of clocks which has cross clock domain path. How do you find whether thereis path between 2 clocks?设计中有 1000 个 clock,你怀疑跨时钟的时序约束有问题,想找出哪些 clock 之间有 realpath,请问如何找?难度:2答案:check_timing或者写一个循环,report_tim
37、ing-clock_from -clock_to34)What are various statisticsavailable in IR-drop analysis reports?IR-drop 的分析报告里面都包含哪些内容?难度:2答案:至少包括各种 mode 下的 static 和 dynamic IR-sropreport,其中 drop 的容许范围可以参考厂家的意见function mode 下的 EM report 和 RJ report35)With respect to clock gate, whatare various issues you faced at vario
38、us stages in the physical design flow?在后端流程的每步中,如何处理门控时钟?难度:3答案:如果是用 latch+and/or 在组合成的 clock gatingcell,比较麻烦,以后估计不多见了,暫不讨论。TomPaul 提到的问题都很让人头痛,特别是做 CTS 时,如何处理那些个 latch 的 clkpin。Place 时,latch 和 and/or cell 一定要靠得很近。一般使用 ICG cell 时,place:使用 clock gating awareplacement 选项CTS:主要看工具的本领了,一般是希望在满足 setup 的前
39、提下,ICGcell 要尽量靠近 clock rootroute:除了 clock net 优先以外,不记得还有什么可做的了36)What is SSO? How to calculate theSSO in pad ring design?什么是 SSO,设计 PAD ring 时,如何计算 SSO?难度:3答案:sso ,即 simultaneous switchingouputs,即允许同时切换的信号 IO 的数量。多个信号 IO 同时切换时,因更多电流流过 pad ring,在 pad 电源 IO 的 bondingwire 及片外引线上的电感上,产生Ldi/dt 的压降。也即 ssn
40、,同时切换噪声。主要是会引起地弹,即 ground bounce。避免 sso 有很多方法。如增加供给 pad 用的电源 IO 数量,采用 doublebonding 或 triple bonding,采用 slew rate control 的 IO,避免把 pad 电源 IO 放在 corner 上(corner 处 bondingwire 引线最长,L 最大),等。主要还是采用增加 pad 用电源 IO 数量的办法,计算方法一般 foundry 会提供,一般是给每个信号PAD 一个 DF 值(还要根据 bondingwire 电感值做出选择),把自己用的所有信号 IO 的 DF 值加在一
41、起,能得出所需要的 POWER PAD 的数量。37)In building the timing constraints,do you need to constrain all IO ports? Can a single port have multi-clocked?How do you set delays for such ports? Can a clock port have multi-clockdefinition? How do you create clock for this port?写时序约束时,是否需要对所有的 IO 端口加约束?一个信号端口是否可以被多个时钟约
42、束?应该如何对这种端口设置 delay?一个时钟端口是否可以定义多个时钟?应该如何定义这些时钟?难度:2答案:CLOCK ports 不需要加,其他都要可以,set_input_delay -add_delay可以,create_clock -add38)What is purpose of lockup latch inscan chain? Does lockup latch always fix the problem of first question? Doeslockup latch clk pin connect to the clock of predecessor flop
43、or successor?scan chain 中插入 lockuplatch 的目的是什么?是不是 lockup latch 总能达到那个目的?lockuplatch 的 clk 端与前一个 flop 的 clock 相连,还是后一个 flop 的 clock 相连?难度:3答案:一般 scan 用的时钟树大部分是与 function 的共享,所以 scanchain 的前一段和后一段的 clock insertion delay 会不一样,因为 scan shift 速度很慢,不太用顾及 setup,但是要确保 hold。所以在前一个 FF 的 clock insertiondelay 小
44、,后一个大时,插入一个 lockup latch,使信号多保持半个周期,以满足后一个 FF 的 hold 要求。它们的时序关系是前 FF 时钟延迟 +1/2 scan 时钟周期 = 后 FF 时钟延迟+ 后 FF hold 要求当后 FF 时钟延迟太大时, lockuplatch 也解决不了 hold 违反的问题按此分析,lockuplatch 的 clk 端是和前一个 FF 的时钟相连的。39)How is scan DEF generated?scan DEF 是怎么生成的?难度:2答案:在第一次做完 scan chain stitch 后,让 DFTtool 输出一个 scan def4
45、0)What are pros/cons of using low Vt,high Vt cells?使用 low Vt 和 high Vt cell 的优缺点?难度:1答案:lvt cell 速度快,耗电高,静态电流大hvt cell 速度慢,静态电流小这是 timing 与 power 的 trade off41)How do you reduce standby (leakage)power? How do you reduce dynamic power?如何减少静态功耗?如何减少动态功耗?难度:3答案:老陈认为,这是最邪恶的一种提问方法!貌似简单,其实覆盖范围很广。leakage p
46、ower + dynamic power 不就是 total power 吗?那么这个问题可以换一个说法:如何减少功耗?这样可以从系统结构,算法,前端,一直说到后端,即可以罗列几个大的方向,也可以具体到每个细节,你也搞不清楚他想问的是那个方面。反过来说,如果他有意刁难你,就可以用这种问法,反正你答不全,到时就说你水平不够!我们就集中在后端的部分(加一小部分前端),而且是细节讨论楼上几位说得都对,总结一下静态功耗:非关键路径 HVT cell 替换coarse grain, fine grain, powershutdown减少 decap_cell散热降温动态功耗:降压power island
47、DVSF非关键路径 HVT cell 替换clock gatingmemory splitsignal gatingtransition time 约束减小高速信号的走线长度42)如何设计 PADring?How do you design PAD ring?如何设计 PAD ring?难度:3(又是一道比较邪恶的题目)答案:大的流程是:1)根据系统(其他芯片的)要求,芯片内部的 floorplan,决定信号 PAD 的位置2)计算出 power PAD 的个数,插入到信号 PAD 里面3)加其他的 PAD,比如 IO filler,powercut ,power on control,cor
48、ner PAD,ESD 等细节可以包括:1)如何计算 core power PAD:估算 corepower,再加 50%,算出电流,除以每个 core power IO的最大电流,就是大致的 PAD 个数。插入到信号 PAD ring 后,还要再计算 powerEM,防止一根电源线上的电流过大。2)如何计算 IO powerPAD:从信号 IO 的功耗算起,同时计算 SSO,取 2 个结果里面较大的3)在什么地方插入 powercut:不同的电压 core 电压和不同的 IO 电压之间,power island 之间,数字和模拟电源之间。4)power on control PAD,一段每个
49、 IOring 需要一个5)ESD 一般要加在每个不同的电源之间43)In hierarchical design flow,explain block level pin placement flow? What are parameters to decide?在 hierarchical 流程中,如何确定 block 的 pin(位置,金属层)?难度:3答案:在 top-down 流程中位置 :主要是看与该 block 相关的其它 block(如 ANALOG 等) 的 interface,一般相关的 PIN/PORT要比较近,同时也尽量不要使 PIN 被 block 内部的 memory(一般放在 block 的 boundary 处)等挡到金属层 :也要看相关的其它 block 的 PIN/PORT 所出的金属层, 尽量用一致的,同时不用 M7.M8 等一般用来走 power 的金属层,当然 M1 也不用encounter(ICC 也应该是同样的道理)用 flatten 的 trialroute 来决定 block pin 的位置和金属层。当然,你可以事先指定,也可以事后修改在 bottom-up