finish alu

This commit is contained in:
2024-07-31 05:36:35 +00:00
parent b96fe73481
commit 284a722015
3 changed files with 308 additions and 1 deletions

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "concept.h"
#ifndef ALU_H #ifndef ALU_H
#include "tools.h" #include "tools.h"
namespace ZYM { namespace ZYM {
@ -6,6 +7,8 @@ struct ALU_Input {
dark::Wire<7 + 3 + 1> request_full_id; dark::Wire<7 + 3 + 1> request_full_id;
dark::Wire<32> operand1; dark::Wire<32> operand1;
dark::Wire<32> operand2; dark::Wire<32> operand2;
dark::Wire<32> imm;
dark::Wire<6> shamt;
dark::Wire<5> request_ROB_index; dark::Wire<5> request_ROB_index;
dark::Wire<32> request_PC; dark::Wire<32> request_PC;
}; };
@ -20,7 +23,307 @@ struct ALU : public dark::Module<ALU_Input, ALU_Output> {
// Constructor // Constructor
} }
void work() { void work() {
// Update function switch (static_cast<max_size_t>(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<max_size_t>(request_PC) + 4;
return;
}
case 0b00000010111: {
// auipc
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(request_PC) + imm;
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00001101111: {
// jal
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(request_PC) + 4;
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
return;
}
case 0b00001100111: {
// jalr
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(request_PC) + 4;
completed_alu_resulting_PC <= ((static_cast<max_size_t>(operand1) + static_cast<max_size_t>(imm)) & 0xfffffffe);
return;
}
case 0b00001100011: {
// beq
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) == static_cast<max_size_t>(operand2)) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b00011100011: {
// bne
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) != static_cast<max_size_t>(operand2)) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b01001100011: {
// blt
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<int32_t>(static_cast<max_size_t>(operand1)) <
static_cast<int32_t>(static_cast<max_size_t>(operand2))) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b01011100011: {
// bge
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<int32_t>(static_cast<max_size_t>(operand1)) >=
static_cast<int32_t>(static_cast<max_size_t>(operand2))) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b01101100011: {
// bltu
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) < static_cast<max_size_t>(operand2)) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b01111100011: {
// bgeu
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) >= static_cast<max_size_t>(operand2)) {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + imm;
} else {
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
}
return;
}
case 0b00000010011: {
// addi
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(operand1) + imm;
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00100010011: {
// slti
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<int32_t>(static_cast<max_size_t>(operand1)) <
static_cast<int32_t>(static_cast<max_size_t>(imm))) {
result <= 1;
} else {
result <= 0;
}
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00110010011: {
// sltiu
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) < static_cast<max_size_t>(imm)) {
result <= 1;
} else {
result <= 0;
}
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01000010011: {
// xori
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) ^ static_cast<max_size_t>(imm));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01100010011: {
// ori
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) | static_cast<max_size_t>(imm));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01110010011: {
// andi
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) & static_cast<max_size_t>(imm));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00010010011: {
// slli
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) << static_cast<max_size_t>(shamt));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01010010011: {
// srli
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) >> static_cast<max_size_t>(shamt));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b11010010011: {
// srai
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
uint32_t res_tmp = static_cast<max_size_t>(operand1) >> static_cast<max_size_t>(shamt);
uint8_t sign = (static_cast<max_size_t>(operand1) >> 31) & 1;
if (sign) {
for (size_t i = 0; i < static_cast<max_size_t>(shamt); i++) {
res_tmp |= 1 << (31 - i);
}
}
result <= res_tmp;
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00000110011: {
// add
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(operand1) + static_cast<max_size_t>(operand2);
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b10000110011: {
// sub
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= static_cast<max_size_t>(operand1) - static_cast<max_size_t>(operand2);
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00010110011: {
// sll
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
uint8_t actual_shamt = static_cast<max_size_t>(operand2) & 0b11111;
result <= (static_cast<max_size_t>(operand1) << actual_shamt);
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00100110011: {
// slt
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<int32_t>(static_cast<max_size_t>(operand1)) <
static_cast<int32_t>(static_cast<max_size_t>(operand2))) {
result <= 1;
} else {
result <= 0;
}
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b00110110011: {
// sltu
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
if (static_cast<max_size_t>(operand1) < static_cast<max_size_t>(operand2)) {
result <= 1;
} else {
result <= 0;
}
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01000110011: {
// xor
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) ^ static_cast<max_size_t>(operand2));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01010110011: {
// srl
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
uint8_t actual_shamt = static_cast<max_size_t>(operand2) & 0b11111;
result <= (static_cast<max_size_t>(operand1) >> actual_shamt);
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b11010110011: {
// sra
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
uint8_t actual_shamt = static_cast<max_size_t>(operand2) & 0b11111;
uint32_t res_tmp = static_cast<max_size_t>(operand1) >> actual_shamt;
uint8_t sign = (static_cast<max_size_t>(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<max_size_t>(request_PC) + 4;
return;
}
case 0b01100110011: {
// or
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) | static_cast<max_size_t>(operand2));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
case 0b01110110011: {
// and
alu_status <= 0b10;
result_ROB_index <= request_ROB_index;
result <= (static_cast<max_size_t>(operand1) & static_cast<max_size_t>(operand2));
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
return;
}
default:
throw std::runtime_error("Invalid instruction occured in ALU");
}
} }
}; };
} // namespace ZYM } // namespace ZYM

View File

@ -50,6 +50,8 @@ struct ReserveStation_Output {
dark::Register<7 + 3 + 1> request_full_id; dark::Register<7 + 3 + 1> request_full_id;
dark::Register<32> operand1; dark::Register<32> operand1;
dark::Register<32> operand2; dark::Register<32> operand2;
dark::Register<32> op_imm;
dark::Register<6> op_shamt;
dark::Register<32> alu_ins_PC; dark::Register<32> alu_ins_PC;
dark::Register<5> request_ROB_index; dark::Register<5> request_ROB_index;
dark::Register<6> RS_remain_space_output; dark::Register<6> RS_remain_space_output;

View File

@ -150,6 +150,8 @@ int main(int argc, char **argv) {
RWConnect(rs.operand2, alu.operand2); RWConnect(rs.operand2, alu.operand2);
RWConnect(rs.request_ROB_index, alu.request_ROB_index); RWConnect(rs.request_ROB_index, alu.request_ROB_index);
RWConnect(rs.alu_ins_PC, alu.request_PC); 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.alu_status, rs.alu_status_receiver);
RWConnect(alu.result_ROB_index, rs.completed_aluins_ROB_index); RWConnect(alu.result_ROB_index, rs.completed_aluins_ROB_index);
RWConnect(alu.result, rs.completed_aluins_result); RWConnect(alu.result, rs.completed_aluins_result);