(四)RTL级低功耗设计

前面介绍了系统级的低功耗设计,换句话说就是在系统级降低功耗可以考虑的方面。系统级的低功耗设计,主要是由系统级设计、具有丰富经验的人员实现,虽然还轮不到我们设计,我们了解一下还是比较好的。我们前端设计人员的重点不在系统级设计上面,而是在RTL级(及综合)上面。下面我们就来介绍RTL编码与逻辑综合的低功耗设计,重点是门控时钟操作数隔离技术。今天主要是讲解操作数和一些常见的方法;门控时钟由于内容比较多,所以写在后面。

  (1)并行与流水的选择

  对于某一个功能模块,我们可以通过并行的方式进行实现,也可以通过流水线的方式进行实现,这两种方法都是面积换速度,不过在一定的场合下可以降低功耗,需要灵活应用,下面就简要地介绍一下这两种方法(的使用)。

  ·并行处理常用于数字信号处理部分。采用并行处理,可以降低系统工作频率,从而可能降低功耗。例如下图中:

                 

用两个乘法器来取代原设计中的一个乘法器。这样,时钟频率可以降低,系统的整体功耗会降低。采用这种方法,要在增加的面积与节省的功耗之间进行权衡。

  ·流水线技术可以将一个较长的组合路径分成M级流水线。路径长度缩短为原始路径长度的1 /M。这样,一个时钟周期内充/放电电容变为C/M。如果在加入流水线之后,时钟速度不变,则在一个周期内,只需要对C/M进行充/放电,而不是原来对C进行充/放电。因此,在相同的速度要求下,可以采用较低的电源电压来驱动系统。这样,系统的整体功耗可能会降低。例如对于下面的流水线设计:

                     

 假设在一个设计中,关键路径是一个32bit X 32bit的乘法器。假设该乘法器的整体电容为C,工作频率为f。

  ->不加流水线时,要达到此工作频率,工作电压应该为V。

  ->当采用流水线方式时,该路径被分成两部分。对于每一部分,整体电容变为C/2。这样,如果要达到原来的工作频率f,工作电压可以降为βV,这里β<1.  因此,整个系统可以工作在βV电压下,整体功耗变为原来的β^2倍,即:

                                  

 

 

  (2)资源共享与状态编码

  对于设计比较多算术运算的设计,如果有同样的操作在多处使用,那我们就可以避免相应的运算逻辑在多个位置重复出现。例如下面是没有进行共享资源的代码:

             

进行资源共享后的代码如下所示:

             

上述代码中,在各分支中只使用一个比较器和一个算术比较器就可以实现相同的功能,因此极大地减少了功耗。

  此外,对于一些变化非常频繁的信号,我们利用数据编码来降低开关活动(例如,用格雷码比用二进制码翻转更少,功耗更低)。

 

 

  (3)操作数隔离

下面我们重点介绍另外一种常用的方法——操作数隔离(operand isolation,简称OI)的方法。

①操作数隔离的原理

我们先来看一个电路,如下所示:

                   

上面的电路图中,当SEL_0≠1,SEL_1≠0时,加法器Add_0的运算结果不能通过mux_0和mux_1到达寄存器reg_0的输入端口,也就是说寄存器reg_0将不会保存加法器Add_0的运算结果,这就意味着加法器Add_0的运算是不必要的。为了节省功耗,我们可以用操作数分离的方法,在某些条件下,使加法器不工作,保持静态,进行操作隔离之后的电路如下所示:

                 

因此,操作数隔离的原理就是:如果在某一段时间内,数据通路的输出是无用的,则将它的输入置成个固定值,这样,数据通路部分没有翻转,功耗就会降低。  

  下面我们再举一个例子,对于下面的电路:

                       

上图所示的乘法器中,如果知道乘法操作延迟超过半个时钟周期,则将乘法器的输出反相时钟进行操作,可以保证在时钟前半周期乘法器的输出不会导致加法器的翻转。这就是操作数隔离技术的基本思想。不过需要注意的是,采用这种方法,会增加面积,并影响到DFT,所以在使用前应该对它的利弊进行权衡。

 

②OI的物体选择

  OI并不是什么时候都可以进行使用的(也就是说不是所有的对象(物体)都符合操作数隔离的要求)。此外操作数隔离主要是:满足一定条件下,通过指定操作数隔离的物体来实现的;指定操作数隔离的物体可以通过EDA工具自动执行(我们一般使用这种方法),也可以通过我们手动进行。下面我们就分别介绍一下这两种方式。

  ·EDA工具自动指定操作数隔离的物体

默认情况下,如果操作数隔离的物体满足下列条件,Power Compiler自动选择它(们):

  1.OI物体是算术运算器或层次组合单元。

  2.OI物体的输出是选择性地使用。

  3.运算器必须有非零的翻转率。

  4.仅当工具进行功耗估算后,用操作数隔离具有潜在的功耗可节省,才把它(们)作为OI物体。

自动进行操作数隔离的脚本如下:

set  do_operand_isolation    true

set_operand_isolation_style

read_saif  

……

compile

 

  ·手动指定操作数隔离的物体

除了使用EDA工具自动选择IO物体,我们也可以手动进行指定,然后进行操作数隔离。手动完成操作数隔离大致可以分为两步:

A:设定操作数隔离的风格为手动(用户自定义模式):

  在约束脚本中加入下面的命令,说明是使用手动的方式指定IO物体:

    set_operand_isolation_style  -user_directives

 

B:手动指定IO物体:

 手动指定IO物体有下面两种方式:

  1.用命令指定OI物体:set_opreand_isolation_cell,例如:

    set_operand_isolation_cell  [get_cells   U1]

  2.在RTL代码中加综合指引(pragma)

    例如:下面的RTL中加入了综合指令“//synopsys_isolate_operands":

          if(c2 == 1’b1)

            o  = a + b ;

          else

            o  = c + d ; //synopsys_isolate_operands

 

完成前面A、B两步的设置之后,在使用compile命令进行综合时,如果手动指定的IO物体满足前面的三点:

  1.OI物体是算术运算器或层次组合单元。

  2.OI物体的输出是选择性地使用。

  3.运算器必须有非零的翻转率。

那么综合器就会进行操作数隔离。

 

③操作数隔离的范围

  有些时候,我们需要在整个设计中指定某些模块要做操作数隔离,某些模块不要做操作数隔离。这时候我就可以使用set_operand_isolation_scope命令来实现了。例如下面的分层模块中:

             

我们只对SUB2模块中的操作数做隔离,其他的模块不做操作数隔离,那么就可以使用下面的示例脚本:

  set_operand_isolation_scope   [get_designs   tops]   false

  set_operand_isolation_scope   [get_designs   sub1]   false

  set_operand_isolation_style

  ······

 

④隔离逻辑的设置

  实现操作数隔离需要插入相应的隔离逻辑,比如与门或者或门之类的。这些逻辑可以由EDA自动选择,也可以由我们自己手动指定。下面就来介绍这两种方式。

  ·默认的EDA工具选择

 默认情况下,隔离逻辑由工具自动选择。工具根据输入数据连线的静态概率(SP)来选择适合的隔离逻辑为“AND'’门或“OR”门。使用的命令如下所示:

        set_operand_isolation_style   -logic   adaptive

如果SP > 0.5,选择“OR”门作为隔离逻辑

如果SP < 0.5,选择“AND”门作为隔离逻辑

 

  ·手动

 我们可以手工地选择隔离逻辑,例如下面命令指定用“AND”门作为隔离逻辑:

        set_operand_isolation_style   -logic   AND

 

  通过前面的描述,我们知道操作隔离的实现可以通过EDA全自动化实现,也可以通过我们指定OI物体的半自动化实现。完成操作数隔离后,我们可以用命令报告设计中的操作数隔离,例如:

    report -operand_isolation  -isolated  -verb命令显示如下的信息:

             

             

              

 

⑤操作数隔离的复原

   加入隔离逻辑之后,如果时序变差达到不能满足要求的情况,我们就要复原原来的逻辑。复原的方法也是有自动和手动的方法。

  ·自动

 一般情况下,如果加了隔离逻辑后,设计的时序变差了,即当WNS(worst negative slack)大于指定的slack时,EDA工具会使设计自动复原到原来没有操作数隔离的状态。例如下面的脚本适用于如果WNS大于0. 5时,设计自动复原到原来的状态:

    set_operand_isolation_slack   0.5

    compile

    compile  -inc

 

  ·手动

 我们也可以用手工的方法复原操作数隔离。用手工的方法进行操作数隔离的复原是在指定的时序路径上删除OI逻辑。这时候不考虑slack。需要执行增量编辑去删除OI逻辑。脚本如下:

    remove_operand_isolation  -from   <starting_point>   to   <end_point>

    compile  -inc

    ······

 

 

最后,提供一个完整的加入操作数隔离的示例脚本,如下所示,使用了默认的隔离逻辑类型操作数隔离的自动恢复

    set   do_operand_isolation   true

    read_verilog   mydesign.v

    current_design   top

    link

    create_clock -p 10 [get_ports   clk]

    set_operand_isolation_style

    set_operand_isolation   -slack 0.1

    compile

    report_operand_isolation -verb  -isolated

    ······

(4)门控时钟

  门控时钟在我的第一篇博客中有简单的描述,这里就进行比较详细的描述吧。我们主要学习门控时钟电路是什么、什么使用门控时钟、综合库里的门控时钟、如何使用门控时钟、对门控时钟的一些处理、手动插入门控时钟。我们重点介绍如何使用门控时钟和门控时钟的处理

①门控时钟概述

  门控时钟有两种方案:一种直接针对寄存器的时钟进行门控,一种对模块级别的时钟进行门控。相比之下,直接对寄存器的时钟进行门控更为灵活。因为在很多时候,我们不能保证刚好将不需要门控的寄存器与需要门控的寄存器分配在不同的模块。因此我们主要介绍寄存器级的门控时钟

=============================================================================

下图是门控时钟的一个简单电路图:

               

上述电路图中,将控制信号(EN)直接与时钟信号(CLK)进行操作,以完成门控。门控后的时钟信号GCLK送到寄存器阵列中。这样,当EN为0时,该时钟被关掉。相应的波形如下所示:

         

可以看出,如果EN信号不加控制,会导致门控时钟信号出现毛刺。时钟上的信号出现毛刺是非常危险的。所以在进行门控时,为了使门控时钟不产生毛刺,使能信号必须满足条件:它是寄存器的输出,该寄存器的时钟信号与要门控的时钟信号是相同的。由于上述原因,虽然采用这种门控方式最直接,但在实际中很少采用。

==============================================================================

为了解决这种问题,引入基于锁存器的门控时钟方案,如下图所示:

                

对应的时序图如下所示:

           

可以看到,这种方式消除了EN与CLK组合产生的毛刺对门控时钟的影响。该方法的原理在于:锁存器在CLK为低时透明。这样,EN 信号上的毛刺仅出现在CLK的低电平处,EN1与CLK进行与操作,可以将这部分毛刺消除掉。这样,GCLK上就没有毛刺了。

   不过需要注意的是,如果在电路中,锁存器与与门相隔很远,到达锁存器的时钟与到达与门的时钟有较大的延迟差别,则仍会出现毛刺,下面就来分析一下:

     

上述的右上图中,B点的时钟比A时钟迟到,并且Skew > delay,这种情况下,产生了毛刺。为了消除毛刺,要控制Clock Skew,使它满足Skew >Latch delay(也就是锁存器的clk-q的延时)。上述的右下图中,B点的时钟比A时钟早到,并且|Skew|  > ENsetup 一 (D->Q),这种情况下,也产生了毛刺。为了消除毛刺,要控制Clock Skew,使它满足|Skew|< ENsetup一(D->Q)。

常见的是第一种毛刺,不过我们可以将这个逻辑做成一个单元,这样就基本上能消除上面的那两种毛刺了,即:

           

============================================================================

  通常情况下,时钟树由大量的缓冲器和反相器组成,时钟信号为设计中翻转率最高的信号,时钟树的功耗可能高达整个设计功耗30%。加入门控时钟电路后,由于减少了时钟树的开关行为,节省了开关功耗。同时,由于减少了时钟引脚的开关行为,寄存器的内部功耗也减少了。采用门控时钟,可以非常有效地降低设计的功耗,一般情况下能够节省20%~60%的功耗。

  此外,由于门控时钟不需要用到MUX单元,加入门控时钟电路后,设计的面积也减少了。门控时钟电路的扇出越大,减低功耗和面积的效能越好。当然,扇出太大了,又会产生时序等的问题。

  门控时钟电路非常容易实现,用工具自动插入门控时钟,不需要修改RTL代码,门控时钟与工艺无关。

  这些优点本来应该放在总结处说的,这里提前进行叙述是为了能够给大家一个印象。其中低功耗的优点是通篇进行讲解的,然后降低面积和实现的问题,我们会在后面的具体实现进行讲解。

 

②综合库中的门控时钟模型

  前面我们说了,门控时钟可以以三种方式实现:一个与门(即不带锁存的门控时钟)、分散的锁存器+与门、集成的锁存器+与门。在综合库中,与门、锁存器是基本逻辑单元,因此可以构成门控时钟。此外,综合库中还专门提供了集成的门控单元。一般情况下,我们使用的是集成的门控单元,因为这个门控单元是对Skew作了控制,不存在前面描述的毛刺问题。

  一个示例的  综合库中的时钟门控单元描述如下所示:

(该综合库模型中,E为门控信号;CK为时钟信号;ENL是锁存器输出;ECK为对输出门控后的时钟信号;statetable描述了该门控单元中内部锁存器的功能。该单元的其他内容描述就不具体描述了,我在Tcl与Design Compiler这个分类的博客里面有对综合库进行具体的介绍。)

           

              

 

 

 

③门控时钟实现

  我们要实现门控时钟,首先就得从RTL代码中进行设置。在RTL代码中将需要门控的寄存器写成“载入-使能”的形式,如下所示:

      always  @(posedge CLK)

         if (EN)

          Q <=D;

上述代码中,如果EN有效,则寄存器在时钟上升沿采样数据,否则保持原值。一般情况下,综合会得到下图右上角的电路,而插入门控时钟的电路为下图右下角的电路:

     

上图的典型综合结果中(即不使用门控时钟的情况),在每个受EN使能控制的寄存器之前加入了一个MUX,当EN信号有效时,寄存器锁存输入信号D;否则保持原值。这种方法也能减少寄存器上的翻转,因而节省翻转功耗。然而,这种“载入一使能”结构中,每个寄存器都有一个MUX,假设MUX面积为4,则8位寄存器需要增加的面积为32。面积越大,意味着芯片成本越高,而且整体的功耗也会增加。另外,这种方式不能消除时钟树上的功耗。

对于右下角的门控时钟形式的综合电路,假设一个门控逻辑的面积为10,一个门控时钟信号可以驱动8位寄存器,则在门控时钟电路中,对每8个寄存器需增加一个门控逻辑,增加的面积为10。由此可以看到,门控时钟的电路比普通综合结果的面积更小、功耗更低。

=============================================================================

  鉴于门控时钟的优点,我们需要把普通的综合结果“转换”为门控时钟的结果,我们主要是通过DC的power compiler来自动实现的。我们主要通过命令来设置门控时钟的风格和通过命令“启动”插入门控时钟。综合工具根据我们所设置的时钟门控的风格,插入相应的门控逻辑。因此,门控时钟的实现主要有两步,一步是设置门控时钟的风格,通过命令set_clock_gating_stale 及其选项来实现;另一步就是在网表中加入门控时钟,通过命令insert_clock_gating来实现。下面我们就来介绍一下这两个设置,由于命令在不同版本的DC中有所不同,命令的具体选项就可能不一样,这里就只介绍一些常用或者说是可能用到的选项。

==============================================================================

  在执行insert_clock_gating命令前,我们一般先使用set_clock_gating_style命令来指定要插入门控时钟电路的结构(或者说是插入门控时钟的风格)。下面我们就来介绍一下使用这个set_clock_gating_style命令可以进行插入哪些门控时钟电路结构。

  ·-sequential_cell 选项设置是否采用基于锁存器的风格。因为我们的门控时钟有三种形式(不适用锁存器的与门,基于锁存器+离散与门,集成的锁存器+与门),因此就要指定使用哪一种形式:

A:基于锁存器的离散门控单元是默认值,可以通过下面的命令来设置:

    set_clock_gating_style   -sequential_cell  latch

B:不使用锁存器的门控单元,可以通过下面的命令来设置:

    set_clock_gating_style   -sequential_cell  none

C:使用集成的门控单元则不需要使用这个-sequential_cell来设置了,因为-sequential_cell 选项设置是否采用基于锁存器的风格。使用集成的门控单元直接设置参数就可以了,例如可以通过下面的命令来设置使用集成的门控单元:

    set_clock_gating_style    “integrated”

一般推荐使用集成门控这种方式。

 

  ·-positive_edg_logic选项(简写为-positive或-pos)设置在RTL代码中用上升沿锁存的寄存器(也就是上升沿沿触发的寄存器)采用何种门控逻辑。

     -negative_edg_logic选项(简写为-negative或-neg)设置在RTL代码中用下降沿锁存的寄存器(也就是下降沿触发的寄存器)采用何种门控逻辑。

例如下面的命令:

    set_clock_gating_style  -sequential_cell  none  -pos  “or”

该命令设置了不适用锁存器的风格,然后对于上升沿触发的寄存器,其门控单元使用或门逻辑构成。

 

    set_clock_gating_style  -neg “integrated”

该命令置在RTL代码中用下降沿锁存的寄存器(也就是下降沿触发的寄存器)使用集成门控时钟单元。

 

    set_clock_gating_style -positive  “integrated”  -negative “integrated”

该命令设置RTL代码中,无论你的寄存器是上升沿触发还是下降沿触发,控制该寄存器的时钟单元都是使用集成门控时钟单元。

 

  ·-minimum_bitwidth 选项用于设置进行时钟门控的寄存器阵列的最小宽度。对于宽度小于该设置的寄存器阵列,不进行时钟门控;然而当电路由有公共使能时,会对电路进行分解进行集体门控。例如下面的命令作用与下面的电路:

    set_clock_gating_style  -minimum_bitwidth  4

    

上述命令意味着一个门控时钟至少要触发4个寄存器。左图中有3个寄存器组,每组只有3个寄存器,不能满足至少要有4个寄存器的要求。因此,对于每个组的寄存器,不能用门控时钟。然而,所有的3个寄存器组,都有1个公共的使能信号”a”,我们可以把它分解出来作为控制时钟的门控信号。这样一来,信号“a”控制9个寄存器,它满足最少要触发4个寄存器的要求。因此将上面的命令约束上面左边的电路时,综合得到结果就会成为右边有门控时钟的电路。

 

  ·-num_stages选项用于设置一个多级门控的级数。在有些设计中,顶层的门控信号会分解成不同的子门控信号。在缺省情况下,仅对跟寄存器阵列相连的门控制信号生成门控逻辑。例如对于下面的电路图:

             

在这个例子中,全局门控信号EN分别跟a,b,c信号组合,然后驱动不同的寄存器阵列。缺省情形下(set_clock_gating_style命令的默认设置为“num_stages”等于“1",缺省时也为1),跟寄存器阵列相连的门控信号   由门控单元给出。

  由于所有的3个寄存器组都有1个公共使能“a",它可以被分解出来产生1个额外(级)的门控时钟单元。在set_clock_gating_style命令加选项“-num_stages 2",就可以产生下图所示的两级门控时钟:

           

 

使用多级门控时钟,时钟综合器可以尽量地摆放门控时钟单元,使它靠近时钟源,从而最大限度地降低时钟树的功耗。

 

  ·-control_point与-control_signal选项跟DFT有关,用于设置该门控单元在DFT时是否可控,DFT控制信号是scan-enable还是test-mode,以及DFT控制信号与EN信号的组合逻辑是放在门逻辑中的锁存器之前还是之后。通常,将DFT控制信号与EN信号进行操作,这样在DFT时,可以控制该门控逻辑。例如下面的命令约束:

    set_clock_gating_style  -control_point  before  -control_signal test_mode

设置得到下面的电路结构:

         

上图给出了在门控逻辑中插入控制点的示例。在这个例子中,DFT控制信号为test_mode,控制点位于锁存器之前。

 

  ·-observation_point选项跟DFT有关,用于设置是否要插入观测逻辑,以便在DFT时能看到门控逻辑内部的信号。

例如下面的约束命令:

    set_clock_gating_style   -observation_point  true

则设置插入观测,逻辑,如下图所示:

         

  

  除了上述选项外,该命令还有一些其他的选项设置,比如-setup选项设置建立时间约束。-hold选项设置保持时间约束。-observation_logic_depth选项用于设置观察电路中异或门的数目。-max_fanout选项设置一个门控单元所驱动的最大负载数目,定义CG单元最大扇出的一个目的是减少CG后面的时钟延迟,门控时钟单元的扇出越大,它到达寄存器的延迟越长;此外,还有用来约束重新平衡(后面会有对重新平衡进行介绍)。"set_clock_gating_style"命令有很多选项,我们可以在Power Compiler用"man  set_clock_gating_style"命令来查看其详细的使用方法。

==============================================================================

  设置了门控时钟的加入风格之后,我们就可以设置在门级网表电路中加入门控时钟。在Power Compile:里,用insert_clock_gating命令可在GTECH网表上加入门控时钟。这个命令可以单独使用,也可以配合一些选项,设置一些功能,我们下面主要介绍一下-global选项。

我们来看一下下面这段代码:

    always @ (posedge clk)begin

        if (a && b) q=d;

    end

当有多个模块都有这段代码时,单单利用insert_clock_gating命令就会得到下面的带门控时钟的电路:

              

上述电路中,有两个模块都有门控时钟,都是同一个控制信号。那么我们就可以使用insert_clock_gating  -global选项,让门控时钟可以穿越层次结构,插入到设计中。这样一来,既可以省门控时钟,又可以省面积。使用该选项后,综合得到的带门控时钟的电路如下所示:

               

因此使用insert_clock_gating加选项“-global",可以使门控时钟穿越层次结构。如果不用选项“-global",在每个模块里有一个门控时钟单元。

  实现门控时钟的方法就如前面所示,主要是设置门控时钟的风格和加入门控时钟这两个命令以及他们的一些选项。

 

④门控时钟的处理

  我们在门级网表中加入门控时钟之后,有时候需要对门控时钟进行修修改改,比如说删除一些门控时钟之类的。下面我们就来介绍一下常见的一些门控时钟处理。

  ·重新连接门控时钟

如下图所示:

       

上面的左边图中,寄存器A由CG1触发(也就是原来由上面的门控单元CG1进行控制)。由于寄存器A距离门控时钟单元CG2更接近,我们更想让寄存器A与门控单元CG2进行连接来减少连线的长度,因此我们需要进行重新连接。重新连接后,寄存器A由CG2触发,如上面右边的图所示。上面重新连接所使用的命令如下所示:

    rewire_clock_gating   -gating_cell  CG2  -gated_objects  {reg_A}

  此外,我们可以使用rewire_clock_gating的-proximity选项,使用这个选项后,Power Compiler会自动重新连接寄存器,使时钟门控单元CG到寄存器的连线最短:

      rewire_clock_gating  -proximity

 

  ·重新平衡门控时钟的扇出

如下图所示:

     

  左图是原来的设计。当我们对电路进行优化时(比如使用compiler_utral -retiming 或者 optimize_registers命令),设计中的寄存器可能被移动或删除,如中图所示。

  寄存器优化后,门控时钟的扇出不平衡。而门控时钟有最小和最大扇出的约束,对于每一个单独的CG单元(如中图所示)最小扇出的条件不能满足。Power Compiler就需要相关的命令重新平衡门控时钟的扇出,使用的命令如下所示:

    rewire_clock_gating   -balance_fanout

使用上述命令后,Power Compiler将CG单元合并,以满足最小/最大扇出的约束。重新平衡后的设计如右图所示。

 

 

  ·合并门控时钟

  如果两个或以上的门控时钟单元的输人逻辑相等,它们可以被合并。合并只能在一个层次内部进行。合并后,冗余的逻辑被删除。如下图所示:

     

合并的命令为"merge_clock_gating_cells"

 

  ·删除门控时钟

  有时候,我们需要删除某些门控时钟,这个时候我可以使用remove_clock_gating命令。该命令即一些选项如下所示:

    remove_clock_gating

      [-gating_cells    CG_cells_list]

      [-gated_registers   gated_register_list]

      [-all]  [hier]

如下图所示:

     

 

上图上半部分是使用了-gated_registers这个选项,将原来的门控单元删除,换成“使能-载入”模式;上图的下半部分是使用了-gating_cells这个选项,原来的一个门控时钟删除。

  因此我们可以通过指定门控时钟单元或通过指定寄存器删除门控时钟。如果在使用删除门控时钟命令时用了开关选项“-all",当前设计中的所有门控时钟都会被删除。

 

 

⑤手动插入门控时钟

  上面介绍的是使用EDA工具,配合代码自动生成门控时钟。我们也可以以手工的方式设计门控时钟,下面是一个手动设计门控时钟的的代码例子:

assign Gated_Clock  =  Clock&Enable  ;

always@(posedge Gated_Clock or negedge Reset)begin

    if(!Reset)

          Data_ Out<=8’b0;

    else

Data Out<=Data Out+8'b1

end

对于手工门控时钟,Power Compiler将不插入时钟门控单元,也不能对它进行操作(比如重新平衡之类的)。

 

  手工门控时钟可以被取代,取代的脚本如下:

······

create_clock   -period   5   [get_ports   clk]

set_clock_gating_style   ...

replace_clock   -gating_cells

······

取代前后的电路如下所示:

     

 

取代手工门控时钟的好处在于:取代后,它可以避免产生潜在的毛刺(glitch),也可以允许在它上使用其他的CG命令。例如我们可以使用remove_clock_gating命令去掉门控时钟或使用rewire_clock_gating命令重新连接门控时钟。

   门控时钟的低功耗设计到这里就介绍完了,关于门控的STA、DFT和CTS的问题我们就不进行介绍了。

 

 

  (5)其他

  有的时候,我们不经意间就会引入多余的翻转,多余翻转就引起的多余的功耗。下面是多余翻转的例子(类似于操作数隔离):

 

       

  上图中,当load_out无效时,如果laod_op有效,那么数据就会进行操作,也就是存在相应的翻转。因为输出是无效的,所以这些翻转是多余的,消耗了功耗,但却没有输出。因此我们就要注意,当load_out无效时,load_op也要设置为无效,这样就可以节省部分功耗。

  对于上面的多余翻转,可以进行相应的压缩来节省功耗,如下所示:

       

sel_in同时控制了数据输入和多路选择器的输出。SEL=0时,读入A和B,选通操作1;SEL=1时,读入C和D,选通操作2;这时候就可以减少另一半操作引起的翻转,从而减少了功耗。

  对于这种数据输入,然后进行操作选择性输出的,可以进行相应的门控来减少多余的翻转,从而减少功耗。

 

  结合综合进行RTL级的低功耗就如上所述了,重点是门控时钟的使用和操作数隔离技术,这是我们前端设计人员需要懂的。

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

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

相关文章

Unity3D 游戏前端开发技能树(思维导图)

如果做游戏也是一种游戏,那么这个游戏的自由度实在是太高了.(导图源文件链接&#xff1a;http://pan.baidu.com/s/1eSHpH5o 密码&#xff1a;qzl5) 最近要用思维导图软件Xmind把自己的思路好好捋一捋,算是温故知新吧. 转载于:https://www.cnblogs.com/qiaogaojian/p/6098962.ht…

SQL Server 死锁的告警监控

原文:SQL Server 死锁的告警监控今天这篇文章总结一下如何监控SQL Server的死锁&#xff0c;其实以前写过MS SQL 监控错误日志的告警信息&#xff0c;这篇文章着重介绍如何监控数据库的死锁&#xff0c;当然这篇文章不分析死锁产生的原因、以及如何解决死锁。死锁&#xff08;D…

关于web性能一些特性汇总

关于web性能一些特性汇总 DOMContentLoaded & load load事件是window对象上的事件。指的是网页资源已经加载完毕&#xff08;包括但不限于DOM、图片、音频、脚本、插件资源以及CSS&#xff09;。 DOMContentLoaded事件是document对象上的事件。指的是DOM已经加载完毕。IE中…

(五)门级电路低功耗设计优化

&#xff08;1&#xff09;门级电路的功耗优化综述 门级电路的功耗优化(Gate Level Power Optimization&#xff0c;简称GLPO)是从已经映射的门级网表开始&#xff0c;对设计进行功耗的优化以满足功耗的约束&#xff0c;同时设计保持其性能&#xff0c;即满足设计规则和时序的要…

Spring3向Spring4升级过程中quartz修改

为什么80%的码农都做不了架构师&#xff1f;>>> 问题 nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name ... 原因 org.spri…

EasyUI--messager

1.    alert 方法 <script type"text/javascript">$( function(){$.messager.alert("调用messager","文本内容") ;});</script> 这里还可以通过icon添加相应的图标及info加入回调函数 <script type"text/javascript&quo…

Redis学习第八课:Redis高级实用特性(一)

Redis高级实用特性 注&#xff1a;我学习的环境是vmware7.1 ubantu10.10 redis 3.0.2 1、安全性 设置客户端连接后进行任何其他指定前需要的密码。因为redis速度相当快&#xff0c;一个外部用户可以在一秒钟进行很多次的密码尝试&#xff0c;这就需要设定非常强大的密码来防止…

分布式缓存的面试题9

1、面试题 如何保证缓存与数据库的双写一致性&#xff1f; 2、面试官心里分析 你只要用缓存&#xff0c;就可能会涉及到缓存与数据库双存储双写&#xff0c;你只要是双写&#xff0c;就一定会有数据一致性的问题&#xff0c;那么你如何解决一致性问题&#xff1f; 3、面试题剖析…

ROS与navigation教程——概述

navigation是ROS的二维导航功能包&#xff0c;简单来说&#xff0c;就是根据输入的里程计等传感器的信息流和机器人的全局位置&#xff0c;通过导航算法&#xff0c;计算得出安全可靠的机器人速度控制指令。 代码库&#xff1a;https://github.com/ros-planning/navigation 代…

【设计模式】单例模式 Singleton Pattern

通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例&#xff08;Instance&#xff09; 的情况&#xff0c; 比如说我们想做一计数器&#xff0c;统计某些接口调用的次数&#xff0c;通常我们的数据库连接也是只期望有一个实例。Windows系统的系统任务管理器…

进程及线程通信总结

上文我们介绍了如何建立一个简单的多线程程序&#xff0c;多线程之间不可避免的需要进行通信 。相比于进程间通信来说&#xff0c;线程间通信无疑是相对比较简单的。 首先我们来看看最简单的方法&#xff0c;那就是使用全局变量&#xff08;静态变量也可以&#xff09;来进行通…

ROS multi-master——multimaster_fkie配置

多主站ROS配置和mutimaster_fkie ROS版本&#xff1a;kinetic 操作系统&#xff1a;Ubuntu 16.04。 multimaster_fkie&#xff1a;github 1网络配置 1.1路由器 设置无线路由器并连接两台计算机/机器人。为这两台计算机设置静态IP地址。相互测试ping命令和ssh。 1.2主机 …

Docker入门

1. Docker简介: docker是一个基于LXC的高级容器引擎。简单地说&#xff0c;docker是一个轻量级的虚拟解决方案&#xff0c;或者说它是一个超轻量级的虚拟机&#xff08;容器&#xff09;。 Docker是一个开源的引擎&#xff0c;可以轻松的为任何应用创建一个轻量级的、可移植的、…

Gmapping——从原理到实践

概述 在SLAM中&#xff0c;机器人位姿和地图都是状态变量&#xff0c;我们需要同时对这两个状态变量进行估计&#xff0c;即机器人获得一张环境地图的同时确定自己相对于该地图的位置。我们用x表示机器人状态&#xff0c;m表示环境地图&#xff0c;z表示传感器观测情况&#xf…

【机器学习经典算法源码分析系列】-- 逻辑回归

1.逻辑回归&#xff08;Logistic Regression&#xff09;又常被成为“逻辑斯蒂回归”&#xff0c;实质上是一个二元分类问题。 逻辑回归代价函数&#xff1a; 代价函数导数&#xff1a; Matlab实现&#xff1a; 采用matlab中自带的无约束最小化函数fminunc来代替梯度下降法&…

ROS——不同版本间ROS进行通信

在相同版本间的ROS进行通信不在赘述了&#xff0c;修改/etc/hosts文件即可。 最近项目遇到在Ubuntu16.04 与Ubuntu18.04两个系统间进行ROS通信&#xff0c;ROS版本分别为Kinetic和Melodic。配置网络后&#xff0c;两边都能够ping通&#xff0c;但是在获取ros数据是&#xff0c…

大数据开发实战:数据流图及相关数据技术

1、大数据流程图 2、大数据各个环节主要技术 2.1、数据处理主要技术 Sqoop&#xff1a;&#xff08;发音&#xff1a;skup&#xff09;作为一款开源的离线数据传输工具&#xff0c;主要用于Hadoop(Hive) 与传统数据库&#xff08;MySql,PostgreSQL&#xff09;间的数据传递。它…

跨时钟域电路设计——亚稳态及双锁存器

一、同步电路 定义&#xff1a;电路中所有受时钟控制的单元&#xff0c;全部由一个统一的时钟控制。 优点&#xff1a;在同步设计中&#xff0c;EDA工具可以保证电路系统的时序收敛&#xff0c;避免电路设计中的竞争冒险。 缺点&#xff1a;时钟树综合需要加入大量延迟单元&…

跨时钟域电路设计——单bit信号

前面提到了简单的双电平锁存器&#xff0c;下面是一些单bit同步电路。 一、慢时钟域向快时钟域 边沿检测同步器 将慢时钟域的脉冲搬移并缩小为快时钟域的脉冲。 既可以检测上升沿&#xff0c;也可以检测下降沿。 如上图&#xff0c;慢时钟下一个有效脉冲的最短周期为慢时钟的…

C语言100例01 PHP版(练习)

题目&#xff1a;有1、2、3、4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f; 程序分析&#xff1a;可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 代码&#xff1a; 1 for($i1;$i&l…