16位5级流水线CPU设计
2016-05-17 23:13
369 查看
使用工具:Xilinx ISE 14.7
PCPU(pipeline—CPU)架构图:
对于CPU5级流水线的设计首先要确定的是它和多周期的区别,在设计多周期CPU时我们会发现,在运行时有些指令是可以并行执行的,因此有了流水线的设计用于提高CPU的利用率。,为了能够并行执行指令我们需要处理指令间的冲突,在这里列出三种冲突的处理(Dataforward,STALL,Control Hazard)
1.4. Hazard处理分析
CPU的dataforward——HAZARD处理即提前预处理.。对Hazard的实现有点类似于对输入数据进行提前操作,及在当得到某一条指令的情况下,马上对目标寄存器进行按路线越级输入,可忽视五级流水线的逐级循序跳跃。用于减少操作步骤与时间,充分体现流水线的设计优势。
DataForward处理
由此我们可以发现,该五级流水线设计经过Hazard处理后,可以减少3个步骤,即减少了3个NOP指令,使CPU运算更加快捷、高速。
举例分析——对reg_A的在ADD指令下Hazard处理:
!——Hazard处理前:
对reg_A赋值时需要经过的路径:
ALUo——reg_C——reg_C1——所调用寄存器——reg_A
!——Hazard处理后:
对reg_A赋值只需判断处于id_ir之后的3个指令寄存器是否满足条件,由于ADD指令中reg_A的调用为id_ir指令“{宏定义,寄存器1,1’bx,寄存器2,1’bx,寄存器3}”的寄存器2,因此判断时所调用的寄存器2与另3个指令寄存器里所调用的目标寄存器一是否一致并且另3个指令寄存器里的指令为有效的运算指令(此时说明id_ir所调用的寄存器与其他3个指令的目标寄存器存在冲突)即可。
具体描述,当id_ir之后的第一个指令寄存器ex_ir 满足条件时,直接间ALUo的值赋予reg_A,否则判断id_ir之后的第二个指令寄存器mem_ir是否满足条件,若满足条件,因为MEM这一级中有可能存在LOAD指令的调用,所需要判断此时指令寄存器mem_ir的指令是否为LOAD,若为LOAD则将d_datain的值赋予reg_A,否则直接将reg_C的值赋予reg_A,若前两者都不满足,则判断最后一个指令寄存器是否满足条件,若满足直接将reg_C1的值赋予reg_A。
若三个指令寄存器接不满足条件,则说明不存在数据冲突,指令间无相关性,则直接用目标寄存器对reg_A赋值即可。
在这里对reg_A的赋值中直接为xxx——reg_A,比Hazard处理前直接减少了三步操作。由此我们可以发现采用了Hazard 处理,避免了在程序进行时的数据冲突,当指令之间存在相关性,而且它们的执行时间相近时,可能会在流水线中重叠操作,或者指令的重新排序改变了有相关的操作数的访问数序,减少了空闲指令的使用,使CPU的运行更高效,更有序。
STALL处理
对于LOAD指令而言,由于需要从Data Memory读取相应的值,也就是说要先在EX阶段算出相应数据在Data Memory的地址,所以通过LOAD指令所获取的数据最快可以在EX之后得到。但是如果在LOAD指令之后的下一条指令需要马上使用LOAD所得的数据时就会产生冲突,因为在LOAD的下一条指令在译码时,LOAD指令恰好正在从Data Memory中获取数据,无法使得通过LOAD所得的数据 在下一条指令中被使用。因此对于这种冲突,可以采用一种简单粗暴的方法来解决,即强制让LOAD的下一条指令延迟一个时钟周期后再被执行
如下图:
Control Hazard处理
对于跳转指令而言,再进行冲突处理之前,除了JUMP以外的跳转指令都是在流水线第四级得到flag之后才会发生跳转,而对于指令而言,最好是在得到上一条指令的输入后,在跳转指令输入时马上可以判断并进行跳转,因此可以将跳转的地址的运算放入IF阶段中,在获取指令的同时,算出将要跳转的位置,这样就可以使得指令的连续执行可以被实现。
冲突处理的主要代码:
Data Forward ->
对reg_A的DataForward(分为r1(指令【10:8】)与r2(指令【7:4】))
R1-》
R2-》
对reg_B的DataForward(寄存器r3(指令【2:0】))
对smdr的DataForward(STORE的数据中转)
Stall Forward ->
LOAD指令
Control Forward ->
跳转指令
跳转
地址获取
附录:
工程实现代码链接:16位5级流水线CPU设计
操作说明对于不同的测试要同时更改在Instruction Memory里的指令以及Data Memory里的数据,使指令与将要被调用的数据对于某个程序而言是一致的,然后进行仿真
PCPU(pipeline—CPU)架构图:
对于CPU5级流水线的设计首先要确定的是它和多周期的区别,在设计多周期CPU时我们会发现,在运行时有些指令是可以并行执行的,因此有了流水线的设计用于提高CPU的利用率。,为了能够并行执行指令我们需要处理指令间的冲突,在这里列出三种冲突的处理(Dataforward,STALL,Control Hazard)
1.4. Hazard处理分析
CPU的dataforward——HAZARD处理即提前预处理.。对Hazard的实现有点类似于对输入数据进行提前操作,及在当得到某一条指令的情况下,马上对目标寄存器进行按路线越级输入,可忽视五级流水线的逐级循序跳跃。用于减少操作步骤与时间,充分体现流水线的设计优势。
DataForward处理
由此我们可以发现,该五级流水线设计经过Hazard处理后,可以减少3个步骤,即减少了3个NOP指令,使CPU运算更加快捷、高速。
举例分析——对reg_A的在ADD指令下Hazard处理:
!——Hazard处理前:
对reg_A赋值时需要经过的路径:
ALUo——reg_C——reg_C1——所调用寄存器——reg_A
!——Hazard处理后:
对reg_A赋值只需判断处于id_ir之后的3个指令寄存器是否满足条件,由于ADD指令中reg_A的调用为id_ir指令“{宏定义,寄存器1,1’bx,寄存器2,1’bx,寄存器3}”的寄存器2,因此判断时所调用的寄存器2与另3个指令寄存器里所调用的目标寄存器一是否一致并且另3个指令寄存器里的指令为有效的运算指令(此时说明id_ir所调用的寄存器与其他3个指令的目标寄存器存在冲突)即可。
具体描述,当id_ir之后的第一个指令寄存器ex_ir 满足条件时,直接间ALUo的值赋予reg_A,否则判断id_ir之后的第二个指令寄存器mem_ir是否满足条件,若满足条件,因为MEM这一级中有可能存在LOAD指令的调用,所需要判断此时指令寄存器mem_ir的指令是否为LOAD,若为LOAD则将d_datain的值赋予reg_A,否则直接将reg_C的值赋予reg_A,若前两者都不满足,则判断最后一个指令寄存器是否满足条件,若满足直接将reg_C1的值赋予reg_A。
若三个指令寄存器接不满足条件,则说明不存在数据冲突,指令间无相关性,则直接用目标寄存器对reg_A赋值即可。
在这里对reg_A的赋值中直接为xxx——reg_A,比Hazard处理前直接减少了三步操作。由此我们可以发现采用了Hazard 处理,避免了在程序进行时的数据冲突,当指令之间存在相关性,而且它们的执行时间相近时,可能会在流水线中重叠操作,或者指令的重新排序改变了有相关的操作数的访问数序,减少了空闲指令的使用,使CPU的运行更高效,更有序。
STALL处理
对于LOAD指令而言,由于需要从Data Memory读取相应的值,也就是说要先在EX阶段算出相应数据在Data Memory的地址,所以通过LOAD指令所获取的数据最快可以在EX之后得到。但是如果在LOAD指令之后的下一条指令需要马上使用LOAD所得的数据时就会产生冲突,因为在LOAD的下一条指令在译码时,LOAD指令恰好正在从Data Memory中获取数据,无法使得通过LOAD所得的数据 在下一条指令中被使用。因此对于这种冲突,可以采用一种简单粗暴的方法来解决,即强制让LOAD的下一条指令延迟一个时钟周期后再被执行
如下图:
Control Hazard处理
对于跳转指令而言,再进行冲突处理之前,除了JUMP以外的跳转指令都是在流水线第四级得到flag之后才会发生跳转,而对于指令而言,最好是在得到上一条指令的输入后,在跳转指令输入时马上可以判断并进行跳转,因此可以将跳转的地址的运算放入IF阶段中,在获取指令的同时,算出将要跳转的位置,这样就可以使得指令的连续执行可以被实现。
冲突处理的主要代码:
Data Forward ->
对reg_A的DataForward(分为r1(指令【10:8】)与r2(指令【7:4】))
R1-》
R2-》
对reg_B的DataForward(寄存器r3(指令【2:0】))
对smdr的DataForward(STORE的数据中转)
Stall Forward ->
LOAD指令
Control Forward ->
跳转指令
跳转
地址获取
附录:
工程实现代码链接:16位5级流水线CPU设计
操作说明对于不同的测试要同时更改在Instruction Memory里的指令以及Data Memory里的数据,使指令与将要被调用的数据对于某个程序而言是一致的,然后进行仿真
相关文章推荐
- 算法解剖系列-Otsu二值化原理及实现
- Lua为啥这么好?
- C++面向对象实验(五)
- centos mysql 安装及配置
- ARC和非ARC区别
- ZUFE2389: Occult的卡片升级计划(DP)
- kombu------python的消息库
- python 安装 cairo
- lua API 小记3(lua虚拟机初始化)
- 读书笔记《iPhone应用开发从入门到精通》——Objective-C的内存管理
- CSS层次选择器温故-2
- Android Studio配置与使用GSON框架解析json数据
- Nginx 多个版本都适用的伪静态配置
- RK3288_emmc走线优化造成不刷机的问题!!三星EMMC_V4.5以上不可用!
- Java认识
- 缓冲区溢出
- 步步学习之用python实战机器学习1-kNN (K-NearestNeighbors)算法(a)
- lua 函数调用1 -- 闭包详解和C调用
- tomcat部署多个项目多个接口配置
- OpenSSL加密系统简介