diff --git a/include/alu.h b/include/alu.h index 69e4cbd..6bd143d 100644 --- a/include/alu.h +++ b/include/alu.h @@ -1,4 +1,5 @@ #pragma once +#include "concept.h" #ifndef ALU_H #include "tools.h" namespace ZYM { @@ -6,6 +7,8 @@ struct ALU_Input { dark::Wire<7 + 3 + 1> request_full_id; dark::Wire<32> operand1; dark::Wire<32> operand2; + dark::Wire<32> imm; + dark::Wire<6> shamt; dark::Wire<5> request_ROB_index; dark::Wire<32> request_PC; }; @@ -20,7 +23,307 @@ struct ALU : public dark::Module { // Constructor } void work() { - // Update function + switch (static_cast(request_full_id)) { + case 0: { + alu_status <= 0b01; + return; + } + case 0b00000000001: { + // fake instruction of halt + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + return; + } + case 0b00000110111: { + // lui + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= imm; + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00000010111: { + // auipc + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(request_PC) + imm; + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00001101111: { + // jal + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(request_PC) + 4; + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + return; + } + case 0b00001100111: { + // jalr + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(request_PC) + 4; + completed_alu_resulting_PC <= ((static_cast(operand1) + static_cast(imm)) & 0xfffffffe); + return; + } + case 0b00001100011: { + // beq + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) == static_cast(operand2)) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b00011100011: { + // bne + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) != static_cast(operand2)) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b01001100011: { + // blt + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(static_cast(operand1)) < + static_cast(static_cast(operand2))) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b01011100011: { + // bge + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(static_cast(operand1)) >= + static_cast(static_cast(operand2))) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b01101100011: { + // bltu + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) < static_cast(operand2)) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b01111100011: { + // bgeu + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) >= static_cast(operand2)) { + completed_alu_resulting_PC <= static_cast(request_PC) + imm; + } else { + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + } + return; + } + case 0b00000010011: { + // addi + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(operand1) + imm; + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00100010011: { + // slti + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(static_cast(operand1)) < + static_cast(static_cast(imm))) { + result <= 1; + } else { + result <= 0; + } + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00110010011: { + // sltiu + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) < static_cast(imm)) { + result <= 1; + } else { + result <= 0; + } + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01000010011: { + // xori + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) ^ static_cast(imm)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01100010011: { + // ori + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) | static_cast(imm)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01110010011: { + // andi + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) & static_cast(imm)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00010010011: { + // slli + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) << static_cast(shamt)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01010010011: { + // srli + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) >> static_cast(shamt)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b11010010011: { + // srai + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + uint32_t res_tmp = static_cast(operand1) >> static_cast(shamt); + uint8_t sign = (static_cast(operand1) >> 31) & 1; + if (sign) { + for (size_t i = 0; i < static_cast(shamt); i++) { + res_tmp |= 1 << (31 - i); + } + } + result <= res_tmp; + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00000110011: { + // add + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(operand1) + static_cast(operand2); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b10000110011: { + // sub + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= static_cast(operand1) - static_cast(operand2); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00010110011: { + // sll + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + uint8_t actual_shamt = static_cast(operand2) & 0b11111; + result <= (static_cast(operand1) << actual_shamt); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00100110011: { + // slt + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(static_cast(operand1)) < + static_cast(static_cast(operand2))) { + result <= 1; + } else { + result <= 0; + } + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b00110110011: { + // sltu + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + if (static_cast(operand1) < static_cast(operand2)) { + result <= 1; + } else { + result <= 0; + } + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01000110011: { + // xor + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) ^ static_cast(operand2)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01010110011: { + // srl + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + uint8_t actual_shamt = static_cast(operand2) & 0b11111; + result <= (static_cast(operand1) >> actual_shamt); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b11010110011: { + // sra + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + uint8_t actual_shamt = static_cast(operand2) & 0b11111; + uint32_t res_tmp = static_cast(operand1) >> actual_shamt; + uint8_t sign = (static_cast(operand1) >> 31) & 1; + if (sign) { + for (size_t i = 0; i < actual_shamt; i++) { + res_tmp |= 1 << (31 - i); + } + } + result <= res_tmp; + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01100110011: { + // or + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) | static_cast(operand2)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + case 0b01110110011: { + // and + alu_status <= 0b10; + result_ROB_index <= request_ROB_index; + result <= (static_cast(operand1) & static_cast(operand2)); + completed_alu_resulting_PC <= static_cast(request_PC) + 4; + return; + } + default: + throw std::runtime_error("Invalid instruction occured in ALU"); + } } }; } // namespace ZYM diff --git a/include/reservestation.h b/include/reservestation.h index 58e6bf0..a71c32f 100644 --- a/include/reservestation.h +++ b/include/reservestation.h @@ -50,6 +50,8 @@ struct ReserveStation_Output { dark::Register<7 + 3 + 1> request_full_id; dark::Register<32> operand1; dark::Register<32> operand2; + dark::Register<32> op_imm; + dark::Register<6> op_shamt; dark::Register<32> alu_ins_PC; dark::Register<5> request_ROB_index; dark::Register<6> RS_remain_space_output; diff --git a/src/main.cpp b/src/main.cpp index a2b6c06..f9ee329 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,6 +150,8 @@ int main(int argc, char **argv) { RWConnect(rs.operand2, alu.operand2); RWConnect(rs.request_ROB_index, alu.request_ROB_index); RWConnect(rs.alu_ins_PC, alu.request_PC); + RWConnect(rs.op_imm, alu.imm); + RWConnect(rs.op_shamt, alu.shamt); RWConnect(alu.alu_status, rs.alu_status_receiver); RWConnect(alu.result_ROB_index, rs.completed_aluins_ROB_index); RWConnect(alu.result, rs.completed_aluins_result);