功耗问题是当前电路设计中的一个关键问题,对于如今的移动设备或者需要控制温度的高性能设备至关重要[5]。时钟门控(clock gating)是降低动态功耗的最有效的技术之一。当设计中的某些模块在进行无效计算时,使相应的时钟失效,不仅可以降低时钟树的功耗,也可以降低模块本身的功耗[5]。时钟门控技术的实现依靠电路网表中 "时钟门控条件(clock gating condition)" 的提取,一个质量好的时钟门控条件,既可以保证功耗优化的效果,又能做到不过度提升电路的复杂度。传统的时钟门控条件提取主要是基于结构化方法,本赛题提倡参赛者使用形式化分析的方法计算该条件。为了简化赛题,本赛题无需用 retiming 将 DFF 的 Q 端门控条件推到 D 端,最终判题只考虑 DFF 的 Q 端。
动态功耗介绍
在数字电路系统中,功耗主要分成两大类:动态功耗和静态功耗。其中影响静态功耗的因素很多,但是大部分是由制作工艺决定。所以在电路设计流程中,对静态功耗的控制和优化有限。相对而言,动态功耗的控制和优化容易很多。动态功耗的计算公式如下:
从公式中可以看出,影响动态功耗的因素主要有:电源电压 Vdd、时钟频率 f、电路基本单元的内部电容 Ci 和单元内逻辑状态切换的频率(switching activity)。其中在电路设计过程中,优化空间最大的就是这开关频率 SWi ,即节点信号从 0 跳转到 1 或者从 1 跳转到 0 的频率。计算公式为:
式子中 P 是该逻辑节点在给定的时间内跳转到 1 或者 0 的概率。如果用 P(x) 表示当前时间节点值跳转到 1 的概率,并且所有的输入在时间上是相互独立且不相关的,那么上述公式可以化解为:
门控时钟(clock gating)介绍
在一个复杂的电路设计中,并不是每一个逻辑单元在每一个时钟周期都能提供有效的计算,因此会产生很多“无效”的功耗。若能在下一个时钟周期来临之前,找出电路中“输出无效”的逻辑单元,并将这些单元的输入信号停掉,便能将这些无效的功耗优化掉。
基于上述的功耗优化策略,门控时钟(clock gating)提供了“时钟使能”方案。当一个逻辑单元的输出在下一个时钟周期里是“多余”的,便选择性的使驱动它的时钟信号失效。这样不仅可以降低逻辑信号的跳变频率,也可以降低时钟信号的跳变频率。因此,它是当前最有效的功耗优化方案之一。图1 为经典的锁存门控时钟电路图。
ODC(observability don’t care)介绍
对于电路网表中的一个信号 s,它在一个指定的条件 C 下,对电路的输出没有影响。那么这个条件 C 称为信号 s 的 ODC,可以表达为 ODCs = C。如果在网表中取一块子网表 Nc,该子网表的函数形式为 Fc(x,s),其中变量 s 作为子网表的输入,其他输入记为 x。如果在条件 x = x0 下,函数能满足:Fc(x0,0) = Fc(x0,1),则称信号 s 是不可观测的。因此信号 s 的 ODC 表达式可以由下式计算得到:
一个信号的 ODC 不仅仅与子网表的其他输入有关,也有可能和子网表的输出有关。如果子网表的输出在某种条件下是不可观测的无关项,那该条件也可以作为输入的 ODC。若上述 Nc 是单扇出的,信号 y 为子网表的输出信号,则信号 s 的 ODC 表达式可以更新为:
如果 Nc 是多扇出的,基于不同的扇出,同一信号的 ODC 表达式都有可能不同,所以可以用集合(ODC sets)来表示每一个 ODC。设 y1, y2, y3...yi 为该网表 i 个扇出信号, 则信号 s 的 ODC 表达式可以更新为:
式子中,ODCyj(y1,...,yj-1 = 1, yj+1,...,yi = 0) 代表着在表达式 ODCyj 中,变量 y1 ∼ yj-1 的值赋 1,变量 yj+1 ∼ yi 的值赋 0。
其中对于基本的 Mux 单元(S0 = 1 : Out = Data0,S1 = 1 : Out = Data1),它输入信号的 ODC 为 ODCData0 = S0 + ODCOut,ODCData1 = S1 + ODCOut(可以由式子5算出);对于 DFF 单元,当使能信号为 0 的时候,输入对输出无效,所以它输入信号的 ODC 为 ODCData = En + ODCOut。
图3 为含有多扇出节点的组合电路网表。假设 ODCU4 = ODCz1 = 0, ODCU5 = ODCz2 = 0,则 U2 输出信号的 ODC 为:
U3 输出信号的 ODC 为:
U1 输出信号的 ODC 为:
一般条件下,信号 z1 和 z2 需要同时满足,所以上式可以化简得到:
问题提出和 ODC 的近似
由上节的计算过程可以看出,若要精确的算出每个节点的 ODC 表达式,过程是非常复杂的。且该表达式的输入变量需要不断往网表的输入方向递归,越接近 PI 节点或者其他 DFF 的输出节点,变量数目便会越大,相应的表达式规模也越大。所以在计算过程中,要尽可能的采用近似且保真的方案缩小算式的规模,简化表达式。
如图4 所示,假设 ODCOut = 0,DFF 的输出端口 Q_Out 的 ODC 为 ODCQ_Out = SEL0 + SEL1。为了降低信号传输延时的影响,需要将变量 SEL0 和 SEL1 往网表输入方向推,假设 SEL0, x[0] ∼ x[5]为网表的 PI 端口,则有 ODCQ_Out = SEL0 + x[0] ⊕ x[1] ⊕ ... ⊕ x[5]。此时表达式的变量数为 7,若要限制表达式规模,将输入变量数约束在 4 个以内,可以直接省去 SEL1,即近似为 ODCOut = SEL0。
上例提供了一个简单的近似思路,通过舍去复杂逻辑来简化表达式。 但是近似也不是简单的 “舍去” 的过程,需要在缩小表达式规模的同时, 既能保证所有表达式的正确性,又能权衡表达式的质量(质量判断标准 见8.1)。在[1][2][3][4]中提供了部分近似思路。
描述
本赛题需要参赛队伍根据所提供的电路网表,给出网表中每一个 Flip-Flop 输出信号的 ODC 表达式,且表达式的变量为该网表的 PI 节点或者 Flip-Flop 的输出节点。本赛题打榜首先需要考虑所给出表达式的正确性,在该表达式约束下,不影响原电路的功能;其次会考虑表达式的质量,其中包括算法所耗的时间、表达式的规模(输入变量数)、在表达式约束下信号的开关频率。且本赛题禁止采用并行计算。
本赛题会通过功能仿真(random simulation)的形式验证 ODC 表达式是否正确。对于给定的 ODC 表达式,会在相应的 DFF 的输出口增加约束,如图5 所示。由于本赛题不考虑电路的面积和延时,这里选择在每个 DFF 的输出接上 D-LATCH,并由 ODC 取反控制使能端口 E。当 ODC 为 1 时,说明 Q_OUT 为无关项,此时 E = 0,数据锁存; 反之,当 ODC 为 0 时,有 out = Q_OUT。在对所有的 DFF 加完约束后,给电路网表随机激励,判断 ODC 约束前后输出是否一致。若一致,则表达式正确。
本赛题通过 ODC 表达式的开关频率来判断质量。由于 ODC 表达式的目标为降低电路网表动态功耗,动态功耗由开关频率决定,所以根据式2 可得图5 中 out 端的开关频率:
这里 SW_ORG 为原网表信号的 SW 值,SW_ODC 为加入 ODC 约束后的信号 SW 值,其中 SW 值由仿真计算得到。
在计算完成后,需要按照图6 的格式进行输出,文件后缀为 .odc。其中, DFF_ID 为 df 的 id,由前端软件中的编号决定;DFF_Name 为 df 的名字,由输入网表中的例化名字决定(在本赛题所提供的网表中,为模块“VERIFIC_DFFRS”后 的例化名字,不可自己改名);VAR_Num 为 ODC 的变量数目;ODC 为具体 的表达式,统一为积之和(sum of product)的形式,其中与为 “&”,或为 “|”,非为 “∼”,格式请严格遵守图6。另外要注意的是,DFF_ID、DFF_Name、 VAR_Num 和 ODC 这些关键字顺序也不能变,和图6 一致即可。
源代码
推荐参赛队伍基于开源逻辑综合工具 Yosys 和 abc 为基础进行开发。Yosys 拥有比较完整的 verilog 网表读入解析功能,其内部 RTLIL 数据结构对电路网表的表达能力很强,可以基于该结构对电路网表进行分析和优化。Yosys 还内置了逻辑综合工具 abc,abc 可以将网表解析成 aig(and-inverter graph) 网表,分析和计算也可以基于 aig 网表。当然,参赛团队也可以使用自己熟悉的工具进行开发。只要最后生成的表达式符合规定即可。
Yosys 源码地址: https://github.com/YosysHQ/yosys
abc 源码地址: https://github.com/berkeley-abc/abc
赛题 case
本赛题会提供两组竞赛 Case,一组是公开的用于日常调测,另一组是非公开的用于竞赛打榜。可参见后文的”评分标准”章节。
接口
若使用 Yosys、abc 等开源代码,请仔细阅读开源代码的 README 或文档。