Check.cc (11800:54436a1784dc) Check.cc (12612:a64e6b723e5f)
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
32#include "base/random.hh"
33#include "base/trace.hh"
34#include "debug/RubyTest.hh"
35#include "mem/ruby/common/SubBlock.hh"
36
37typedef RubyTester::SenderState SenderState;
38
39Check::Check(Addr address, Addr pc, int _num_writers, int _num_readers,
40 RubyTester* _tester)
41 : m_num_writers(_num_writers), m_num_readers(_num_readers),
42 m_tester_ptr(_tester)
43{
44 m_status = TesterStatus_Idle;
45
46 pickValue();
47 pickInitiatingNode();
48 changeAddress(address);
49 m_pc = pc;
50 m_access_mode = RubyAccessMode(random_mt.random(0,
51 RubyAccessMode_NUM - 1));
52 m_store_count = 0;
53}
54
55void
56Check::initiate()
57{
58 DPRINTF(RubyTest, "initiating\n");
59 debugPrint();
60
61 // currently no protocols support prefetches
62 if (false && (random_mt.random(0, 0xf) == 0)) {
63 initiatePrefetch(); // Prefetch from random processor
64 }
65
66 if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
67 initiateFlush(); // issue a Flush request from random processor
68 }
69
70 if (m_status == TesterStatus_Idle) {
71 initiateAction();
72 } else if (m_status == TesterStatus_Ready) {
73 initiateCheck();
74 } else {
75 // Pending - do nothing
76 DPRINTF(RubyTest,
77 "initiating action/check - failed: action/check is pending\n");
78 }
79}
80
81void
82Check::initiatePrefetch()
83{
84 DPRINTF(RubyTest, "initiating prefetch\n");
85
86 int index = random_mt.random(0, m_num_readers - 1);
87 MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
88
89 Request::Flags flags;
90 flags.set(Request::PREFETCH);
91
92 Packet::Command cmd;
93
94 // 1 in 8 chance this will be an exclusive prefetch
95 if (random_mt.random(0, 0x7) != 0) {
96 cmd = MemCmd::ReadReq;
97
98 // if necessary, make the request an instruction fetch
99 if (m_tester_ptr->isInstOnlyCpuPort(index) ||
100 (m_tester_ptr->isInstDataCpuPort(index) &&
101 (random_mt.random(0, 0x1)))) {
102 flags.set(Request::INST_FETCH);
103 }
104 } else {
105 cmd = MemCmd::WriteReq;
106 flags.set(Request::PF_EXCLUSIVE);
107 }
108
109 // Prefetches are assumed to be 0 sized
110 Request *req = new Request(m_address, 0, flags,
111 m_tester_ptr->masterId(), curTick(), m_pc);
112 req->setContext(index);
113
114 PacketPtr pkt = new Packet(req, cmd);
115 // despite the oddity of the 0 size (questionable if this should
116 // even be allowed), a prefetch is still a read and as such needs
117 // a place to store the result
118 uint8_t *data = new uint8_t[1];
119 pkt->dataDynamic(data);
120
121 // push the subblock onto the sender state. The sequencer will
122 // update the subblock on the return
123 pkt->senderState = new SenderState(m_address, req->getSize());
124
125 if (port->sendTimingReq(pkt)) {
126 DPRINTF(RubyTest, "successfully initiated prefetch.\n");
127 } else {
128 // If the packet did not issue, must delete
129 delete pkt->senderState;
130 delete pkt->req;
131 delete pkt;
132
133 DPRINTF(RubyTest,
134 "prefetch initiation failed because Port was busy.\n");
135 }
136}
137
138void
139Check::initiateFlush()
140{
141
142 DPRINTF(RubyTest, "initiating Flush\n");
143
144 int index = random_mt.random(0, m_num_writers - 1);
145 MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
146
147 Request::Flags flags;
148
149 Request *req = new Request(m_address, CHECK_SIZE, flags,
150 m_tester_ptr->masterId(), curTick(), m_pc);
151
152 Packet::Command cmd;
153
154 cmd = MemCmd::FlushReq;
155
156 PacketPtr pkt = new Packet(req, cmd);
157
158 // push the subblock onto the sender state. The sequencer will
159 // update the subblock on the return
160 pkt->senderState = new SenderState(m_address, req->getSize());
161
162 if (port->sendTimingReq(pkt)) {
163 DPRINTF(RubyTest, "initiating Flush - successful\n");
164 }
165}
166
167void
168Check::initiateAction()
169{
170 DPRINTF(RubyTest, "initiating Action\n");
171 assert(m_status == TesterStatus_Idle);
172
173 int index = random_mt.random(0, m_num_writers - 1);
174 MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
175
176 Request::Flags flags;
177
178 // Create the particular address for the next byte to be written
179 Addr writeAddr(m_address + m_store_count);
180
181 // Stores are assumed to be 1 byte-sized
182 Request *req = new Request(writeAddr, 1, flags, m_tester_ptr->masterId(),
183 curTick(), m_pc);
184
185 req->setContext(index);
186 Packet::Command cmd;
187
188 // 1 out of 8 chance, issue an atomic rather than a write
189 // if ((random() & 0x7) == 0) {
190 // cmd = MemCmd::SwapReq;
191 // } else {
192 cmd = MemCmd::WriteReq;
193 // }
194
195 PacketPtr pkt = new Packet(req, cmd);
196 uint8_t *writeData = new uint8_t[1];
197 *writeData = m_value + m_store_count;
198 pkt->dataDynamic(writeData);
199
200 DPRINTF(RubyTest, "Seq write: index %d data 0x%x check 0x%x\n", index,
201 *(pkt->getConstPtr<uint8_t>()), *writeData);
202
203 // push the subblock onto the sender state. The sequencer will
204 // update the subblock on the return
205 pkt->senderState = new SenderState(writeAddr, req->getSize());
206
207 if (port->sendTimingReq(pkt)) {
208 DPRINTF(RubyTest, "initiating action - successful\n");
209 DPRINTF(RubyTest, "status before action update: %s\n",
210 (TesterStatus_to_string(m_status)).c_str());
211 m_status = TesterStatus_Action_Pending;
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
32#include "base/random.hh"
33#include "base/trace.hh"
34#include "debug/RubyTest.hh"
35#include "mem/ruby/common/SubBlock.hh"
36
37typedef RubyTester::SenderState SenderState;
38
39Check::Check(Addr address, Addr pc, int _num_writers, int _num_readers,
40 RubyTester* _tester)
41 : m_num_writers(_num_writers), m_num_readers(_num_readers),
42 m_tester_ptr(_tester)
43{
44 m_status = TesterStatus_Idle;
45
46 pickValue();
47 pickInitiatingNode();
48 changeAddress(address);
49 m_pc = pc;
50 m_access_mode = RubyAccessMode(random_mt.random(0,
51 RubyAccessMode_NUM - 1));
52 m_store_count = 0;
53}
54
55void
56Check::initiate()
57{
58 DPRINTF(RubyTest, "initiating\n");
59 debugPrint();
60
61 // currently no protocols support prefetches
62 if (false && (random_mt.random(0, 0xf) == 0)) {
63 initiatePrefetch(); // Prefetch from random processor
64 }
65
66 if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
67 initiateFlush(); // issue a Flush request from random processor
68 }
69
70 if (m_status == TesterStatus_Idle) {
71 initiateAction();
72 } else if (m_status == TesterStatus_Ready) {
73 initiateCheck();
74 } else {
75 // Pending - do nothing
76 DPRINTF(RubyTest,
77 "initiating action/check - failed: action/check is pending\n");
78 }
79}
80
81void
82Check::initiatePrefetch()
83{
84 DPRINTF(RubyTest, "initiating prefetch\n");
85
86 int index = random_mt.random(0, m_num_readers - 1);
87 MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
88
89 Request::Flags flags;
90 flags.set(Request::PREFETCH);
91
92 Packet::Command cmd;
93
94 // 1 in 8 chance this will be an exclusive prefetch
95 if (random_mt.random(0, 0x7) != 0) {
96 cmd = MemCmd::ReadReq;
97
98 // if necessary, make the request an instruction fetch
99 if (m_tester_ptr->isInstOnlyCpuPort(index) ||
100 (m_tester_ptr->isInstDataCpuPort(index) &&
101 (random_mt.random(0, 0x1)))) {
102 flags.set(Request::INST_FETCH);
103 }
104 } else {
105 cmd = MemCmd::WriteReq;
106 flags.set(Request::PF_EXCLUSIVE);
107 }
108
109 // Prefetches are assumed to be 0 sized
110 Request *req = new Request(m_address, 0, flags,
111 m_tester_ptr->masterId(), curTick(), m_pc);
112 req->setContext(index);
113
114 PacketPtr pkt = new Packet(req, cmd);
115 // despite the oddity of the 0 size (questionable if this should
116 // even be allowed), a prefetch is still a read and as such needs
117 // a place to store the result
118 uint8_t *data = new uint8_t[1];
119 pkt->dataDynamic(data);
120
121 // push the subblock onto the sender state. The sequencer will
122 // update the subblock on the return
123 pkt->senderState = new SenderState(m_address, req->getSize());
124
125 if (port->sendTimingReq(pkt)) {
126 DPRINTF(RubyTest, "successfully initiated prefetch.\n");
127 } else {
128 // If the packet did not issue, must delete
129 delete pkt->senderState;
130 delete pkt->req;
131 delete pkt;
132
133 DPRINTF(RubyTest,
134 "prefetch initiation failed because Port was busy.\n");
135 }
136}
137
138void
139Check::initiateFlush()
140{
141
142 DPRINTF(RubyTest, "initiating Flush\n");
143
144 int index = random_mt.random(0, m_num_writers - 1);
145 MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
146
147 Request::Flags flags;
148
149 Request *req = new Request(m_address, CHECK_SIZE, flags,
150 m_tester_ptr->masterId(), curTick(), m_pc);
151
152 Packet::Command cmd;
153
154 cmd = MemCmd::FlushReq;
155
156 PacketPtr pkt = new Packet(req, cmd);
157
158 // push the subblock onto the sender state. The sequencer will
159 // update the subblock on the return
160 pkt->senderState = new SenderState(m_address, req->getSize());
161
162 if (port->sendTimingReq(pkt)) {
163 DPRINTF(RubyTest, "initiating Flush - successful\n");
164 }
165}
166
167void
168Check::initiateAction()
169{
170 DPRINTF(RubyTest, "initiating Action\n");
171 assert(m_status == TesterStatus_Idle);
172
173 int index = random_mt.random(0, m_num_writers - 1);
174 MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
175
176 Request::Flags flags;
177
178 // Create the particular address for the next byte to be written
179 Addr writeAddr(m_address + m_store_count);
180
181 // Stores are assumed to be 1 byte-sized
182 Request *req = new Request(writeAddr, 1, flags, m_tester_ptr->masterId(),
183 curTick(), m_pc);
184
185 req->setContext(index);
186 Packet::Command cmd;
187
188 // 1 out of 8 chance, issue an atomic rather than a write
189 // if ((random() & 0x7) == 0) {
190 // cmd = MemCmd::SwapReq;
191 // } else {
192 cmd = MemCmd::WriteReq;
193 // }
194
195 PacketPtr pkt = new Packet(req, cmd);
196 uint8_t *writeData = new uint8_t[1];
197 *writeData = m_value + m_store_count;
198 pkt->dataDynamic(writeData);
199
200 DPRINTF(RubyTest, "Seq write: index %d data 0x%x check 0x%x\n", index,
201 *(pkt->getConstPtr<uint8_t>()), *writeData);
202
203 // push the subblock onto the sender state. The sequencer will
204 // update the subblock on the return
205 pkt->senderState = new SenderState(writeAddr, req->getSize());
206
207 if (port->sendTimingReq(pkt)) {
208 DPRINTF(RubyTest, "initiating action - successful\n");
209 DPRINTF(RubyTest, "status before action update: %s\n",
210 (TesterStatus_to_string(m_status)).c_str());
211 m_status = TesterStatus_Action_Pending;
212 DPRINTF(RubyTest, "Check %s, State=Action_Pending\n", m_address);
212 DPRINTF(RubyTest, "Check %#x, State=Action_Pending\n", m_address);
213 } else {
214 // If the packet did not issue, must delete
215 // Note: No need to delete the data, the packet destructor
216 // will delete it
217 delete pkt->senderState;
218 delete pkt->req;
219 delete pkt;
220
221 DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
222 }
223
224 DPRINTF(RubyTest, "status after action update: %s\n",
225 (TesterStatus_to_string(m_status)).c_str());
226}
227
228void
229Check::initiateCheck()
230{
231 DPRINTF(RubyTest, "Initiating Check\n");
232 assert(m_status == TesterStatus_Ready);
233
234 int index = random_mt.random(0, m_num_readers - 1);
235 MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
236
237 Request::Flags flags;
238
239 // If necessary, make the request an instruction fetch
240 if (m_tester_ptr->isInstOnlyCpuPort(index) ||
241 (m_tester_ptr->isInstDataCpuPort(index) &&
242 (random_mt.random(0, 0x1)))) {
243 flags.set(Request::INST_FETCH);
244 }
245
246 // Checks are sized depending on the number of bytes written
247 Request *req = new Request(m_address, CHECK_SIZE, flags,
248 m_tester_ptr->masterId(), curTick(), m_pc);
249
250 req->setContext(index);
251 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
252 uint8_t *dataArray = new uint8_t[CHECK_SIZE];
253 pkt->dataDynamic(dataArray);
254
255 DPRINTF(RubyTest, "Seq read: index %d\n", index);
256
257 // push the subblock onto the sender state. The sequencer will
258 // update the subblock on the return
259 pkt->senderState = new SenderState(m_address, req->getSize());
260
261 if (port->sendTimingReq(pkt)) {
262 DPRINTF(RubyTest, "initiating check - successful\n");
263 DPRINTF(RubyTest, "status before check update: %s\n",
264 TesterStatus_to_string(m_status).c_str());
265 m_status = TesterStatus_Check_Pending;
213 } else {
214 // If the packet did not issue, must delete
215 // Note: No need to delete the data, the packet destructor
216 // will delete it
217 delete pkt->senderState;
218 delete pkt->req;
219 delete pkt;
220
221 DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
222 }
223
224 DPRINTF(RubyTest, "status after action update: %s\n",
225 (TesterStatus_to_string(m_status)).c_str());
226}
227
228void
229Check::initiateCheck()
230{
231 DPRINTF(RubyTest, "Initiating Check\n");
232 assert(m_status == TesterStatus_Ready);
233
234 int index = random_mt.random(0, m_num_readers - 1);
235 MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
236
237 Request::Flags flags;
238
239 // If necessary, make the request an instruction fetch
240 if (m_tester_ptr->isInstOnlyCpuPort(index) ||
241 (m_tester_ptr->isInstDataCpuPort(index) &&
242 (random_mt.random(0, 0x1)))) {
243 flags.set(Request::INST_FETCH);
244 }
245
246 // Checks are sized depending on the number of bytes written
247 Request *req = new Request(m_address, CHECK_SIZE, flags,
248 m_tester_ptr->masterId(), curTick(), m_pc);
249
250 req->setContext(index);
251 PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
252 uint8_t *dataArray = new uint8_t[CHECK_SIZE];
253 pkt->dataDynamic(dataArray);
254
255 DPRINTF(RubyTest, "Seq read: index %d\n", index);
256
257 // push the subblock onto the sender state. The sequencer will
258 // update the subblock on the return
259 pkt->senderState = new SenderState(m_address, req->getSize());
260
261 if (port->sendTimingReq(pkt)) {
262 DPRINTF(RubyTest, "initiating check - successful\n");
263 DPRINTF(RubyTest, "status before check update: %s\n",
264 TesterStatus_to_string(m_status).c_str());
265 m_status = TesterStatus_Check_Pending;
266 DPRINTF(RubyTest, "Check %s, State=Check_Pending\n", m_address);
266 DPRINTF(RubyTest, "Check %#x, State=Check_Pending\n", m_address);
267 } else {
268 // If the packet did not issue, must delete
269 // Note: No need to delete the data, the packet destructor
270 // will delete it
271 delete pkt->senderState;
272 delete pkt->req;
273 delete pkt;
274
275 DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
276 }
277
278 DPRINTF(RubyTest, "status after check update: %s\n",
279 TesterStatus_to_string(m_status).c_str());
280}
281
282void
283Check::performCallback(NodeID proc, SubBlock* data, Cycles curTime)
284{
285 Addr address = data->getAddress();
286
287 // This isn't exactly right since we now have multi-byte checks
288 // assert(getAddress() == address);
289
290 assert(makeLineAddress(m_address) == makeLineAddress(address));
291 assert(data != NULL);
292
293 DPRINTF(RubyTest, "RubyTester Callback\n");
294 debugPrint();
295
296 if (m_status == TesterStatus_Action_Pending) {
297 DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
298 (m_value + m_store_count), data->getByte(0));
299 // Perform store one byte at a time
300 data->setByte(0, (m_value + m_store_count));
301 m_store_count++;
302 if (m_store_count == CHECK_SIZE) {
303 m_status = TesterStatus_Ready;
267 } else {
268 // If the packet did not issue, must delete
269 // Note: No need to delete the data, the packet destructor
270 // will delete it
271 delete pkt->senderState;
272 delete pkt->req;
273 delete pkt;
274
275 DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
276 }
277
278 DPRINTF(RubyTest, "status after check update: %s\n",
279 TesterStatus_to_string(m_status).c_str());
280}
281
282void
283Check::performCallback(NodeID proc, SubBlock* data, Cycles curTime)
284{
285 Addr address = data->getAddress();
286
287 // This isn't exactly right since we now have multi-byte checks
288 // assert(getAddress() == address);
289
290 assert(makeLineAddress(m_address) == makeLineAddress(address));
291 assert(data != NULL);
292
293 DPRINTF(RubyTest, "RubyTester Callback\n");
294 debugPrint();
295
296 if (m_status == TesterStatus_Action_Pending) {
297 DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
298 (m_value + m_store_count), data->getByte(0));
299 // Perform store one byte at a time
300 data->setByte(0, (m_value + m_store_count));
301 m_store_count++;
302 if (m_store_count == CHECK_SIZE) {
303 m_status = TesterStatus_Ready;
304 DPRINTF(RubyTest, "Check %s, State=Ready\n", m_address);
304 DPRINTF(RubyTest, "Check %#x, State=Ready\n", m_address);
305 } else {
306 m_status = TesterStatus_Idle;
305 } else {
306 m_status = TesterStatus_Idle;
307 DPRINTF(RubyTest, "Check %s, State=Idle store_count: %d\n",
307 DPRINTF(RubyTest, "Check %#x, State=Idle store_count: %d\n",
308 m_address, m_store_count);
309 }
310 DPRINTF(RubyTest, "Action callback return data now %d\n",
311 data->getByte(0));
312 } else if (m_status == TesterStatus_Check_Pending) {
313 DPRINTF(RubyTest, "Check callback\n");
314 // Perform load/check
315 for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
316 if (uint8_t(m_value + byte_number) != data->getByte(byte_number)) {
308 m_address, m_store_count);
309 }
310 DPRINTF(RubyTest, "Action callback return data now %d\n",
311 data->getByte(0));
312 } else if (m_status == TesterStatus_Check_Pending) {
313 DPRINTF(RubyTest, "Check callback\n");
314 // Perform load/check
315 for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
316 if (uint8_t(m_value + byte_number) != data->getByte(byte_number)) {
317 panic("Action/check failure: proc: %d address: %s data: %s "
317 panic("Action/check failure: proc: %d address: %#x data: %s "
318 "byte_number: %d m_value+byte_number: %d byte: %d %s"
319 "Time: %d\n",
320 proc, address, data, byte_number,
321 (int)m_value + byte_number,
322 (int)data->getByte(byte_number), *this, curTime);
323 }
324 }
325 DPRINTF(RubyTest, "Action/check success\n");
326 debugPrint();
327
328 // successful check complete, increment complete
329 m_tester_ptr->incrementCheckCompletions();
330
331 m_status = TesterStatus_Idle;
318 "byte_number: %d m_value+byte_number: %d byte: %d %s"
319 "Time: %d\n",
320 proc, address, data, byte_number,
321 (int)m_value + byte_number,
322 (int)data->getByte(byte_number), *this, curTime);
323 }
324 }
325 DPRINTF(RubyTest, "Action/check success\n");
326 debugPrint();
327
328 // successful check complete, increment complete
329 m_tester_ptr->incrementCheckCompletions();
330
331 m_status = TesterStatus_Idle;
332 DPRINTF(RubyTest, "Check %s, State=Idle\n", m_address);
332 DPRINTF(RubyTest, "Check %#x, State=Idle\n", m_address);
333 pickValue();
334
335 } else {
336 panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
337 "time: %d\n", *this, proc, data, m_status, curTime);
338 }
339
340 DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
341 makeLineAddress(m_address));
342 DPRINTF(RubyTest, "Callback done\n");
343 debugPrint();
344}
345
346void
347Check::changeAddress(Addr address)
348{
349 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
350 m_status = TesterStatus_Idle;
351 m_address = address;
333 pickValue();
334
335 } else {
336 panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
337 "time: %d\n", *this, proc, data, m_status, curTime);
338 }
339
340 DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
341 makeLineAddress(m_address));
342 DPRINTF(RubyTest, "Callback done\n");
343 debugPrint();
344}
345
346void
347Check::changeAddress(Addr address)
348{
349 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
350 m_status = TesterStatus_Idle;
351 m_address = address;
352 DPRINTF(RubyTest, "Check %s, State=Idle\n", m_address);
352 DPRINTF(RubyTest, "Check %#x, State=Idle\n", m_address);
353 m_store_count = 0;
354}
355
356void
357Check::pickValue()
358{
359 assert(m_status == TesterStatus_Idle);
360 m_value = random_mt.random(0, 0xff); // One byte
361 m_store_count = 0;
362}
363
364void
365Check::pickInitiatingNode()
366{
367 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
368 m_status = TesterStatus_Idle;
369 m_initiatingNode = (random_mt.random(0, m_num_writers - 1));
353 m_store_count = 0;
354}
355
356void
357Check::pickValue()
358{
359 assert(m_status == TesterStatus_Idle);
360 m_value = random_mt.random(0, 0xff); // One byte
361 m_store_count = 0;
362}
363
364void
365Check::pickInitiatingNode()
366{
367 assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
368 m_status = TesterStatus_Idle;
369 m_initiatingNode = (random_mt.random(0, m_num_writers - 1));
370 DPRINTF(RubyTest, "Check %s, State=Idle, picked initiating node %d\n",
370 DPRINTF(RubyTest, "Check %#x, State=Idle, picked initiating node %d\n",
371 m_address, m_initiatingNode);
372 m_store_count = 0;
373}
374
375void
376Check::print(std::ostream& out) const
377{
378 out << "["
379 << m_address << ", value: "
380 << (int)m_value << ", status: "
381 << m_status << ", initiating node: "
382 << m_initiatingNode << ", store_count: "
383 << m_store_count
384 << "]" << std::flush;
385}
386
387void
388Check::debugPrint()
389{
390 DPRINTF(RubyTest,
391 "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
392 m_address, (int)m_value, TesterStatus_to_string(m_status).c_str(),
393 m_initiatingNode, m_store_count);
394}
371 m_address, m_initiatingNode);
372 m_store_count = 0;
373}
374
375void
376Check::print(std::ostream& out) const
377{
378 out << "["
379 << m_address << ", value: "
380 << (int)m_value << ", status: "
381 << m_status << ", initiating node: "
382 << m_initiatingNode << ", store_count: "
383 << m_store_count
384 << "]" << std::flush;
385}
386
387void
388Check::debugPrint()
389{
390 DPRINTF(RubyTest,
391 "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
392 m_address, (int)m_value, TesterStatus_to_string(m_status).c_str(),
393 m_initiatingNode, m_store_count);
394}