aboutsummaryrefslogtreecommitdiff
path: root/src/alu_op_decode.v
blob: 4a812ab0025e3b89519d25bdba3f8e4c733be879 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
module alu_op_decode (
  input [6:0] opcode,
  input [2:0] funct3,
  input [6:0] funct7,
  
  input alu_ctrl,
  
  output reg [3:0] alu_op
);

parameter ALU_OP_ADD  = 4'b0000,
          ALU_OP_SUB  = 4'b0001,
          ALU_OP_SLT  = 4'b0010,
          ALU_OP_SLTU = 4'b0011,
          ALU_OP_AND  = 4'b0100,
          ALU_OP_OR   = 4'b0101,
          ALU_OP_XOR  = 4'b0110,
          ALU_OP_SLL  = 4'b1000,
          ALU_OP_SRL  = 4'b1001,
          ALU_OP_SRA  = 4'b1011;


always @ (*) begin
  if (alu_ctrl == 1'b1) alu_op <= ALU_OP_ADD;
  else case (opcode)
    7'b0110011: begin // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND
      case (funct3)
        3'b000:  alu_op <= funct7[5] ? ALU_OP_SUB : ALU_OP_ADD;
        3'b001:  alu_op <= ALU_OP_SLL;
        3'b010:  alu_op <= ALU_OP_SLT;
        3'b011:  alu_op <= ALU_OP_SLTU;
        3'b100:  alu_op <= ALU_OP_XOR;
        3'b101:  alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
        3'b110:  alu_op <= ALU_OP_OR;
        3'b111:  alu_op <= ALU_OP_AND;
        default: alu_op <= ALU_OP_ADD;
      endcase
    end
    7'b0010011: begin // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI
      case (funct3)
        3'b000:  alu_op <= ALU_OP_ADD;
        3'b001:  alu_op <= ALU_OP_SLL;
        3'b010:  alu_op <= ALU_OP_SLT;
        3'b011:  alu_op <= ALU_OP_SLTU;
        3'b100:  alu_op <= ALU_OP_XOR;
        3'b101:  alu_op <= funct7[5] ? ALU_OP_SRA : ALU_OP_SRL;
        3'b110:  alu_op <= ALU_OP_OR;
        3'b111:  alu_op <= ALU_OP_AND;
        default: alu_op <= ALU_OP_ADD;
      endcase
    end
    7'b0000011: begin // LB, LH, LW, LBU, LHU
      alu_op <= ALU_OP_ADD;
    end
    7'b1100111: begin // JALR
      alu_op <= ALU_OP_ADD;
    end
    7'b0100011: begin // SB, SH, SW
      alu_op <= ALU_OP_ADD;
    end
    7'b1100011: begin // BEQ, BNE, BLT, BGE, BLTU, BGEU
      if ((funct3 == 3'b000) | (funct3 == 3'b001)) alu_op <= ALU_OP_SUB;
      else if ((funct3 == 3'b100) | (funct3 == 3'b101)) alu_op <= ALU_OP_SLT;
      else if ((funct3 == 3'b110) | (funct3 == 3'b111)) alu_op <= ALU_OP_SLTU; 
      else alu_op <= ALU_OP_ADD;
    end
    7'b0110111: begin // LUI
      alu_op <= ALU_OP_ADD;
    end
    7'b0010111: begin // AUIPC
      alu_op <= ALU_OP_ADD;
    end
    7'b1101111: begin // JAL
      alu_op <= ALU_OP_ADD;
    end
    7'b0001111: begin // FENCE, FENCE.I
      alu_op <= ALU_OP_ADD;
    end
    7'b1110011: begin // ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI
      alu_op <= ALU_OP_ADD;
    end
    default: alu_op <= ALU_OP_ADD;
  endcase
end

endmodule