1. 为什么要引入暂停机制
这是未添加流水线暂停的系统机构框图,电脑绘图的话有时候添加输入输出就要进行大改动,我就手画了
在OpenMIPS流水线CPU设计中,乘累加、乘类减指令在流水线的运行阶段占用多个时钟周期,因此需要暂停流水线,等待这些多周期指令运行完成。
2. 暂停机制的设计
实现流水线的暂停:只需要保持取指令地址PC的值不变。同一时候保持流水线各个阶段的寄存器(也就是IF/ID、ID/EX、EX/MEM、MEM/WB模块的输出)不变。
OpenMIPS采用的改进方法:假如位于流水线第n阶段的指令需要多个时钟周期,进而请求流水线暂停,那么需要保持取指令地址PC的值不变。同一时候保持流水线第N阶段、第n阶段之前的各个阶段的寄存器不变,而第n阶段后面的指令继续执行。
比如,流水线执行阶段的指令请求流水线暂停,那么保持PC值不变,同一时候保持取指、译码、执行阶段的寄存器不变。可是能够同意访存、回写阶段的指令继续进行。
为此,设计加入CTRL模块。其作用是接收各个阶段传递过来的流水线暂停请求信号,从而控制流水线各个阶段的运行。为了实现流水线暂停机制,对原有的系统结构框图做了些修改。
3. CTRL模块
添加流水线暂停的结构框图
- CTRL模块的输入来自ID、EX、模块的请求暂停信号stallreq。暂时只考虑译码、执行阶段会有暂停请求,取指、访存阶段都没有暂停请求。指令读取、数据存储器的读写操作都在一个时钟周期完成。
- CTRL模块对暂停请求信号进行推断,然后输出流水线暂停信号stall。stall输出到PC、IF/ID、ID/EX、EX/MEM、MEM/WB等模块,从而控制PC的值,已经流水线各个阶段的寄存器。
4. 流水线暂停机制的实现
4.1 CTRL模块
输出stall是6位的信号,各位含义如下:
- stall[0]:表示取值地址PC是否保持不变,为1表示不变
- stall[1]:表示流水线取值阶段是否暂停,为1表示暂停
- stall[2]:表示流水线译码阶段是否暂停,为1表示暂停
- stall[3]:表示流水线执行阶段是否暂停,为1表示暂停
- stall[4]:表示流水线访存阶段是否暂停,为1表示暂停
- stall[5]:表示流水下回写阶段是否暂停,为1表示暂停
`define Stop 1'b1
`define NoStop 1'b0
module ctrl (
output reg [5:0] stall, // 暂停流水线的控制信号
input wire rst,
input wire stallreq_from_id, // 来自译码阶段的暂停请求
input wire stallseq_from_ex // 来自执行阶段的暂停请求
);
always @ (*) begin
if (rst == `RstEnable) begin
stall <= 6'b 00_0000;
end else if (stallreq_from_ex == `Stop) begin
stall <= 6'b 00_1111;
end else if (stallseq_from_id == `Stop) begin
stall <= 6'b 00_0111;
end else begin
stall <= 6'b 00_0000;
end
endmodule
- A. 当处于流水线执行阶段的指令请求暂停时,要求取指、译码、运行阶段暂停,访存、回写阶段继续,设置stall为6’b 00_1111;
- B. 当处于流水线译码阶段的指令请求暂停时,要求取指、译码阶段暂停,执行、访存、回写阶段继续,设置stall为6’b 00_0111;
- C. 其余情况,设置stall为6’b 00_0000,表示流水线不暂停;
其他模块
- 添加对应的输入输出信号;
- PC模块,增加PC赋值的选择情况分支;
- ID模块:在实现载入、存储指令的时候给stallreq信号赋值;
- EX模块:在实现乘累加、乘类减、除法指令的时候给stallreq信号赋值;
- 修改顶层模块OpenMIPS对应接口;