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 ALUOpadd 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;