fix fatal bugs, ready to inspect value processing
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
unsigned int global_clock=0;
|
||||||
// RISC-V
|
// RISC-V
|
||||||
enum class Opcode : dark::max_size_t {
|
enum class Opcode : dark::max_size_t {
|
||||||
ADD,
|
ADD,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
unsigned int global_clock=0;
|
||||||
struct RegFile_Input {
|
struct RegFile_Input {
|
||||||
Wire <5> rs1_index; // Read
|
Wire <5> rs1_index; // Read
|
||||||
Wire <5> rs2_index; // Read
|
Wire <5> rs2_index; // Read
|
||||||
|
@ -23,6 +23,8 @@ struct ALU : public dark::Module<ALU_Input, ALU_Output> {
|
|||||||
// Constructor
|
// Constructor
|
||||||
}
|
}
|
||||||
void work() {
|
void work() {
|
||||||
|
std::cerr << "ALU: cur request_full_id=" << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
|
||||||
|
<< static_cast<max_size_t>(request_full_id) << std::endl;
|
||||||
switch (static_cast<max_size_t>(request_full_id)) {
|
switch (static_cast<max_size_t>(request_full_id)) {
|
||||||
case 0: {
|
case 0: {
|
||||||
alu_status <= 0b01;
|
alu_status <= 0b01;
|
||||||
@ -39,6 +41,7 @@ struct ALU : public dark::Module<ALU_Input, ALU_Output> {
|
|||||||
alu_status <= 0b10;
|
alu_status <= 0b10;
|
||||||
result_ROB_index <= request_ROB_index;
|
result_ROB_index <= request_ROB_index;
|
||||||
result <= imm;
|
result <= imm;
|
||||||
|
std::cerr << "lui: imm=" << std::hex << static_cast<max_size_t>(imm) << std::endl;
|
||||||
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
|
completed_alu_resulting_PC <= static_cast<max_size_t>(request_PC) + 4;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
extern unsigned int global_clock;
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
@ -64,12 +64,14 @@ public:
|
|||||||
auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once;
|
auto func = shuffle ? &CPU::run_once_shuffle : &CPU::run_once;
|
||||||
reset_signal=true;
|
reset_signal=true;
|
||||||
while (max_cycles == 0 || cycles < max_cycles) {
|
while (max_cycles == 0 || cycles < max_cycles) {
|
||||||
|
std::cerr<<"clock: "<<std::dec<<global_clock<<std::endl;
|
||||||
(this->*func)();
|
(this->*func)();
|
||||||
reset_signal=false;
|
reset_signal=false;
|
||||||
uint32_t halt_signal_value = max_size_t(halt_signal);
|
uint32_t halt_signal_value = max_size_t(halt_signal);
|
||||||
if(halt_signal_value &(1<<9)) {
|
if(halt_signal_value &(1<<9)) {
|
||||||
return halt_signal_value&0xff;
|
return halt_signal_value&0xff;
|
||||||
}
|
}
|
||||||
|
global_clock++;
|
||||||
}
|
}
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
#include "concept.h"
|
#include "concept.h"
|
||||||
#ifndef CSU_H
|
#ifndef CSU_H
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -139,7 +140,8 @@ struct CentralScheduleUnit
|
|||||||
decoded_imm = static_cast<uint32_t>(decoded_imm) | 0xFFFFF000;
|
decoded_imm = static_cast<uint32_t>(decoded_imm) | 0xFFFFF000;
|
||||||
}
|
}
|
||||||
uint8_t funct3 = ins >> 12 & 0x7;
|
uint8_t funct3 = ins >> 12 & 0x7;
|
||||||
uint8_t funct7 = ins >> 25 & 0x7F;
|
uint8_t funct7 = 0;
|
||||||
|
if (opcode == 0b0010011 && funct3 == 0b101) funct7 = ins >> 25 & 0x7F;
|
||||||
full_ins_id = opcode | (funct3 << 7) | (((funct7 >> 5) & 1) << 10);
|
full_ins_id = opcode | (funct3 << 7) | (((funct7 >> 5) & 1) << 10);
|
||||||
decoded_shamt = ins >> 20 & 0x3F;
|
decoded_shamt = ins >> 20 & 0x3F;
|
||||||
} else if (opcode == 0b0100011) {
|
} else if (opcode == 0b0100011) {
|
||||||
@ -177,7 +179,7 @@ struct CentralScheduleUnit
|
|||||||
has_decoded_rs1 = 0;
|
has_decoded_rs1 = 0;
|
||||||
has_decoded_rs2 = 0;
|
has_decoded_rs2 = 0;
|
||||||
decoded_rd = ins >> 7 & 0x1F;
|
decoded_rd = ins >> 7 & 0x1F;
|
||||||
decoded_imm = ins >> 12;
|
decoded_imm = (ins >> 12) << 12;
|
||||||
full_ins_id = opcode;
|
full_ins_id = opcode;
|
||||||
} else if (opcode == 0b1101111) {
|
} else if (opcode == 0b1101111) {
|
||||||
// J-type
|
// J-type
|
||||||
@ -218,6 +220,7 @@ struct CentralScheduleUnit
|
|||||||
}
|
}
|
||||||
has_instruction_issued_last_cycle <= 0;
|
has_instruction_issued_last_cycle <= 0;
|
||||||
is_issuing <= 0;
|
is_issuing <= 0;
|
||||||
|
is_committing <= 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bool(force_clear_announcer)) {
|
if (bool(force_clear_announcer)) {
|
||||||
@ -233,17 +236,21 @@ struct CentralScheduleUnit
|
|||||||
has_predicted_PC <= 1;
|
has_predicted_PC <= 1;
|
||||||
has_instruction_issued_last_cycle <= 0;
|
has_instruction_issued_last_cycle <= 0;
|
||||||
is_issuing <= 0;
|
is_issuing <= 0;
|
||||||
|
is_committing <= 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// STEP1: try to commit and see if we need to rollback
|
// STEP1: try to commit and see if we need to rollback
|
||||||
uint32_t ROB_next_remain_space = static_cast<max_size_t>(ROB_remain_space);
|
uint32_t ROB_next_remain_space = static_cast<max_size_t>(ROB_remain_space);
|
||||||
|
bool has_committed = false;
|
||||||
{
|
{
|
||||||
uint32_t i = -1;
|
uint32_t i = static_cast<max_size_t>(ROB_head);
|
||||||
for (auto &record : ROB_records) {
|
auto &record = ROB_records[i];
|
||||||
++i;
|
if (static_cast<max_size_t>(record.state) == 3) {
|
||||||
if (static_cast<max_size_t>(record.state) != 3) continue;
|
|
||||||
ROB_head <= (static_cast<max_size_t>(ROB_head) + 1) % kROBSize;
|
ROB_head <= (static_cast<max_size_t>(ROB_head) + 1) % kROBSize;
|
||||||
|
std::cerr << "csu is committing instruct " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
|
||||||
|
<< static_cast<max_size_t>(record.instruction) << std::endl;
|
||||||
is_committing <= 1;
|
is_committing <= 1;
|
||||||
|
has_committed = true;
|
||||||
commit_has_resulting_register <= record.has_resulting_register;
|
commit_has_resulting_register <= record.has_resulting_register;
|
||||||
commit_reg_index <= record.resulting_register_idx;
|
commit_reg_index <= record.resulting_register_idx;
|
||||||
commit_reg_value <= record.resulting_register_value;
|
commit_reg_value <= record.resulting_register_value;
|
||||||
@ -251,11 +258,15 @@ struct CentralScheduleUnit
|
|||||||
actual_PC <= static_cast<max_size_t>(record.resulting_PC);
|
actual_PC <= static_cast<max_size_t>(record.resulting_PC);
|
||||||
if (static_cast<max_size_t>(record.PC_mismatch_mark) == 1) {
|
if (static_cast<max_size_t>(record.PC_mismatch_mark) == 1) {
|
||||||
force_clear_announcer <= 1;
|
force_clear_announcer <= 1;
|
||||||
|
std::cerr << "[warning] csu is announcing rolling back due to PC mismatch" << std::endl;
|
||||||
}
|
}
|
||||||
ROB_next_remain_space++;
|
ROB_next_remain_space++;
|
||||||
break;
|
if (record.instruction == 0x0ff00513) {
|
||||||
|
halt_signal <= 0b100000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!has_committed) is_committing <= 0;
|
||||||
if (force_clear_announcer.peek()) {
|
if (force_clear_announcer.peek()) {
|
||||||
ROB_remain_space <= ROB_next_remain_space;
|
ROB_remain_space <= ROB_next_remain_space;
|
||||||
return;
|
return;
|
||||||
@ -311,6 +322,9 @@ struct CentralScheduleUnit
|
|||||||
static_cast<max_size_t>(has_instruction_issued_last_cycle);
|
static_cast<max_size_t>(has_instruction_issued_last_cycle);
|
||||||
if (ROB_next_remain_space > 0 && actual_remain_space > 0) {
|
if (ROB_next_remain_space > 0 && actual_remain_space > 0) {
|
||||||
// can issue
|
// can issue
|
||||||
|
std::cerr << "csu is issuing mem instruct " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
|
||||||
|
<< instruction << " full_ins_id= " << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< std::uppercase << full_ins_id << std::endl;
|
||||||
is_issuing <= 1;
|
is_issuing <= 1;
|
||||||
has_instruction_issued_last_cycle <= 1;
|
has_instruction_issued_last_cycle <= 1;
|
||||||
uint32_t tail = static_cast<max_size_t>(ROB_tail);
|
uint32_t tail = static_cast<max_size_t>(ROB_tail);
|
||||||
@ -347,6 +361,9 @@ struct CentralScheduleUnit
|
|||||||
static_cast<max_size_t>(has_instruction_issued_last_cycle);
|
static_cast<max_size_t>(has_instruction_issued_last_cycle);
|
||||||
if (ROB_next_remain_space > 0 && actual_remain_space > 0) {
|
if (ROB_next_remain_space > 0 && actual_remain_space > 0) {
|
||||||
// can issue
|
// can issue
|
||||||
|
std::cerr << "csu is issuing alu instruct " << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
|
||||||
|
<< instruction << " full_ins_id= " << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< std::uppercase << full_ins_id << std::endl;
|
||||||
is_issuing <= 1;
|
is_issuing <= 1;
|
||||||
has_instruction_issued_last_cycle <= 1;
|
has_instruction_issued_last_cycle <= 1;
|
||||||
uint32_t tail = static_cast<max_size_t>(ROB_tail);
|
uint32_t tail = static_cast<max_size_t>(ROB_tail);
|
||||||
@ -366,6 +383,7 @@ struct CentralScheduleUnit
|
|||||||
break;
|
break;
|
||||||
case 0b1100111:
|
case 0b1100111:
|
||||||
// jalr
|
// jalr
|
||||||
|
std::cerr<<"encounter jalr"<<std::endl;
|
||||||
ROB_records[tail].resulting_PC_ready <= 0;
|
ROB_records[tail].resulting_PC_ready <= 0;
|
||||||
has_predicted_PC <= 0;
|
has_predicted_PC <= 0;
|
||||||
break;
|
break;
|
||||||
@ -383,6 +401,10 @@ struct CentralScheduleUnit
|
|||||||
ROB_records[tail].PC_mismatch_mark <= 0;
|
ROB_records[tail].PC_mismatch_mark <= 0;
|
||||||
this->issue_type <= 0;
|
this->issue_type <= 0;
|
||||||
this->issue_ROB_index <= tail;
|
this->issue_ROB_index <= tail;
|
||||||
|
if (instruction == 0x0ff00513) {
|
||||||
|
this->full_ins_id <= 1;
|
||||||
|
has_predicted_PC <= 0;
|
||||||
|
} else
|
||||||
this->full_ins_id <= full_ins_id;
|
this->full_ins_id <= full_ins_id;
|
||||||
this->full_ins <= instruction;
|
this->full_ins <= instruction;
|
||||||
this->issuing_PC <= static_cast<max_size_t>(predicted_PC);
|
this->issuing_PC <= static_cast<max_size_t>(predicted_PC);
|
||||||
@ -431,6 +453,11 @@ struct CentralScheduleUnit
|
|||||||
}
|
}
|
||||||
// other data
|
// other data
|
||||||
ROB_remain_space <= ROB_next_remain_space;
|
ROB_remain_space <= ROB_next_remain_space;
|
||||||
|
for (auto &record : ROB_records) {
|
||||||
|
if (static_cast<max_size_t>(record.state) == 1) {
|
||||||
|
record.state <= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ZYM
|
} // namespace ZYM
|
||||||
|
@ -43,7 +43,8 @@ struct assert {
|
|||||||
std::cerr << "Message: ";
|
std::cerr << "Message: ";
|
||||||
((std::cerr << args), ...) << std::endl;
|
((std::cerr << args), ...) << std::endl;
|
||||||
}
|
}
|
||||||
std::exit(EXIT_FAILURE);
|
// std::exit(EXIT_FAILURE);
|
||||||
|
throw std::runtime_error("Assertion failed");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
explicit assert(_Tp &&, _Args &&...) {}
|
explicit assert(_Tp &&, _Args &&...) {}
|
||||||
|
@ -211,15 +211,14 @@ struct LoadStoreQueue : public dark::Module<LoadStoreQueue_Input, LoadStoreQueue
|
|||||||
// other data
|
// other data
|
||||||
if (bool(has_accepted_ins_last_cycle)) LSQ_queue[last_idx].state <= 2;
|
if (bool(has_accepted_ins_last_cycle)) LSQ_queue[last_idx].state <= 2;
|
||||||
bool can_execute = false;
|
bool can_execute = false;
|
||||||
if (static_cast<uint32_t>(mem_data_sign) > 0) {
|
if (static_cast<uint32_t>(mem_data_sign) > 0 && static_cast<max_size_t>(request_type_output) == 0) {
|
||||||
if (static_cast<uint32_t>(LSQ_head) != static_cast<uint32_t>(LSQ_tail)) {
|
if (static_cast<uint32_t>(LSQ_head) != static_cast<uint32_t>(LSQ_tail)) {
|
||||||
uint32_t head = static_cast<uint32_t>(LSQ_head);
|
uint32_t head = static_cast<uint32_t>(LSQ_head);
|
||||||
if (LSQ_queue[head].state.peek() == 2) {
|
if (LSQ_queue[head].state == 2) {
|
||||||
if (((LSQ_queue[head].E1.peek() == 0) ||
|
if (((LSQ_queue[head].E1 == 0) || (LSQ_queue[head].E1 == 1 && LSQ_queue[head].D1 == 1)) &&
|
||||||
(LSQ_queue[head].E1.peek() == 1 && LSQ_queue[head].D1.peek() == 1)) &&
|
((LSQ_queue[head].E2 == 0) || (LSQ_queue[head].E2 == 1 && LSQ_queue[head].D2 == 1))) {
|
||||||
((LSQ_queue[head].E2.peek() == 0) ||
|
|
||||||
(LSQ_queue[head].E2.peek() == 1 && LSQ_queue[head].D2.peek() == 1))) {
|
|
||||||
// now we can execute the instruction
|
// now we can execute the instruction
|
||||||
|
std::cerr << "Load Store queue is executing instruction" << std::endl;
|
||||||
next_remain_space--;
|
next_remain_space--;
|
||||||
can_execute = true;
|
can_execute = true;
|
||||||
LSQ_head <= (head + 1) % 32;
|
LSQ_head <= (head + 1) % 32;
|
||||||
|
@ -218,7 +218,7 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
int addr, tmp;
|
int addr, tmp;
|
||||||
std::vector<uint8_t> buf;
|
std::vector<uint8_t> buf;
|
||||||
fin >> addr;
|
fin >> addr;
|
||||||
DEBUG_CERR << "begin:" << std::hex << addr << std::endl;
|
// DEBUG_CERR << "begin:" << std::hex << addr << std::endl;
|
||||||
while (fin >> tmp) {
|
while (fin >> tmp) {
|
||||||
buf.push_back(tmp);
|
buf.push_back(tmp);
|
||||||
}
|
}
|
||||||
@ -227,8 +227,8 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < buf.size(); i++) {
|
for (int i = 0; i < buf.size(); i++) {
|
||||||
memory_data[addr + i] = buf[i];
|
memory_data[addr + i] = buf[i];
|
||||||
DEBUG_CERR << std::hex << addr + i << ' ' << std::uppercase << std::setw(2) << std::setfill('0') << std::hex
|
// DEBUG_CERR << std::hex << addr + i << ' ' << std::uppercase << std::setw(2) << std::setfill('0') << std::hex
|
||||||
<< (int)buf[i] << std::endl;
|
// << (int)buf[i] << std::endl;
|
||||||
}
|
}
|
||||||
fin.clear();
|
fin.clear();
|
||||||
} while (!fin.eof());
|
} while (!fin.eof());
|
||||||
|
@ -212,18 +212,18 @@ struct ReserveStation : public dark::Module<ReserveStation_Input, ReserveStation
|
|||||||
if (bool(has_accepted_ins_last_cycle)) RS_records[last_idx].state <= 2;
|
if (bool(has_accepted_ins_last_cycle)) RS_records[last_idx].state <= 2;
|
||||||
bool can_execute = false;
|
bool can_execute = false;
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
if (RS_records[last_idx].state.peek() != 2) continue;
|
if (RS_records[i].state != 2) continue;
|
||||||
if (RS_records[last_idx].E1.peek() == 1 && RS_records[last_idx].D1.peek() == 0) continue;
|
if (RS_records[i].E1 == 1 && RS_records[i].D1 == 0) continue;
|
||||||
if (RS_records[last_idx].E2.peek() == 1 && RS_records[last_idx].D2.peek() == 0) continue;
|
if (RS_records[i].E2 == 1 && RS_records[i].D2 == 0) continue;
|
||||||
can_execute = true;
|
can_execute = true;
|
||||||
request_full_id <= RS_records[last_idx].full_ins_id;
|
request_full_id <= RS_records[i].full_ins_id;
|
||||||
operand1 <= RS_records[last_idx].V1;
|
operand1 <= RS_records[i].V1;
|
||||||
operand2 <= RS_records[last_idx].V2;
|
operand2 <= RS_records[i].V2;
|
||||||
op_imm <= RS_records[last_idx].ins_imm;
|
op_imm <= RS_records[i].ins_imm;
|
||||||
op_shamt <= RS_records[last_idx].ins_shamt;
|
op_shamt <= RS_records[i].ins_shamt;
|
||||||
alu_ins_PC <= RS_records[last_idx].ins_self_PC;
|
alu_ins_PC <= RS_records[i].ins_self_PC;
|
||||||
request_ROB_index <= RS_records[last_idx].ins_ROB_index;
|
request_ROB_index <= RS_records[i].ins_ROB_index;
|
||||||
RS_records[last_idx].state <= 0;
|
RS_records[i].state <= 0;
|
||||||
next_remain_space++;
|
next_remain_space++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,10 @@
|
|||||||
#include "wire.h"
|
#include "wire.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include<iostream>
|
||||||
|
#include<iomanip>
|
||||||
|
|
||||||
|
extern unsigned int global_clock;
|
||||||
using dark::Bit;
|
using dark::Bit;
|
||||||
using dark::sign_extend;
|
using dark::sign_extend;
|
||||||
using dark::zero_extend;
|
using dark::zero_extend;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "registerfile.h"
|
#include "registerfile.h"
|
||||||
#include "reservestation.h"
|
#include "reservestation.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
unsigned int global_clock = 0;
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
inline static void RWConnect(dark::Register<N> &src, dark::Wire<N> &dest) {
|
inline static void RWConnect(dark::Register<N> &src, dark::Wire<N> &dest) {
|
||||||
dest.assign([&]() -> auto & { return src; });
|
dest.assign([&]() -> auto & { return src; });
|
||||||
@ -168,6 +169,6 @@ int main(int argc, char **argv) {
|
|||||||
RWConnect(rf.rs2_deps, rs.rs2_deps);
|
RWConnect(rf.rs2_deps, rs.rs2_deps);
|
||||||
RWConnect(rf.rs2_value, rs.rs2_value);
|
RWConnect(rf.rs2_value, rs.rs2_value);
|
||||||
// now start running
|
// now start running
|
||||||
std::cout << cpu.run(0, true) << std::endl;
|
std::cout << cpu.run(100, false) << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Reference in New Issue
Block a user