Multicycle CPU

多周期CPU

多周期数据通路

R lw or sw beq J
IF PC<=PC+4; IR <=MemInst[PC]; * * *
ID opcode<=IR[31:26]; A<=Reg[IR[25:21]]; B<=Reg[IR[20:16]]; ALUOut<=PC+(signext(IR[15:0]«2)) * * *
EX ALUOut <= A op B ALUOut<=A+sign-ext(IR[15:0]) if (A=B)PC<=ALUOut PC <= {PC[31:28],IR[25:0],2’b00}
MEM Reg[IR[15:11]]<=ALUOut Lw:MDR<=MemData[ALUOut];Sw:MemData[ALUout] <=B
WB Reg[IR[20:16]]<=MDR

重点控制信号的周期:

  • IRWrite:在Instruction fench阶段被置为1,但在lw的Memory access阶段被置为0,因为在lw的Register writeback阶段,Instruction Register不能再更新,如果更新的话,会被读出的数据覆盖。
  • MemRead:在Instruction fench阶段被置为1(用于读取指令),在Instruction decode阶段为0,在lw的Memory access阶段被置为1。
  • MemWrite:默认0,在sw的Memory access阶段被置为1。
  • ALUSrc1:在Instruction fench阶段为00(PC),在Execution阶段根据实际情况修改。
  • ALUSrc2:在Instruction fench阶段为01(4),在Instruction decode阶段为11(imm«2),在Execution阶段根据实际情况修改。
  • PCWrite:在Instruction fench阶段为1(PC<=PC+4),在Instruction decode阶段为0,此后若执行跳转类指令则被置为1。
  • PCSource:默认为00(PC<=PC+4),在Execution阶段视情况改变。
  • IorD:默认0(取指令),在Memory access阶段被置为1。
  • PCWriteCond:在beq的Execution阶段被置为1。
  • MemtoReg:默认00。
  • RegDst:默认00。
  • RegWrite:默认0,在jal和jalr以及Register writeback中被置为1。
  • ExtOp:在Instruction decode阶段被置为1,因为需要算跳转地址。
  • ALUOp:在Instruction fench和Instruction decode均为00,因为需要执行加法操作;R type被置为10,beq被置为01。

多周期异常和中断处理

异常指内部不可预知事件(溢出,同步),中断指外部不可预知事件(I/O,异步)。

简单起见,假设我们需要处理两种异常:1)未定义指令的执行 2)算术溢出,异常处理程序的入口为0x80000180。

我们需要添加2个寄存器:

  • EPC Register:保存受影响的指令的地址。注意写入EPC的地址应该为PC-4。
  • Cause Register:记录产生异常事件原因。此处0为未定义指令,1为算术溢出。

4个控制信号:

  • EPCWrite:EPC写入使能,在触发异常/中断时被置为1。
  • CauseWrite:Cause写入使能。
  • PCSource:增加0x80000180。
  • IntCause:异常原因选择信号。

异常处理的步骤大致如下:

  1. 异常检测。通过检测 ALU 的溢出信号,判断是否发生溢出异常。

  2. 保存现场。在异常程序计数器(Exception Program Counter,EPC)中保存出错的指令地址。

  3. 跳转到异常处理程序。通过修改程序计数器(PC)的值,使得处理器进入异常处理程序。

  4. 异常/中断处理程序采取操作,比如可以执行对溢出情况实现定义的一些操作,或者终止程序运行并报告。在异常处理完成后,异常处理程序可以选择终止程序,也可以根据 EPC 存储的指令地址恢复并继续执行程序。

Built with Hugo
Theme Stack designed by Jimmy
visitors: total visits: time(s) reads: time(s)