diff --git a/rv32_alu.sv b/rv32_alu.sv index fc7a99a..15faaff 100644 --- a/rv32_alu.sv +++ b/rv32_alu.sv @@ -1,18 +1,4 @@ -localparam RV32_ALU_OP_ADD_SUB = 4'b0000; -localparam RV32_ALU_OP_XOR = 4'b0001; -localparam RV32_ALU_OP_OR = 4'b0010; -localparam RV32_ALU_OP_AND = 4'b0011; -localparam RV32_ALU_OP_SLL = 4'b0100; -localparam RV32_ALU_OP_SRL_SRA = 4'b0101; -localparam RV32_ALU_OP_SLT = 4'b0110; -localparam RV32_ALU_OP_SLTU = 4'b0111; -localparam RV32_ALU_OP_SRC2 = 4'b1000; - -localparam RV32_ALU_SRC1_REG = 1'b0; -localparam RV32_ALU_SRC1_PC = 1'b1; - -localparam RV32_ALU_SRC2_REG = 1'b0; -localparam RV32_ALU_SRC2_IMM = 1'b1; +`include "rv32_alu_ops.sv" module rv32_alu ( input clk, diff --git a/rv32_alu_ops.sv b/rv32_alu_ops.sv new file mode 100644 index 0000000..46ee50a --- /dev/null +++ b/rv32_alu_ops.sv @@ -0,0 +1,15 @@ +localparam RV32_ALU_OP_ADD_SUB = 4'b0000; +localparam RV32_ALU_OP_XOR = 4'b0001; +localparam RV32_ALU_OP_OR = 4'b0010; +localparam RV32_ALU_OP_AND = 4'b0011; +localparam RV32_ALU_OP_SLL = 4'b0100; +localparam RV32_ALU_OP_SRL_SRA = 4'b0101; +localparam RV32_ALU_OP_SLT = 4'b0110; +localparam RV32_ALU_OP_SLTU = 4'b0111; +localparam RV32_ALU_OP_SRC2 = 4'b1000; + +localparam RV32_ALU_SRC1_REG = 1'b0; +localparam RV32_ALU_SRC1_PC = 1'b1; + +localparam RV32_ALU_SRC2_REG = 1'b0; +localparam RV32_ALU_SRC2_IMM = 1'b1; diff --git a/rv32_decode.sv b/rv32_decode.sv index 553aa9b..d570589 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -1,3 +1,4 @@ +`include "rv32_alu_ops.sv" `include "rv32_opcodes.sv" `include "rv32_regs.sv" @@ -64,11 +65,17 @@ module rv32_decode ( {RV32_OPCODE_LUI, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin /* LUI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SRC2; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_u; end {RV32_OPCODE_AUIPC, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin /* AUIPC */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_PC; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_u; end {RV32_OPCODE_JAL, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin @@ -84,157 +91,281 @@ module rv32_decode ( {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BEQ, RV32_FUNCT7_ANY}: begin /* BEQ */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BNE, RV32_FUNCT7_ANY}: begin /* BNE */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BLT, RV32_FUNCT7_ANY}: begin /* BLT */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLT; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BGE, RV32_FUNCT7_ANY}: begin /* BGE */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLT; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BLTU, RV32_FUNCT7_ANY}: begin /* BLTU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLTU; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BGEU, RV32_FUNCT7_ANY}: begin /* BGEU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLTU; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; imm_out <= imm_b; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LB, RV32_FUNCT7_ANY}: begin /* LB */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LH, RV32_FUNCT7_ANY}: begin /* LH */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LW, RV32_FUNCT7_ANY}: begin /* LW */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LBU, RV32_FUNCT7_ANY}: begin /* LBU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LHU, RV32_FUNCT7_ANY}: begin /* LHU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SB, RV32_FUNCT7_ANY}: begin /* SB */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_s; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SH, RV32_FUNCT7_ANY}: begin /* SH */ valid_out <= 1; - imm_out <= imm_s; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; + imm_out <= imm_s; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SW, RV32_FUNCT7_ANY}: begin /* SW */ valid_out <= 1; - imm_out <= imm_s; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; + imm_out <= imm_s; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ANY}: begin /* ADDI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ANY}: begin /* SLTI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLT; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ANY}: begin /* SLTIU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLTU; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ANY}: begin /* XORI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_XOR; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ANY}: begin /* ORI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_OR; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ANY}: begin /* ANDI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_AND; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= imm_i; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin /* SLLI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLL; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= shamt; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin /* SRLI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SRL_SRA; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= shamt; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin /* SRAI */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SRL_SRA; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_IMM; imm_out <= shamt; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ZERO}: begin /* ADD */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_OP_SUB}: begin /* SUB */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin /* SLL */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLL; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ZERO}: begin /* SLT */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLT; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ZERO}: begin /* SLTU */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SLTU; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ZERO}: begin /* XOR */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_XOR; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin /* SRL */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SRL_SRA; + alu_sub_sra_out <= 0; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin /* SRA */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_SRL_SRA; + alu_sub_sra_out <= 1; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ZERO}: begin /* OR */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_OR; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end {RV32_OPCODE_OP, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ZERO}: begin /* AND */ valid_out <= 1; + alu_op_out <= RV32_ALU_OP_AND; + alu_src1_out <= RV32_ALU_SRC1_REG; + alu_src2_out <= RV32_ALU_SRC2_REG; end endcase end