下冰雹 · 2023年10月19日

芯片中的层次化的设计(hierarchy design)

层次化设计适当下非常流行的设计思路,随着芯片的规模越来越大,fullchip的数据量和复杂度和过去已经不能同日而语了,无论是工具的runtime还是QoR,直接完成full-chip的工作越来越不现实。所以,在这里,就需要引入 层次化的设计(hierarchy design) 的概念。

从芯片的规划开始,层次化的理念贯穿整个设计流程,下面的各个设计方面都会受到不同程度的影响

RTL
UPF
verification
DFT
Timing constraint
synthesis
EC
layout
STA
stream-out
layout verification
Power analysis

一个项目的开始,需要根据实际的需要确定层次,这主要是基于模块功能规模,一起来看下面这个实例

image.png

从上边这个示例可以看到

主控:CPU和core
辅助(子功能模块):soc-subsystem
总线:AHB_BUS
中心控制:clock/power/reset
额外(上述框图并未体现):PHY以及各种接口(MIPI,DDR,USB等等)
IO:由于使用的层级都是芯片的inout,通常都放在顶层
存储单元:例化在各个模块的内部,提供给模块自身使用

根据这种结构,在做partition的分割的时候,会按照真实的需求来定义,

类别

partition

独立约束(UPF/SDC etc.)

image.png

可以看出,从整个SOC的设计当中,主要的partition分割是两种,top和none-top。理论上讲,所有的none-top,互相之间都没有依赖关系(dependency),除非它本身也是一个小top,具体可见下面的示例:

image.png

这里的top和sub-top_1就是所谓的hierarchy design,在一个芯片里边,top通常只有一个,但是可能会有多个sub-top,甚至是sub-sub-top,这取决于芯片层次化的深度和芯片的复杂度。可以预见,层次化越多,单个partition的复杂度会降低,但是给top的partition划分带来了更多的工作量,譬如

UPF
SDC
physical partition boundary

还有一个影响就是dependency,所有的sub-top,都和top一样,在后端实现的时候(synthesis/layout),任何的top的后端工作,都需要sub partition的支持,譬如上图,要想开始sub-top1的synthesis,就必须先要完成 sub_par_1_1,sub_par_1_2,sub_par_1_3的综合工作。

这就是runtime的瓶颈。实际项目中,为了减少这方面的影响,通常都会有一些变通的手段,来快速支持顶层设计,这个小技巧的具体细节,也会在本系列文章里边提及。

业界里边还有一种更为前卫的partition的设计,被称为abut-partition的设计,简单的讲就是没有top的概念,所有的partition都是完全贴合的,譬如下面这个floorplan的partition的框图

image.png

这种架构更为简练,所有的设计全部都推到了partition,从物理实现上来讲,top level已经不包含任何的leaf cell,所有的存在就是一些连线关系、PG、terminal以及co-design routing了,这种极简的abut设计有其优越性,也有一些限制。

一个完整的层次化设计,在代码设计阶段,就应该树立层次化的理念。这里边主要由以下几个考量

简化大规模设计的必经之路
后端实现的真实需求
验证和设计的一致性
相关配套、支持文件的参照点(SDC、UPF等等)

从架构入手,合理分布RTL的层次结构,让整个设计看起来张弛有道。这个思路体现如下

640.gif

前端设计人员按照下面的思路过程来设计代码

  1. 完成inst1的模块代码设计
  2. 完成inst1的内部连线
  3. 完成inst2的模块代码设计
  4. 完成inst2的内部连线
  5. 完成top-level的模块代码设计
  6. 完成top-level的连线

可以看到,这里边涉及了三个部分的设计

  1. inst1
  2. inst2
  3. top-level

通常来讲,合理的分配各个模块可以加速full-chip的收敛。从上面的例子可以看出,top-level的东西比较简单,只有一个控制逻辑和PAD,主要的功能都在子模块里边,这样的好处是非常明显的

  1. 子模块的实际内容多,但是总体规模不会很大,综合和版图的可控性会很好
  2. 相互关联密切的功能IP封装在一个模块里,有利于时序收敛和后端工具优化
  3. top-level的主要用途就是穿线,以及中心控制和PAD等等,有利于整体功能布局的规划,主要精力要放到interface的时序上,以及可绕通性。

每一个模块都有一套自己独立的文件结构,譬如inst1对应的是design1,整个design1的文件架构类似如下:

image.png

有了这些文件,design1的综合就可以开始了。综合的流程通常比较简单,这里不做过多的讨论,基本流程可以参见下面的列表

  1. HDL analysis 和 elaboration
  2. read_sdc和read_upf 以及一些基础配置
  3. 运行compile_ultra和DFT insertion
  4. 创建Block Abstraction view
  5. 生成DDC和网表

重要的第四步时一定要执行的,这里生成了后面层次化设计的重要信息。

对应的,这里也列一下inst2(design2)的文件目录结构

image.png

使用综合器,分别可以得到下面的文件

  1. design1.ddc 和 design1.v
  2. design2.ddc 和 design1.v

基于不同的DCT/DCG环境,可以开始根植于如下目录结构的顶层综合

image.png

顶层综合的思路会有一些不同,具体流程如下

  1. 配置block implementation的状态
  2. 读入底层带有Block Abstraction的DDC(不要读入子模块netlist,会导致非常多的困惑),工具回显如下例

image.png

  1. HDL analysis 只分析top-level的verilog,譬如:top_ctrl_design.v、PAD_design.v 、designFC.v
  2. elaboration的时候,一定要注意一下子模块的链接状态,保证模块信息都可以被正确挂载进来
  3. 在保证link无误的情况下,读入designFC.sdc和designFC.upf,运行compile_ultra和DFT insertion
  4. 生成DDC和网表,完成top-level的综合

对应的,在做层次化的设计的时候, 需要注意下面的事项:

  • 调用底层模块的时候,一定要使用带有block Abstraction的DDC,DDC里边包含了block的
  • 时序约束信息
  • UPF信息
  • 时钟结构信息
  • 边界时序信息
  • top-level的UPF只有顶层的low power需求
  • 顶层的LS、ISOLATION的需求,如果被约束的cell在顶层
  • 顶层和block的PG连接关系
  • top-level的SDC包含了整个top-level和block-level的时序约束
  • 顶层的SDC一定要和block的SDC,在block级别呈现出高度的一致性,譬如纯粹block 内部的MCP、false path等等
  • 如果时钟的源头在顶层,block级别的clock无需二次声明,譬如下面示例
    image.png

在design1/desing2综合的时候,分别在各自的sdc里边定义pclk,如果把视角放到顶层,那么画风是这样的

image.png

可以看到,从toplevel来看的话,以前的design1/design2的pclk,其实都是从top-level的pll驱动的,在top-level构建SDC的时候,只需要生命pll的clock就可以了(Pll_clk),剩下的就交给工具自动衍生。

写到这里,相信读者们对层次化设计流程有一个比较具体的了解了。

作者:艾思后端设计
文章来源:艾思后端实现

推荐阅读

更多IC设计干货请关注IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
11508
内容数
1227
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息