simX refactoring
This commit is contained in:
381
simX/core.cpp
381
simX/core.cpp
@@ -1,10 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string.h>
|
||||
|
||||
// #define USE_DEBUG 7
|
||||
// #define PRINT_ACTIVE_THREADS
|
||||
|
||||
#include <assert.h>
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
#include "archdef.h"
|
||||
@@ -14,21 +11,25 @@
|
||||
#include "debug.h"
|
||||
|
||||
#define INIT_TRACE(trace_inst) \
|
||||
trace_inst.valid_inst = false; \
|
||||
trace_inst.pc = 0; \
|
||||
trace_inst.valid = false; \
|
||||
trace_inst.PC = 0; \
|
||||
trace_inst.wid = schedule_w_; \
|
||||
trace_inst.rs1 = -1; \
|
||||
trace_inst.rs2 = -1; \
|
||||
trace_inst.rd = -1; \
|
||||
trace_inst.vs1 = -1; \
|
||||
trace_inst.vs2 = -1; \
|
||||
trace_inst.vd = -1; \
|
||||
trace_inst.irs1 = -1; \
|
||||
trace_inst.irs2 = -1; \
|
||||
trace_inst.frs1 = -1; \
|
||||
trace_inst.frs2 = -1; \
|
||||
trace_inst.frs3 = -1; \
|
||||
trace_inst.frd = -1; \
|
||||
trace_inst.ird = -1; \
|
||||
trace_inst.vrs1 = -1; \
|
||||
trace_inst.vrs2 = -1; \
|
||||
trace_inst.vrd = -1; \
|
||||
trace_inst.is_lw = false; \
|
||||
trace_inst.is_sw = false; \
|
||||
if (trace_inst.mem_addresses != NULL) \
|
||||
free(trace_inst.mem_addresses); \
|
||||
trace_inst.mem_addresses = (unsigned *)malloc(32 * sizeof(unsigned)); \
|
||||
for (ThdNum tid = 0; tid < arch_.getNumThreads(); tid++) \
|
||||
for (int tid = 0; tid < arch_.num_threads(); tid++) \
|
||||
trace_inst.mem_addresses[tid] = 0xdeadbeef; \
|
||||
trace_inst.mem_stall_cycles = 0; \
|
||||
trace_inst.fetch_stall_cycles = 0; \
|
||||
@@ -37,18 +38,22 @@
|
||||
trace_inst.stalled = false;
|
||||
|
||||
#define CPY_TRACE(drain, source) \
|
||||
drain.valid_inst = source.valid_inst; \
|
||||
drain.pc = source.pc; \
|
||||
drain.valid = source.valid; \
|
||||
drain.PC = source.PC; \
|
||||
drain.wid = source.wid; \
|
||||
drain.rs1 = source.rs1; \
|
||||
drain.rs2 = source.rs2; \
|
||||
drain.rd = source.rd; \
|
||||
drain.vs1 = source.vs1; \
|
||||
drain.vs2 = source.vs2; \
|
||||
drain.vd = source.vd; \
|
||||
drain.irs1 = source.irs1; \
|
||||
drain.irs2 = source.irs2; \
|
||||
drain.ird = source.ird; \
|
||||
drain.frs1 = source.frs1; \
|
||||
drain.frs2 = source.frs2; \
|
||||
drain.frs3 = source.frs3; \
|
||||
drain.frd = source.frd; \
|
||||
drain.vrs1 = source.vrs1; \
|
||||
drain.vrs2 = source.vrs2; \
|
||||
drain.vrd = source.vrd; \
|
||||
drain.is_lw = source.is_lw; \
|
||||
drain.is_sw = source.is_sw; \
|
||||
for (ThdNum tid = 0; tid < arch_.getNumThreads(); tid++)\
|
||||
for (int tid = 0; tid < arch_.num_threads(); tid++) \
|
||||
drain.mem_addresses[tid] = source.mem_addresses[tid]; \
|
||||
drain.mem_stall_cycles = source.mem_stall_cycles; \
|
||||
drain.fetch_stall_cycles = source.fetch_stall_cycles; \
|
||||
@@ -60,17 +65,17 @@ using namespace vortex;
|
||||
|
||||
void printTrace(trace_inst_t *trace, const char *stage_name) {
|
||||
__unused(trace, stage_name);
|
||||
D(3, stage_name << ": valid=" << trace->valid_inst);
|
||||
D(3, stage_name << ": PC=" << std::hex << trace->pc << std::dec);
|
||||
D(3, stage_name << ": wid=" << trace->wid);
|
||||
D(3, stage_name << ": rd=" << trace->rd << ", rs1=" << trace->rs1 << ", trs2=" << trace->rs2);
|
||||
D(3, stage_name << ": is_lw=" << trace->is_lw);
|
||||
D(3, stage_name << ": is_sw=" << trace->is_sw);
|
||||
D(3, stage_name << ": fetch_stall_cycles=" << trace->fetch_stall_cycles);
|
||||
D(3, stage_name << ": mem_stall_cycles=" << trace->mem_stall_cycles);
|
||||
D(3, stage_name << ": stall_warp=" << trace->stall_warp);
|
||||
D(3, stage_name << ": wspawn=" << trace->wspawn);
|
||||
D(3, stage_name << ": stalled=" << trace->stalled);
|
||||
D(4, stage_name << ": valid=" << trace->valid);
|
||||
D(4, stage_name << ": PC=" << std::hex << trace->PC << std::dec);
|
||||
D(4, stage_name << ": wid=" << trace->wid);
|
||||
D(4, stage_name << ": rd=" << trace->ird << ", rs1=" << trace->irs1 << ", trs2=" << trace->irs2);
|
||||
D(4, stage_name << ": is_lw=" << trace->is_lw);
|
||||
D(4, stage_name << ": is_sw=" << trace->is_sw);
|
||||
D(4, stage_name << ": fetch_stall_cycles=" << trace->fetch_stall_cycles);
|
||||
D(4, stage_name << ": mem_stall_cycles=" << trace->mem_stall_cycles);
|
||||
D(4, stage_name << ": stall_warp=" << trace->stall_warp);
|
||||
D(4, stage_name << ": wspawn=" << trace->wspawn);
|
||||
D(4, stage_name << ": stalled=" << trace->stalled);
|
||||
}
|
||||
|
||||
Core::Core(const ArchDef &arch, Decoder &decoder, MemoryUnit &mem, Word id)
|
||||
@@ -79,8 +84,7 @@ Core::Core(const ArchDef &arch, Decoder &decoder, MemoryUnit &mem, Word id)
|
||||
, decoder_(decoder)
|
||||
, mem_(mem)
|
||||
, steps_(0)
|
||||
, num_instructions_(0) {
|
||||
release_warp_ = false;
|
||||
, num_insts_(0) {
|
||||
foundSchedule_ = true;
|
||||
schedule_w_ = 0;
|
||||
|
||||
@@ -98,23 +102,17 @@ Core::Core(const ArchDef &arch, Decoder &decoder, MemoryUnit &mem, Word id)
|
||||
INIT_TRACE(inst_in_lsu_);
|
||||
INIT_TRACE(inst_in_wb_);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
stalled_warps_[i] = false;
|
||||
for (int j = 0; j < 32; j++) {
|
||||
renameTable_[i][j] = true;
|
||||
}
|
||||
iRenameTable_.resize(arch.num_warps(), std::vector<bool>(arch.num_regs(), false));
|
||||
fRenameTable_.resize(arch.num_warps(), std::vector<bool>(arch.num_regs(), false));
|
||||
vRenameTable_.resize(arch.num_regs(), false);
|
||||
|
||||
stalled_warps_.resize(arch.num_warps(), false);
|
||||
|
||||
for (int i = 0; i < arch_.num_warps(); ++i) {
|
||||
warps_.emplace_back(this, i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
vecRenameTable_[i] = true;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < arch_.getNumWarps(); ++i) {
|
||||
warps_.push_back(Warp(this, i));
|
||||
}
|
||||
|
||||
warps_[0].setActiveThreads(1);
|
||||
warps_[0].setSpawned(true);
|
||||
warps_[0].setTmask(0, true);
|
||||
}
|
||||
|
||||
Core::~Core() {
|
||||
@@ -125,32 +123,20 @@ void Core::step() {
|
||||
D(3, "###########################################################");
|
||||
|
||||
steps_++;
|
||||
D(3, "cycle: " << steps_);
|
||||
D(3, std::dec << "Core" << id_ << ": cycle: " << steps_);
|
||||
|
||||
DPH(3, "stalled warps:");
|
||||
for (ThdNum widd = 0; widd < arch_.getNumWarps(); widd++) {
|
||||
DPN(3, " " << stalled_warps_[widd]);
|
||||
for (int i = 0; i < arch_.num_warps(); i++) {
|
||||
DPN(3, " " << stalled_warps_[i]);
|
||||
}
|
||||
DPN(3, "\n");
|
||||
|
||||
// cout << "About to call writeback" << std::endl;
|
||||
this->writeback();
|
||||
// cout << "About to call load_store" << std::endl;
|
||||
this->load_store();
|
||||
// cout << "About to call execute_unit" << std::endl;
|
||||
this->execute_unit();
|
||||
// cout << "About to call scheduler" << std::endl;
|
||||
this->scheduler();
|
||||
// cout << "About to call decode" << std::endl;
|
||||
this->decode();
|
||||
// D(3, "About to call fetch" << std::flush);
|
||||
this->fetch();
|
||||
// D(3, "Finished fetch" << std::flush);
|
||||
|
||||
if (release_warp_) {
|
||||
release_warp_ = false;
|
||||
stalled_warps_[release_warp_num_] = false;
|
||||
}
|
||||
|
||||
DPN(3, std::flush);
|
||||
}
|
||||
@@ -161,10 +147,8 @@ void Core::warpScheduler() {
|
||||
for (size_t wid = 0; wid < warps_.size(); ++wid) {
|
||||
// round robin scheduling
|
||||
next_warp = (next_warp + 1) % warps_.size();
|
||||
|
||||
bool has_active_threads = (warps_[next_warp].getActiveThreads() > 0);
|
||||
bool has_active_threads = warps_[next_warp].active();
|
||||
bool stalled = stalled_warps_[next_warp];
|
||||
|
||||
if (has_active_threads && !stalled) {
|
||||
foundSchedule_ = true;
|
||||
break;
|
||||
@@ -174,35 +158,28 @@ void Core::warpScheduler() {
|
||||
}
|
||||
|
||||
void Core::fetch() {
|
||||
|
||||
// D(-1, "Found schedule: " << foundSchedule_);
|
||||
|
||||
if ((!inst_in_scheduler_.stalled)
|
||||
&& (inst_in_fetch_.fetch_stall_cycles == 0)) {
|
||||
// CPY_TRACE(inst_in_decode_, inst_in_fetch_);
|
||||
// if (warps_[schedule_w_].activeThreads)
|
||||
{
|
||||
INIT_TRACE(inst_in_fetch_);
|
||||
INIT_TRACE(inst_in_fetch_);
|
||||
|
||||
if (foundSchedule_) {
|
||||
auto active_threads_b = warps_[schedule_w_].getActiveThreads();
|
||||
if (foundSchedule_) {
|
||||
auto active_threads_b = warps_[schedule_w_].getActiveThreads();
|
||||
num_insts_ = num_insts_ + warps_[schedule_w_].getActiveThreads();
|
||||
|
||||
num_instructions_ = num_instructions_ + warps_[schedule_w_].getActiveThreads();
|
||||
warps_[schedule_w_].step(&inst_in_fetch_);
|
||||
warps_[schedule_w_].step(&inst_in_fetch_);
|
||||
|
||||
auto active_threads_a = warps_[schedule_w_].getActiveThreads();
|
||||
if (active_threads_b != active_threads_a) {
|
||||
D(3, "** warp #" << schedule_w_ << " active threads changed from " << active_threads_b << " to " << active_threads_a);
|
||||
}
|
||||
|
||||
this->getCacheDelays(&inst_in_fetch_);
|
||||
|
||||
if (inst_in_fetch_.stall_warp) {
|
||||
stalled_warps_[inst_in_fetch_.wid] = true;
|
||||
}
|
||||
auto active_threads_a = warps_[schedule_w_].getActiveThreads();
|
||||
if (active_threads_b != active_threads_a) {
|
||||
D(3, "** warp #" << schedule_w_ << " active threads changed from " << active_threads_b << " to " << active_threads_a);
|
||||
}
|
||||
|
||||
this->getCacheDelays(&inst_in_fetch_);
|
||||
|
||||
if (inst_in_fetch_.stall_warp) {
|
||||
stalled_warps_[inst_in_fetch_.wid] = true;
|
||||
}
|
||||
this->warpScheduler();
|
||||
}
|
||||
this->warpScheduler();
|
||||
} else {
|
||||
inst_in_fetch_.stalled = false;
|
||||
if (inst_in_fetch_.fetch_stall_cycles > 0)
|
||||
@@ -218,7 +195,6 @@ void Core::decode() {
|
||||
CPY_TRACE(inst_in_decode_, inst_in_fetch_);
|
||||
INIT_TRACE(inst_in_fetch_);
|
||||
}
|
||||
//printTrace(&inst_in_decode_, "Decode");
|
||||
}
|
||||
|
||||
void Core::scheduler() {
|
||||
@@ -226,136 +202,162 @@ void Core::scheduler() {
|
||||
CPY_TRACE(inst_in_scheduler_, inst_in_decode_);
|
||||
INIT_TRACE(inst_in_decode_);
|
||||
}
|
||||
//printTrace(&inst_in_scheduler_, "Scheduler");
|
||||
}
|
||||
|
||||
void Core::load_store() {
|
||||
if ((inst_in_lsu_.mem_stall_cycles > 0) || (inst_in_lsu_.stalled)) {
|
||||
if ((inst_in_lsu_.mem_stall_cycles > 0) || inst_in_lsu_.stalled) {
|
||||
// LSU currently busy
|
||||
if ((inst_in_scheduler_.is_lw || inst_in_scheduler_.is_sw)) {
|
||||
inst_in_scheduler_.stalled = true;
|
||||
}
|
||||
} else {
|
||||
// LSU not busy
|
||||
if (inst_in_scheduler_.is_lw || inst_in_scheduler_.is_sw) {
|
||||
// Scheduler has LSU inst
|
||||
bool scheduler_srcs_ready = true;
|
||||
if (inst_in_scheduler_.rs1 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs1];
|
||||
}
|
||||
if (!inst_in_scheduler_.is_lw && !inst_in_scheduler_.is_sw)
|
||||
return;
|
||||
|
||||
if (inst_in_scheduler_.rs2 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs2];
|
||||
}
|
||||
// Scheduler has LSU inst
|
||||
bool scheduler_srcs_busy = false;
|
||||
|
||||
if (inst_in_scheduler_.vs1 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && vecRenameTable_[inst_in_scheduler_.vs1];
|
||||
}
|
||||
if (inst_in_scheduler_.vs2 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && vecRenameTable_[inst_in_scheduler_.vs2];
|
||||
}
|
||||
if (inst_in_scheduler_.irs1 > 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.irs1];
|
||||
}
|
||||
|
||||
if (scheduler_srcs_ready) {
|
||||
if (inst_in_scheduler_.rd != -1)
|
||||
renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rd] = false;
|
||||
if (inst_in_scheduler_.rd != -1)
|
||||
vecRenameTable_[inst_in_scheduler_.vd] = false;
|
||||
CPY_TRACE(inst_in_lsu_, inst_in_scheduler_);
|
||||
INIT_TRACE(inst_in_scheduler_);
|
||||
} else {
|
||||
inst_in_scheduler_.stalled = true;
|
||||
// INIT_TRACE(inst_in_lsu_);
|
||||
}
|
||||
} else {
|
||||
// INIT_TRACE(inst_in_lsu_);
|
||||
if (inst_in_scheduler_.irs2 > 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.irs2];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs1 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs1];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs2 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs2];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs3 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs3];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.vrs1 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || vRenameTable_[inst_in_scheduler_.vrs1];
|
||||
}
|
||||
if (inst_in_scheduler_.vrs2 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || vRenameTable_[inst_in_scheduler_.vrs2];
|
||||
}
|
||||
|
||||
if (scheduler_srcs_busy) {
|
||||
inst_in_scheduler_.stalled = true;
|
||||
} else {
|
||||
if (inst_in_scheduler_.ird > 0)
|
||||
iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.ird] = true;
|
||||
|
||||
if (inst_in_scheduler_.frd >= 0)
|
||||
fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frd] = true;
|
||||
|
||||
if (inst_in_scheduler_.vrd >= 0)
|
||||
vRenameTable_[inst_in_scheduler_.vrd] = true;
|
||||
|
||||
CPY_TRACE(inst_in_lsu_, inst_in_scheduler_);
|
||||
INIT_TRACE(inst_in_scheduler_);
|
||||
}
|
||||
}
|
||||
|
||||
if (inst_in_lsu_.mem_stall_cycles > 0)
|
||||
inst_in_lsu_.mem_stall_cycles--;
|
||||
|
||||
//printTrace(&inst_in_lsu_, "LSU");
|
||||
}
|
||||
|
||||
void Core::execute_unit() {
|
||||
// EXEC is always not busy
|
||||
if (inst_in_scheduler_.is_lw || inst_in_scheduler_.is_sw) {
|
||||
// Not an execute instruction
|
||||
// INIT_TRACE(inst_in_exe_);
|
||||
} else {
|
||||
bool scheduler_srcs_ready = true;
|
||||
if (inst_in_scheduler_.rs1 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs1];
|
||||
// cout << "Rename RS1: " << inst_in_scheduler_.rs1 << " is " << renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs1] << " wid: " << inst_in_scheduler_.wid << '\n';
|
||||
}
|
||||
if (inst_in_scheduler_.is_lw || inst_in_scheduler_.is_sw)
|
||||
return;
|
||||
|
||||
bool scheduler_srcs_busy = false;
|
||||
|
||||
if (inst_in_scheduler_.rs2 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs2];
|
||||
// cout << "Rename RS2: " << inst_in_scheduler_.rs1 << " is " << renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rs2] << " wid: " << inst_in_scheduler_.wid << '\n';
|
||||
}
|
||||
|
||||
// cout << "About to check vs*\n" << std::flush;
|
||||
if (inst_in_scheduler_.vs1 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && vecRenameTable_[inst_in_scheduler_.vs1];
|
||||
}
|
||||
if (inst_in_scheduler_.vs2 > 0) {
|
||||
scheduler_srcs_ready = scheduler_srcs_ready && vecRenameTable_[inst_in_scheduler_.vs2];
|
||||
}
|
||||
// cout << "Finished sources\n" << std::flush;
|
||||
|
||||
if (scheduler_srcs_ready) {
|
||||
if (inst_in_scheduler_.rd != -1) {
|
||||
// cout << "rename setting rd: " << inst_in_scheduler_.rd << " to not useabel wid: " << inst_in_scheduler_.wid << '\n';
|
||||
renameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.rd] = false;
|
||||
}
|
||||
|
||||
// cout << "About to check vector wb: " << inst_in_scheduler_.vd << "\n" << std::flush;
|
||||
if (inst_in_scheduler_.vd != -1) {
|
||||
vecRenameTable_[inst_in_scheduler_.vd] = false;
|
||||
}
|
||||
// cout << "Finished wb checking" << "\n" << std::flush;
|
||||
CPY_TRACE(inst_in_exe_, inst_in_scheduler_);
|
||||
INIT_TRACE(inst_in_scheduler_);
|
||||
// cout << "Finished trace copying and clearning" << "\n" << std::flush;
|
||||
} else {
|
||||
D(3, "Execute: srcs not ready!");
|
||||
inst_in_scheduler_.stalled = true;
|
||||
// INIT_TRACE(inst_in_exe_);
|
||||
}
|
||||
if (inst_in_scheduler_.irs1 > 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.irs1];
|
||||
}
|
||||
|
||||
//printTrace(&inst_in_exe_, "EXE");
|
||||
// INIT_TRACE(inst_in_exe_);
|
||||
if (inst_in_scheduler_.irs2 > 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.irs2];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs1 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs1];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs2 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs2];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frs3 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frs3];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.vrs1 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || vRenameTable_[inst_in_scheduler_.vrs1];
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.vrs2 >= 0) {
|
||||
scheduler_srcs_busy = scheduler_srcs_busy || vRenameTable_[inst_in_scheduler_.vrs2];
|
||||
}
|
||||
|
||||
if (scheduler_srcs_busy) {
|
||||
D(3, "Execute: srcs not ready!");
|
||||
inst_in_scheduler_.stalled = true;
|
||||
} else {
|
||||
if (inst_in_scheduler_.ird > 0) {
|
||||
iRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.ird] = true;
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.frd >= 0) {
|
||||
fRenameTable_[inst_in_scheduler_.wid][inst_in_scheduler_.frd] = true;
|
||||
}
|
||||
|
||||
if (inst_in_scheduler_.vrd >= 0) {
|
||||
vRenameTable_[inst_in_scheduler_.vrd] = true;
|
||||
}
|
||||
|
||||
CPY_TRACE(inst_in_exe_, inst_in_scheduler_);
|
||||
INIT_TRACE(inst_in_scheduler_);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::writeback() {
|
||||
if (inst_in_wb_.rd > 0)
|
||||
renameTable_[inst_in_wb_.wid][inst_in_wb_.rd] = true;
|
||||
if (inst_in_wb_.vd > 0)
|
||||
vecRenameTable_[inst_in_wb_.vd] = true;
|
||||
if (inst_in_wb_.ird > 0) {
|
||||
iRenameTable_[inst_in_wb_.wid][inst_in_wb_.ird] = false;
|
||||
}
|
||||
|
||||
if (inst_in_wb_.frd >= 0) {
|
||||
fRenameTable_[inst_in_wb_.wid][inst_in_wb_.frd] = false;
|
||||
}
|
||||
|
||||
if (inst_in_wb_.vrd >= 0) {
|
||||
vRenameTable_[inst_in_wb_.vrd] = false;
|
||||
}
|
||||
|
||||
if (inst_in_wb_.stall_warp) {
|
||||
stalled_warps_[inst_in_wb_.wid] = false;
|
||||
// release_warp_ = true;
|
||||
// release_warp_num_ = inst_in_wb_.wid;
|
||||
}
|
||||
|
||||
INIT_TRACE(inst_in_wb_);
|
||||
|
||||
bool serviced_exe = false;
|
||||
if ((inst_in_exe_.rd > 0) || (inst_in_exe_.stall_warp)) {
|
||||
if ((inst_in_exe_.ird > 0)
|
||||
|| (inst_in_exe_.frd >= 0)
|
||||
|| (inst_in_exe_.vrd >= 0)
|
||||
|| (inst_in_exe_.stall_warp)) {
|
||||
CPY_TRACE(inst_in_wb_, inst_in_exe_);
|
||||
INIT_TRACE(inst_in_exe_);
|
||||
serviced_exe = true;
|
||||
// cout << "WRITEBACK SERVICED EXE\n";
|
||||
}
|
||||
|
||||
if (inst_in_lsu_.is_sw) {
|
||||
INIT_TRACE(inst_in_lsu_);
|
||||
} else {
|
||||
if (((inst_in_lsu_.rd > 0) || (inst_in_lsu_.vd > 0)) && (inst_in_lsu_.mem_stall_cycles == 0)) {
|
||||
if (((inst_in_lsu_.ird > 0)
|
||||
|| (inst_in_lsu_.frd >= 0)
|
||||
|| (inst_in_lsu_.vrd >= 0))
|
||||
&& (inst_in_lsu_.mem_stall_cycles == 0)) {
|
||||
if (serviced_exe) {
|
||||
D(3, "$$$$$$$$$$$$$$$$$$$$ Stalling LSU because EXE is being used");
|
||||
// Stalling LSU because EXE is busy
|
||||
inst_in_lsu_.stalled = true;
|
||||
} else {
|
||||
CPY_TRACE(inst_in_wb_, inst_in_lsu_);
|
||||
@@ -366,27 +368,28 @@ void Core::writeback() {
|
||||
}
|
||||
|
||||
void Core::getCacheDelays(trace_inst_t *trace_inst) {
|
||||
trace_inst->fetch_stall_cycles += 3;
|
||||
trace_inst->fetch_stall_cycles += 1;
|
||||
if (trace_inst->is_sw || trace_inst->is_lw) {
|
||||
trace_inst->mem_stall_cycles += 5;
|
||||
trace_inst->mem_stall_cycles += 3;
|
||||
}
|
||||
}
|
||||
|
||||
bool Core::running() const {
|
||||
bool stages_have_valid = inst_in_fetch_.valid_inst
|
||||
|| inst_in_decode_.valid_inst
|
||||
|| inst_in_scheduler_.valid_inst
|
||||
|| inst_in_lsu_.valid_inst
|
||||
|| inst_in_exe_.valid_inst
|
||||
|| inst_in_wb_.valid_inst;
|
||||
bool stages_have_valid = inst_in_fetch_.valid
|
||||
|| inst_in_decode_.valid
|
||||
|| inst_in_scheduler_.valid
|
||||
|| inst_in_lsu_.valid
|
||||
|| inst_in_exe_.valid
|
||||
|| inst_in_wb_.valid;
|
||||
|
||||
if (stages_have_valid)
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0; i < warps_.size(); ++i)
|
||||
if (warps_[i].running()) {
|
||||
for (unsigned i = 0; i < warps_.size(); ++i) {
|
||||
if (warps_[i].active()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user