gem5 v24.0.0.0
Loading...
Searching...
No Matches
RubyTester.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
15 * Copyright (c) 2009 Advanced Micro Devices, Inc.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
43
44#include "base/logging.hh"
45#include "base/trace.hh"
47#include "debug/RubyTest.hh"
49#include "sim/sim_exit.hh"
50#include "sim/system.hh"
51
52namespace gem5
53{
54
57 checkStartEvent([this]{ wakeup(); }, "RubyTester tick",
58 false, Event::CPU_Tick_Pri),
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),
64 m_num_writers(0),
65 m_num_readers(0),
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)
70{
71 m_checks_completed = 0;
72
73 //
74 // Create the requested inst and data ports and place them on the
75 // appropriate read and write port lists. The reason for the subtle
76 // difference between inst and data ports vs. read and write ports is
77 // from the tester's perspective, it only needs to know whether a port
78 // supports reads (checks) or writes (actions). Meanwhile, the protocol
79 // controllers have data ports (support read and writes) or inst ports
80 // (support only reads).
81 // Note: the inst ports are the lowest elements of the readPort vector,
82 // then the data ports are added to the readPort vector
83 //
84 int idx = 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),
87 this, i, idx));
88 idx++;
89 }
90 for (int i = 0; i < p.port_cpuInstDataPort_connection_count; ++i) {
91 CpuPort *port = new CpuPort(csprintf("%s-instDataPort%d", name(), i),
92 this, i, idx);
93 readPorts.push_back(port);
94 writePorts.push_back(port);
95 idx++;
96 }
97 for (int i = 0; i < p.port_cpuDataPort_connection_count; ++i) {
98 CpuPort *port = new CpuPort(csprintf("%s-dataPort%d", name(), i),
99 this, i, idx);
100 readPorts.push_back(port);
101 writePorts.push_back(port);
102 idx++;
103 }
104
105 // add the check start event to the event queue
106 schedule(checkStartEvent, 1);
107}
108
110{
111 delete m_checkTable_ptr;
112 // Only delete the readPorts since the writePorts are just a subset
113 for (int i = 0; i < readPorts.size(); i++)
114 delete readPorts[i];
115}
116
117void
119{
120 assert(writePorts.size() > 0 && readPorts.size() > 0);
121
123 for (int i = 0; i < m_last_progress_vector.size(); i++) {
125 }
126
127 m_num_writers = writePorts.size();
128 m_num_readers = readPorts.size();
129 assert(m_num_readers == m_num_cpus);
130
132}
133
134Port &
135RubyTester::getPort(const std::string &if_name, PortID idx)
136{
137 if (if_name != "cpuInstPort" && if_name != "cpuInstDataPort" &&
138 if_name != "cpuDataPort") {
139 // pass it along to our super class
140 return ClockedObject::getPort(if_name, idx);
141 } else {
142 if (if_name == "cpuInstPort") {
143 if (idx > m_num_inst_only_ports) {
144 panic("RubyTester::getPort: unknown inst port %d\n",
145 idx);
146 }
147 //
148 // inst ports map to the lowest readPort elements
149 //
150 return *readPorts[idx];
151 } else if (if_name == "cpuInstDataPort") {
152 if (idx > m_num_inst_data_ports) {
153 panic("RubyTester::getPort: unknown inst+data port %d\n",
154 idx);
155 }
156 int read_idx = idx + m_num_inst_only_ports;
157 //
158 // inst+data ports map to the next readPort elements
159 //
160 return *readPorts[read_idx];
161 } else {
162 assert(if_name == "cpuDataPort");
163 //
164 // data only ports map to the final readPort elements
165 //
166 if (idx > (static_cast<int>(readPorts.size()) -
168 panic("RubyTester::getPort: unknown data port %d\n",
169 idx);
170 }
171 int read_idx = idx + m_num_inst_only_ports + m_num_inst_data_ports;
172 return *readPorts[read_idx];
173 }
174 // Note: currently the Ruby Tester does not support write only ports
175 // but that could easily be added here
176 }
177}
178
179bool
181{
182 // retrieve the subblock and call hitCallback
183 RubyTester::SenderState* senderState =
185 ruby::SubBlock& subblock = senderState->subBlock;
186
187 tester->hitCallback(globalIdx, &subblock);
188
189 // Now that the tester has completed, delete the senderState
190 // (includes sublock) and the packet, then return
191 delete pkt->senderState;
192 delete pkt;
193 return true;
194}
195
196bool
198{
199 return idx < m_num_inst_only_ports;
200}
201
202bool
204{
205 return ((idx >= m_num_inst_only_ports) &&
207}
208
211{
212 assert(idx >= 0 && idx < readPorts.size());
213
214 return readPorts[idx];
215}
216
219{
220 assert(idx >= 0 && idx < writePorts.size());
221
222 return writePorts[idx];
223}
224
225void
227{
228 // Mark that we made progress
230
231 DPRINTF(RubyTest, "completed request for proc: %d", proc);
232 DPRINTFR(RubyTest, " addr: 0x%x, size: %d, data: ",
233 data->getAddress(), data->getSize());
234 for (int byte = 0; byte < data->getSize(); byte++) {
235 DPRINTFR(RubyTest, "%d ", data->getByte(byte));
236 }
237 DPRINTFR(RubyTest, "\n");
238
239 // This tells us our store has 'completed' or for a load gives us
240 // back the data to make the check
241 Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress());
242 assert(check_ptr != NULL);
243 check_ptr->performCallback(proc, data, curCycle());
244}
245
246void
248{
250 // Try to perform an action or check
251 Check* check_ptr = m_checkTable_ptr->getRandomCheck();
252 assert(check_ptr != NULL);
253 check_ptr->initiate();
254
256
258 } else {
259 exitSimLoop("Ruby Tester completed");
260 }
261}
262
263void
265{
266 int size = m_last_progress_vector.size();
267 Cycles current_time = curCycle();
268 for (int processor = 0; processor < size; processor++) {
269 if ((current_time - m_last_progress_vector[processor]) >
271 panic("Deadlock detected: current_time: %d last_progress_time: %d "
272 "difference: %d processor: %d\n",
273 current_time, m_last_progress_vector[processor],
274 current_time - m_last_progress_vector[processor], processor);
275 }
276 }
277}
278
279void
280RubyTester::print(std::ostream& out) const
281{
282 out << "[RubyTester]" << std::endl;
283}
284
285} // namespace gem5
#define DPRINTFR(x,...)
Definition trace.hh:224
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
Check * getRandomCheck()
Check * getCheck(Addr address)
void initiate()
Definition Check.cc:59
void performCallback(ruby::NodeID proc, ruby::SubBlock *data, Cycles curTime)
Definition Check.cc:287
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
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.
Definition types.hh:79
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
SenderState * senderState
This packet's sender state.
Definition packet.hh:545
Ports are used to interface objects to each other.
Definition port.hh:62
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition port.hh:136
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
EventFunctionWrapper checkStartEvent
void checkForDeadlock()
std::vector< RequestPort * > readPorts
bool isInstOnlyCpuPort(int idx)
RequestPort * getWritableCpuPort(int idx)
void hitCallback(ruby::NodeID proc, ruby::SubBlock *data)
RubyTester(const Params &p)
Definition RubyTester.cc:55
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)
uint64_t m_checks_to_complete
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
std::vector< Cycles > m_last_progress_vector
RubyTesterParams Params
Definition RubyTester.hh:97
void print(std::ostream &out) const
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Definition eventq.hh:207
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
unsigned int NodeID
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T safe_cast(U &&ref_or_ptr)
Definition cast.hh:74
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition sim_events.cc:88
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0