Design Compiler指南——设计综合过程

        在前面一章介绍完施加约束之后,接下来要做的工作就是将设计进行综合编译(compile),本文我们将主要讨论综合编译的过程。主要分为这样几个部分:

  • 优化的三个阶段及其特点
  • 编译的策略
  • 编译层次化的设计

一、优化的三个阶段

        这一节我们介绍Design Compiler进行优化的三个阶段:结构级、逻辑级以及门级,在不同的阶段,DC运用的方法和优化余地是不一样的,我们将对这几个阶段的特点和优化方法进行一个介绍,这里一起归纳一下,希望能加深认识。

        上图是这三个阶段的关系图,可以看到,结构级属于最高的抽象层次,当读入Verilog代码或者没有经过映射的db文件后,DC的优化从这个阶段层次开始,可以说,结构级是优化的最高层次,所以对DC来说,这个层次的综合可以称为高层次综合(High-Level Synthesis)。结构层的下一个优化阶段是逻辑级阶段,也是读入映射过的db文件的DC的初始优化阶段。再往下一个阶段是门级阶段,也是优化的最后阶段,这里所要作的工作主要就是GTECH到工艺库的映射。

1、结构级优化

        因为结构级是优化过程中层次最高的一级,因此它也是DC可以采用的优化方法最多的一级,它的主要优化方法如下图所示

1)DesignWare选择

        DW选择是结构级优化的一个很主要的特点,在这个阶段DC能够根据设计者施加的时序或者面积的约束在DW的不同实现方式中找到它认为最佳的实现方案。比如加法器的实现方式一共有如下几种

        其中DW Foundation需要有专门的license,而且使用之前还要设置综合库(synthetic library)。 

2)共享子表达式(Sub-Expressions)

        这里的子表达式主要是指数学表达式,比如下面这个例子,如果按照原来的语句综合,会包含6各加法器,但是如果表达式之间的公共项提取出来,便可以大大的减小面积,如下图

        如果要直接综合出共享后的电路,可以在编写RTL代码的时候强制指定共享项:

3)资源共享(Resource Sharing)

        资源共享的原理与共享子表达式类似,只不过这里指的所谓资源是一些HDL的运算符和表达式,比如加(+)、减(-)、乘(*)、除(/)以及大于(>)、大于等于(>=)、小于(<)、小于等于(<=)。比如给定一个语句

        DC会根据具体的约束条件综合出最符合要求的结构来。

4)运算符排序(Operator Reordering)

        对于下面这个表达式Z <= A + B + C + D(输出Z是施加了一定时序约束),DC最初是按照从左至右的顺序计算的,也就是说它最初的排序如下

        如果几个输入信号到达的时间相同,DC会通过运算符排序优化成下图的平衡的结构,减小延时:

        如果A信号较迟到达,则综合出的电路结构会如下 :

2、逻辑级优化

        在经过结构级优化之后,电路被转化成了工艺无关的GTECH库的形式,这级也称为逻辑级,对于逻辑级优化来说,只有一个方法,那就是——结构化 (structure)或者扁平化(flatten)。

1)结构化(structure)

        结构化是DC在逻辑级的默认的优化方法,它是指:使用电路的一些中间项构成一个多级的电路结构。如下图的电路一共有三级逻辑,下一级的输入是上一级的输出,使用这种优化方法一般情况下能综合出兼顾时序和面积的电路来。

        结构化电路的典型是奇偶校验电路。

2)扁平化(flatten)

        扁平化是将所有的组合逻辑打平成乘积项和(SOP)的两级结构,类似与可编程阵列逻辑(PAL)。使用这种结构的特点由于没有利用中间项,综合后电路面积将会变得很大,但是却不一定能取得较好的时序。

        扁平化结构的电路和设置扁平化的DC命令如下所示:

dc_shell > set_flatten true -effort low | medium | high

综合结构化和扁平化的特点,可以归纳如下:

        由于DC默认是用结构化的方式综合逻辑级电路,而且这种方式可以得到兼顾时序和面积的结果,因此我们可以先用这种(结构化)方式优化。在优化后的电路中找出关键路径,看看关键路径上有没有符合使用SOP电路的模块,再将这些方便使用SOP的模块set_flatten,以便取得最佳的效果。 

3、门级优化

        门级优化是优化的最后阶段,它所要完成的任务就是将GTECH的电路映射到最终的工艺库中,并且保证映射后的电路不违反设计规则(Design Rule)。

1)工艺映射

        工艺映射包括组合逻辑映射时序逻辑映射。组合逻辑映射是指DC使用工艺库中的各种门替换GTECH单元,并选择能实现相同逻辑的符合时序及面积要求的单元。

        时序逻辑映射的方法和组合逻辑相类似,也是出于速度和面积的考虑,尽量使用复杂的时序单元吸收一部分组合逻辑。 

 

2)设计规则检查(DRC)

        对于工艺库的单元而言,Foundry都指定了每个单元的工作条件的限制,比如最大电容(max_capacitance)等等,这些限制也可以称为设计规则(Design Rule),在设计规则限定的范围内,Foundry提供的参数才有实际的意义。比如一个单元允许的最大电容为5pf,而实际工作电路中出现的电容值为10pf,那么这时,便违反了设计规则,单元的参数也就不能确保是准确的了。

        因此,DC在作门级优化的时候,在映射的过程中也会检查电路的设计规则,一般的做法是在单元中插入buffer增加驱动能力,或者将小驱动的单元替换为大单元。设计规则检查分为两个过程——DRC I 和DRC II 。

        DRC I是指Design Compiler在不影响电路的时序和面积的前提下修正违反规则的一些单元,如果在这个前提下不能完全修正,则要进行下一步的检查,即DRC II,这一步的修正必然是以牺牲一部分时序和面积为代价的。

二、编译策略

        编译过程是指设计经过三个阶段的优化,最终形成门级网表的过程,在这一节里,我们主要就编译的策略,它包含如下几方面的内容——

  • 中断编译的方法
  • 从报告中检查时序,调整策略
  • 修正保持时间违反(Hold time violations)

1、中断编译的方法

        在DC-Tcl的界面下,当我们键入compile命令时,DC就开始了编译,也就是优化的过程。优化是在设计规则的条件下,运用不同的算法,综合最终出满足时序和面积的电路。优化首先是时序驱动(timing-driven)的一个过程,其次再是面积。如果找到了一个满足时序和面积等约束的电路,编译将会停止;如果通过种种编译仍不能满足时序,编译也会停止下来;另外,我们也可以人为的中断编译。

        人为中断编译的方法是键入Ctrl-C,经过一段时间的等待后(有可能时间会很长),优化过程暂停,并弹出如下菜单:

        这里有四个选项,设计者可以根据情况作出选择。

        DC在编译的过程中,会自动打印出一个报表,报告编译的总时间,设计的面积,关键路径的时序违反和总共时序违反情况,我们可以根据需要更改打印的列项目:

2、分析报告,调整策略

        一般情况下,我们先作一个默认的编译,这样一般可以取得既快又准确的结果,然后在编译完成后使用一些报告时序的命令,并分析它们的输出结果,使用的命令主要有

        从这些报告中,我们可以看到电路中是否有违反的约束,如果有,那么它是什么类型,还有电路中的最大负裕量(worst negative slack)是多少,等等。下面我们就几个常见的约束违反情况,谈谈纠正它的综合策略

1)较大的时序违例

        以下图为例

        从report_constraint –all这个命令的报告可以看出,需要到达的时间是1.20ns,而实际到达为2.84ns,违反了1.64ns。之所以判断它是一个较大时序违反的情况,并不是因为1.64这个绝对值很大,而是相比较需要时间而言,1.64是一个较大的值。一般而言,如果电路中的最大负裕量(简称WNS)所占时钟周期的15%以上的话,可以认为电路存在较大的时序违反

      确认存在较大时序违反之后,下一步就是找出原因,消除违反情况。可供参考的步骤有下面几种:

  1. 检查约束条件,看是否有疏漏或错误
  2. 检查模块划分,看组合逻辑是否穿过多个模块
  3. 重新编译优化后的网表
  4. 修改RTL代码   

重新编译(Re-Compile)

        当重新读入映射后的网表进行重新编译时,DC会自动将门级的网表重新返回到GTECH的结构,相当于逻辑级。然后分别进行逻辑级和门级的优化,但是同时也可以进行DesignWare的替换。

        如果设计者仅仅将映射后的网表拿来再做一次compile,编译后的结果并不会不一定会比原来的好,无非把以前做过的优化再跑一遍。因此,重新编译之前会改变一些参数,如——改变设计约束、改变set_structure和set_flatten参数以及改变编译的map_effort

改变map_effort重新编译

        对设计进行编译的时候,有三种编译级别可以选择,它们分别时低级、中级和高级。

dc_shell > compile -map_effort low | medium | high

        不同的级别编译要求的编译时间和编译结果都各不相同,compile –map_effort low编译时间最短,但是结果不一定好,它一般用于设计预估(Design Exploration),不用在重新编译环节。
compile –map_effort medium是DC默认的编译级别,大多能在一定的时间内得到较为满意的结果。这也是我们推荐的初始编译级别。

        compile –map_effort high 编译的过程中会使用前面的级别中没有的算法,因此它所要求的时间是最多的,结果也是相对最好的。这种级别一般用在重新编译的阶段。

修改RTL代码

        修改源代码所能取得的效果是最直接的,同时也是代价最高的。修改代码后,DC会从最上层的结构级开始优化,前面也讨论过,越上层次的优化方法越多。所以通常这样得到的结果也越满意。但是,修改代码也不一定放之四海皆准的方法,因此并不是所有的设计我们都能获得源代码,同时也不是可以随便修改的。

2)较小的时序违例

        以下图为例

        从上图看出,相比较1.20的允许路径延时,0.10的负最大裕量(WNS)是比较小的(小于15%),而且已经认定了约束和模块划分都是正确的,那么应该怎样修复这个错误呢?

        这里主要讲一下Incremental Mapping:

dc_shell > compile -incremental_mapping

        这个开关告诉DC,在重新编译的时候不需要把网表返回到GTECH结构,因此也不需要作逻辑级优化,速度也较一般的编译更省时间。这里DC所要作的是进行门级单元的替换,即在不违反设计规则的情况下用延时小的单元替换延时较大的单元。另外,如果读入的是db格式的网表,在这个阶段也可以进行DesignWare的替换。

        如果要同时优化多条路径,需要使用另外一个命令——set_critical_range。这个命令设置的critical_range是以WNS的值为基准的,优化的是和这个值的绝对值差设置值的那些路径。因此,如果设置值为0,那么就仅仅优化一条关键路径。

dc_shell > set_critical_range 2 [current_design]

3)设计规则违反

        有些时候的时序违反是由于设计规则违反引起的,比如说一个单元的扇出(fanout)过大,导致它的transition time的时间迅速增加。对于这种情况,我们可以通过

dc_shell > report_net -connections -verbose

dc_shell > report_timing -net

        两个命令审查连线的连接和负载情况。

        要修正设计规则的错误,可以使用一个编译的开关:

dc_shell > compile -only_design_rule

        如下面这个例子,为了满足最大电容的规则,在A端口的内部加上了一个buffer,用于缓冲N路径对A的负载。

3、修正保持时间违例

        一个时序电路要想正常工作,除了必须满足建立时间要求之外,也需要满足保持时间要求。虽然保持时间检查和建立时间检查是同样重要的,但是我们在实际综合的过程中却不是把它们同时考虑,而是更多的把保持时间的检查放到布局后。这是因为

  • 时钟偏移必须要到布局完成后才能得到准确值
  • 修正保持时间的通常做法是插入buffer,而这可能会增加建立时间违反的可能性,并且增大了组合电路的面积
  • 保持时间检查用的一般都是电路工作的最佳条件,而在这个条件下,连线延时往往是被忽略的,连线延时也是必须在布局后才准确。

        如果确定要同时作建立和保持时间检查,那么在施加电路约束的时候要加入相应的开关,如:

        以及设置各自的工艺库—— 

        

        默认情况下,DC不修正保持时间的违反。如果确定要作修正,需要先设置一个变量再作检查 :

dc_shell > set_fix_hold [all clocks]

dc_shell > compile -only_design_rule

        加上only_design_rule的开关后,编译过程中仅仅更换单元大小,并增加buffer,以便修正设计规则违反和保持时间违反。

三、层次化设计的编译

        一个层次化设计的编译过程包含两个阶段:1、将所有的子模块映射到门级,2、优化。

          在一个层次化的设计中,我们可能会遇到下面这种情况

      

        上图中,被综合的模块中D_design中含有三个子模块U1、U2和U3,其中U1和U3都是由模块Ades例化而来,这里的Ades称为多次例化的模块。对于这样一个设计,在compile之前使用check_design作检查的时候会报一个warning,即设计中存在多次例化的模块(multiple instantiations),如果在这种情况下,我们不考虑多次例化的模块(Ades),那么在继续的compile时候程序会终止退出。因此,必须对它进行处理,这里我们介绍两种方法——uniquify和compile + dont_touch。 

1、uniquify

        使用uniquify,DC会对每个例化的模块作一份拷贝,然后对它们分别取一个名字,即把不同的例化模块当作不同的两个模块处理。

        注意看上图,U1和U3两个模块的设计名分别由原来的Ades变成了Ades_0和Ades_1,因此在编译时,DC会将它们当作两个不同的模块,这样就可以根据它们不同的周围环境作优化。

        使用uniquify的具体实现方法如下

 dc_shell > uniquify

dc_shell > compile

2、compile + dont_touch

        这种方法先将多次例化的模块作单独的约束和编译,然后在整合到上一级模块的过程中将它的属性设置为dont_touch,再编译。

        上图中,U1和U3两个模块的设计名都没有变化,只是在编译D_design之前先将Ades编译一次。这样U1和U3实际上是一模一样的模块。

        compile+dont_touch的实现方法如下

        这里的约束文件有两个,一个是Ades的Aconstraints.tcl,另一个是D_design的Dconstraints.tcl,并且在source后一个约束文件之前要对编译过的Ades设置成dont_touch。
在设置了dont_touch属性之后,编译D_design的时候就会忽略Ades,这样有好处也有坏处,好处是可以保护模块不被修改,但是这样同时也限制了DC对U1和U3的进一步的优化。 

3、uniquify Vs compile + dont_touch

        通过对上述两种方法的介绍,我们不难看出它们各自的优缺点——

        compile+dont_touch由于只需要对多次例化的模块编译一次,因此可以减少整个设计的编译时间,也可以减少内存的使用量。在多次例化的模块很复杂并且工作站的硬件条件有限的情况下,使用这种方法的优越性的比较明显的。还有,如果这个Ades是一个第三方提供的硬核(hard-core),那么我们也只能使用这种方法。

        使用这种方法的缺陷也是显而易见的:由于顶层模块在编译的时候Ades设置了dont_touch,这就妨碍了DC针对Ades的各个实例周围环境的不同的进一步优化,从而使得结果不能真实的反映各个实例周围的环境变化。

        uniquify由于把各个多例化模块作为独立的模块来看,因此DC可以分别针对它们作出更好的优化,从而得到的结果也是比较理想的。缺点就是编译的时间稍微较长,但是对于一些不大的模块来说,这些是可以忽略的。        

        正因为uniquify可以综合出更好的结果,所以如果一般推荐使用uniquify解决多例化模块的综合问题

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

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

相关文章

How to find Material based on Sales Organization and Distribution Channel

Fetch data from Database View /BEV1/RBEA_V Fields: VKORG - Sales Organization VTWEG - Distribution Channel MATNR - Material Number 转载于:https://www.cnblogs.com/JulietLV/p/7436028.html

iOS开发 iOS10兼容访问http

添加NSAppTransportSecurity的字典会自动变成 AppTransportSecurity再添加 allow Arbitary Loads Boolean YES转载于:https://www.cnblogs.com/diweinan/p/6233052.html

django 利用PIL 保存图片

在使用django时不知道怎么保存图片&#xff0c;又不想用它的form &#xff0c;在网上找了许久&#xff0c;终于找到个解决方案&#xff0c;利用PIL.image 将POST上来的图片保存到media目录下&#xff0c;然后再修改models from PIL import Imagescreen_name request.POST.get(…

图像转灰度图

MyYuanLaiPic imread(e:/image/matlab/darkMouse.jpg);%读取RGB格式的图像 MyFirstGrayPic rgb2gray(MyYuanLaiPic);%用已有的函数进行RGB到灰度图像的转换 [rows , cols , colors] size(MyYuanLaiPic);%得到原来图像的矩阵的参数 MidGrayPic zeros(rows , cols);…

Design Compiler指南——后综合过程

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

web worker原理 SSE原理

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

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

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

afx_msg函数意思

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

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

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

Visual computing——概述

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

推荐!手把手教你使用Git

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

I2C协议学习

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

ajax的简单介绍

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

DM365 color space

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

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

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

P1136 迎接仪式

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

云服务器 VNC 远程连接

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

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

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

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

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

MFc消息映射机制理解

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