一、写在前面
流水线?大家好,我是富土康三号流水线的张全蛋。
在这之前,我们谈一谈:什么是流水线思想。
如果一家公司的主要工作是做数字IC设计,那么假设该公司做一个项目的周期为两年,每隔两年完成一个项目,然后开始一个新的项目。也就是说,完成N个项目需要的时间要20N个月,如下图所示。
那么,在数字IC设计中,我们可以根据流程划分为4个部门,分别完成:确定项目需求、系统级设计、前端设计、后端设计,其所需的时间分别为3个月、4个月、7个月和6个月,如下图所示。
于是,我们得到了下面分开独立工作的四个部门,如下图所示。
那么,在这里,部门1在第3个月完成工作后将项目一交给部门2进行下一步工作,此时,部门1就可以开始第二个项目的工作了。在第6个月,部门1已经完成了第二个项目的工作,可以将第二个项目交给部门2进行下一步工作了,但是问题在于部门2每做一个项目需要4个月,此时,部门2的第一个项目的工作都还没做完,需要等到第7个月完成第一个项目后才能接手第二个项目。所以,在这里虽然部门1做一个项目只需要3个月,但是要将当前做完的项目交接给部门2,必须等部门2完成上一个项目的工作后,也就是4个月,所以我们给部门1一个冗余的时间,让其每4个月接一个项目,于是就得到如下图所示的设计周期。
按照上图所示的设计周期,在第12个月,部门2完成了第二个项目,可以把第二个项目交接给部门3进行下一步的工作,但是和上面同样的问题,部门3此时第一个项目都还没做完,必须等到部门3的第一个项目做完了才能接手来自部门2的第二个项目。按照上面的处理方法,以此类推,我们只需要将所有部门完成一项工作的所需时间都调整为所有部门中完成一项工作所需时间的最大值即可,如下图所示。
那么,这样一来,该公司完成第一个项目需要28个月,虽然相较于最前面的每完成一个项目需要20个月的时间要多,但是以后的每隔7个月,该公司就可以完成一个项目,而最前面所讲的则是每个项目都需要20个月。相比之下,流水线生产要快的多,这就是流水线的思想。
二、正文开始
在这之前,在编写Verilog代码时,我总在想:时序逻辑中每插入一级寄存器,计算我们需要的数据就要多等一拍(一个时钟周期),那么输入的数据从输入端的寄存器到输出端的寄存器中间的运算如果都使用组合逻辑,也就不用浪费多个时钟的等待时间,那不是可以以最少的时间到达输出端。那么是不是这样的呢?带着这样的疑问我们开始下面的学习。
2.1举个栗子
2.2.1情况一(组合逻辑)
对于R=A&B&C&D,如果中间的三级与运算采用组合逻辑,如下图所示。假设系统时钟频率为33.33MHz(时钟周期为30ns),且所有的寄存器均工作在同一时钟下,那么在系统时钟的第一个时钟上升沿处(0ns),数据A、B、C、D分别从源寄存器发出,经过三个与门(这里内部连线延迟暂时不考虑,仅考虑逻辑单元的延迟,每个与门输入到输出的延迟假设为10ns),则需要30ns的时间,也就是说正好在系统时钟的第二个上升沿处(30ns)可以得到我们需要的正确输出值。
2.1.2情况二(流水线设计)
那么,对于上面这种情况,如果我们采用流水线设计的思想,将两个寄存器之间的计算步骤再进行拆分,拆分为多级寄存器到寄存器之间的运算,在三级与运算中再插入两级寄存器REG_1和REG_2,如下图所示。
在这里,很多人可能很疑惑,对于上面这种情况一,我计算一组数据(A&B&C&D)只需要30ns啊。那你这样子采用流水线设计,插入了两级的寄存器,计算一组数据就多出了两个时钟周期,也就是60ns,那不是采用流水线设计的需要90ns吗?
那么,在这里上面的分析是对的,对于一组数据的计算,确实是这样的。那如果说要计算5组数据呢?我们可以手算一下。
- 情况一:非流水线设计
第一个上升沿处(设为0点),源寄存器的数值分别输入到三个与门进行计算,在第二个时钟的上升沿得到第一组数据的计算结果,同时将第二组数据送入到三个与门进行计算,在第三个时钟的上升沿处得到了第二组数据的计算结果,同时将第三组数据送入到三个与门进行计算,在第四个时钟的上升沿处得到了第三组数据的计算结果,以此类推,计算五组数据需要五个时钟周期,所以计算五组数据的最小时间需要:
Time = 5 x 30ns = 150ns
- 情况二:流水线设计
对于第一组数据,第一个时钟上升沿(设为0点)处,源寄存器REG_A与REG_B的值同时输入到第一个与门进行计算,而在第二个时钟上升沿处,将源寄存器REG_C的值输入到第二个与门和第一个与门的计算结果进行计算,同时,可以将第二组数据的REG_A和REG_B输入到第一个与门进行计算。依次类推,在第三个时钟上升沿处,源寄存器REG_D的值输入到第三个与门和第二个与门的计算结果进行计算,同时,可以将第二组数据的REG_C的值和第一个与门的计算结果进行计算,同时,将第三组数据的REG_A和REG_B输入到第一个与门进行计算。依此类推。。。。。
在第四个上升沿后每隔一个时钟周期,都可以得到一组数据的计算结果,所以这里采用流水线设计计算五组数据所需的最小时间为:
Time = 3 x 30ns + 30ns + 30ns + 30ns + 30ns = 210ns
啊?这不是流水线设计比非流水线设计计算所需时间还要多吗?其实这里不是这样算的,或者可以说在流水线设计里面时钟周期不能以原始的时钟周期30ns来算了。因为在流水线设计中各级与门到寄存器的D端的时间为10ns,但是时钟周期为30ns,也就是说这中间的20ns差值是可以进行优化的,即提升主频至100MHz(缩短时钟周期为10ns)。那么,实际上流水线设计所需的最小时间为:
Time = 3 x 10ns + 10ns + 10ns + 10ns + 10ns = 70ns
这里,对于计算五组数据,流水线设计所需的运算时间70ns明显要比非流水线设计的时间150ns要小。
2.1.4 小总结
对于上面这种情况,取五组数据进行举例只是我随机选择的,在这里只是想说明一点,流水线设计(情况二)相对于非流水线设计(情况一),其第一组数据的计算时间要多或者相等(这里假设三级与门计算的时间相同,且相加起来正好等于时钟周期),但是随着计算数据组数的增加,非流水线设计需要每隔一个时钟周期(其时钟周期为30ns)才能输出一组数据的计算结果,而流水线设计每隔一个时钟周期(其时钟周期为10ns)就可以输出一组数据。
我们用Matlab进行仿真,以验证我们上面手算的结果,与我们手算的结果一致的是,如果在输入数据组数为5时,非流水线设计计算所需的时间时小于流水线设计计算所需的时间的,非流水线设计计算所需的时间为150ns,而流水线设计所需的时间为70ns,且随着组数的不断增加,这一差距不断增大。
2.2举第二个栗子
那么,我们在上面是三级一样的与门,所以我们假设其每级与门从输入到输出的时间一致,为10ns。那么,如果这里三级运算我们假设是其他的运算,且计算所需的时间分别为5ns、10ns、20ns,如下图所示。
则其采用非流水线设计计算五组数据所需要的时间还是一样的:
Time = 5 x 30ns = 150ns
但是我们如果采用流水线设计,则其最大时钟频率可以提升至66.67MHz(时钟周期为15ns),如下图所示。
那么,流水线设计计算五组数据所需的时间为:
Time = (15ns + 15ns + 15ns)+ 15ns + 15ns + 15ns + 15ns = 105ns
这里括号中是第一组数据计算得到结果所需的时间为第一组数据计算所需的时间,这里可以明显看出:对于流水线设计,其第一组数据计算所需时间(45ns)要比非流水线设计第一组数据计算所需时间(30ns)要多,但是从第二组数据开始,流水线设计每隔一个时钟周期(15ns)就会输出一组数据的计算结果,而非流水线设计每隔一个时钟周期(30ns)才会输出一组数据。
同样的,在这里,我们使用Matlab进行仿真,以验证我们的计算结果。
如上图所示,在输入数据的组数小于2时,流水线设计计算所需要时间要比非流水线设计计算所需要时间要多,但是当输入数据的组数大于2时,流水线设计计算所需要的时间要比非流水线设计计算所需要的时间要少,且这一差距随着输入数据组数的增大而增大。
写在最后
流水线设计是我们在设计中常用的一种方法,它通过”拆分“的方式将一项工作拆分为多项工作,可以提升系统设计的最高主频,降低大量数据计算所需的时间,以达到增加吞吐量的目的。那么,对于写在前面中的疑问也就迎刃而解。
好了,上面就是关于FPGA中流水线设计的一些学习笔记,如果有疑义的地方欢迎评论区友好探讨学习!!!!!