将陆续上传本人写的新书《自己动手写CPU》,今天是第28篇。我尽量每周四篇

China-pub的预售地址例如以下(有文件夹、内容简单介绍、前言):

http://product.china-pub.com/3804025

亚马逊的预售地址例如以下,欢迎大家围观呵。

http://www.amazon.cn/dp/b00mqkrlg8/ref=cm_sw_r_si_dp_5kq8tb1gyhja4

7.5 流水线暂停机制的设计与实现

7.5.1 流水线暂停机制设计

由于OpenMIPS设计乘累加、乘累减、除法指令在流水线运行阶段占用多个时钟周期,因此须要暂停流水线,以等待这些多周期指令运行完成。一种直观的实现方法是:要暂停流水线,仅仅需保持取指令地址PC的值不变。同一时候保持流水线各个阶段的寄存器(也就是IF/ID、ID/EX、EX/MEM、MEM/WB模块的输出)不变。

OpenMIPS採用的是一种改进的方法:假如位于流水线第n阶段的指令须要多个时钟周期,进而请求流水线暂停,那么需保持取指令地址PC的值不变。同一时候保持流水线第n阶段、第n阶段之前的各个阶段的寄存器不变,而第n阶段后面的指令继续执行。

比方:流水线执行阶段的指令请求流水线暂停,那么保持PC不变,同一时候保持取指、译码、执行阶段的寄存器不变。可是能够同意訪存、回写阶段的指令继续执行。

为此,设计加入CTRL模块。其作用是接收各个阶段传递过来的流水线暂停请求信号,从而控制流水线各个阶段的执行。

为了实现流水线暂停机制,对系统结构做如图7-10所看到的的改动。

CTRL模块的输入来自ID、EX模块的请求暂停信号stallreq。对于OpenMIPS教学版而言,仅仅有译码、运行阶段可能会有暂停请求。取指、訪存阶段都没有暂停请求。由于指令读取、数据存储器的读写操作都能够在一个时钟周期完毕。

CTRL模块对暂停请求信号进行推断,然后输出流水线暂停信号stall。从图7-10中可知,stall输出到PC、IF/ID、ID/EX、EX/MEM、MEM/WB等模块。从而控制PC的值,以及流水线各个阶段的寄存器。

7.5.2 流水线暂停机制实现

      1、CTRL模块的实现

CTRL模块的接口如图7-10中所看到的,各接口作用如表7-1所看到的。

读者须要注意:输出信号stall是一个宽度为6的信号。其含义例如以下。

  • stall[0]表示取指地址PC是否保持不变。为1表示保持不变
  • stall[1]表示流水线取指阶段是否暂停,为1表示暂停
  • stall[2]表示流水线译码阶段是否暂停。为1表示暂停
  • stall[3]表示流水线运行阶段是否暂停,为1表示暂停
  • stall[4]表示流水线訪存阶段是否暂停,为1表示暂停
  • stall[5]表示流水线回写阶段是否暂停,为1表示暂停

CTRL模块的代码例如以下。源文件是本书附带光盘Code\Chapter7_2文件夹下的ctrl.v。

module ctrl(input wire        rst,input wire          stallreq_from_id,   // 来自译码阶段的暂停请求input wire          stallreq_from_ex,   // 来自运行阶段的暂停请求output reg[5:0]     stall       );always @ (*) beginif(rst == `RstEnable) beginstall <= 6'b000000;end else if(stallreq_from_ex == `Stop) beginstall <= 6'b001111;end else if(stallreq_from_id == `Stop) beginstall <= 6'b000111;end else beginstall <= 6'b000000;endendendmodule当中宏定义Stop在defines.v中定义。例如以下:
`define Stop                 1'b1               // 流水线暂停
`define NoStop               1'b0               // 流水线继续

能够从下面三点理解。

(1)当处于流水线运行阶段的指令请求暂停时(即stallreq_from_ex等于Stop),依照OpenMIPS流水线暂停机制的设计。要求取指、译码、运行阶段暂停。而訪存、回写阶段继续,所以设置stall为6'b001111。

(2)当处于流水线译码阶段的指令请求暂停时(即stallreq_from_id等于Stop),依照OpenMIPS流水线暂停机制的设计。要求取指、译码阶段暂停,而运行、訪存、回写阶段继续,所以设置stall为6'b000111。

(3)其余情况下。设置stall为6'b000000,表示不暂停流水线。

      2、改动取指阶段

(1)改动PC模块

从图7-10中可知,PC模块新添加了一个输入信号stall,其值就是CTRL模块的接口stall。改动取指阶段PC模块的代码例如以下,当中改动的代码使用加粗、斜体标识。

源文件是本书附带光盘Code\Chapter7_2文件夹下的pc_reg.v。

module pc_reg(input   wire              clk,input  wire             rst,input  wire[5:0]              stall,  // 来自控制模块CTRLoutput reg[`InstAddrBus]      pc ,output reg                    ce
);always @ (posedge clk) beginif (rst == `RstEnable) begince <= `ChipDisable;end else begince <= `ChipEnable;endend// 当stall[0]为NoStop时,pc加4,否则,保持pc不变always @ (posedge clk) beginif (ce == `ChipDisable) beginpc <= 32'h00000000;end else if(stall[0] == `NoStop) beginpc <= pc + 4'h4;endendendmodule

(2)改动IF/ID模块

參考图7-10,IF/ID模块也新增了一个输入信号stall,主要改动例如以下,改动的代码使用加粗、斜体标识。完整代码參考本书附带光盘Code\Chapter7_2文件夹下的if_id.v文件。

module if_id(
......input wire[5:0]               stall,
);//(1)当stall[1]为Stop,stall[2]为NoStop时。表示取指阶段暂停,//     而译码阶段继续,所以使用空指令作为下一个周期进入译码阶段的指令。//(2)当stall[1]为NoStop时,取指阶段继续。取得的指令进入译码阶段。

//(3)其余情况下。保持译码阶段的寄存器id_pc、id_inst不变。 always @ (posedge clk) begin if (rst == `RstEnable) begin id_pc <= `ZeroWord; id_inst <= `ZeroWord; end else if(stall[1] == `Stop && stall[2] == `NoStop) begin id_pc <= `ZeroWord; id_inst <= `ZeroWord; end else if(stall[1] == `NoStop) begin id_pc <= if_pc; id_inst <= if_inst; end end endmodule

      3、改动译码阶段

(1)改动ID模块

參考图7-10,ID模块新增了一个输出信号stallreq,在实现载入、存储指令的时候会给该信号赋值,眼下临时设置这个输出就是NoStop,详细代码不再给出。读者能够參考本书附带光盘Code\Chapter7_2文件夹下的id.v文件。

(2)改动ID/EX模块

參考图7-10,ID/EX模块新增了一个输入信号stall,主要改动例如以下,改动的代码使用加粗、斜体标识。完整代码位于本书附带光盘Code\Chapter7_2文件夹下的id_ex.v文件。

module id_ex(
......//来自控制模块的信息input wire[5:0]    stall,......
);//(1)当stall[2]为Stop,stall[3]为NoStop时。表示译码阶段暂停,//     而运行阶段继续,所以使用空指令作为下一个周期进入运行阶段的指令。

//(2)当stall[2]为NoStop时。译码阶段继续。译码后的指令进入运行阶段。

//(3)其余情况下,保持运行阶段的寄存器ex_aluop、ex_alusel、ex_reg1、 // ex_reg2、ex_wd、ex_wreg不变。

always @ (posedge clk) begin if (rst == `RstEnable) begin ...... end else if(stall[2] == `Stop && stall[3] == `NoStop) begin ex_aluop <= `EXE_NOP_OP; ex_alusel <= `EXE_RES_NOP; ex_reg1 <= `ZeroWord; ex_reg2 <= `ZeroWord; ex_wd <= `NOPRegAddr; ex_wreg <= `WriteDisable; end else if(stall[2] == `NoStop) begin ex_aluop <= id_aluop; ex_alusel <= id_alusel; ex_reg1 <= id_reg1; ex_reg2 <= id_reg2; ex_wd <= id_wd; ex_wreg <= id_wreg; end end endmodule

      4、改动运行阶段

(1)改动EX模块

參考图7-10,EX模块新增了一个输出信号stallreq_from_ex,在本章后面实现乘累加、乘累减、除法指令的时候会给该信号赋值。

(2)改动EX/MEM模块

參考图7-10,EX/MEM模块新增了一个输入信号stall,主要改动例如以下。改动的代码使用加粗、斜体标识。完整代码位于本书附带光盘Code\Chapter7_2文件夹下的ex_mem.v文件。

module ex_mem(
......//来自控制模块的信息input wire[5:0]         stall,......
);//(1)当stall[3]为Stop,stall[4]为NoStop时,表示运行阶段暂停。//     而訪存阶段继续,所以使用空指令作为下一个周期进入訪存阶段的指令。

//(2)当stall[3]为NoStop时,运行阶段继续,运行后的指令进入訪存阶段。 //(3)其余情况下。保持訪存阶段的寄存器mem_wb、mem_wreg、mwm_wdata、 // mem_hi、mem_lo、mem_whilo不变。 always @ (posedge clk) begin if(rst == `RstEnable) begin ...... end else if(stall[3] == `Stop && stall[4] == `NoStop) begin mem_wd <= `NOPRegAddr; mem_wreg <= `WriteDisable; mem_wdata <= `ZeroWord; mem_hi <= `ZeroWord; mem_lo <= `ZeroWord; mem_whilo <= `WriteDisable; end else if(stall[3] == `NoStop) begin mem_wd <= ex_wd; mem_wreg <= ex_wreg; mem_wdata <= ex_wdata; mem_hi <= ex_hi; mem_lo <= ex_lo; mem_whilo <= ex_whilo; end //if end //always endmodule

      5、改动訪存阶段

訪存阶段仅仅要改动MEM/WB模块。參考图7-10,MEM/WB模块也新增了一个输入信号stall。主要改动例如以下,改动的代码使用加粗、斜体标识。

完整代码位于本书附带光盘Code\Chapter7_2文件夹下的mem_wb.v文件。

module mem_wb(
...... //来自控制模块的信息input wire[5:0]               stall,  ......
);//(1)当stall[4]为Stop。stall[5]为NoStop时,表示訪存阶段暂停,//     而回写阶段继续。所以使用空指令作为下一个周期进入回写阶段的指令。//(2)当stall[4]为NoStop时。訪存阶段继续,訪存后的指令进入回写阶段。

//(3)其余情况下,保持回写阶段的寄存器wb_wd、wb_wreg、wb_wdata、 // wb_hi、wb_lo、wb_whilo不变。 always @ (posedge clk) begin if(rst == `RstEnable) begin ...... end else if(stall[4] == `Stop && stall[5] == `NoStop) begin wb_wd <= `NOPRegAddr; wb_wreg <= `WriteDisable; wb_wdata <= `ZeroWord; wb_hi <= `ZeroWord; wb_lo <= `ZeroWord; wb_whilo <= `WriteDisable; end else if(stall[4] == `NoStop) begin wb_wd <= mem_wd; wb_wreg <= mem_wreg; wb_wdata <= mem_wdata; wb_hi <= mem_hi; wb_lo <= mem_lo; wb_whilo <= mem_whilo; end //if end //always endmodule

      6、改动顶层模块OpenMIPS

由于上面加入了CTRL模块,并且对流水线各个阶段的模块也都添加了对应的接口。所以要改动OpenMIPS模块。以将新增接口与CTRL模块连接起来,连接关系如图7-10所看到的,详细代码不在书中列出,读者能够參考本书附带光盘Code\Chapter7_2文件夹下的openmips.v文件。

下一次将利用上面实现的流水线暂停机制实现乘累加、乘累减指令,敬请关注!

自己动手写CPU之第七阶段(5)——流水线暂停机制的设计与实现相关推荐

  1. 自己动手写cpu 光盘_自己动手写CPU配套源码

    自己动手写CPU的源代码,一共15章,可以完整实现MIPS的指令 文件:n459.com/file/25127180-476886294 以下内容无关: ----------------------- ...

  2. 【自己动手写CPU】异常相关指令的实现

    MIPS架构中定义的异常类型 MIPS32架构中,有些事情打断程序的正常的执行流程,这些事情称为中断.陷阱.系统调用以及其他打断程序执行流程的情况,统称为异常. 此处的OpenMIPS处理器只实现了其 ...

  3. 自己动手写CPU(2)第一条ori指令

    本博客内容基于<自己动手写CPU>这本书 上一篇文章介绍了一下流水线思想.设计流程等,下面我们可以实操一下实现第一条ori指令. 其实实现一条ori指令不难,我目前对这一条指令的理解简单来 ...

  4. 【自己动手写CPU】第一条指令ori的实现

    验证过程 实现ori指令->建立最小SOPC->验证ori指令是否正确 ori指令说明 ori是进行逻辑"或"的运算指令 ori指令的指令码是6'b001101.处理器 ...

  5. 自己动手写CPU(8)加载存储指令的实现

    自己动手写CPU(8)加载存储指令的实现 好久没更新blog了,暑假提前放了.现在收假也该收收心了,继续捡起之前的CPU,自己开的坑不管咋样把它填完吧. 指令介绍 1.加载指令 2.存储指令 修改系统 ...

  6. 自己动手写CPU(7)转移指令的实现

    自己动手写CPU(7)转移指令的实现 分支延迟槽 在MIPS五级流水线中,一条指令被分成了五个阶段:取指.译指.执行.仿存.回写.当第一条指令的执行阶段结束时,第二条指令的译指阶段也已经结束了. 那么 ...

  7. 自己动手写CPU(6)流水线暂停、乘累加减与除法器的实现

    自己动手写CPU(6)流水线暂停.乘累加减与除法器的实现 流水线暂停 因为OpenMIPS设计乘累加.乘累减.除法指令在流水线执行阶段占用多个时钟周期,因此需要暂停流水线,以等待这些多周期指令执行完毕 ...

  8. 自己动手写CPU(5)简单算术操作指令实现_1

    自己动手写CPU(5)简单算数操作指令实现_1 指令介绍 MIPS32指令集架构定义的所有算术操作指令,共有21条 共有三类,分别是: 简单算术指令 乘累加.乘累减指令 除法指令 算术指令操作介绍 一 ...

  9. 自己动手写CPU(4)移动操作指令的实现

    自己动手写CPU(4)移动操作指令的实现 指令说明 MIPS32指令集架构中定义的移动操作指令共有6条: movn.movz.mfhi.mthi.mflo.mtlo,后4条指令涉及对特殊寄存器HI.L ...

最新文章

  1. Android DDMS应用
  2. 机房做隔断为什么要用防火玻璃?
  3. 教你一秒分辨真假芯片!
  4. linux和windows和鸿蒙,linux很好,但为何大家都用Win,鸿蒙系统站错阵营了吗?
  5. SQL SERVER 2008 中分页方法
  6. Spark报错 Failed to send RPC xxx to/ip:43074 java.nio.channels.ClosedChannelException
  7. Outlook 2003解除附件下载限制
  8. 服务器上搭shinyApp:shiny-server配置及报错解决
  9. Python批量下载抖音大V主页视频
  10. 怎么打开系统服务器,Win10怎么打开系统服务管理器 Win10打开系统服务管理器操作方法...
  11. 层次化网络设计(三层网络结构)
  12. linux各个文件夹,linux各个目录文件夹含义
  13. 域远程管理计算机,远程控制局域网电脑 图解局域网怎么远程控制
  14. altf4不管用.是因为未使用内置管理员账户.
  15. 世界上没有技术驱动型公司!
  16. 章子怡对婚姻的憧憬:一生一世!——丹比奴
  17. 如何绘制业务流程图(一)
  18. #Reading Paper#STAM:A Spatiotemporal Aggregation Method for Graph Neural Network-based Recommendatio
  19. WoShop分销积分直播短视频商城全开源无加密商城源码
  20. vsCode中Server is already running from different workspace错误解决办法

热门文章

  1. python开发范围_Python上的字母范围
  2. 单片机产生可调方波(c语言),单片机产生占空比可调方波(PWM)
  3. octave安装 缺java_Octave信号包安装
  4. win7计算机管理对话框功能,win7鼠标设置在哪里|win7打开鼠标属性对话框方法
  5. 微型计算机普遍使用的编码是,微型计算机中普遍使用的字符编码是什么吗
  6. Canvas设置样式无效导致圆变成椭圆的问题研究剖析
  7. java求完数(完全数 完美数)
  8. Oracle代码大全.从入门到熟练
  9. mysql5.6安装51cto_MySQL 5.6 for Windows配置安装之解压缩版
  10. 数据大屏产品介绍PPT_有这些图表美化工具,十分钟配出炫酷的数据可视化大屏...