Design Compiler指南——后综合过程

       本文我们着重讨论使用Design Compiler综合大型设计时要注意的一些问题,比如怎样调整综合方法,出现约束违反后怎样修正,怎样给不同的子模块作时序和负载预算,以及给整个设计在具体综合之前先作一个预估(Design Exploration)等等。

一、编译一个大型设计

        对于一个大型设计而言,由于模块规模的扩大,编译时间也相应的变长,要长达几个小时甚至超过一天,这样的时间对于讲究”Time to market”的设计者是比较重要的。因此就更加注重编译的技巧,本节我们主要讨论下面三个方面的技巧——

  • 编译层次化设计的技巧
  • 第二次(Second-pass)编译技巧
  • characterize

1、层次化编译

        对一个大型设计来讲,有两种层次化编译技巧——自上而下(Top-down)以及自下而上(Bottom-up)。自上而下的方法是指将整个设计一次性读入,施加顶层约束后直接进行编译;自下而上的方法则先一个个编译比较底层的子模块,给它们加入时序和负载预算,然后在顶层将各个子模块整合起来。

1)自上而下(Top-down)

        上图是自上而下编译方法的具体步骤,可以看出假如顶层设计是RISC_CORE这个模块,则先直接将它读入,然后处理多次例化的模块,施加顶层约束后就直接编译。它的代码基本上如下所示 

        自上而下的编译方法有一个明显的优点,即它使得设计者无需考虑各个子模块之间的依赖关系,也就不需要制定子模块之间的时序和负载预算,这一切都由Design Compiler自动考虑。另外,使用这种方法也使得设计者编写脚本变得简单,维护起来也比较方便。 

        在介绍自上而下的编译方法的时候,我们还要顺便提及DC编译的一种模式——Simple Compile Mode(简单编译模式)。这种模式在设计没有严格的约束的情况下能取得较快的编译速度,另外多例化模块的处理也自动进行。下面是RISC_CORE的Simple Compile Mode脚本:

        可见,使用这种模式省去了uniquify这句,同时编译之前要先设置一个变量set_simple_comile_mod。 

2)自下而上(Bottom-Up)

        自下而上的编译方法其步骤如下图所示        

        和前一种方法不同,自下而上的编译方法需要先单独编译各个子模块,在编译子模块的同时要考虑到与其它模块之间的关系,看是否满足约束,然后再读入顶层文件,施加顶层约束,顶层编译完成之后还必须看顶层约束是否满足。下面是单个模块编译的脚本:

        下面是顶层模块编译脚本:

         从上面的过程不难看出Bottom-Up方法的一些特点:

        优点是利用了”分而治之”的策略,这对于大型的不可能一次编译的设计是十分有用的;另外它也摆脱了Top-down方法的对工作站硬件条件的限制,使得大型设计也能在一般的机器上编译完成。

        缺点是实现步骤比较多,尤其对各个模块之间的时序和负载预算要求很高,如果不注意会很容易造成违反。

        综合上述两种方法,我们可以做一个小结:对于规模不算太大的设计,我们推荐使用Top-down的编译方法,这样可以在不长的时间内得到满意的结果。对于其他需要Bottom-Up的设计,我们必须确认时序负载预算能很好的反映实际的工作情况。

2、第二次(Second-pass)编译

         第二阶段(Second-Pass)编译是指当第一阶段(First-Pass)编译出现违反之后,分析违反原因从而重新编译的过程,对应的还有第零(Zero-Pass)阶段编译。

        关于第二阶段编译,前面的编译策略中有比较详细的介绍,上一节介绍的Top-down的第二阶段编译的步骤主要有

  • 检查模块划分
  • 检查约束脚本
  • 用更高的map_effort编译——compile –inc –map_effort high

        这一节中,我们主要讨论用Bottom-Up方法编译后出现违反的情况

1)重新编译顶层模块

        这种方法是在Bottom-Up出现顶层模块时序违反的情况下采用的,具体的命令如下:

dc_shell > compile  -top

        这个命令仅仅修正顶层子模块之间的路径,因此速度会比compile –inc更快。

2)修正设计预算(Design Budget)

        设计预算对于Bottom-Up的方法来说是至关重要的,在预算的时候,我们都尽量能收紧(Tighten)每一个子模块时序、负载和驱动的预算,例如我们在最初介绍设计预算的时候,举的例子是给本模块留整条路径的40%,因此模块之间能够空出20%的裕量。在编译子模块的时候能尽量做到满足预算的要求。这样最后整合顶层设计的时候就不会出现大的问题。

        如果出现问题了,一个方法就是调整预算脚本。看看施加的约束是否与综合后的电路相吻合。下一节,我们将介绍调整设计预算的一个很有用的命令——characterize。

3、characterize

        Characterize这个命令用于映射到门级的子模块,作用是计算出该子模块周围的环境(延时、负载和驱动),并将得到的实际值作为该子模块的新的约束。如下图一个例子

        由于整个设计已经映射到了门级,因此这个例子可以计算出子模块U2周围的输入输出延时、输入驱动和输出负载的实际值。然后将这些实际值施加在U2模块中,作为U2的新的约束。这种方法有点类似于给U2的周围照了一张照片。U2施加了新的约束之后,就可以在这个基础上做一次高级别的编译。

        通过write_script命令,我们可以看到characterize之后到底照下了哪些信息

        characterize给我们提供了一种比较好的第二次编译的方法,加入一个子模块所占的延时很重,就可以在保持其他模块不动的情况下将这个子模块重新编译一次,当然重新编译可以从HDL代码开始,下面是一个例子:

        这个例子和前一个例子的不同在于,它没用compile –inc high,而是直接将它从内存中删除,读入它的源文件重新编译,这样可以取得较上一种方法更好的结果。

        characterize无疑向我们提供一种较好的子模块二次编译方法,但是同时它也有一定的局限性,在使用的时候务必要注意——

  1. 它要求所有的模块必须映射到门级,这是使用characterize的一个前提。
  2. characterize只能一次对一个子模块使用,即给U2作characterize的时候U1和U3模块必须保持不变,否则U2得到的环境就不是确定的值。
  3. characterize将外界环境直接作为它的约束,这使得它和其他的子模块之间不存在任何裕量(margin),这些裕量全部被该子模块吸收。

二、设计预估

        设计预估(Design Exploration)是指在整个设计的RTL代码尚处在验证的阶段就对设计进行预先综合的过程,在这一节里,我们将讨论相比瀑布式的设计流程,设计预估的优点以及设计预估的流程,这些内容可能更多的不是介绍Design Compiler的使用,而是设计方法学问题。

1、为什么要设计预估

        

        上图左边是一个传统的设计流程,这个流程先作HDL代码的编写,在代码仿真通过之后作设计综合,然后插入扫描单元,通过以后作后端的物理设计,直到最后交给Foundry流片。这种流程之所以称为瀑布式的是因为后面的步骤都必须等前一个步骤完成之后才能进行。

        稍加分析,不难发现这种流程有很大的危险性,从上图的右半部分可以看到,从综合到后端设计,每一个步骤都不可能不产生错误,如综合的时候碰到RTL代码引起的时序违反,加入扫描单元后发现测试覆盖率很低,后端布线由于过于拥挤而布不通,等等。这些错误如果可以通过工具的技巧修复还好,如果不能修复,就必须要返回到前面的步骤直至RTL代码的修改,这样做的代价是随着从前到后迅速增加的 。

        因此,要提高设计的效率,就必须在很早的情况下就发现问题并解决它,越是拖到后面,则越不划算。最理想的情况就是在编写RTL代码的时候就万无一失,并且在这个时候就能估算出最后的芯片面积和运行速度,以及内部长线的延时。这种思想就要进行设计预估的初衷。

        下面是引入设计预估之后的设计流程图

        在这个流程中,前端逻辑设计与后端物理设计同时进行,在编写code的同时,对芯片的初步布局和布线先作一个规划,然后检查工艺库中提供的连线负载模型(WLM),根据实际需要创建新的负载模型。而code在仿真的同时也可以作一个设计规划,在设计规划的时候调用新的WLM,以便得出更加真实的结果。

        在设计预估做完,code仿真完成之后,就可以正式编译设计的主要模块,并将它们整合到顶层模块中去。同时对这些模块进行布局重新创建更加真实的WLM,直到最后的分析直至流片。

        可以看到这个流程是一个前端与后端同时进行的过程,也是一个不断融合的过程。前端的设计者总是想尽早知道模块在实际的芯片中的位置,以便得到准确的WLM。这样才能尽量把错误提前找出来,避免留到后面的高成本。

2、设计预估的目标

        在上面的这个流程中,设计预估是与code的功能验证平行进行的,而不是等到功能验证完成后再作。每当code的改动足以影响系统性能的时候,我们都需要进行一次设计预估。

        一般说来,设计预估有下面几个目标——

  • 验证代码的可综合性:这是设计预估的一个基本功能,不能综合的代码对后面的一切步骤都只能是空谈。
  • 控制代码的时序违反在一定的范围(10-15%):预估后的网表的时序违反如果超过这个范围就可以即使更改代码,保证在正式综合的时候能通过调整综合参数达到时序要求,而不再该代码。
  • 验证施加的约束的真实性和充分性:设计约束不是设计者凭空想象出来的,他需要通过多次的设计预估,并对得到的网表进行分析,从而对施加的约束不断修正,让他能足够反映真实情况,并且不漏掉容易忽视的约束条件。
  • 鉴别时序的特殊情况:大型设计中难免会有一些DC不能综合或者无需综合的路径,设计预估需要把这些路径找到。
  • 鉴别模块划分问题:模块划分可以在编写code的时候进行,也可以在DC的约束脚本中用group/ungroup完成,设计预估需要得到一个较好的设计划分。
  • 鉴别测试问题:测试问题我们再DFT课程中详细介绍。
  • 保证WLM的合理:WLM是DC处理连线延时的依据之一,合理的WLM可以保证时序准确性。

3、设计预估的流程

        上面的设计预估流程可以看出设计预估包括——读入HDL代码,施加约束,加入扫描链,分析综合结果,根据初始化布局和创建的新WLM分析时序等等。每当其中一个步骤出现大的错误,都需要修改代码。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web worker原理 SSE原理

第一部分 什么是 web worker? 我们一直强调JavaScript是单线程的,但是web worker的出现使得JavaScript可以在多线程上跑,只是web worker本身适合用于一些复杂的、耗费cpu的运算,不能操作window、document、parent对象&#xff0c…

如何寻回xp盘符丢失的数据

分区丢失是比较常见的数据恢复案例,需要注意,分区丢失后不要再重建新的分区。保护好资料丢失现场,可以最大程度的恢复出资料。具体的恢复方法看正文了解。 工具/软件:星空数据恢复软件 步骤1:先百度搜索并下载程序打开…

afx_msg函数意思

应用程序框架产生的消息映射函数 例如:afx_msg void OnBnClickedButton1(); 其中 afx_msg为消息标志,它向系统声明:有消息映射到函数实现体; 而在map宏定义中,就有具体消息和此函数的映射定义(可以是自定义…

文件得编码和文件名的编码是不一样的

1.新知识,通过文件后坠名的编码判断文件类型,可以有效的防止脚本文件伪装为正常得文件。 2.拦截器和过滤器。 过滤器只能够在http请求和回复的时候进行处理。 但是拦截器可以在很多地方拦截,例如程序抛异常等都可以捕获的到。还可以进行权限得…

Visual computing——概述

Visual Computing(视觉计算)是所有处理二维图像和三维模型的计算机科学学科的总称,即计算机图形学、图像处理、可视化、计算机视觉、虚拟和增强现实、视频处理,但也包括模式识别、人机交互、机器学习等方面。核心挑战是视觉信息&a…

推荐!手把手教你使用Git

一:Git是什么? Git是目前世界上最先进的分布式版本控制系统。 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑&#xff0…

I2C协议学习

I2C Bus(Inter-Integrated Circuit Bus) 最早是由Philips半导体(现被NXP收购)开发的两线式串行总线,常用于微控制器与外设之间的连接。 一、概述 以下是 I2C 总线的一些特性: 只需要两条总线;一条串行数据线 (SDA) 和…

ajax的简单介绍

响应主体,就是服务器给我们返回的结果内容(浏览器里的responsive) 请求主体,是我们给服务器的数据 输入域名发起一次请求,得到的可能是标签,标签可能还要在发一次请求 post怎么发请求:form表单 …

DM365 color space

YUV的几种格式 420P:420P数据的存放方式一般是先存放Y,然后存放U,最后存放V的数据,每一个像素使用12bits(1.5BYTE)保存。 422P:422P数据的存放方式也是先存放Y,然后存放U,最后存放V的数据&…

JavaScript 标准参考教程-阅读总结(三)

1、DOM模型 DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。 1)do…

P1136 迎接仪式

P1136 迎接仪式 题目描述 LHX教主要来X市指导OI学习工作了。为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大字。一旁的Orzer依次摆出“欢迎欢迎欢迎欢迎……”的大字,但是领队突然…

云服务器 VNC 远程连接

此服务器买来是为了搭建IC EDA云的,因此选用的是centOS 6的环境,对各EDA软件兼容较好。本人手头拮据,因此买的是腾讯云活动期间的云服务器,只能说够用吧。 一、桌面安装 在云服务器控制台登陆上远程主机,依次执行下列…

Python自动化测试框架有哪些?

作者 | KITTY GUPTA 译者 | 张健欣 令开发者万分高兴的是,开发自己的测试框架的日子终于结束了。以前,开发团队接手一个项目并开始开发时,除了项目模块的实际开发之外,他们不得不为这个项目构建一个自动化测试框架。一个测试框架应…

面试题——4种数组去重的方法

数组去重或者其衍生作为笔试题或者机试题出现的几率也是很大的,写出的方法越多,则让面试官觉得你思维越开阔,那么成功的几率当然就大了。 废话不多说,下面来说说下面我整理的4中数组去重的方法 方法一: findInArr方法s…

MFc消息映射机制理解

何谓消息、消息处理函数、消息映射?消息简单的说就是指通过输入设备向程序发出指令要执行某个操作。具体的某个操作是你的一系列代码。称为消息处理函数。在SDK中消息其实非常容易理解,当窗口建立后便会有一个函数(窗口处理函数)开…

Effective C++ 条款11:在operator=中处理自我赋值

”自我赋值”发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w w; // 赋值给自己 a[i] a[j]; // 潜在的自我赋值 *px *py; // 潜在的自我赋值class Base { ... }; class Derived: public Base { ... }; void doS…

Demosaic算法学习

一、概述 由于成本和面积等因素的限定,CMOS图像传感器在成像时,感光面阵列前通常会有CFA (color filter array),CFA过滤不同频段的光,因此,Sensor的输出的RAW数据信号包含了3个通道的信息。 CFA的排列方式一般有以下几种: 现在应用最广泛的是Bayer CFA。…

Sql Server中查询当天,最近三天,本周,本月,最近一个月,本季度的数据的sql语句...

--当天&#xff1a;select * from T_news where datediff(day,addtime,getdate())0--最近三天&#xff1a;select * from T_news where datediff(day,addtime,getdate())< 2 and datediff(day,addtime,getdate())> 0--本周&#xff1a;select * from T_news WHERE (DATEP…

linux设备驱动归纳总结(五):3.操作硬件——IO静态映射【转】

本文转载自&#xff1a;http://blog.chinaunix.net/uid-25014876-id-83299.html linux设备驱动归纳总结&#xff08;五&#xff09;&#xff1a;3.操作硬件——IO静态映射 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 有时候会觉…

UML中关联,聚合,组合的区别及C++实现

类间关系 在类图中&#xff0c;除了需要描述单独的类的名称、属性和操作外&#xff0c;我们还需要描述类之间的联系&#xff0c;因为没有类是单独存在的&#xff0c;它们通常需要和别的类协作&#xff0c;创造比单独工作更大的语义。在UML类图中&#xff0c;关系用类框之间的连…