diff --git a/include/csu.h b/include/csu.h index b64f4c8..8251c78 100644 --- a/include/csu.h +++ b/include/csu.h @@ -1,7 +1,10 @@ #pragma once +#include +#include "concept.h" #ifndef CSU_H #include #include +#include #include "tools.h" namespace ZYM { const int kROBSize = 32; @@ -88,6 +91,105 @@ struct CentralScheduleUnit private: std::function instruction_fetcher; bool instruction_fetcher_initialized = false; + inline uint8_t ReadBit(uint32_t data, int pos) { return (data >> pos) & 1; } + inline void WriteBit(uint32_t &data, int pos, uint8_t bit) { + data &= ~(1 << pos); + data |= bit << pos; + } + std::tuple, dark::Bit<5>, dark::Bit<1>, dark::Bit<5>, dark::Bit<1>, dark::Bit<5>, dark::Bit<1>, + dark::Bit<32>, dark::Bit<6>> + Decode(max_size_t ins) { + // Decode the instruction + dark::Bit<7 + 3 + 1> full_ins_id; + dark::Bit<5> decoded_rd; + dark::Bit<1> has_decoded_rd; + dark::Bit<5> decoded_rs1; + dark::Bit<1> has_decoded_rs1; + dark::Bit<5> decoded_rs2; + dark::Bit<1> has_decoded_rs2; + dark::Bit<32> decoded_imm; + dark::Bit<6> decoded_shamt; + uint8_t opcode = ins & 0x7F; + if (opcode == 0b0110011) { + // R-type + has_decoded_rd = 1; + has_decoded_rs1 = 1; + has_decoded_rs2 = 1; + decoded_rd = ins >> 7 & 0x1F; + decoded_rs1 = ins >> 15 & 0x1F; + decoded_rs2 = ins >> 20 & 0x1F; + uint8_t funct3 = ins >> 12 & 0x7; + uint8_t funct7 = ins >> 25 & 0x7F; + full_ins_id = opcode | (funct3 << 7) | (((funct7 >> 5) & 1) << 10); + } else if (opcode == 0b1100111 || opcode == 0b0000011 || opcode == 0b0010011) { + // I-type + has_decoded_rd = 1; + has_decoded_rs1 = 1; + has_decoded_rs2 = 0; + decoded_rd = ins >> 7 & 0x1F; + decoded_rs1 = ins >> 15 & 0x1F; + decoded_imm = ins >> 20; + uint32_t sign_bit = ins >> 31; + if (sign_bit) { + decoded_imm = static_cast(decoded_imm) | 0xFFFFF000; + } + uint8_t funct3 = ins >> 12 & 0x7; + uint8_t funct7 = ins >> 25 & 0x7F; + full_ins_id = opcode | (funct3 << 7) | (((funct7 >> 5) & 1) << 10); + decoded_shamt = ins >> 20 & 0x3F; + } else if (opcode == 0b0100011) { + // S-type + has_decoded_rd = 0; + has_decoded_rs1 = 1; + has_decoded_rs2 = 1; + decoded_rs1 = (ins >> 15) & 0x1F; + decoded_rs2 = (ins >> 20) & 0x1F; + decoded_imm = ((ins >> 7) & 0x1F) | ((ins >> 25) << 5); + uint32_t sign_bit = ins >> 31; + if (sign_bit) { + decoded_imm = static_cast(decoded_imm) | 0xFFFFF000; + } + uint8_t funct3 = ins >> 12 & 0x7; + full_ins_id = opcode | (funct3 << 7); + } else if (opcode == 0b1100011) { + // B-type + has_decoded_rd = 0; + has_decoded_rs1 = 1; + has_decoded_rs2 = 1; + decoded_rs1 = (ins >> 15) & 0x1F; + decoded_rs2 = (ins >> 20) & 0x1F; + decoded_imm = (((ins >> 8) & 0xF) << 1) | (((ins >> 25) & 0x3F) << 5) | (((ins >> 7) & 0x1) << 11) | + (((ins >> 31) & 0x1) << 12); + uint32_t sign_bit = ins >> 31; + if (sign_bit) { + decoded_imm = static_cast(decoded_imm) | 0xFFFFE000; + } + uint8_t funct3 = ins >> 12 & 0x7; + full_ins_id = opcode | (funct3 << 7); + } else if(opcode==0b0110111) { + // U-type + has_decoded_rd = 1; + has_decoded_rs1 = 0; + has_decoded_rs2 = 0; + decoded_rd = ins >> 7 & 0x1F; + decoded_imm = ins >> 12; + full_ins_id = opcode; + } else if(opcode==0b1101111) { + // J-type + has_decoded_rd = 1; + has_decoded_rs1 = 0; + has_decoded_rs2 = 0; + decoded_rd = ins >> 7 & 0x1F; + decoded_imm = (ins & 0xFF000) | (((ins >> 20) & 1)<<11) | (((ins >> 21) & 0x3FF)<<1) | ((ins >> 31) << 20); + uint32_t sign_bit = ins >> 31; + if (sign_bit) { + decoded_imm = static_cast(decoded_imm) | 0xFFE00000; + } + full_ins_id = opcode; + } else throw std::runtime_error("Unknown instruction in Decode"); + return std::make_tuple(full_ins_id, decoded_rd, has_decoded_rd, decoded_rs1, has_decoded_rs1, decoded_rs2, + has_decoded_rs2, decoded_imm, decoded_shamt); + } public: CentralScheduleUnit() { ; } diff --git a/include/reservestation.h b/include/reservestation.h index 3b2b6c1..58e6bf0 100644 --- a/include/reservestation.h +++ b/include/reservestation.h @@ -50,6 +50,7 @@ struct ReserveStation_Output { dark::Register<7 + 3 + 1> request_full_id; dark::Register<32> operand1; dark::Register<32> operand2; + 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 8452511..a2b6c06 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,6 +149,7 @@ int main(int argc, char **argv) { RWConnect(rs.operand1, alu.operand1); RWConnect(rs.operand2, alu.operand2); RWConnect(rs.request_ROB_index, alu.request_ROB_index); + RWConnect(rs.alu_ins_PC, alu.request_PC); 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);