通过前面两篇文章我们学习了现代数字芯片中主要的功耗来源、降低功耗的必要性、如何对功耗进行分析等内容:
这一篇文章将从系统级、RTL级、门级、电路级、版图级这几个不同的层面分析如何降低功耗。
1、系统级低功耗设计和优化技术
1.1、软硬件划分
- 软硬件划分是从系统功能的抽象描述(如C语言)着手,把系统功能分解为硬件和软件来实现。
- 对于一个系统功能的任务,可通过在微处理器上运行软件来实现和通过专用电路实现。比较两者的功耗得出一个低功耗的实现方案。软硬件划分的技术处于设计的起始阶段,可以给降低功耗带来更大的可能。
对于一款SoC芯片而言,软硬件如何进行划分通常由芯片架构师决定。理论上硬件能够实现的功能,软件一定也能实现。对于灵活性较强,且计算频率不是特别高的运算单元(或者是算子)如果使用专用的ASIC电路实现,会显得得不偿失。而对于计算密集型且计算频率特别高的运算单元,使用硬件实现,可以利用流水线和并行等技术大幅增加系统吞吐率,减少系统延时。
上面也是一些最基本的划分软硬件的方式,真实的SoC设计中,这一部分非常重要,需要工作多年的架构师和下属员工展开充分的讨论,才能够得到相应的结果。ZYNQ、EFPGA等技术都充分体现了软硬件协同设计的思想,如何更好的进行软硬件划分,需要大家多实践才能体会。此外有关高效的软硬件协同设计,大家可以看一下下面这个视频和对应的文章,讲的非常好。
1.2、指令集优化
什么默认大家都知道什么是指令集。指令集是处理器的语言,规定了处理器的行为。传统的CPU、GPU、近期流行起来的NPU等都是基于指令运行的(NPU不一定是)。对指令集进行优化可以显著降低功耗,指令集优化主要包括以下几个方面:
- 指令集提取:对于确定的处理器,其每条指令的功耗是一定的,选择一个指令集实现系统并使得功耗最小。
- 选择合适的指令长度(如16位、32位、64位或可变长度)以及指令压缩:如CISC的变长指令,ARM的thumb指令,RISC-V的C(compress)类指令,都是采用这种方式来提高程度的代码密度,以减少对存储器访问的功耗。其核心思想在于用更少的代码字节数,做更多的事情。因为本身从ICache/IRAM搬运数据对处理器而言就是很大的一笔开销。
- 指令编码优化:通过对应用程序指令相关性的统计,对指令进行编码优化,使读取指令时总线上的信号翻转最少。
你以为ARM/RISC-V/MIPS等指令集架构在制定的时候,指令编码都是随便规定的吗?那你就太Naive了。对于这种通用处理器设计,相关的研究人员会统计最常见的应用程序,需要哪些指令,指令与指令之间是什么关系,不能一条指令到另外一条指令翻转太多,考虑这一系列的因素。最终制定出你现在所看到的指令集架构。
目前各个公司的NPU设计有没有类似的优化我不太清楚,但我认为如果可以统计哪些典型网络跑的最频繁,先跑哪个算子再跑哪个算子的概率最大,从而制定相应的编码,可以有效地降低相关功耗,如果只是凭空想象指令编码,那就有点too simple了。
1.3、动态功耗管理
动态功耗管理是一种使系统或系统单元在不工作时候进入低功耗的休眠状态的控制技术。由于系统在正常工作状态和休眠状态之间的转换需要时间,会影响系统性能。
- 动态功耗管理技术的核心就是如何根据系统的状态信息决定系统何时进入低功耗的休眠状态。
- 动态功耗管理的实现需要有操作系统(Operating System,OS)的帮助,非常适合在嵌入式系统使用,事实上目前大部分的MCU都有相应的机制。下面是恩智浦的一个文档,是学习MCU如何使用功耗管理技术一个非常好的学习资料。
1.4、总线技术
根据维基百科的定义:总线(Bus)是指计算机组件间规范化的交换数据(data)的方式,即以一种通用的方式为各组件提供数据传送和控制逻辑。总线由于电容大、数据传输密度高,产生大量的功耗。总线的低功耗设计技术包括:
- 减小总线上信号的电压变化幅度(通常小于1V)对降低具有特大电容总线的功耗非常有效,它的额外代价是总线和功能模块之间的信号电平的变换电路。
- 对总线进行分段控制,根据总线和功能模块连接的物理结构,在信号传输的时候,隔断总线的无关部分,从而减小总线的实际电容,以达到降低功耗的作用。
- 通过对总线数据进行编码,是数据在总线上传输时引起的电平翻转减少(即减少了活性因子)。该方法使用最广泛、关于这一方法有相当多的研究。
2、RTL级低功耗设计和优化技术
2.1、状态分配
有限状态机的状态分配对其最终逻辑实现的面积有很大的影响
- 编码算法来减小每个状态转换过程的平均比特变化(如格雷码)。
- 将相关性强的状态分配汉明距离近的状态编码,来减小状态转换引起的电路活动。(很自然的逻辑,相邻的状态本身编码就该靠近)。
2.2、时钟技术
- 门控时钟(Gated Clock)技术在系统的某一部分电路处于空闲状态或做无用运算的时候,使其时钟信号无效,从而有效减少时钟驱动的功耗。这个相关的文章非常多,大家可以搜来看看。
- 另外一个常用的方法是双边沿触发器(DDR),此时输出在两个时钟沿都会发生改变,这样有效速率就达到系统时钟的两倍。这个额外的速率可以换取电源电压的降低。
2.3、预计算逻辑
预计算逻辑的基本思想是有选择地对电路输出的逻辑值进行提前一个时钟的预计算,然后利用预计算的值来减少电路内部的开关活动。
这个其实很好理解,就是在不影响关键路径的前提下,在本级逻辑中多算一些下一级逻辑需要的数据,减少下一级逻辑需要的运算,此方法还可以缩短关键路径。
- G应该尽可能多的包含输入信号,但又不能使得G太复杂。
- 电路的面积会有所增加,必须选择非关键模块和非关键路径的信号进行预计算。