Check.cc (7805:f249937228b5) Check.cc (7823:dac01f14f20f)
1/*
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
3 * Copyright (c) 2009 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "cpu/testers/rubytest/Check.hh"
31#include "mem/ruby/common/SubBlock.hh"
32#include "mem/ruby/system/Sequencer.hh"
33#include "mem/ruby/system/System.hh"
34
35typedef RubyTester::SenderState SenderState;
36
37Check::Check(const Address& address, const Address& pc,
38 int _num_cpu_sequencers, RubyTester* _tester)
39 : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
40{
41 m_status = TesterStatus_Idle;
42
43 pickValue();
44 pickInitiatingNode();
45 changeAddress(address);
46 m_pc = pc;
47 m_access_mode = AccessModeType(random() % AccessModeType_NUM);
48 m_store_count = 0;
49}
50
51void
52Check::initiate()
53{
54 DPRINTF(RubyTest, "initiating\n");
55 debugPrint();
56
57 // currently no protocols support prefetches
58 if (false && (random() & 0xf) == 0) {
59 initiatePrefetch(); // Prefetch from random processor
60 }
61
62 if (m_status == TesterStatus_Idle) {
63 initiateAction();
64 } else if (m_status == TesterStatus_Ready) {
65 initiateCheck();
66 } else {
67 // Pending - do nothing
68 DPRINTF(RubyTest,
69 "initiating action/check - failed: action/check is pending\n");
70 }
71}
72
73void
74Check::initiatePrefetch()
75{
76 DPRINTF(RubyTest, "initiating prefetch\n");
77
78 int index = random() % m_num_cpu_sequencers;
79 RubyTester::CpuPort* port =
80 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
81
82 Request::Flags flags;
83 flags.set(Request::PREFETCH);
84
85 Packet::Command cmd;
86
87 // 1 in 8 chance this will be an exclusive prefetch
88 if ((random() & 0x7) != 0) {
89 cmd = MemCmd::ReadReq;
90
91 // 50% chance that the request will be an instruction fetch
92 if ((random() & 0x1) == 0) {
93 flags.set(Request::INST_FETCH);
94 }
95 } else {
96 cmd = MemCmd::WriteReq;
97 flags.set(Request::PF_EXCLUSIVE);
98 }
99
100 // Prefetches are assumed to be 0 sized
1/*
2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
3 * Copyright (c) 2009 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "cpu/testers/rubytest/Check.hh"
31#include "mem/ruby/common/SubBlock.hh"
32#include "mem/ruby/system/Sequencer.hh"
33#include "mem/ruby/system/System.hh"
34
35typedef RubyTester::SenderState SenderState;
36
37Check::Check(const Address& address, const Address& pc,
38 int _num_cpu_sequencers, RubyTester* _tester)
39 : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester)
40{
41 m_status = TesterStatus_Idle;
42
43 pickValue();
44 pickInitiatingNode();
45 changeAddress(address);
46 m_pc = pc;
47 m_access_mode = AccessModeType(random() % AccessModeType_NUM);
48 m_store_count = 0;
49}
50
51void
52Check::initiate()
53{
54 DPRINTF(RubyTest, "initiating\n");
55 debugPrint();
56
57 // currently no protocols support prefetches
58 if (false && (random() & 0xf) == 0) {
59 initiatePrefetch(); // Prefetch from random processor
60 }
61
62 if (m_status == TesterStatus_Idle) {
63 initiateAction();
64 } else if (m_status == TesterStatus_Ready) {
65 initiateCheck();
66 } else {
67 // Pending - do nothing
68 DPRINTF(RubyTest,
69 "initiating action/check - failed: action/check is pending\n");
70 }
71}
72
73void
74Check::initiatePrefetch()
75{
76 DPRINTF(RubyTest, "initiating prefetch\n");
77
78 int index = random() % m_num_cpu_sequencers;
79 RubyTester::CpuPort* port =
80 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
81
82 Request::Flags flags;
83 flags.set(Request::PREFETCH);
84
85 Packet::Command cmd;
86
87 // 1 in 8 chance this will be an exclusive prefetch
88 if ((random() & 0x7) != 0) {
89 cmd = MemCmd::ReadReq;
90
91 // 50% chance that the request will be an instruction fetch
92 if ((random() & 0x1) == 0) {
93 flags.set(Request::INST_FETCH);
94 }
95 } else {
96 cmd = MemCmd::WriteReq;
97 flags.set(Request::PF_EXCLUSIVE);
98 }
99
100 // Prefetches are assumed to be 0 sized
101 Request *req = new Request(m_address.getAddress(), 0, flags, curTick,
101 Request *req = new Request(m_address.getAddress(), 0, flags, curTick(),
102 m_pc.getAddress());
103
104 PacketPtr pkt = new Packet(req, cmd, port->idx);
105
106 // push the subblock onto the sender state. The sequencer will
107 // update the subblock on the return
108 pkt->senderState =
109 new SenderState(m_address, req->getSize(), pkt->senderState);
110
111 if (port->sendTiming(pkt)) {
112 DPRINTF(RubyTest, "successfully initiated prefetch.\n");
113 } else {
114 // If the packet did not issue, must delete
115 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
116 pkt->senderState = senderState->saved;
117 delete senderState;
118 delete pkt->req;
119 delete pkt;
120
121 DPRINTF(RubyTest,
122 "prefetch initiation failed because Port was busy.\n");
123 }
124}
125
126void
127Check::initiateAction()
128{
129 DPRINTF(RubyTest, "initiating Action\n");
130 assert(m_status == TesterStatus_Idle);
131
132 int index = random() % m_num_cpu_sequencers;
133 RubyTester::CpuPort* port =
134 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
135
136 Request::Flags flags;
137
138 // Create the particular address for the next byte to be written
139 Address writeAddr(m_address.getAddress() + m_store_count);
140
141 // Stores are assumed to be 1 byte-sized
102 m_pc.getAddress());
103
104 PacketPtr pkt = new Packet(req, cmd, port->idx);
105
106 // push the subblock onto the sender state. The sequencer will
107 // update the subblock on the return
108 pkt->senderState =
109 new SenderState(m_address, req->getSize(), pkt->senderState);
110
111 if (port->sendTiming(pkt)) {
112 DPRINTF(RubyTest, "successfully initiated prefetch.\n");
113 } else {
114 // If the packet did not issue, must delete
115 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
116 pkt->senderState = senderState->saved;
117 delete senderState;
118 delete pkt->req;
119 delete pkt;
120
121 DPRINTF(RubyTest,
122 "prefetch initiation failed because Port was busy.\n");
123 }
124}
125
126void
127Check::initiateAction()
128{
129 DPRINTF(RubyTest, "initiating Action\n");
130 assert(m_status == TesterStatus_Idle);
131
132 int index = random() % m_num_cpu_sequencers;
133 RubyTester::CpuPort* port =
134 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
135
136 Request::Flags flags;
137
138 // Create the particular address for the next byte to be written
139 Address writeAddr(m_address.getAddress() + m_store_count);
140
141 // Stores are assumed to be 1 byte-sized
142 Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick,
142 Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick(),
143 m_pc.getAddress());
144
145 Packet::Command cmd;
146
147 // 1 out of 8 chance, issue an atomic rather than a write
148 // if ((random() & 0x7) == 0) {
149 // cmd = MemCmd::SwapReq;
150 // } else {
151 cmd = MemCmd::WriteReq;
152 // }
153
154 PacketPtr pkt = new Packet(req, cmd, port->idx);
155 uint8_t* writeData = new uint8_t;
156 *writeData = m_value + m_store_count;
157 pkt->dataDynamic(writeData);
158
159 DPRINTF(RubyTest, "data 0x%x check 0x%x\n",
160 *(pkt->getPtr<uint8_t>()), *writeData);
161
162 // push the subblock onto the sender state. The sequencer will
163 // update the subblock on the return
164 pkt->senderState =
165 new SenderState(writeAddr, req->getSize(), pkt->senderState);
166
167 if (port->sendTiming(pkt)) {
168 DPRINTF(RubyTest, "initiating action - successful\n");
169 DPRINTF(RubyTest, "status before action update: %s\n",
170 (TesterStatus_to_string(m_status)).c_str());
171 m_status = TesterStatus_Action_Pending;
172 } else {
173 // If the packet did not issue, must delete
174 // Note: No need to delete the data, the packet destructor
175 // will delete it
176 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
177 pkt->senderState = senderState->saved;
178 delete senderState;
179 delete pkt->req;
180 delete pkt;
181
182 DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
183 }
184
185 DPRINTF(RubyTest, "status after action update: %s\n",
186 (TesterStatus_to_string(m_status)).c_str());
187}
188
189void
190Check::initiateCheck()
191{
192 DPRINTF(RubyTest, "Initiating Check\n");
193 assert(m_status == TesterStatus_Ready);
194
195 int index = random() % m_num_cpu_sequencers;
196 RubyTester::CpuPort* port =
197 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
198
199 Request::Flags flags;
200
201 // 50% chance that the request will be an instruction fetch
202 if ((random() & 0x1) == 0) {
203 flags.set(Request::INST_FETCH);
204 }
205
206 // Checks are sized depending on the number of bytes written
207 Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
143 m_pc.getAddress());
144
145 Packet::Command cmd;
146
147 // 1 out of 8 chance, issue an atomic rather than a write
148 // if ((random() & 0x7) == 0) {
149 // cmd = MemCmd::SwapReq;
150 // } else {
151 cmd = MemCmd::WriteReq;
152 // }
153
154 PacketPtr pkt = new Packet(req, cmd, port->idx);
155 uint8_t* writeData = new uint8_t;
156 *writeData = m_value + m_store_count;
157 pkt->dataDynamic(writeData);
158
159 DPRINTF(RubyTest, "data 0x%x check 0x%x\n",
160 *(pkt->getPtr<uint8_t>()), *writeData);
161
162 // push the subblock onto the sender state. The sequencer will
163 // update the subblock on the return
164 pkt->senderState =
165 new SenderState(writeAddr, req->getSize(), pkt->senderState);
166
167 if (port->sendTiming(pkt)) {
168 DPRINTF(RubyTest, "initiating action - successful\n");
169 DPRINTF(RubyTest, "status before action update: %s\n",
170 (TesterStatus_to_string(m_status)).c_str());
171 m_status = TesterStatus_Action_Pending;
172 } else {
173 // If the packet did not issue, must delete
174 // Note: No need to delete the data, the packet destructor
175 // will delete it
176 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
177 pkt->senderState = senderState->saved;
178 delete senderState;
179 delete pkt->req;
180 delete pkt;
181
182 DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
183 }
184
185 DPRINTF(RubyTest, "status after action update: %s\n",
186 (TesterStatus_to_string(m_status)).c_str());
187}
188
189void
190Check::initiateCheck()
191{
192 DPRINTF(RubyTest, "Initiating Check\n");
193 assert(m_status == TesterStatus_Ready);
194
195 int index = random() % m_num_cpu_sequencers;
196 RubyTester::CpuPort* port =
197 safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index));
198
199 Request::Flags flags;
200
201 // 50% chance that the request will be an instruction fetch
202 if ((random() & 0x1) == 0) {
203 flags.set(Request::INST_FETCH);
204 }
205
206 // Checks are sized depending on the number of bytes written
207 Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
208 curTick, m_pc.getAddress());
208 curTick(), m_pc.getAddress());
209
210 PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx);
211 uint8_t* dataArray = new uint8_t[CHECK_SIZE];
212 pkt->dataDynamicArray(dataArray);
213
214 // push the subblock onto the sender state. The sequencer will
215 // update the subblock on the return
216 pkt->senderState =
217 new SenderState(m_address, req->getSize(), pkt->senderState);
218
219 if (port->sendTiming(pkt)) {
220 DPRINTF(RubyTest, "initiating check - successful\n");
221 DPRINTF(RubyTest, "status before check update: %s\n",
222 TesterStatus_to_string(m_status).c_str());
223 m_status = TesterStatus_Check_Pending;
224 } else {
225 // If the packet did not issue, must delete
226 // Note: No need to delete the data, the packet destructor
227 // will delete it
228 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
229 pkt->senderState = senderState->saved;
230 delete senderState;
231 delete pkt->req;
232 delete pkt;
233
234 DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
235 }
236
237 DPRINTF(RubyTest, "status after check update: %s\n",
238 TesterStatus_to_string(m_status).c_str());
239}
240
241void
242Check::performCallback(NodeID proc, SubBlock* data)
243{
244 Address address = data->getAddress();
245
246 // This isn't exactly right since we now have multi-byte checks
247 // assert(getAddress() == address);
248
249 assert(getAddress().getLineAddress() == address.getLineAddress());
250 assert(data != NULL);
251
252 DPRINTF(RubyTest, "RubyTester Callback\n");
253 debugPrint();
254
255 if (m_status == TesterStatus_Action_Pending) {
256 DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
257 (m_value + m_store_count), data->getByte(0));
258 // Perform store one byte at a time
259 data->setByte(0, (m_value + m_store_count));
260 m_store_count++;
261 if (m_store_count == CHECK_SIZE) {
262 m_status = TesterStatus_Ready;
263 } else {
264 m_status = TesterStatus_Idle;
265 }
266 DPRINTF(RubyTest, "Action callback return data now %d\n",
267 data->getByte(0));
268 } else if (m_status == TesterStatus_Check_Pending) {
269 DPRINTF(RubyTest, "Check callback\n");
270 // Perform load/check
271 for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
272 if (uint8(m_value + byte_number) != data->getByte(byte_number)) {
273 panic("Action/check failure: proc: %d address: %s data: %s "
274 "byte_number: %d m_value+byte_number: %d byte: %d %s"
275 "Time: %d\n",
276 proc, address, data, byte_number,
277 (int)m_value + byte_number,
278 (int)data->getByte(byte_number), *this,
279 g_eventQueue_ptr->getTime());
280 }
281 }
282 DPRINTF(RubyTest, "Action/check success\n");
283 debugPrint();
284
285 // successful check complete, increment complete
286 m_tester_ptr->incrementCheckCompletions();
287
288 m_status = TesterStatus_Idle;
289 pickValue();
290
291 } else {
292 panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
293 "time: %d\n",
294 *this, proc, data, m_status, g_eventQueue_ptr->getTime());
295 }
296
297 DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
298 getAddress().getLineAddress());
299 DPRINTF(RubyTest, "Callback done\n");
300 debugPrint();
301}
302
303void
304Check::changeAddress(const Address& address)
305{
306 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
307 m_status = TesterStatus_Idle;
308 m_address = address;
309 m_store_count = 0;
310}
311
312void
313Check::pickValue()
314{
315 assert(m_status == TesterStatus_Idle);
316 m_status = TesterStatus_Idle;
317 m_value = random() & 0xff; // One byte
318 m_store_count = 0;
319}
320
321void
322Check::pickInitiatingNode()
323{
324 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
325 m_status = TesterStatus_Idle;
326 m_initiatingNode = (random() % m_num_cpu_sequencers);
327 DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
328 m_store_count = 0;
329}
330
331void
332Check::print(std::ostream& out) const
333{
334 out << "["
335 << m_address << ", value: "
336 << (int)m_value << ", status: "
337 << m_status << ", initiating node: "
338 << m_initiatingNode << ", store_count: "
339 << m_store_count
340 << "]" << std::flush;
341}
342
343void
344Check::debugPrint()
345{
346 DPRINTF(RubyTest,
347 "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
348 m_address.getAddress(), (int)m_value,
349 TesterStatus_to_string(m_status).c_str(),
350 m_initiatingNode, m_store_count);
351}
209
210 PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx);
211 uint8_t* dataArray = new uint8_t[CHECK_SIZE];
212 pkt->dataDynamicArray(dataArray);
213
214 // push the subblock onto the sender state. The sequencer will
215 // update the subblock on the return
216 pkt->senderState =
217 new SenderState(m_address, req->getSize(), pkt->senderState);
218
219 if (port->sendTiming(pkt)) {
220 DPRINTF(RubyTest, "initiating check - successful\n");
221 DPRINTF(RubyTest, "status before check update: %s\n",
222 TesterStatus_to_string(m_status).c_str());
223 m_status = TesterStatus_Check_Pending;
224 } else {
225 // If the packet did not issue, must delete
226 // Note: No need to delete the data, the packet destructor
227 // will delete it
228 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
229 pkt->senderState = senderState->saved;
230 delete senderState;
231 delete pkt->req;
232 delete pkt;
233
234 DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
235 }
236
237 DPRINTF(RubyTest, "status after check update: %s\n",
238 TesterStatus_to_string(m_status).c_str());
239}
240
241void
242Check::performCallback(NodeID proc, SubBlock* data)
243{
244 Address address = data->getAddress();
245
246 // This isn't exactly right since we now have multi-byte checks
247 // assert(getAddress() == address);
248
249 assert(getAddress().getLineAddress() == address.getLineAddress());
250 assert(data != NULL);
251
252 DPRINTF(RubyTest, "RubyTester Callback\n");
253 debugPrint();
254
255 if (m_status == TesterStatus_Action_Pending) {
256 DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
257 (m_value + m_store_count), data->getByte(0));
258 // Perform store one byte at a time
259 data->setByte(0, (m_value + m_store_count));
260 m_store_count++;
261 if (m_store_count == CHECK_SIZE) {
262 m_status = TesterStatus_Ready;
263 } else {
264 m_status = TesterStatus_Idle;
265 }
266 DPRINTF(RubyTest, "Action callback return data now %d\n",
267 data->getByte(0));
268 } else if (m_status == TesterStatus_Check_Pending) {
269 DPRINTF(RubyTest, "Check callback\n");
270 // Perform load/check
271 for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
272 if (uint8(m_value + byte_number) != data->getByte(byte_number)) {
273 panic("Action/check failure: proc: %d address: %s data: %s "
274 "byte_number: %d m_value+byte_number: %d byte: %d %s"
275 "Time: %d\n",
276 proc, address, data, byte_number,
277 (int)m_value + byte_number,
278 (int)data->getByte(byte_number), *this,
279 g_eventQueue_ptr->getTime());
280 }
281 }
282 DPRINTF(RubyTest, "Action/check success\n");
283 debugPrint();
284
285 // successful check complete, increment complete
286 m_tester_ptr->incrementCheckCompletions();
287
288 m_status = TesterStatus_Idle;
289 pickValue();
290
291 } else {
292 panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
293 "time: %d\n",
294 *this, proc, data, m_status, g_eventQueue_ptr->getTime());
295 }
296
297 DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
298 getAddress().getLineAddress());
299 DPRINTF(RubyTest, "Callback done\n");
300 debugPrint();
301}
302
303void
304Check::changeAddress(const Address& address)
305{
306 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
307 m_status = TesterStatus_Idle;
308 m_address = address;
309 m_store_count = 0;
310}
311
312void
313Check::pickValue()
314{
315 assert(m_status == TesterStatus_Idle);
316 m_status = TesterStatus_Idle;
317 m_value = random() & 0xff; // One byte
318 m_store_count = 0;
319}
320
321void
322Check::pickInitiatingNode()
323{
324 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
325 m_status = TesterStatus_Idle;
326 m_initiatingNode = (random() % m_num_cpu_sequencers);
327 DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
328 m_store_count = 0;
329}
330
331void
332Check::print(std::ostream& out) const
333{
334 out << "["
335 << m_address << ", value: "
336 << (int)m_value << ", status: "
337 << m_status << ", initiating node: "
338 << m_initiatingNode << ", store_count: "
339 << m_store_count
340 << "]" << std::flush;
341}
342
343void
344Check::debugPrint()
345{
346 DPRINTF(RubyTest,
347 "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
348 m_address.getAddress(), (int)m_value,
349 TesterStatus_to_string(m_status).c_str(),
350 m_initiatingNode, m_store_count);
351}