can halt
This commit is contained in:
@ -24,7 +24,8 @@ struct ALU : public dark::Module<ALU_Input, ALU_Output> {
|
|||||||
}
|
}
|
||||||
void work() {
|
void work() {
|
||||||
std::cerr << "ALU: cur request_full_id=" << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
|
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;
|
<< static_cast<max_size_t>(request_full_id) << " request_ROB_index=" << std::dec
|
||||||
|
<< static_cast<max_size_t>(request_ROB_index) << 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;
|
||||||
@ -66,6 +67,8 @@ 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 <= static_cast<max_size_t>(request_PC) + 4;
|
result <= static_cast<max_size_t>(request_PC) + 4;
|
||||||
|
std::cerr << "alu: jalr: imm=" << std::hex << static_cast<max_size_t>(imm) << std::endl;
|
||||||
|
std::cerr << "alu: jalr: operand1=" << std::hex << static_cast<max_size_t>(operand1) << std::endl;
|
||||||
completed_alu_resulting_PC <= ((static_cast<max_size_t>(operand1) + static_cast<max_size_t>(imm)) & 0xfffffffe);
|
completed_alu_resulting_PC <= ((static_cast<max_size_t>(operand1) + static_cast<max_size_t>(imm)) & 0xfffffffe);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "concept.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "wire.h"
|
#include "wire.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -64,11 +65,13 @@ 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;
|
std::cerr<<"\nclock: "<<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);
|
halt_signal.sync();
|
||||||
if(halt_signal_value &(1<<9)) {
|
uint32_t halt_signal_value = static_cast<max_size_t>(halt_signal);
|
||||||
|
std::cerr<<"simulator received halt_signal_value="<<std::dec<<halt_signal_value<<std::endl;
|
||||||
|
if(halt_signal_value &(1<<8)) {
|
||||||
return halt_signal_value&0xff;
|
return halt_signal_value&0xff;
|
||||||
}
|
}
|
||||||
global_clock++;
|
global_clock++;
|
||||||
|
@ -12,6 +12,7 @@ namespace ZYM {
|
|||||||
const int kROBSize = 32;
|
const int kROBSize = 32;
|
||||||
const int kTotalRegister = 32;
|
const int kTotalRegister = 32;
|
||||||
struct CentralScheduleUnit_Input {
|
struct CentralScheduleUnit_Input {
|
||||||
|
dark::Wire<8> a0;
|
||||||
dark::Wire<1> reset;
|
dark::Wire<1> reset;
|
||||||
// data from load store queue
|
// data from load store queue
|
||||||
dark::Wire<6> load_store_queue_emptyspace_receiver;
|
dark::Wire<6> load_store_queue_emptyspace_receiver;
|
||||||
@ -262,7 +263,8 @@ struct CentralScheduleUnit
|
|||||||
}
|
}
|
||||||
ROB_next_remain_space++;
|
ROB_next_remain_space++;
|
||||||
if (record.instruction == 0x0ff00513) {
|
if (record.instruction == 0x0ff00513) {
|
||||||
halt_signal <= 0b100000000;
|
halt_signal <= (0b100000000 | static_cast<max_size_t>(a0));
|
||||||
|
std::cerr << "halting with code " << std::dec << int(halt_signal.peek()) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,23 +283,28 @@ struct CentralScheduleUnit
|
|||||||
record.resulting_register_value <= res_data;
|
record.resulting_register_value <= res_data;
|
||||||
if (!bool(record.resulting_PC_ready)) {
|
if (!bool(record.resulting_PC_ready)) {
|
||||||
record.resulting_PC <= res_PC;
|
record.resulting_PC <= res_PC;
|
||||||
if (res_PC != static_cast<max_size_t>(record.resulting_PC)) {
|
if (res_PC != static_cast<max_size_t>(record.resulting_PC) &&
|
||||||
|
(static_cast<max_size_t>(record.instruction) & 0x7F) != 0b1100111) {
|
||||||
record.PC_mismatch_mark <= 1;
|
record.PC_mismatch_mark <= 1;
|
||||||
}
|
}
|
||||||
record.resulting_PC_ready <= 1;
|
record.resulting_PC_ready <= 1;
|
||||||
if ((static_cast<max_size_t>(record.instruction) & 0x7F) == 0b1100111) {
|
if ((static_cast<max_size_t>(record.instruction) & 0x7F) == 0b1100111) {
|
||||||
has_predicted_PC <= 1;
|
has_predicted_PC <= 1;
|
||||||
predicted_PC <= record.resulting_PC;
|
predicted_PC <= res_PC;
|
||||||
|
std::cerr << "The jalr instruction is committed, now predicted_PC is " << std::hex << std::setw(8)
|
||||||
|
<< std::setfill('0') << std::uppercase << predicted_PC.peek() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
record.state <= 3;
|
record.state <= 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
std::cerr << "csu is listening data from memory" << std::endl;
|
||||||
if (static_cast<max_size_t>(mem_status_receiver) == 0b10) {
|
if (static_cast<max_size_t>(mem_status_receiver) == 0b10) {
|
||||||
process_data(static_cast<max_size_t>(completed_memins_ROB_index),
|
process_data(static_cast<max_size_t>(completed_memins_ROB_index),
|
||||||
static_cast<max_size_t>(completed_memins_read_data), 0);
|
static_cast<max_size_t>(completed_memins_read_data), 0);
|
||||||
}
|
}
|
||||||
|
std::cerr << "csu is listening data from alu" << std::endl;
|
||||||
if (static_cast<max_size_t>(alu_status_receiver) == 0b10) {
|
if (static_cast<max_size_t>(alu_status_receiver) == 0b10) {
|
||||||
process_data(static_cast<max_size_t>(completed_aluins_ROB_index),
|
process_data(static_cast<max_size_t>(completed_aluins_ROB_index),
|
||||||
static_cast<max_size_t>(completed_aluins_result),
|
static_cast<max_size_t>(completed_aluins_result),
|
||||||
@ -383,7 +390,7 @@ struct CentralScheduleUnit
|
|||||||
break;
|
break;
|
||||||
case 0b1100111:
|
case 0b1100111:
|
||||||
// jalr
|
// jalr
|
||||||
std::cerr<<"encounter jalr"<<std::endl;
|
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;
|
||||||
@ -427,23 +434,39 @@ struct CentralScheduleUnit
|
|||||||
}
|
}
|
||||||
// provide the potentially missing data for instruction issued last cycle
|
// provide the potentially missing data for instruction issued last cycle
|
||||||
if (bool(has_instruction_issued_last_cycle)) {
|
if (bool(has_instruction_issued_last_cycle)) {
|
||||||
|
std::cerr << "CSU is processing potentially missing data for instruction issued last cycle" << std::endl;
|
||||||
uint8_t rs1 = static_cast<max_size_t>(this->decoded_rs1);
|
uint8_t rs1 = static_cast<max_size_t>(this->decoded_rs1);
|
||||||
uint8_t found_rs1 = 0;
|
uint8_t found_rs1 = 0;
|
||||||
uint32_t rs1_v;
|
uint32_t rs1_v;
|
||||||
uint8_t rs2 = static_cast<max_size_t>(this->decoded_rs2);
|
uint8_t rs2 = static_cast<max_size_t>(this->decoded_rs2);
|
||||||
uint8_t found_rs2 = 0;
|
uint8_t found_rs2 = 0;
|
||||||
uint32_t rs2_v;
|
uint32_t rs2_v;
|
||||||
for (uint32_t ptr = static_cast<max_size_t>(ROB_head); ptr != static_cast<max_size_t>(ROB_tail);
|
for (uint32_t ptr = static_cast<max_size_t>(ROB_head);
|
||||||
|
ptr != static_cast<max_size_t>(ROB_tail) && (ptr + 1) % kROBSize != static_cast<max_size_t>(ROB_tail);
|
||||||
ptr = (ptr + 1) % kROBSize) {
|
ptr = (ptr + 1) % kROBSize) {
|
||||||
if (ROB_records[ptr].state.peek() == 3) {
|
if (ROB_records[ptr].state.peek() == 3) {
|
||||||
if (static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs1) {
|
if (bool(ROB_records[ptr].has_resulting_register) &&
|
||||||
|
static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs1) {
|
||||||
rs1_v = ROB_records[ptr].resulting_register_value.peek();
|
rs1_v = ROB_records[ptr].resulting_register_value.peek();
|
||||||
found_rs1 = 1;
|
found_rs1 = 1;
|
||||||
|
std::cerr << "matching rs1=" << std::dec << int(rs1) << " ptr=" << std::dec << ptr << " rs1_v=" << std::hex
|
||||||
|
<< std::setw(8) << std::setfill('0') << rs1_v << std::endl;
|
||||||
}
|
}
|
||||||
if (static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs2) {
|
if (bool(ROB_records[ptr].has_resulting_register) &&
|
||||||
|
static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs2) {
|
||||||
rs2_v = ROB_records[ptr].resulting_register_value.peek();
|
rs2_v = ROB_records[ptr].resulting_register_value.peek();
|
||||||
found_rs2 = 1;
|
found_rs2 = 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (bool(ROB_records[ptr].has_resulting_register) &&
|
||||||
|
static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs1) {
|
||||||
|
found_rs1 = 0;
|
||||||
|
std::cerr << "dematching rs1=" << std::dec << int(rs1) << " ptr=" << std::dec << ptr << std::endl;
|
||||||
|
}
|
||||||
|
if (bool(ROB_records[ptr].has_resulting_register) &&
|
||||||
|
static_cast<max_size_t>(ROB_records[ptr].resulting_register_idx) == rs2) {
|
||||||
|
found_rs2 = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->rs1_is_in_ROB <= found_rs1;
|
this->rs1_is_in_ROB <= found_rs1;
|
||||||
|
@ -124,6 +124,16 @@ struct LoadStoreQueue : public dark::Module<LoadStoreQueue_Input, LoadStoreQueue
|
|||||||
LSQ_queue[cur_queue_tail].E2 <= has_decoded_rs2;
|
LSQ_queue[cur_queue_tail].E2 <= has_decoded_rs2;
|
||||||
LSQ_queue[cur_queue_tail].D1 <= 1; // temporarily
|
LSQ_queue[cur_queue_tail].D1 <= 1; // temporarily
|
||||||
LSQ_queue[cur_queue_tail].D2 <= 1; // temporarily
|
LSQ_queue[cur_queue_tail].D2 <= 1; // temporarily
|
||||||
|
std::cerr << "LoadStoreQueue is accepting instruction" << std::endl;
|
||||||
|
std::cerr << "\tfull_ins_id: " << std::hex << static_cast<max_size_t>(full_ins_id) << std::endl;
|
||||||
|
std::cerr << "\tins_ROB_index: " << std::dec << static_cast<max_size_t>(issue_ROB_index) << std::endl;
|
||||||
|
std::cerr << "\tins_self_PC: " << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< static_cast<max_size_t>(issuing_PC) << std::endl;
|
||||||
|
std::cerr << "\tins_imm: " << std::hex << static_cast<max_size_t>(decoded_imm) << std::endl;
|
||||||
|
std::cerr << "\thas_decoded_rs1: " << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< static_cast<max_size_t>(has_decoded_rs1) << std::endl;
|
||||||
|
std::cerr << "\thas_decoded_rs2: " << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< static_cast<max_size_t>(has_decoded_rs2) << std::endl;
|
||||||
// LSQ_queue[cur_queue_tail].Q1 <= decoded_rs1; // temporarily, no use
|
// LSQ_queue[cur_queue_tail].Q1 <= decoded_rs1; // temporarily, no use
|
||||||
// LSQ_queue[cur_queue_tail].Q2 <= decoded_rs2; // temporarily, no use
|
// LSQ_queue[cur_queue_tail].Q2 <= decoded_rs2; // temporarily, no use
|
||||||
} else
|
} else
|
||||||
@ -134,10 +144,13 @@ struct LoadStoreQueue : public dark::Module<LoadStoreQueue_Input, LoadStoreQueue
|
|||||||
if (bool(has_accepted_ins_last_cycle)) {
|
if (bool(has_accepted_ins_last_cycle)) {
|
||||||
// now dependency info can be read from the register file, in the mean time, CSU will provide the
|
// now dependency info can be read from the register file, in the mean time, CSU will provide the
|
||||||
// potentially missing data
|
// potentially missing data
|
||||||
|
std::cerr << "LoadStoreQueue is process dependency information from register file and ROB" << std::endl;
|
||||||
if (bool(LSQ_queue[last_idx].E1) && bool(rs1_nodep)) {
|
if (bool(LSQ_queue[last_idx].E1) && bool(rs1_nodep)) {
|
||||||
LSQ_queue[last_idx].V1 <= rs1_value;
|
LSQ_queue[last_idx].V1 <= rs1_value;
|
||||||
LSQ_queue[last_idx].D1 <= 1;
|
LSQ_queue[last_idx].D1 <= 1;
|
||||||
last_cycle_V1_proccessed = true;
|
last_cycle_V1_proccessed = true;
|
||||||
|
std::cerr << "\t from register file: LSQ_queue[last_idx].V1=" << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< static_cast<max_size_t>(LSQ_queue[last_idx].V1) << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(LSQ_queue[last_idx].E2) && bool(rs2_nodep)) {
|
if (bool(LSQ_queue[last_idx].E2) && bool(rs2_nodep)) {
|
||||||
LSQ_queue[last_idx].V2 <= rs2_value;
|
LSQ_queue[last_idx].V2 <= rs2_value;
|
||||||
@ -148,12 +161,15 @@ struct LoadStoreQueue : public dark::Module<LoadStoreQueue_Input, LoadStoreQueue
|
|||||||
LSQ_queue[last_idx].V1 <= rs1_in_ROB_value;
|
LSQ_queue[last_idx].V1 <= rs1_in_ROB_value;
|
||||||
LSQ_queue[last_idx].D1 <= 1;
|
LSQ_queue[last_idx].D1 <= 1;
|
||||||
last_cycle_V1_proccessed = true;
|
last_cycle_V1_proccessed = true;
|
||||||
|
std::cerr << "\t from ROB: LSQ_queue[last_idx].V1=" << std::hex << std::setw(8) << std::setfill('0')
|
||||||
|
<< static_cast<max_size_t>(LSQ_queue[last_idx].V1) << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(LSQ_queue[last_idx].E2) && (!bool(rs2_nodep)) && bool(rs2_is_in_ROB)) {
|
if (bool(LSQ_queue[last_idx].E2) && (!bool(rs2_nodep)) && bool(rs2_is_in_ROB)) {
|
||||||
LSQ_queue[last_idx].V2 <= rs2_in_ROB_value;
|
LSQ_queue[last_idx].V2 <= rs2_in_ROB_value;
|
||||||
LSQ_queue[last_idx].D2 <= 1;
|
LSQ_queue[last_idx].D2 <= 1;
|
||||||
last_cycle_V2_proccessed = true;
|
last_cycle_V2_proccessed = true;
|
||||||
}
|
}
|
||||||
|
std::cerr << "End of processing dependency information from register file and ROB" << std::endl;
|
||||||
}
|
}
|
||||||
bool should_monitor_V1 =
|
bool should_monitor_V1 =
|
||||||
bool(has_accepted_ins_last_cycle) && bool(LSQ_queue[last_idx].E1) && !last_cycle_V1_proccessed;
|
bool(has_accepted_ins_last_cycle) && bool(LSQ_queue[last_idx].E1) && !last_cycle_V1_proccessed;
|
||||||
@ -188,10 +204,12 @@ struct LoadStoreQueue : public dark::Module<LoadStoreQueue_Input, LoadStoreQueue
|
|||||||
ptr = (ptr + 1) % 32;
|
ptr = (ptr + 1) % 32;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
std::cerr << "Load Store Queue is listening data from alu" << std::endl;
|
||||||
if (static_cast<max_size_t>(alu_status_receiver) == 0b10) {
|
if (static_cast<max_size_t>(alu_status_receiver) == 0b10) {
|
||||||
process_listend_data(static_cast<max_size_t>(completed_aluins_ROB_index),
|
process_listend_data(static_cast<max_size_t>(completed_aluins_ROB_index),
|
||||||
static_cast<max_size_t>(completed_aluins_result));
|
static_cast<max_size_t>(completed_aluins_result));
|
||||||
}
|
}
|
||||||
|
std::cerr << "Load Store Queue is listening data from memory" << std::endl;
|
||||||
if (static_cast<max_size_t>(mem_data_sign) == 0b10) {
|
if (static_cast<max_size_t>(mem_data_sign) == 0b10) {
|
||||||
process_listend_data(static_cast<max_size_t>(completed_memins_ROB_index),
|
process_listend_data(static_cast<max_size_t>(completed_memins_ROB_index),
|
||||||
static_cast<max_size_t>(completed_memins_read_data));
|
static_cast<max_size_t>(completed_memins_read_data));
|
||||||
|
@ -116,6 +116,8 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
completed_memins_read_data <= tmp;
|
completed_memins_read_data <= tmp;
|
||||||
|
std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(2) << tmp << " from " << std::hex
|
||||||
|
<< static_cast<max_size_t>(cur_opt_addr) << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
@ -127,10 +129,15 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
completed_memins_read_data <= tmp;
|
completed_memins_read_data <= tmp;
|
||||||
|
std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(4) << tmp << " from " << std::hex
|
||||||
|
<< static_cast<max_size_t>(cur_opt_addr) << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
completed_memins_read_data <= *reinterpret_cast<uint32_t *>(&memory_data[max_size_t(cur_opt_addr)]);
|
completed_memins_read_data <= *reinterpret_cast<uint32_t *>(&memory_data[max_size_t(cur_opt_addr)]);
|
||||||
|
std::cerr << "memory read: " << std::hex << std::setfill('0') << std::setw(8)
|
||||||
|
<< *reinterpret_cast<uint32_t *>(&memory_data[max_size_t(cur_opt_addr)]) << " from " << std::hex
|
||||||
|
<< static_cast<max_size_t>(cur_opt_addr) << std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid bytes");
|
throw std::runtime_error("Invalid bytes");
|
||||||
@ -181,11 +188,12 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
playback[cur_opt_ROB_index].changes[3].addr <= cur_opt_addr + 3;
|
playback[cur_opt_ROB_index].changes[3].addr <= cur_opt_addr + 3;
|
||||||
playback[cur_opt_ROB_index].changes[3].before <= memory_data[max_size_t(cur_opt_addr) + 3];
|
playback[cur_opt_ROB_index].changes[3].before <= memory_data[max_size_t(cur_opt_addr) + 3];
|
||||||
*reinterpret_cast<uint32_t *>(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data);
|
*reinterpret_cast<uint32_t *>(&memory_data[max_size_t(cur_opt_addr)]) = max_size_t(cur_opt_data);
|
||||||
|
std::cerr << "Memory executing sw" << std::endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Invalid bytes");
|
throw std::runtime_error("Invalid bytes");
|
||||||
}
|
}
|
||||||
data_sign <= 1; // free
|
data_sign <= 2; // free
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,6 +209,7 @@ struct Memory : dark::Module<Memory_Input, Memory_Output, Memory_Private> {
|
|||||||
cur_opt_data <= data_input;
|
cur_opt_data <= data_input;
|
||||||
cur_opt_type <= rw_type;
|
cur_opt_type <= rw_type;
|
||||||
cur_opt_bytes <= opt_bytes;
|
cur_opt_bytes <= opt_bytes;
|
||||||
|
std::cerr << "Memory is accepting a request" << std::endl;
|
||||||
}
|
}
|
||||||
max_size_t FetchInstruction(max_size_t addr) { // assume we have a super nb instruction fetch method that can fetch
|
max_size_t FetchInstruction(max_size_t addr) { // assume we have a super nb instruction fetch method that can fetch
|
||||||
// an instruction immediately
|
// an instruction immediately
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <iomanip>
|
||||||
#include "concept.h"
|
#include "concept.h"
|
||||||
#ifndef REGISTERFILE_H
|
#ifndef REGISTERFILE_H
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -43,6 +44,7 @@ struct RegisterFile : public dark::Module<RegisterFile_Input, RegisterFile_Outpu
|
|||||||
RegisterFile() {
|
RegisterFile() {
|
||||||
// Constructor
|
// Constructor
|
||||||
}
|
}
|
||||||
|
uint8_t ReturnExitCodeImmediately() { return registers[10].peek() & 0xff; }
|
||||||
void work() {
|
void work() {
|
||||||
if (bool(reset)) {
|
if (bool(reset)) {
|
||||||
for (auto ® : registers) {
|
for (auto ® : registers) {
|
||||||
@ -65,8 +67,13 @@ struct RegisterFile : public dark::Module<RegisterFile_Input, RegisterFile_Outpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bool(is_issuing)) {
|
if (bool(is_issuing)) {
|
||||||
|
std::cerr << "Register File Found CSU is issuing" << std::endl;
|
||||||
if (bool(has_decoded_rs1)) {
|
if (bool(has_decoded_rs1)) {
|
||||||
if ((!bool(is_committing)) || (commit_reg_index != decoded_rs1)) {
|
if (static_cast<max_size_t>(decoded_rs1) == 0) {
|
||||||
|
rs1_deps <= 0;
|
||||||
|
rs1_value <= 0;
|
||||||
|
rs1_nodep <= 1;
|
||||||
|
} else if ((!bool(is_committing)) || (commit_reg_index != decoded_rs1)) {
|
||||||
rs1_deps <= register_deps[static_cast<max_size_t>(decoded_rs1)].peek();
|
rs1_deps <= register_deps[static_cast<max_size_t>(decoded_rs1)].peek();
|
||||||
rs1_value <= registers[static_cast<max_size_t>(decoded_rs1)].peek();
|
rs1_value <= registers[static_cast<max_size_t>(decoded_rs1)].peek();
|
||||||
rs1_nodep <= register_nodep[static_cast<max_size_t>(decoded_rs1)].peek();
|
rs1_nodep <= register_nodep[static_cast<max_size_t>(decoded_rs1)].peek();
|
||||||
@ -75,9 +82,16 @@ struct RegisterFile : public dark::Module<RegisterFile_Input, RegisterFile_Outpu
|
|||||||
rs1_value <= commit_reg_value;
|
rs1_value <= commit_reg_value;
|
||||||
rs1_nodep <= 1;
|
rs1_nodep <= 1;
|
||||||
}
|
}
|
||||||
|
std::cerr << std::dec << "rs1_deps=" << rs1_deps.peek() << std::endl;
|
||||||
|
std::cerr << std::hex << std::setw(8) << std::setfill('0') << "rs1_value=" << rs1_value.peek() << std::endl;
|
||||||
|
std::cerr << "rs1_nodep=" << rs1_nodep.peek() << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(has_decoded_rs2)) {
|
if (bool(has_decoded_rs2)) {
|
||||||
if ((!bool(is_committing)) || (commit_reg_index != decoded_rs2)) {
|
if (static_cast<max_size_t>(decoded_rs2) == 0) {
|
||||||
|
rs2_deps <= 0;
|
||||||
|
rs2_value <= 0;
|
||||||
|
rs2_nodep <= 1;
|
||||||
|
} else if ((!bool(is_committing)) || (commit_reg_index != decoded_rs2)) {
|
||||||
rs2_deps <= register_deps[static_cast<max_size_t>(decoded_rs2)].peek();
|
rs2_deps <= register_deps[static_cast<max_size_t>(decoded_rs2)].peek();
|
||||||
rs2_value <= registers[static_cast<max_size_t>(decoded_rs2)].peek();
|
rs2_value <= registers[static_cast<max_size_t>(decoded_rs2)].peek();
|
||||||
rs2_nodep <= register_nodep[static_cast<max_size_t>(decoded_rs2)].peek();
|
rs2_nodep <= register_nodep[static_cast<max_size_t>(decoded_rs2)].peek();
|
||||||
@ -86,6 +100,9 @@ struct RegisterFile : public dark::Module<RegisterFile_Input, RegisterFile_Outpu
|
|||||||
rs2_value <= commit_reg_value;
|
rs2_value <= commit_reg_value;
|
||||||
rs2_nodep <= 1;
|
rs2_nodep <= 1;
|
||||||
}
|
}
|
||||||
|
std::cerr << std::dec << "rs2_deps=" << rs2_deps.peek() << std::endl;
|
||||||
|
std::cerr << std::hex << std::setw(8) << std::setfill('0') << "rs2_value=" << rs2_value.peek() << std::endl;
|
||||||
|
std::cerr << "rs2_nodep=" << rs2_nodep.peek() << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(has_decoded_rd)) {
|
if (bool(has_decoded_rd)) {
|
||||||
register_deps[static_cast<max_size_t>(decoded_rd)] <= static_cast<max_size_t>(issue_ROB_index);
|
register_deps[static_cast<max_size_t>(decoded_rd)] <= static_cast<max_size_t>(issue_ROB_index);
|
||||||
|
@ -135,25 +135,30 @@ struct ReserveStation : public dark::Module<ReserveStation_Input, ReserveStation
|
|||||||
if (bool(has_accepted_ins_last_cycle)) {
|
if (bool(has_accepted_ins_last_cycle)) {
|
||||||
// TODO: now dependency info can be read from the register file, in the mean time, CSU will provide the
|
// TODO: now dependency info can be read from the register file, in the mean time, CSU will provide the
|
||||||
// potentially missing data
|
// potentially missing data
|
||||||
|
std::cerr << "Reserve Station is listening dependency info from Register File and CSU" << std::endl;
|
||||||
if (bool(RS_records[last_idx].E1) && bool(rs1_nodep)) {
|
if (bool(RS_records[last_idx].E1) && bool(rs1_nodep)) {
|
||||||
RS_records[last_idx].V1 <= rs1_value;
|
RS_records[last_idx].V1 <= rs1_value;
|
||||||
RS_records[last_idx].D1 <= 1;
|
RS_records[last_idx].D1 <= 1;
|
||||||
last_cycle_V1_proccessed = true;
|
last_cycle_V1_proccessed = true;
|
||||||
|
std::cerr << "\t Register File: RS1 is not dependent" << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(RS_records[last_idx].E2) && bool(rs2_nodep)) {
|
if (bool(RS_records[last_idx].E2) && bool(rs2_nodep)) {
|
||||||
RS_records[last_idx].V2 <= rs2_value;
|
RS_records[last_idx].V2 <= rs2_value;
|
||||||
RS_records[last_idx].D2 <= 1;
|
RS_records[last_idx].D2 <= 1;
|
||||||
last_cycle_V2_proccessed = true;
|
last_cycle_V2_proccessed = true;
|
||||||
|
std::cerr << "\t Register File: RS2 is not dependent" << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(RS_records[last_idx].E1) && (!bool(rs1_nodep)) && bool(rs1_is_in_ROB)) {
|
if (bool(RS_records[last_idx].E1) && (!bool(rs1_nodep)) && bool(rs1_is_in_ROB)) {
|
||||||
RS_records[last_idx].V1 <= rs1_in_ROB_value;
|
RS_records[last_idx].V1 <= rs1_in_ROB_value;
|
||||||
RS_records[last_idx].D1 <= 1;
|
RS_records[last_idx].D1 <= 1;
|
||||||
last_cycle_V1_proccessed = true;
|
last_cycle_V1_proccessed = true;
|
||||||
|
std::cerr << "\t ROB: RS1 is in ROB" << std::endl;
|
||||||
}
|
}
|
||||||
if (bool(RS_records[last_idx].E2) && (!bool(rs2_nodep)) && bool(rs2_is_in_ROB)) {
|
if (bool(RS_records[last_idx].E2) && (!bool(rs2_nodep)) && bool(rs2_is_in_ROB)) {
|
||||||
RS_records[last_idx].V2 <= rs2_in_ROB_value;
|
RS_records[last_idx].V2 <= rs2_in_ROB_value;
|
||||||
RS_records[last_idx].D2 <= 1;
|
RS_records[last_idx].D2 <= 1;
|
||||||
last_cycle_V2_proccessed = true;
|
last_cycle_V2_proccessed = true;
|
||||||
|
std::cerr << "\t ROB: RS2 is in ROB" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: now alu, memory may provide data to satisfy the dependency
|
// TODO: now alu, memory may provide data to satisfy the dependency
|
||||||
@ -203,10 +208,12 @@ struct ReserveStation : public dark::Module<ReserveStation_Input, ReserveStation
|
|||||||
if (should_monitor_V1) {
|
if (should_monitor_V1) {
|
||||||
RS_records[last_idx].Q1 <= rs1_deps;
|
RS_records[last_idx].Q1 <= rs1_deps;
|
||||||
RS_records[last_idx].D1 <= 0;
|
RS_records[last_idx].D1 <= 0;
|
||||||
|
std::cerr << "\t RS1 depend on ins of ROB index " << std::dec << RS_records[last_idx].Q1.peek() << std::endl;
|
||||||
}
|
}
|
||||||
if (should_monitor_V2) {
|
if (should_monitor_V2) {
|
||||||
RS_records[last_idx].Q2 <= rs2_deps;
|
RS_records[last_idx].Q2 <= rs2_deps;
|
||||||
RS_records[last_idx].D2 <= 0;
|
RS_records[last_idx].D2 <= 0;
|
||||||
|
std::cerr << "\t RS2 depend on ins of ROB index " << std::dec << RS_records[last_idx].Q2.peek() << std::endl;
|
||||||
}
|
}
|
||||||
// TODO: now, we can check if we can execute the instruction, memory and L0 cache will listen to this
|
// TODO: now, we can check if we can execute the instruction, memory and L0 cache will listen to this
|
||||||
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;
|
||||||
|
@ -61,6 +61,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void sync() { this->_M_holds = false; }
|
void sync() { this->_M_holds = false; }
|
||||||
|
friend class CPU;
|
||||||
|
|
||||||
template<details::WireFunction<_Len> _Fn>
|
template<details::WireFunction<_Len> _Fn>
|
||||||
static auto _M_new_func(_Fn &&fn) {
|
static auto _M_new_func(_Fn &&fn) {
|
||||||
|
@ -35,6 +35,7 @@ int main(int argc, char **argv) {
|
|||||||
// alu.reset.assign([&]() { return cpu.GetResetSignal(); });
|
// alu.reset.assign([&]() { return cpu.GetResetSignal(); });
|
||||||
rf.reset.assign([&]() { return cpu.GetResetSignal(); });
|
rf.reset.assign([&]() { return cpu.GetResetSignal(); });
|
||||||
rs.reset.assign([&]() { return cpu.GetResetSignal(); });
|
rs.reset.assign([&]() { return cpu.GetResetSignal(); });
|
||||||
|
csu.a0.assign([&]() { return rf.ReturnExitCodeImmediately(); });
|
||||||
// now connect the wires, see the comment and docs for help
|
// now connect the wires, see the comment and docs for help
|
||||||
// csu <-> memory
|
// csu <-> memory
|
||||||
RWConnect(csu.force_clear_announcer, memory.force_clear_receiver);
|
RWConnect(csu.force_clear_announcer, memory.force_clear_receiver);
|
||||||
@ -169,6 +170,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(100, false) << std::endl;
|
std::cout << uint32_t(cpu.run(1000, false)) << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Reference in New Issue
Block a user