pipeline RISC设计(8)--提高时钟频率,三级流水线变五级流水线<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
增加时钟频率。使用增加流水线级数来增加时钟频率。
先观察前面的结构图,找出关键路径(因为在FPGA中乘法器已经经过专门的优化,暂时在关键路径寻找过程中忽略乘法器):如下图
为了提高时钟频率(fmax),需要在关键路径上增加寄存器将长的关键路径化为短的路径,见下图,草绿色的寄存器为增加的流水线寄存器。
注意在使用Pipeline register切分关键路径的技巧时,一定要保证不要破坏原有逻辑的内在时序要求;以两条数据路径为例来描述,所谓违反了原有逻辑的时序要求是指,原来的两条数据路径的入口和出口有同样的流水线层次,给一条数据路径增加了Pipeline register,使得两条数据路径的入口和出口的流水线层次不同了,而造成了错误。比如上图中因为增加了Pipeline register而引起的违反时序要求的的几处地方:
1) 从寄存器RFa取出的数据,按照要求应该和从RFb中取出的数据同时到达逻辑运算单元和算数运算单元的输入端;也就相当于寄存器的一个读端口(图中是RFa端口)跨越了两个流水级(流水级就是两条红色虚线所隔开的空间)
2) 移位运算跨越了3个流水级;也就是移位运算一个cycle就出结果,而alu运算或者移位运算需要3个cycles(以操作数读入“执行”级寄存器为第一个cycle)
3) External Memory Read跨越了2个流水级。把External Memory Read也看作一种运算,其输入是逻辑运算或者算数运算的结果,把该结果看作是External Memory的地址;因此该运算需要两个cycles
两条数据路径的入口和出口之间的流水线层次发生变化并不一定引起错误,要看具体的设计要求,要看两条数据路径的各自运算总cycle数要求。例如我们要求改装后两条数据路径正常运转后的Iteration为1个cycle,也就是每个cycle都能计算出各自得结果来,这时,就必须要求改装后两条数据路径的Pipeline级数必须是相同的。例如A/B数据路径改装前都是一个cycle的“流水线”,A数据路径改装后为3个cycle流水线,而B数据路径改装后为2个cycle的流水线,虽然A和B都能一个cycle计算出各自得结果,但是两条数据路径计算出的结果在时序上却对不齐了。要想对齐,必须在B数据路径增加一级流水线,简单的做法就是在B数据路径的输出级再增加一个输出锁存寄存器,使B也有三级流水线结构,最后只是简单的将数据多缓冲一个cycle。
那可不可以不增加输出寄存器,而只是通过时序的控制,使B计算出的数据在原有的流水线结构第二级多呆一个cycle呢?这要看具体情况了,如果设计可以使B的输入级每提供1个数据就休息一个cycle,也可以将B虚拟成3个cycle流水级结构。
跑题了,现在回到我们具体问题。例如我们的第2条违规,算数和逻辑运算的数据路径改造后经过的增加了3级流水线(译码/取数-运算-MEM级),而移位运算的数据路径还是改造前的一级(一个cycle),而对于CPU来说,如果我们要求CPU改造前/后都还是一个cycle执行一条指令,那么移位运算保持一级的流水线结构就是违例了,因为假如有如下的指令执行序:
算数指令—移位指令—算数指令—算数指令
第一条算数指令需要3个cycle,而紧接着的移位指令仅需要1个cycle,因此移位指令会先于第一条指令运算完毕,使得CPU执行运算出现异常(指令后执行却先得到结果)。
这时候为了修正这个异常,有两个常用办法,一个是改变控制方法虚拟两个cycle出来,一个是真正增加两个流水线级给移位计算路径。
第一种方法,改变对移位计算的控制方法,使得移位计算的结果空等两个cycle出来,让第一条指令执行完毕;但这时需要注意的是,还必须控制移位指令的输入级(也就是取指令/译码逻辑),使得前级暂停取指令/译码。这样一来,每执行一条移位指令,就会增加两个流水线bubble,造成流水线效率下降。
第二种方法,真正增加流水线级,如下图,代价是比第一种方法的芯片/FPGA的面积(逻辑)增加了。
上图增加流水线寄存器后,整个CPU数据路径原有的三级流水线结构变成了五级流水线结构:取指令(FD),指令译码/取操作数(ID),执行(EX),Memory读/写(ME),寄存器写回(WB)。
文章评论(0条评论)
登录后参与讨论