USTC-RVSoC/hardware/RTL/core_alu.sv
2019-03-13 02:49:52 +08:00

80 lines
3.8 KiB
Systemverilog

module core_alu(
input logic [ 6:0] i_opcode, i_funct7,
input logic [ 2:0] i_funct3,
input logic [31:0] i_num1u, i_num2u, i_pc, i_immu,
output logic o_branch_jalr,
output logic [31:0] o_res, o_branch_jalr_target
);
logic [ 4:0] shamt_rs, shamt_imm;
logic [31:0] num1_plus_imm, pc_plus_imm;
logic signed [31:0] i_num1s, i_num2s, i_imms;
assign shamt_imm = i_immu[4:0];
assign shamt_rs = i_num2u[4:0];
assign num1_plus_imm = i_num1u + i_immu;
assign pc_plus_imm = i_pc + i_immu;
assign i_num1s = i_num1u;
assign i_num2s = i_num2u;
assign i_imms = i_immu;
always_comb
case(i_opcode)
7'b1100111 : begin // JALR
o_branch_jalr <= 1'b1;
o_branch_jalr_target <= num1_plus_imm;
end
7'b1100011 : begin // BRANCH类
case(i_funct3)
3'b000 : o_branch_jalr <= (i_num1u == i_num2u); // BEQ
3'b001 : o_branch_jalr <= (i_num1u != i_num2u); // BNE
3'b100 : o_branch_jalr <= (i_num1s < i_num2s); // BLT
3'b101 : o_branch_jalr <= (i_num1s >= i_num2s); // BGE
3'b110 : o_branch_jalr <= (i_num1u < i_num2u); // BLTU
3'b111 : o_branch_jalr <= (i_num1u >= i_num2u); // BGEU
default: o_branch_jalr <= 1'b0;
endcase
o_branch_jalr_target <= pc_plus_imm;
end
default : begin // 不跳转
o_branch_jalr <= 1'b0;
o_branch_jalr_target <= 0;
end
endcase
always_comb
casex({i_funct7,i_funct3,i_opcode})
// JAL类与JALR类
17'bxxxxxxx_xxx_110x111 : o_res <= i_pc + 4; // JAL, JALR
// LUI类
17'bxxxxxxx_xxx_0110111 : o_res <= i_immu; // LUI
// AUIPC类
17'bxxxxxxx_xxx_0010111 : o_res <= pc_plus_imm ; // AUIPC
// 算术类
17'b0000000_000_0110011 : o_res <= i_num1u + i_num2u; // ADD
17'bxxxxxxx_000_0010011 : o_res <= num1_plus_imm ; // ADDI
17'b0100000_000_0110011 : o_res <= i_num1u - i_num2u; // SUB
// 逻辑类
17'b0000000_100_0110011 : o_res <= i_num1u ^ i_num2u; // XOR
17'bxxxxxxx_100_0010011 : o_res <= i_num1u ^ i_immu ; // XORI
17'b0000000_110_0110011 : o_res <= i_num1u | i_num2u; // OR
17'bxxxxxxx_110_0010011 : o_res <= i_num1u | i_immu ; // ORI
17'b0000000_111_0110011 : o_res <= i_num1u & i_num2u; // AND
17'bxxxxxxx_111_0010011 : o_res <= i_num1u & i_immu ; // ANDI
// 位移类
17'b0000000_001_0110011 : o_res <= i_num1u << shamt_rs ; // SLL
17'b0000000_001_0010011 : o_res <= i_num1u << shamt_imm; // SLLI
17'b0000000_101_0110011 : o_res <= i_num1u >> shamt_rs ; // SRL
17'b0000000_101_0010011 : o_res <= i_num1u >> shamt_imm; // SRL
17'b0100000_101_0110011 : o_res <= i_num1s >> shamt_rs ; // SRA
17'b0100000_101_0010011 : o_res <= i_num1s >> shamt_imm; // SRAI
// 比较类
17'b0000000_010_0110011 : o_res <= (i_num1s < i_num2s) ? 1 : 0; // SLT
17'bxxxxxxx_010_0010011 : o_res <= (i_num1s < i_imms ) ? 1 : 0; // SLTI
17'b0000000_011_0110011 : o_res <= (i_num1u < i_num2u) ? 1 : 0; // SLTU
17'bxxxxxxx_011_0010011 : o_res <= (i_num1u < i_immu ) ? 1 : 0; // SLTIU
// 无操作
default : o_res <= 0;
endcase
endmodule