simx timing simulation refactoring

This commit is contained in:
Blaise Tine
2021-11-14 08:52:34 -05:00
parent 9656779d48
commit 808bddb586
22 changed files with 1123 additions and 903 deletions

View File

@@ -9,6 +9,17 @@
using namespace vortex;
NopUnit::NopUnit(Core*) : ExeUnit("NOP") {}
void NopUnit::step(uint64_t /*cycle*/) {
pipeline_state_t state;
if (!inputs_.try_pop(&state))
return;
this->schedule_output(state, 1);
}
///////////////////////////////////////////////////////////////////////////////
LsuUnit::LsuUnit(Core* core)
: ExeUnit("LSU")
, core_(core)
@@ -17,61 +28,77 @@ LsuUnit::LsuUnit(Core* core)
, fence_lock_(false)
{}
void LsuUnit::handleCacheReponse(const MemRsp& response, uint32_t port_id) {
auto entry = pending_dcache_.at(response.tag);
entry.second.reset(port_id); // track remaining blocks
if (!entry.second.any()) {
auto latency = (SimPlatform::instance().cycles() - entry.first.dcache_latency);
entry.first.dcache_latency = latency;
this->schedule_output(entry.first, 1);
pending_dcache_.release(response.tag);
}
}
void LsuUnit::step(uint64_t cycle) {
__unused (cycle);
// handle dcache response
for (uint32_t t = 0; t < num_threads_; ++t) {
MemRsp mem_rsp;
if (!core_->dcache_->CoreRspPorts.at(t).read(&mem_rsp))
continue;
auto& entry = pending_dcache_.at(mem_rsp.tag);
DT(3, cycle, "dcache-rsp: addr=" << std::hex << entry.first.mem_addrs.at(t) << ", tag=" << mem_rsp.tag << ", type=" << entry.first.lsu.type << ", tid=" << t << ", " << entry.first);
assert(entry.second.test(t));
entry.second.reset(t); // track remaining blocks
if (!entry.second.any()) {
auto latency = (SimPlatform::instance().cycles() - entry.first.dcache_latency);
entry.first.dcache_latency = latency;
this->schedule_output(entry.first, 1);
pending_dcache_.release(mem_rsp.tag);
}
}
void LsuUnit::step() {
if (fence_lock_) {
// wait for all pending memory operations to complete
if (!pending_dcache_.empty())
return;
this->schedule_output(fence_state_, 1);
fence_lock_ = false;
DT(3, cycle, "fence-unlock: " << fence_state_);
}
// check input queue
if (inputs_.empty())
return;
auto state = inputs_.top();
if (state.lsu.fence) {
if (state.lsu.type == LsuType::FENCE) {
// schedule fence lock
fence_state_ = state;
fence_lock_ = true;
inputs_.pop();
DT(3, cycle, "fence-lock: " << state);
return;
}
// send dcache requests
if (!pending_dcache_.full()) {
state.dcache_latency = SimPlatform::instance().cycles();
auto tag = pending_dcache_.allocate({state, state.tmask});
for (uint32_t t = 0; t < num_threads_; ++t) {
if (!state.tmask.test(t))
continue;
MemReq mem_req;
mem_req.addr = state.mem_addrs.at(t);
mem_req.write = state.lsu.store;
mem_req.tag = tag;
core_->dcache_->CoreReqPorts.at(t).send(mem_req, 1);
}
inputs_.pop();
// check pending queue capacity
if (pending_dcache_.full()) {
DT(3, cycle, "*** lsu-queue-stall: " << state);
return;
}
// send dcache request
state.dcache_latency = SimPlatform::instance().cycles();
auto tag = pending_dcache_.allocate({state, state.tmask});
for (uint32_t t = 0; t < num_threads_; ++t) {
if (!state.tmask.test(t))
continue;
MemReq mem_req;
mem_req.addr = state.mem_addrs.at(t);
mem_req.write = (state.lsu.type == LsuType::STORE);
mem_req.tag = tag;
core_->dcache_->CoreReqPorts.at(t).send(mem_req, 1);
DT(3, cycle, "dcache-req: addr=" << std::hex << mem_req.addr << ", tag=" << mem_req.tag << ", type=" << state.lsu.type << ", tid=" << t << ", " << state);
}
inputs_.pop();
}
///////////////////////////////////////////////////////////////////////////////
AluUnit::AluUnit(Core*) : ExeUnit("ALU") {}
void AluUnit::step() {
void AluUnit::step(uint64_t /*cycle*/) {
pipeline_state_t state;
if (!inputs_.try_pop(&state))
return;
@@ -95,7 +122,7 @@ void AluUnit::step() {
CsrUnit::CsrUnit(Core*) : ExeUnit("CSR") {}
void CsrUnit::step() {
void CsrUnit::step(uint64_t /*cycle*/) {
pipeline_state_t state;
if (!inputs_.try_pop(&state))
return;
@@ -106,7 +133,7 @@ void CsrUnit::step() {
FpuUnit::FpuUnit(Core*) : ExeUnit("FPU") {}
void FpuUnit::step() {
void FpuUnit::step(uint64_t /*cycle*/) {
pipeline_state_t state;
if (!inputs_.try_pop(&state))
return;
@@ -133,7 +160,7 @@ void FpuUnit::step() {
GpuUnit::GpuUnit(Core*) : ExeUnit("GPU") {}
void GpuUnit::step() {
void GpuUnit::step(uint64_t /*cycle*/) {
pipeline_state_t state;
if (!inputs_.try_pop(&state))
return;