47#include "debug/RubyTest.hh"
59 _requestorId(
p.system->getRequestorId(
this)),
60 m_checkTable_ptr(
nullptr),
61 m_num_cpus(
p.num_cpus),
62 m_checks_to_complete(
p.checks_to_complete),
63 m_deadlock_threshold(
p.deadlock_threshold),
66 m_wakeup_frequency(
p.wakeup_frequency),
67 m_check_flush(
p.check_flush),
68 m_num_inst_only_ports(
p.port_cpuInstPort_connection_count),
69 m_num_inst_data_ports(
p.port_cpuInstDataPort_connection_count)
71 m_checks_completed = 0;
85 for (
int i = 0;
i <
p.port_cpuInstPort_connection_count; ++
i) {
86 readPorts.push_back(
new CpuPort(
csprintf(
"%s-instPort%d",
name(),
i),
90 for (
int i = 0;
i <
p.port_cpuInstDataPort_connection_count; ++
i) {
91 CpuPort *port =
new CpuPort(
csprintf(
"%s-instDataPort%d",
name(),
i),
93 readPorts.push_back(port);
94 writePorts.push_back(port);
97 for (
int i = 0;
i <
p.port_cpuDataPort_connection_count; ++
i) {
98 CpuPort *port =
new CpuPort(
csprintf(
"%s-dataPort%d",
name(),
i),
100 readPorts.push_back(port);
101 writePorts.push_back(port);
106 schedule(checkStartEvent, 1);
133 if (if_name !=
"cpuInstPort" && if_name !=
"cpuInstDataPort" &&
134 if_name !=
"cpuDataPort") {
138 if (if_name ==
"cpuInstPort") {
140 panic(
"RubyTester::getPort: unknown inst port %d\n",
147 }
else if (if_name ==
"cpuInstDataPort") {
149 panic(
"RubyTester::getPort: unknown inst+data port %d\n",
158 assert(if_name ==
"cpuDataPort");
162 if (idx > (
static_cast<int>(
readPorts.size()) -
164 panic(
"RubyTester::getPort: unknown data port %d\n",
208 assert(idx >= 0 && idx <
readPorts.size());
224 DPRINTF(RubyTest,
"completed request for proc: %d", proc);
225 DPRINTFR(RubyTest,
" addr: 0x%x, size: %d, data: ",
226 data->getAddress(),
data->getSize());
227 for (
int byte = 0;
byte <
data->getSize();
byte++) {
235 assert(check_ptr != NULL);
245 assert(check_ptr != NULL);
261 for (
int processor = 0; processor < size; processor++) {
263 DPRINTF(RubyTest,
"Processor %d is idle now, skip\n", processor);
266 for (
const auto& [
addr, last_cycle] :
269 panic(
"Possible deadlock detected:\n"
272 " Current Time: %d\n"
273 " Last Progress Time: %d\n"
274 " Difference: %d cycles\n",
275 processor,
addr, current_time,
276 last_cycle, current_time - last_cycle);
285 DPRINTF(RubyTest,
"Update progress: index: %d \
286 address: %#x current_time: %d\n",
287 index, address, current_time);
295 DPRINTF(RubyTest,
"Erase progress: index: %d address: %#x\n",
302 out <<
"[RubyTester]" << std::endl;
void performCallback(ruby::NodeID proc, ruby::SubBlock *data, Cycles curTime)
void initiate(Cycles current_time)
ClockedObject(const ClockedObjectParams &p)
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
Cycles is a wrapper class for representing cycle counts, i.e.
SenderState * senderState
This packet's sender state.
Ports are used to interface objects to each other.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
EventFunctionWrapper checkStartEvent
std::vector< RequestPort * > readPorts
void eraseProgress(int idx, Addr address)
bool isInstOnlyCpuPort(int idx)
void updateProgress(int idx, Addr address, Cycles current_time)
RequestPort * getWritableCpuPort(int idx)
void hitCallback(ruby::NodeID proc, ruby::SubBlock *data)
int m_num_inst_only_ports
RubyTester(const Params &p)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
bool isInstDataCpuPort(int idx)
std::vector< RequestPort * > writePorts
RequestPort * getReadableCpuPort(int idx)
std::vector< std::unordered_map< Addr, Cycles > > m_last_progress_vector
uint64_t m_checks_to_complete
int m_num_inst_data_ports
CheckTable * m_checkTable_ptr
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
uint64_t m_checks_completed
void print(std::ostream &out) const
void schedule(Event &event, Tick when)
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
#define panic(...)
This implements a cprintf based panic() function.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Copyright (c) 2024 Arm Limited All rights reserved.
T safe_cast(U &&ref_or_ptr)
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
The "old style" exitSimLoop functions.
std::string csprintf(const char *format, const Args &...args)
const std::string & name()