在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 134414|回复: 306

[原创] low power RTL 设计优化

[复制链接]
发表于 2017-9-9 03:23:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 yaya126 于 2017-9-9 15:32 编辑

论坛里面讨论low power RTL前端设计的帖子好像不多,许多大牛的书上来就谈工艺,半导体结构,让我高山仰止,但也只能心向往之(实在有些看不懂)

工艺的提升带来的收益可能远比RTL深度优化高,如TSMC 40LP vs TSMC 28HPC+, 后者基本上比前者面积小一半,速度快一倍,dynamic power40~50%
代价是leakage3~4倍。在老工艺上如何绞尽脑汁优化设计,可能也很难达到这种效果。

但作为前端RTL designer, 一旦工艺选定,我们只能在自己的一亩三分地里面做到最好,本帖就此抛砖迎玉,结合自己的工作经验讨论下low power RTLdesign, 挖个坑,希望坛子里的大牛一起帮忙填坑


刚入行做design时,考虑的是Area speed,近些年来,power变成了越来越重要的指标,有时候更是牺牲Areaspeed来换取power的收益,毕竟有些领域, 电池容量是很难增大的。


有人做过大体统计,降低功耗的方法和收益大体如下,对于前端RTL 设计,最好用的还是clock gating, 收益最显巨,代价最小,
其他方法也能有可观的收益,具体还的依靠具体应用场景分析。


low power.png

Power 主要消耗在 1),combinational logic, 2) sequential logic, 3) memory 4) clock network

下面我将就下面几个方面展开讨论,

1.Improve clock gating efficiency.

   a.Block level clock gating.

   b.RTL clock gating. (重点)

2.Reduce data toggle rate.

   a.FIFO vs PIPE

   b.FSM coding style

   c.Unnecessary reset.

3.Refine Memory Selection.

   a.Area power balance

   b.I/F bitwidth selection.

   c.Depth selection.

4.Reduce memory accessing

   a.Address caching.

5.Reduce logic size

   a.Logic sharing.

   b.Logic balancing

   c.Divider optimization.

   d.Reduce pipe line length

   e.Hardmacro vs Register

   f.Reduce bitwidth

   g.Async reset vs non-async-reset.

6.Misunderstanding

(未完待续)

 楼主| 发表于 2017-9-9 14:33:51 | 显示全部楼层
本帖最后由 yaya126 于 2017-9-9 15:11 编辑

1.a block level clock gating

如果某个模块或者功能可以打开或关闭,且logic相对独立,则可以在这部分logic的时钟上加手动插入一个ICG,用模块是能控制ICG的开关,这样能最大限度的提升gating效率。

1.ICG最好选取驱动能力较大的,以便于驱动足够多的DFF

2.ICG建议加一个wrapper,这样当需要替换其他工艺时,只需要将wrapper里的instance 换掉。

3.综合时对此类ICG设置don’t touch


1. b RTL clock gating.

Lowpower RTL综合的精髓就是把本该综合在D端的enable信号,综合到CLK端,这样只有enable有效才能释放一个clk使得D端数据传递到Q端。当D超过一定bit数,通常认定>=4bit能节省power, 为了达到这种效果,寄存器的赋值一定是条件赋值,示范代码和电路如下,


RTL.png

Mentorpower_pro能够帮助分析RTL,提取有效的enable,并完成代码的优化,但就我看下来,它优化过的代码可读性非常差,条件有时候也有冗余,导致过多的使能ICG,而且后续如果需要ECO还需要购买它的formal工具,不然很难再改它的code.


此处我提供一个自己写代码分析的perl脚本,可以用来查所有代码中不符合low power RTL 代码规范的code, designer可以根据它的报告来优化赋值使能条件,已经过实际项目测试。

欢迎大家使用并提意见。(后面会解释为毛要查2d arry, initial和乘法器)


power_check.pl –v –f [filelist] –d [directory] -filter [N]–b –2d –init -mul [top.v]

-v or –verbose   :print verbose log for debug.

-f or –file       : input file list.

-d or –dir       : set searching directory, script will findVerilog file under this directory.

-b or bak       : back up previous result.

-filter [N]       : filter <= N bits register error.

-2d or 2d_array  :report2D register array.

-initial or init   :report initial block

-mul          :report multiplier info

Verfilog file     : input Verilog file

case1.JPG

产生结果文件,最重要的power_check.v。

case2.JPG

运行时报告:

case3.JPG


power_check.rar

7.87 KB, 下载次数: 1085 , 下载积分: 资产 -2 信元, 下载支出 2 信元

power check script

 楼主| 发表于 2017-9-9 14:41:06 | 显示全部楼层
本帖最后由 yaya126 于 2017-9-12 12:39 编辑

Low power RTL 理想代码结构:

      1 always@(posedge clk or negedge rstn) begin

     2     if(!rstn)begin

     3         Q<= 'h0;

     4     end

     5     else if (condition_1)begin

     6         Q<= D_1;

     7     //other condition 2, 3, 4 …

     8     else begin

     9         Q<= Q;  //better to remove this assignment, then data willbe kept.

    10     end

          11   end

错误代码的示例, 如果不管在什么情况下,总有D值需要打到Q, 使得即使综合出来ICG, 该ICG也不能关断。错误远不止下面几种,if/else if/else, case/default 等等
1. 没有赋值条件
   1 always@(posedge clk) begin //”if-else”hierarchy 0, default is “else” block

   2    Q <= D;             //Error: no condition for Dataassignment.

    3  end
2 . else 赋值

1 always@(posedge clk or negedge rstn)begin  //hier0

2    If(!rstn)begin                       //hier1 “if” block

3        Q <=’h0;   

4    end else begin                      //hier1 “else” block

5        Q<=D;                        //Error: no condition for Dataassignment.

6    end

7end


3. 多级条件中的else

1 always@(posedge clk or negedge rstn)begin  //hier0

2    If(!rstn)begin                       //hier1 “if” block

3        Q <=’h0;  

4    end else if(condition1)begin           //hier1 “else if” block

5        If(condition1_1)begin            //hier2“if”block

6             Q<=D1_1;

7        end else begin                  //hier2“else” block

8           Q<=D1_2;                  //not report error, as it is in “else if”block.

9       end

10     end else begin                   //hier1 “else” block

11         If(conditon2_1) begin         //hier2“if” block

12              Q<=D2_1;

13         end else begin              //hier2“else” block, in hier1 “else” block

14              Q<=D2_2;              //Error: no condition for Data assignment.

15         end

16    end

end


4. 下面这个例子不会报错。

1 always@(posedge clk or negedge rstn)begin  //hier0

2    If(!rstn)begin                                                       //hier1 “if” block

3        Q <=’h0;   

4    end else if(condition1) begin                          //hire1 “else if” block

5        Q<=Q;                                                             //”Q<=Q”ensure ICG insertion

6    end else begin                                                  //hier1 “else” block

7        Q<=D;                                                             //Not reportERROR as “Q<=Q” in “else if”.

8    end

         9end
 楼主| 发表于 2017-9-9 15:20:36 | 显示全部楼层
本帖最后由 yaya126 于 2017-9-12 15:35 编辑

2. a FIFO vs PIPE当数据需要穿过N拍delay后再使用时,我们通常有两种方法来实现, 1是讲数据打N级pipe,一级一级往传。 2是将数据存入FIFO, 到后级需要使用时直接读出来。 两种方式VLD都需要单独传递
对比PIPE的方式,FIFO的方式有额外地址计算比较的开销,但每个数据只需要读写各一次,不像PIPE,数据需要在整个PIPE中shift一轮,FIFO 方式每个寄存器的toggle rate将大幅下降。 假设数据的toggle rate 位Tr, N级pipe的 toggle 为N*Tr, FIFO 为 Tr。
fifo_vs_pipe.JPG

如果由于FIFO输出数据+后续计算timing不满足,可以考虑缩短一级FIFO,最后一级仍由PIPE输出。
FIFO.JPG

根据我在TSMC 40nm和28nm下PTPX仿真结果分析。(具体数据可以单独找我要)
结论:

FIFOreplace PIPE for power reduction:

when ADDR >=2 bit , DATA should be >=4 bit, DATA 越宽,级数越深,FIFO power 收益越高,但有额外的面积开销。


上面脚本提供命令 power_check.pl -2d -d . 来把代码中所有的 2D array 找出来,有些同学喜欢把PIPE 赋值写成下面的样子

for( i= 1 ; i< N; i ++) begin

   if(VLD[N-1])

     Array[N] <= Array[N-1] ;    //这个代码虽然是有条件赋值,但如果符合上面的条件,可以考虑换成FIFO.

end

发表于 2017-9-9 23:29:32 | 显示全部楼层
刚开始接触低功耗设计,mark一个
发表于 2017-9-11 10:14:47 | 显示全部楼层
好贴,期待更新,感谢楼主分享
 楼主| 发表于 2017-9-11 11:41:43 | 显示全部楼层
本帖最后由 yaya126 于 2017-9-11 11:52 编辑

2. b FSM code style:  状态机常用编码有3种:
   1. one-hot: 如 3'b001->3'b010->3'h100, 状态个数 = 比特位宽一样, 每次状态变化,最多只有两个bit变化。
   2. 2进制编码,   如 3'b000->3'b001->3'b010->...,  Nbit 能支持 2exp(N)中状态。
   3. 格雷码, 3'b000->3b001->3'b011-> 3'b010-> ... 如果按照顺序变化,每次只有一个bit跳变。

  总体来说,one-hot使用bit数较多,power最差,如果状态跳变有一定顺序,采用格雷码编码能降低toggle rate.
40LP下4 bit FSM, 16个状态,从4‘h0 跳转到4'hf’’的状态机, 功耗面积对比结果如下。

   即使状态机不能完全按照格雷码编码,把频繁跳转的状态用格雷码编码,也能获得举手之劳的power收益。尽量少用one-hot编码。
  

FSM

  
  

power

  
  

area

  
  

Gray code

  
  

8.697e-06

  
  

110.95(best)

  
  

One-hot

  
  

1.023e-05

  
  

166.69

  
  

binary

  
  

9.984e-06

  
  

108.48

  


2. c Unnecessary reset:
对于控制寄存器,清理掉残余状态很多情况下是必要的, 但对于data寄存器,数据残余可以不要复位。

  如果只在read_en的条件下把有效的数据写入rdata, 完全没有必要在!read_en的时候复位寄存器,这个做只是白白增加toggle rate.

If(read_en)      rdata <= read_data

Elseif(!read_en)  rdata <= ‘h0;                //Don’t reset rdata to all 0.

  如果写了这种语句,即使用power优化工具,或者上面那个脚本,都是没有办法来优化的, 总的来说,寄存器使能调件越精确(打开ICG几率越少), 越有利于power 优化。

 楼主| 发表于 2017-9-11 12:46:28 | 显示全部楼层

Memory Selection

SRAM的选择有很多讲究,我们需要看throughput, size, width 来决定到底是选1p, 2p, spra 1prf,通常情况下,在满足速度要求的情况下,挑选面积小的。 在这里我提一种新的挑选方法,即在速度达到要求的前提下,挑选power, area 性价比最高的。

当我们选的面积最小的为基准时,看面积增加的百分比和power减少的百分比的差值,假设area power对性价比评估各占50%的权重,如面积增大10%, power 下降20%则认为性价比变好了,如果只换来5%power下降,则认为性价比变差了。

当然我们可以调整area/power的权重来改变挑选规则,极端情况下,把area权重设置为100%就是通常下挑面积最小的那种方法。


那么,我们只需要用memory生成工具,将满足尺寸的sram按照不同的rf/sram segment_option  ,MUX,Width, Bits 用脚本全部生成一遍, 用上叙规则挑选最优,有些面积相差不大的srampower20~30%.


除了同样存储大小的sram, 位宽扩大一倍,深度减小一半的也可以考虑,如256x10,可以考虑生成128x20,位宽大一倍,不意味着每次读写power大一倍,但读写次数如果减少一半,这样也能带来可观的收益。


另外同样位宽,深度减半的也可以考虑,(这个从我做的实验看,收益不如double位宽的)


总之,挑sram不光考虑面积,可以尝试不同的选择,更多的考虑性价比


Sram面积可以直接从生成文件里读出,但power需要手工计算:假设standby power 不考虑,只考虑read/write power, 我们可以从生成文件中得到每次读写所需要的power,Pwr, Prd, 然后根据sram使用的特性,比如在一定时间内(周期内),是多少写多少读,乘上单次读写的对应的power,就可以大体估计srampower.


另外强烈建议在生成的sram 外面加个wrapper, 并手动插入一个ICG只有在RD或者WR的时候才打开ICG通常情况下,sramclock是被gating掉的。


Memory AddressCaching:  
当sram使用场景需要对同一地址多次查表时,可以考虑将上一轮读地址存下来,于新地址比较,如果在上次读之后没有对该地址的写操作,且新地址等于寄存的地址,则可以省略该轮读访问。
发表于 2017-9-11 14:33:43 | 显示全部楼层
持续关注!
发表于 2017-9-12 10:38:20 | 显示全部楼层
我觉得可以加精
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-16 19:30 , Processed in 0.026888 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表