手写一个简易的多周期 MIPS CPU (3)

ALU 为算术逻辑运算单元,功能如下:

ALUOp[2..0] 功能 功能
000   Y=A+B   加法运算  
001   Y=A-B   减法运算  
010   Y=B<<A   左移运算  
011   Y=A∨B   或运算  
100   Y=A∧B   与运算  
101   Y=(A<B) ? 1 : 0   无符号比较  
110   Y=(((A<B)&&(A[31] == B[31])) ||
((A[31]==1&& B[31] == 0))) ? 1 : 0
  带符号比较  
111   Y=A⊕B   异或  
模块设计 符号定义

为了更加明晰程序代码,并避免因二进制代码书写错误导致的问题,对状态码、操 作码等做出如下定义:

`define ALU_OP_ADD 3'b000 `define ALU_OP_SUB 3'b001 `define ALU_OP_SLL 3'b010 `define ALU_OP_OR 3'b011 `define ALU_OP_AND 3'b100 `define ALU_OP_LT 3'b101 `define ALU_OP_SLT 3'b110 `define ALU_OP_XOR 3'b111 `define OP_ADD 6'b000000 `define OP_SUB 6'b000001 `define OP_ADDIU 6'b000010 `define OP_AND 6'b010000 `define OP_ANDI 6'b010001 `define OP_ORI 6'b010010 `define OP_XORI 6'b010011 `define OP_SLL 6'b011000 `define OP_SLTI 6'b100110 `define OP_SLT 6'b100111 `define OP_SW 6'b110000 `define OP_LW 6'b110001 `define OP_BEQ 6'b110100 `define OP_BNE 6'b110101 `define OP_BLTZ 6'b110110 `define OP_J 6'b111000 `define OP_JR 6'b111001 `define OP_JAL 6'b111010 `define OP_HALT 6'b111111 `define PC_NEXT 2'b00 `define PC_REL_JUMP 2'b01 `define PC_REG_JUMP 2'b10 `define PC_ABS_JUMP 2'b11 `define STATE_IF 3'b000 `define STATE_ID 3'b001 `define STATE_EXE_AL 3'b110 `define STATE_EXE_BR 3'b101 `define STATE_EXE_LS 3'b010 `define STATE_MEM 3'b011 `define STATE_WB_AL 3'b111 `define STATE_WB_LD 3'b100 控制单元 状态转移 always @(posedge CLK or negedge RST) begin if (!RST) State <= `STATE_IF; else begin case (State) `STATE_IF: State <= `STATE_ID; `STATE_ID: begin case (OpCode) `OP_ADD, `OP_SUB, `OP_ADDIU, `OP_AND, `OP_ANDI, `OP_ORI, `OP_XORI, `OP_SLL, `OP_SLTI, `OP_SLT: State <= `STATE_EXE_AL; `OP_BNE, `OP_BEQ, `OP_BLTZ: State <= `STATE_EXE_BR; `OP_SW, `OP_LW: State <= `STATE_EXE_LS; `OP_J, `OP_JAL, `OP_JR, `OP_HALT: State <= `STATE_IF; default: State <= `STATE_EXE_AL; endcase end `STATE_EXE_AL: State <= `STATE_WB_AL; `STATE_EXE_BR: State <= `STATE_IF; `STATE_EXE_LS: State <= `STATE_MEM; `STATE_WB_AL: State <= `STATE_IF; `STATE_MEM: begin case (OpCode) `OP_SW: State <= `STATE_IF; `OP_LW: State <= `STATE_WB_LD; endcase end `STATE_WB_LD: State <= `STATE_IF; default: State <= `STATE_IF; endcase end end 控制信号

不同控制信号根据不同的操作码得到,因此可以列出对于不同操作码的各控制信号的真值表:

Op PCWre ALUSrcA ALUSrcB DBDataSrc RegWre WrRegDSrc InsMemRW mRD mWR IRWre ExtSel PCSrc RegDst ALUOp
add   0   0   0   0   1   1   1   X   X   1   X   00   10   000  
sub   0   0   0   0   1   1   1   X   X   1   X   00   10   001  
addiu   0   0   1   0   1   1   1   X   X   1   1   00   01   000  
and   0   0   0   0   1   1   1   X   X   1   X   00   10   100  
andi   0   0   1   0   1   1   1   X   X   1   0   00   01   100  
ori   0   0   1   0   1   1   1   X   X   1   0   00   01   011  
xori   0   0   1   0   1   1   1   X   X   1   0   00   01   111  
sll   0   1   0   0   1   1   1   X   X   1   X   00   10   010  
slti   0   0   1   0   1   1   1   X   X   1   1   00   01   110  
slt   0   0   0   0   1   1   1   X   X   1   X   00   10   110  
sw   0   0   1   X   0   X   1   X   1   1   1   00   XX   000  
lw   0   0   1   1   1   1   1   1   X   1   1   00   01   000  
beq   0   0   0   X   0   X   1   X   X   1   1   00(Zero=0) 01(Zero=1)   XX   001  
bne   0   0   0   X   0   X   1   X   X   1   1   00(Zero=1) 01(Zero=0)   XX   001  
bltz   0   0   0   X   0   X   1   X   X   1   1   00(Sign=0) 01(Sign=1)   XX   001  
j   0   X   X   X   0   X   1   X   X   1   X   11   XX   XXX  
jr   0   X   X   X   0   X   1   X   X   1   X   10   XX   XXX  
jal   0   X   X   X   1   0   1   X   X   1   X   11   00   XXX  
halt   1   X   X   X   0   X   1   X   X   1   X   XX   XX   XXX  

控制信号不仅仅取决于操作码,还取决于当前的状态。各控制信号实现如下:

ALUSrcA:EXE 阶段 LS、SLL

ALUSrcA = ((State == `STATE_EXE_AL || State == `STATE_EXE_BR || State == `STATE_EXE_LS) && OpCode == `OP_SLL) ? 1 : 0;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjsgx.html