前提
其实在第一篇文章里面我们就有讲了一点点流水线的相关知识,而这篇文章是在我写完了RISC-V的功能实现后补上的一篇文章,因为这里面涉及到不少关于RISC-V设计的重点知识。
RISC-V实践部分我们使用的是三级流水,包含了取指、译码和执行三个步骤。
tinyriscv的流水线结构图:
1.流水线
流水线是一种能够实现多条指令重叠执行的技术,和工业流水线相似,能极大的提高处理器的工作效率。
作者对使用流水线的解释:
在RISC-V上采用流水线方式执行指令通常是5步,也就是我们常说的5级流水:
1.从存储器中取出指令
2.读寄存器并译码指令
3.执行操作或计算地址
4.访问数据存储器中的操作数 (如有必要)
5.将结果写入寄存器人(如有必要)
单周期、非流水线的指令执行(上方图像)和流水线指令执行(下方图像)的对比图:
注释:采用流水线指令执行的指令平均执行时间是单周期、非流水线的指令执行的1/4,执行速度直接提升了4倍(速度提升并非一定是4倍,这里是为了突出流水线对指令执行速度的重要性)。
1.时钟周期
所有的流水线阶段都需要一个时钟周期,流水线的时钟周期必须满足最慢指令执行的时间。
时钟周期也叫 时钟周期数,滴答数,为计算机一个时钟周期的时间,有时候我们也会提及它的倒数-时钟频率
2.流水线冒险
流水线冒险:在流水线中有可能出现在下一个时钟周期中下一条指令无法执行的情况,其中又有3种冒险。
1.结构冒险:因缺乏硬件支持导致指令在预期时钟周期内无法执行完毕。
2.数据冒险:因不能提供指令执行所需要的数据导致指令在预期时钟周期中无法执行完毕。
3.控制冒险(分支冒险):因取到的指令不是所需要的或者指令流向不是流水线预期的导致正确指令在预期时钟周期中无法执行完毕。
3. 流水线数据通路和控制
数据线通路
用来操作或保存处理器中数据的单元。在RISC-V中包括指令寄存器、数据寄存器、寄存器堆炖好ALU和加法器
数据通路分5部分:
扩展:
在IF和ID中间的流水线寄存器被命名为IF/ID
4.流水线停顿
流水线停顿也称气泡,为解决流水线冒险而实施的一种阻塞。其实就是发送空指令(一种不执行任何操作、不改变任何状态的指令,也就是NOP指令)。
项目作者的解释:
ctrl.v(控制模块,用来发出跳转、暂停流水线信号)
序号 信号名 输入/输出 位宽(bits) 说明 1 rst 输入 1 复位信号 2 jump_flag_i 输入 1 跳转标志,来源于ex.v的jump_flag_o 3 jump_addr_i 输入 32 跳转地址,来源于ex.v的jump_addr_o 4 hold_flag_ex_i 输入 1 来自执行模块的暂停标志,来源于ex.v的hold_flag_ex_o 5 hold_flag_rib_i 输入 1 来自总线模块的暂停标志,来源于rib.v的hold_flag_o 6 jtag_halt_flag_i 输入 1 来自jtag模块的暂停标志,来源于jtag_top.v的halt_req_o 7 hold_flag_clint_i 输入 1 来自中断模块的暂停标志,来源于hold_flag_o 8 hold_flag_o 输出 3 暂停标志,输出到pc_reg.v的hold_flag_i 9 jump_flag_o 输出 1 跳转标志,输出到pc_reg.v的jump_flag_i 10 jump_addr_o 输出 32 跳转地址,输出到pc_reg.v的jump_addr_i