gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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/misc.hh"
45 #include "base/trace.hh"
47 #include "debug/RubyTest.hh"
49 #include "sim/sim_exit.hh"
50 #include "sim/system.hh"
51 
53  : MemObject(p), checkStartEvent(this),
54  _masterId(p->system->getMasterId(name())),
55  m_checkTable_ptr(nullptr),
56  m_num_cpus(p->num_cpus),
57  m_checks_to_complete(p->checks_to_complete),
58  m_deadlock_threshold(p->deadlock_threshold),
59  m_num_writers(0),
60  m_num_readers(0),
61  m_wakeup_frequency(p->wakeup_frequency),
62  m_check_flush(p->check_flush),
63  m_num_inst_only_ports(p->port_cpuInstPort_connection_count),
64  m_num_inst_data_ports(p->port_cpuInstDataPort_connection_count)
65 {
67 
68  //
69  // Create the requested inst and data ports and place them on the
70  // appropriate read and write port lists. The reason for the subtle
71  // difference between inst and data ports vs. read and write ports is
72  // from the tester's perspective, it only needs to know whether a port
73  // supports reads (checks) or writes (actions). Meanwhile, the protocol
74  // controllers have data ports (support read and writes) or inst ports
75  // (support only reads).
76  // Note: the inst ports are the lowest elements of the readPort vector,
77  // then the data ports are added to the readPort vector
78  //
79  int idx = 0;
80  for (int i = 0; i < p->port_cpuInstPort_connection_count; ++i) {
81  readPorts.push_back(new CpuPort(csprintf("%s-instPort%d", name(), i),
82  this, i, idx));
83  idx++;
84  }
85  for (int i = 0; i < p->port_cpuInstDataPort_connection_count; ++i) {
86  CpuPort *port = new CpuPort(csprintf("%s-instDataPort%d", name(), i),
87  this, i, idx);
88  readPorts.push_back(port);
89  writePorts.push_back(port);
90  idx++;
91  }
92  for (int i = 0; i < p->port_cpuDataPort_connection_count; ++i) {
93  CpuPort *port = new CpuPort(csprintf("%s-dataPort%d", name(), i),
94  this, i, idx);
95  readPorts.push_back(port);
96  writePorts.push_back(port);
97  idx++;
98  }
99 
100  // add the check start event to the event queue
102 }
103 
105 {
106  delete m_checkTable_ptr;
107  // Only delete the readPorts since the writePorts are just a subset
108  for (int i = 0; i < readPorts.size(); i++)
109  delete readPorts[i];
110 }
111 
112 void
114 {
115  assert(writePorts.size() > 0 && readPorts.size() > 0);
116 
118  for (int i = 0; i < m_last_progress_vector.size(); i++) {
120  }
121 
122  m_num_writers = writePorts.size();
123  m_num_readers = readPorts.size();
124  assert(m_num_readers == m_num_cpus);
125 
127 }
128 
130 RubyTester::getMasterPort(const std::string &if_name, PortID idx)
131 {
132  if (if_name != "cpuInstPort" && if_name != "cpuInstDataPort" &&
133  if_name != "cpuDataPort") {
134  // pass it along to our super class
135  return MemObject::getMasterPort(if_name, idx);
136  } else {
137  if (if_name == "cpuInstPort") {
138  if (idx > m_num_inst_only_ports) {
139  panic("RubyTester::getMasterPort: unknown inst port %d\n",
140  idx);
141  }
142  //
143  // inst ports map to the lowest readPort elements
144  //
145  return *readPorts[idx];
146  } else if (if_name == "cpuInstDataPort") {
147  if (idx > m_num_inst_data_ports) {
148  panic("RubyTester::getMasterPort: unknown inst+data port %d\n",
149  idx);
150  }
151  int read_idx = idx + m_num_inst_only_ports;
152  //
153  // inst+data ports map to the next readPort elements
154  //
155  return *readPorts[read_idx];
156  } else {
157  assert(if_name == "cpuDataPort");
158  //
159  // data only ports map to the final readPort elements
160  //
161  if (idx > (static_cast<int>(readPorts.size()) -
163  panic("RubyTester::getMasterPort: unknown data port %d\n",
164  idx);
165  }
166  int read_idx = idx + m_num_inst_only_ports + m_num_inst_data_ports;
167  return *readPorts[read_idx];
168  }
169  // Note: currently the Ruby Tester does not support write only ports
170  // but that could easily be added here
171  }
172 }
173 
174 bool
176 {
177  // retrieve the subblock and call hitCallback
178  RubyTester::SenderState* senderState =
180  SubBlock& subblock = senderState->subBlock;
181 
182  tester->hitCallback(globalIdx, &subblock);
183 
184  // Now that the tester has completed, delete the senderState
185  // (includes sublock) and the packet, then return
186  delete pkt->senderState;
187  delete pkt->req;
188  delete pkt;
189  return true;
190 }
191 
192 bool
194 {
195  return idx < m_num_inst_only_ports;
196 }
197 
198 bool
200 {
201  return ((idx >= m_num_inst_only_ports) &&
203 }
204 
205 MasterPort*
207 {
208  assert(idx >= 0 && idx < readPorts.size());
209 
210  return readPorts[idx];
211 }
212 
213 MasterPort*
215 {
216  assert(idx >= 0 && idx < writePorts.size());
217 
218  return writePorts[idx];
219 }
220 
221 void
223 {
224  // Mark that we made progress
226 
227  DPRINTF(RubyTest, "completed request for proc: %d", proc);
228  DPRINTFR(RubyTest, " addr: 0x%x, size: %d, data: ",
229  data->getAddress(), data->getSize());
230  for (int byte = 0; byte < data->getSize(); byte++) {
231  DPRINTFR(RubyTest, "%d ", data->getByte(byte));
232  }
233  DPRINTFR(RubyTest, "\n");
234 
235  // This tells us our store has 'completed' or for a load gives us
236  // back the data to make the check
237  Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress());
238  assert(check_ptr != NULL);
239  check_ptr->performCallback(proc, data, curCycle());
240 }
241 
242 void
244 {
246  // Try to perform an action or check
247  Check* check_ptr = m_checkTable_ptr->getRandomCheck();
248  assert(check_ptr != NULL);
249  check_ptr->initiate();
250 
252 
254  } else {
255  exitSimLoop("Ruby Tester completed");
256  }
257 }
258 
259 void
261 {
262  int size = m_last_progress_vector.size();
263  Cycles current_time = curCycle();
264  for (int processor = 0; processor < size; processor++) {
265  if ((current_time - m_last_progress_vector[processor]) >
267  panic("Deadlock detected: current_time: %d last_progress_time: %d "
268  "difference: %d processor: %d\n",
269  current_time, m_last_progress_vector[processor],
270  current_time - m_last_progress_vector[processor], processor);
271  }
272  }
273 }
274 
275 void
276 RubyTester::print(std::ostream& out) const
277 {
278  out << "[RubyTester]" << std::endl;
279 }
280 
281 RubyTester *
282 RubyTesterParams::create()
283 {
284  return new RubyTester(this);
285 }
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
Definition: port.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:212
void initiate()
Definition: Check.cc:56
RubyTester * tester
Definition: RubyTester.hh:62
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
const std::string & name()
Definition: trace.cc:49
int m_num_inst_data_ports
Definition: RubyTester.hh:161
Bitfield< 7 > i
Definition: miscregs.hh:1378
Addr getAddress() const
Definition: SubBlock.hh:45
#define panic(...)
Definition: misc.hh:153
void checkForDeadlock()
Definition: RubyTester.cc:260
int m_num_inst_only_ports
Definition: RubyTester.hh:160
MasterPort * getReadableCpuPort(int idx)
Definition: RubyTester.cc:206
int m_num_readers
Definition: RubyTester.hh:157
bool isInstOnlyCpuPort(int idx)
Definition: RubyTester.cc:193
void performCallback(NodeID proc, SubBlock *data, Cycles curTime)
Definition: Check.cc:283
std::vector< Cycles > m_last_progress_vector
Definition: RubyTester.hh:148
CheckStartEvent checkStartEvent
Definition: RubyTester.hh:134
Definition: Check.hh:45
RubyTester(const Params *p)
Definition: RubyTester.cc:52
const char data[]
Definition: circlebuf.cc:43
int getSize() const
Definition: SubBlock.hh:48
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
uint64_t m_checks_completed
Definition: RubyTester.hh:151
unsigned int NodeID
Definition: TypeDefines.hh:34
system
Definition: isa.cc:226
Tick curTick()
The current simulated tick.
Definition: core.hh:47
bool isInstDataCpuPort(int idx)
Definition: RubyTester.cc:199
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
int m_num_cpus
Definition: RubyTester.hh:150
const RequestPtr req
A pointer to the original request.
Definition: packet.hh:304
int m_deadlock_threshold
Definition: RubyTester.hh:155
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
Definition: RubyTester.cc:130
RubyTesterParams Params
Definition: RubyTester.hh:93
uint8_t getByte(int offset) const
Definition: SubBlock.hh:50
T safe_cast(U ptr)
Definition: cast.hh:61
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
CheckTable * m_checkTable_ptr
Definition: RubyTester.hh:147
MasterPort * getWritableCpuPort(int idx)
Definition: RubyTester.cc:214
std::vector< MasterPort * > writePorts
Definition: RubyTester.hh:152
void print(std::ostream &out) const
Definition: RubyTester.cc:276
void hitCallback(NodeID proc, SubBlock *data)
Definition: RubyTester.cc:222
Check * getRandomCheck()
Definition: CheckTable.cc:111
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:83
int size()
Definition: pagetable.hh:146
virtual const std::string name() const
Definition: sim_object.hh:117
SenderState * senderState
This packet's sender state.
Definition: packet.hh:454
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
Definition: mem_object.hh:60
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: RubyTester.cc:113
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
Definition: port.hh:115
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the slave port.
Definition: RubyTester.cc:175
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
std::vector< MasterPort * > readPorts
Definition: RubyTester.hh:153
Check * getCheck(Addr address)
Definition: CheckTable.cc:118
uint64_t m_checks_to_complete
Definition: RubyTester.hh:154
Bitfield< 0 > p
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
Definition: mem_object.cc:52
int m_num_writers
Definition: RubyTester.hh:156
int m_wakeup_frequency
Definition: RubyTester.hh:158
void wakeup()
Definition: RubyTester.cc:243
#define DPRINTFR(...)
Definition: trace.hh:214

Generated on Fri Jun 9 2017 13:03:44 for gem5 by doxygen 1.8.6