ic进阶|面积篇01:改善面积的神器--折叠技术!以fir滤波器为例带你了解折叠技术!

在这里插入图片描述对于芯片来说,如果能够减少其中的大面积单元(例如乘法器、除法器、ram等等)的使用,对芯片面积的优化是十分重要的。本篇文章,我们介绍一种用于减少芯片面积的技术——折叠技术,这种技术是通过对同一运算单元(例如一个加法器)的共享,使得其能够分时复用在多个不同时刻的运算过程中,也就是以一个运算单元来替代多个运算单元,这样自然能够减少芯片的面积。

一、折叠技术

首先,让我们举一个例子,来说明折叠技术的应用:假设我们需要计算输入信号a、b、c的求和结果,最为直接的方法即使用两个同样的加法器先计算a+b,再计算b+c,例如下图左侧所示:
在这里插入图片描述
为了对面积进行优化,我们可以使用折叠计算,即使用一个加法器和两个选择器,对上述输入信号进行分时计算,例如:

  • 周期0:选择信号a和b作为加法器的输入进行加法计算,并对加法器输出结果打一拍。

  • 周期1:选择上一周期的计算结果(a+b)、和c作为加法器的输入,同样加法器输出结果将再打一拍。

  • 周期2: 输出完整的a+b+c的计算结果,同时,加法器输出下一轮计算的中间结果a+b。

从以上的分析,我们可以发现折叠计算实质上就是一种以时间换取面积的技术。通常,折叠技术可以在增加计算时间N倍的代价之下,减少硬件功能单元的数目到1/N。因此,如果我们只使用了并行结构或折叠技术的话,就会有两种相反的极端情况:一个是只采用并行结构,每个算法运算都分配了单独的功能单元,这样的话计算速度会很快,但是面积也会相应的增长;另一个是只使用折叠技术,相同的功能都在一个功能单元上执行,这样的话对面积优化,但是计算效率就会延迟。因此,在实际芯片设计中,最好是结合芯片设计指标,对这两种设计方法综合应用。

二、折叠变换

当我们需要使用折叠技术时,首先我们要做的就是定义折叠集,及其元素的顺序,这里的折叠集是由相同功能单元所执行运算的有序集,每一个折叠集包含**N个单元,我们将N称为折叠因子,也就是折叠到一个功能单元的运算数目,用于表征折叠的强度,**其中的一些可能是空运算。以下是一个3阶fir的例子:
在这里插入图片描述
如上图所示,一个3阶的fir滤波器,由4个乘法器和3个加法器组成,由于乘法器和加法器之间没有延时单元,我们可以认为由一个乘法器和一个加法器构成了一个基础功能单元(如上图的虚线框所示),因此,我们可以定义折叠因子N=4,于是有折叠集S0={MA0,MA1,MA2,MA3}。在这些节点之中,比较特别的是MA3节点处只有乘法器,我们只需要控制该节点计算时的加法器其中一个输入为0即可。

接着,我们定义**折叠序数,用于表示该节点在迭代周期N的第几个子周期被计算。**我们定义MA0最先计算,因此MA0的折叠序数(使用ma0表示)为0,可以写为S0|0,即该节点属于折叠集S0,折叠序数ma0为1;类似的我们分别定义节点MA1,MA2,MA3为S0|1,S0|2,S0|3。

在得到了折叠集和折叠序数后,我们就需要考虑各个节点之间计算的调度了,由于折叠因子N为4,因此我们一次迭代需要4个周期完成,在第1个子周期时,我们完成节点MA1到MA0的运算调度,我们使用这一条边举例:

  1. 首先,为了优化时序,我们可以在每个节点的出口加上流水线进行优化,节点MA1流水线的级数可以用Pma1表示,这里我们不加流水线,因此Pma1=0;

  2. 我们把迭代轮次设为l,那么节点MA1的第l次迭代结果将会在Nl+ma1+Pma1得到,其中的ma1为节点MA1的折叠序数。

  3. 从节点MA1到MA0这一条边有w(e)=1拍的延迟(有一个触发器),节点MA1的l次迭代结果被节点MA0在N(l+w(e))+ma2时刻执行的第(l+w(e))次迭代运算使用,因此,中间过程必须存储:

  4. 在这里插入图片描述
    以上就是一个节点到下一个节点的计算结果需要存储的拍数,ma0可推广到任一接收节点V,ma1可推广到任一发送节点U,如下图所示:
    在这里插入图片描述
    原有的功能单元在折叠后变成了右图一样的结构。从上图我们可以发现,我们需要求出的就是每个边之间的数据缓存拍数Df(U->V),我们将求Df(U->V)的方程称为折叠方程,3阶fir滤波器的折叠方程有:
    Df(MA3->MA2)=4*1-0+2-3=3

    Df(MA2->MA1)=4*1-0+1-2=3

    Df(MA1->MA0)=4*1-0+0-1=3

需要提醒的是这里的Df(U->V)不可以为负数,理由很简单负延时是不可实现的,也就是说只要所有折叠方程的结果非负,那么这个折叠变换就是可以进行的。

三、寄存器最小化

我们注意到折叠过程中需要添加很多寄存器用于缓存数据,这些寄存器也会有一定的面积,为了避免采用过量的寄存器,在本节我们来讨论如何使得这些寄存器数量最小化。

3.1 寿命分析

首先,我们需要进行寿命分析以求得折叠后需要的最少寄存器(即Df(U->V)),我们将从一个节点产生的变量到其被应用的时刻这之间的时间称为激活,变量在其激活的每个周期都要占据着一个寄存器。因此,我们只要确定了任意单位时间里的最大激活变量数,就可以确定折叠中所使用的最小寄存器数目了。

需要提示的是,在变量产生的时候是非激活的,也即不占用Df(U->V)这条线上的寄存器,从产生后的一个周期到被使用的周期才是激活的,也就会占用Df(U->V)这条线上的寄存器,直到变量被使用后该变量才会消亡。

我们可以采用线性寿命图的形式表示每个变量的寿命,首先,我们需要使用以下公式确定变量的产生和应用周期:
Tinput = u + Pu

Toutput = u + Pu + max{Df(U->V)}
解释一下,变量的产生周期为发送节点的折叠序数加上其流水线级数。变量的应用周期为产生周期加上其最大的数据缓存拍数。于是3阶fir的寿命表格如下所示:

在这里插入图片描述
上表中,MA0产生的变量直接输出,因此不需要求Tinput->Toutput。以 MA1为例,它的Tinput为1,表示MA1节点的变量在每次迭代的第2个子周期产生,Toutput为4,表示节点的变量在下一次迭代的第0个子周期被使用(消亡)。

接着,我们采用图形化的线性寿命图表示3阶fir中各个变量的寿命,我们采用水平线表示时钟周期,垂直线表示变量的寿命,如下图所示:

在这里插入图片描述
如上图所示,在周期4时,变量的激活数是最大的,为3,因此该折叠设计最少需要3个寄存器用于缓存数据(在Df(U->V)这条路径上)。此外,我们可以发现,在周期6时,变量激活数为1+1=2,这是因为下一次迭代,MA1输出的变量已经激活,因此使用1+1=2进行表示此时的变量激活数为2。

3.2 前向-后向寄存器分配的数据分配技术

在通过寿命分析确定了最小寄存数后,我们需要对变量进行分析,以确定变量在Df(U->V)这条路径上的寄存器分配方式。我们可以使用名为寿命分配表的方式进行分配,具体步骤如下所示:

  1. 在寿命期开始所对应的时间步输入每个变量,如下面的表格中的input一栏,如果在同一周期,有多个变量输入,那么就按照寿命最长的变量分配给初始寄存器,其他的按照寿命递减逐个分配给后续寄存器,
  • 举个例子:在周期0,有变量a,寿命为5,变量b,寿命为4,变量c,寿命为2,那么就把a、b、c依次分配给寄存器R1,R2,R3。
  1. 按照前向分配(即R0、R1、R2…Rn)的方式传递变量,直至变量消亡(如下图中的圆圈表示该变量的消亡),或者到达末尾寄存器。
  • 如下图所示,如果变量ma1在周期2,存放在寄存器R1中,那么在周期3,变量ma1应当传递到R2中,如果R2被占用了,那么按照前向分配的顺序传递给后续的第一个可用的前向寄存器。
    在这里插入图片描述
  1. 分配应是周期性的,当前迭代的分配在后续的迭代中会一直重复下去,这很好理解,如果每个周期的分配不同,只会增加控制电路的设计难度和造成资源浪费。
  • 举个例子:如果某个寄存器Rx在周期l,被变量a占据,那么在后续的迭代周期l+Nx(N是折叠因子)仍然会被变量a占据。
  1. 对于到达末尾寄存器但仍未消亡的变量,可以计算它的剩余寿命,然后基于先到先得(即寿命越短的变量应该安排的越接近末尾寄存器)的原则,将这些变量以后向(即Rn、Rn-1、Rn-2…R0)的方式分配给寄存器。
  • 我们需要先进行各个变量的前向分配,再进行剩余变量的后向分配。

  • 如果后向分配中有多个寄存器可以选择:

    首先选择已进行过后向分配的寄存器。

    选取其中有足够的数目的前向寄存器来完成变量分配的寄存器,如果仍有多个,则选择其中前向寄存器最少的那个寄存器。

    上述的前向分配到后向分配,再到前向分配的过程可能需要重复进行,直到变量的消亡。下面我们再举一个例子说明寿命分配表的使用:
    在这里插入图片描述
    简单解释一下:

  1. 首先进行前向分配的过程,各个变量在对应周期产生,并按照R1-R2-R3-R4的顺序进行前向分配,如上面的左图所示。

  2. 在周期5,变量b到达了末尾寄存器R4,且在周期6,只有一个寄存器R3可用于后向分配,因此在周期6将b分配给R3。

  3. 在周期6,变量c也到达了末尾寄存器R4,此时在周期7,有R1和R4两个寄存器可用于分配,且变量b的剩余寿命为1,c的剩余寿命为4,因此将变量b分配给R4,变量c分配给R1。

  4. 在周期9时,变量f也到达了末尾寄存器R4,且变量c的剩余寿命为1,f的剩余寿命为2,因此将f分配给R3,c分配给R4。

  5. 图中的黑色方块代表下一迭代时,这些对应的寄存器被占用。

通过上述分析,我们可以发现在未经过寿命分析,以及寄存器分配之前,该折叠结构至少需要8个额外的寄存器,但是经过了优化之后,只需要4个寄存器即可。

在完成了寄存器的分配后,我们就可以得到简化的折叠电路结构了,如下是3阶的fir滤波器的折叠结构:
在这里插入图片描述
上图中的括号中的内容代表的该变量在什么时刻有效或被选择,例如4l+1,代表在迭代次数l,第二个子周期该滤波器系数被选择。可以发现相比最初的结构来说,该3阶fir滤波器少了3个乘法器和2个加法器,多了1个寄存器和2个选择器以及对应的控制电路。面积方面还是节省了不少的,当然,代价就是速率的降低,原本结构下1个周期能够完成的动作,折叠后的结构需要4个周期才能够完成。

四、对3阶fir折叠结构的仿真

接下来,我们将上述的3阶fir结构使用verilog实现,并进行仿真验证。

首先,我们需要使用matlab产生原始输入数据,以及使用matlab的Filter Design来完成对3阶fir滤波器的设计。

在这里插入图片描述
如上图所示,我们需要确定fir的阶数,输入信号的采样频率,滤波器的通带上限截止频率和阻带截止频率,以及对滤波器的系数进行定点化操作,在这里我们使用8位的滤波器系数,并且其中有7位的小数,输入滤波器数据为16位整数。

依照上面的3阶fir折叠电路结构写出verilog代码,电路结构如下图所示,需要注意的是,由于折叠的fir4拍输出一个有效数据,因此添加了个data_vld用以指示data_out有效:
在这里插入图片描述
之后,我们使用matlab生成的原始数据和滤波器系数对我们的3阶fir滤波器进行仿真,并最终将fir滤波结果保存至txt文件中,并使用matlab进行读取,便于我们对滤波结构进行比较,结果如下所示:
在这里插入图片描述
上图从上往下,图1是原始数据,图2是matlab使用滤波器参数计算出来的滤波结果,图3是对我们使用verilog实现的3阶fir结构进行仿真得到的数据,图4是使用matlab和verilog的滤波结果之差,可以发现两者之间的差值在0.5以内,这可以说明我们折叠后的电路功能没啥大问题。此外,这个滤波器的滤波效果虽然有,但是如果想要更好的滤波效果,可以使用更加高阶的fir滤波器。

五、总结

以上就是我们本篇文章的主要内容了,除了上面讲到的寄存器最小化技术,我们还可以应用重定时对折叠结构进行优化,我们会在以后的篇章进行介绍~最后,如果想要获取上述3阶折叠fir滤波器的完整verilog代码和matlab等仿真文件,可以按照以下方式进行获取,并私信“fir源码”哦~
在这里插入图片描述
最后的最后,如果大家有什么感兴趣的ic内容,欢迎在评论区留言,可能会根据你们的需求出相关的文章哟~

如果你喜欢这篇文章的话,请关注我的公众号-熊熊的ic车间,里面还有ic设计和ic验证的学习资料和书籍等着你呢~欢迎您的关注!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数字ic小熊饼干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值