fixes quantum and quantum break handling
This commit is contained in:
parent
09db0cd35d
commit
e6f11081eb
|
@ -391,7 +391,10 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
|
||||||
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) {
|
if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && addr + length <= lut_entry.get_end_address() + 1) {
|
||||||
auto offset = addr - lut_entry.get_start_address();
|
auto offset = addr - lut_entry.get_start_address();
|
||||||
std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data);
|
std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data);
|
||||||
quantum_keeper.inc(lut_entry.get_read_latency());
|
if(is_fetch)
|
||||||
|
ibus_inc+=lut_entry.get_read_latency()/curr_clk;
|
||||||
|
else
|
||||||
|
dbus_inc+=lut_entry.get_read_latency()/curr_clk;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
auto& sckt = is_fetch? ibus : dbus;
|
auto& sckt = is_fetch? ibus : dbus;
|
||||||
|
@ -409,12 +412,17 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
|
||||||
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
|
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
|
||||||
gp.set_extension(preExt);
|
gp.set_extension(preExt);
|
||||||
}
|
}
|
||||||
sckt->b_transport(gp, delay);
|
auto pre_delay = delay;
|
||||||
auto incr = delay-quantum_keeper.get_local_time();
|
dbus->b_transport(gp, delay);
|
||||||
|
if(pre_delay>delay) {
|
||||||
|
quantum_keeper.reset();
|
||||||
|
} else {
|
||||||
|
auto incr = (delay-quantum_keeper.get_local_time())/curr_clk;
|
||||||
if(is_fetch)
|
if(is_fetch)
|
||||||
ibus_inc+=incr;
|
ibus_inc+=incr;
|
||||||
else
|
else
|
||||||
dbus_inc+=incr;
|
dbus_inc+=incr;
|
||||||
|
}
|
||||||
SCCTRACE(this->name()) << "[local time: "<<delay<<"]: finish read_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data);
|
SCCTRACE(this->name()) << "[local time: "<<delay<<"]: finish read_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data);
|
||||||
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
|
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -439,7 +447,7 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
|
||||||
addr + length <= lut_entry.get_end_address() + 1) {
|
addr + length <= lut_entry.get_end_address() + 1) {
|
||||||
auto offset = addr - lut_entry.get_start_address();
|
auto offset = addr - lut_entry.get_start_address();
|
||||||
std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset);
|
std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset);
|
||||||
quantum_keeper.inc(lut_entry.get_read_latency());
|
dbus_inc+=lut_entry.get_write_latency()/curr_clk;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
write_buf.resize(length);
|
write_buf.resize(length);
|
||||||
|
@ -455,8 +463,12 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
|
||||||
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
|
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
|
||||||
gp.set_extension(preExt);
|
gp.set_extension(preExt);
|
||||||
}
|
}
|
||||||
|
auto pre_delay = delay;
|
||||||
dbus->b_transport(gp, delay);
|
dbus->b_transport(gp, delay);
|
||||||
dbus_inc+=delay-quantum_keeper.get_local_time();
|
if(pre_delay>delay)
|
||||||
|
quantum_keeper.reset();
|
||||||
|
else
|
||||||
|
dbus_inc+=(delay-quantum_keeper.get_local_time())/curr_clk;
|
||||||
SCCTRACE() << "[local time: "<<delay<<"]: finish write_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data);
|
SCCTRACE() << "[local time: "<<delay<<"]: finish write_mem(0x" << std::hex << addr << ") : 0x" << (length==4?*(uint32_t*)data:length==2?*(uint16_t*)data:(unsigned)*data);
|
||||||
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
|
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -156,17 +156,21 @@ public:
|
||||||
|
|
||||||
~core_complex();
|
~core_complex();
|
||||||
|
|
||||||
|
|
||||||
|
inline unsigned get_last_bus_cycles() {
|
||||||
|
auto mem_incr = std::max(ibus_inc, dbus_inc);
|
||||||
|
ibus_inc = dbus_inc = 0;
|
||||||
|
return mem_incr>1?mem_incr:1;
|
||||||
|
}
|
||||||
|
|
||||||
inline void sync(uint64_t cycle) {
|
inline void sync(uint64_t cycle) {
|
||||||
auto core_inc = curr_clk * (cycle - last_sync_cycle);
|
auto core_inc = curr_clk * (cycle - last_sync_cycle);
|
||||||
auto incr = std::max(core_inc, std::max(ibus_inc, dbus_inc));
|
quantum_keeper.inc(core_inc);
|
||||||
quantum_keeper.inc(incr);
|
|
||||||
if (quantum_keeper.need_sync()) {
|
if (quantum_keeper.need_sync()) {
|
||||||
wait(quantum_keeper.get_local_time());
|
wait(quantum_keeper.get_local_time());
|
||||||
quantum_keeper.reset();
|
quantum_keeper.reset();
|
||||||
}
|
}
|
||||||
last_sync_cycle = cycle;
|
last_sync_cycle = cycle;
|
||||||
ibus_inc = sc_core::SC_ZERO_TIME;
|
|
||||||
dbus_inc = sc_core::SC_ZERO_TIME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch);
|
bool read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch);
|
||||||
|
@ -198,7 +202,7 @@ protected:
|
||||||
std::vector<uint8_t> write_buf;
|
std::vector<uint8_t> write_buf;
|
||||||
core_wrapper* cpu{nullptr};
|
core_wrapper* cpu{nullptr};
|
||||||
sc_core::sc_signal<sc_core::sc_time> curr_clk;
|
sc_core::sc_signal<sc_core::sc_time> curr_clk;
|
||||||
sc_core::sc_time ibus_inc, dbus_inc;
|
uint64_t ibus_inc{0}, dbus_inc{0};
|
||||||
core_trace* trc{nullptr};
|
core_trace* trc{nullptr};
|
||||||
std::unique_ptr<scc::tick2time> t2t;
|
std::unique_ptr<scc::tick2time> t2t;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -39,9 +39,14 @@ public:
|
||||||
uint64_t get_state() override { return this->state.mstatus.backing.val; }
|
uint64_t get_state() override { return this->state.mstatus.backing.val; }
|
||||||
|
|
||||||
void notify_phase(iss::arch_if::exec_phase p) override {
|
void notify_phase(iss::arch_if::exec_phase p) override {
|
||||||
if (p == iss::arch_if::ISTART)
|
if (p == iss::arch_if::ISTART && !first) {
|
||||||
|
auto cycle_incr = owner->get_last_bus_cycles();
|
||||||
|
if(cycle_incr>1)
|
||||||
|
this->instr_if.update_last_instr_cycles(cycle_incr);
|
||||||
owner->sync(this->instr_if.get_total_cycles());
|
owner->sync(this->instr_if.get_total_cycles());
|
||||||
}
|
}
|
||||||
|
first=false;
|
||||||
|
}
|
||||||
|
|
||||||
iss::sync_type needed_sync() const override { return iss::PRE_SYNC; }
|
iss::sync_type needed_sync() const override { return iss::PRE_SYNC; }
|
||||||
|
|
||||||
|
@ -175,8 +180,9 @@ public:
|
||||||
private:
|
private:
|
||||||
sysc::tgfs::core_complex *const owner;
|
sysc::tgfs::core_complex *const owner;
|
||||||
sc_core::sc_event wfi_evt;
|
sc_core::sc_event wfi_evt;
|
||||||
uint64_t hostvar;
|
uint64_t hostvar{std::numeric_limits<uint64_t>::max()};
|
||||||
unsigned to_host_wr_cnt = 0;
|
unsigned to_host_wr_cnt = 0;
|
||||||
|
bool first{true};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
|
||||||
|
|
Loading…
Reference in New Issue