Check.cc revision 11800:54436a1784dc
112605Sgiacomo.travaglini@arm.com/*
212605Sgiacomo.travaglini@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
312605Sgiacomo.travaglini@arm.com * Copyright (c) 2009 Advanced Micro Devices, Inc.
412605Sgiacomo.travaglini@arm.com * All rights reserved.
512605Sgiacomo.travaglini@arm.com *
612605Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
712605Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
812605Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
912605Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
1012605Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1112605Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
1212605Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
1312605Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
1412605Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
1512605Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
1612605Sgiacomo.travaglini@arm.com *
1712605Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1812605Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1912605Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2012605Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2112605Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2212605Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2312605Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2412605Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2512605Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2612605Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2712605Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2812605Sgiacomo.travaglini@arm.com */
2912605Sgiacomo.travaglini@arm.com
3012605Sgiacomo.travaglini@arm.com#include "cpu/testers/rubytest/Check.hh"
3112605Sgiacomo.travaglini@arm.com
3212605Sgiacomo.travaglini@arm.com#include "base/random.hh"
3312605Sgiacomo.travaglini@arm.com#include "base/trace.hh"
3412605Sgiacomo.travaglini@arm.com#include "debug/RubyTest.hh"
3512605Sgiacomo.travaglini@arm.com#include "mem/ruby/common/SubBlock.hh"
3612605Sgiacomo.travaglini@arm.com
3712605Sgiacomo.travaglini@arm.comtypedef RubyTester::SenderState SenderState;
3812605Sgiacomo.travaglini@arm.com
3912605Sgiacomo.travaglini@arm.comCheck::Check(Addr address, Addr pc, int _num_writers, int _num_readers,
4012605Sgiacomo.travaglini@arm.com             RubyTester* _tester)
4112605Sgiacomo.travaglini@arm.com    : m_num_writers(_num_writers), m_num_readers(_num_readers),
4212605Sgiacomo.travaglini@arm.com      m_tester_ptr(_tester)
4312605Sgiacomo.travaglini@arm.com{
4412605Sgiacomo.travaglini@arm.com    m_status = TesterStatus_Idle;
4512605Sgiacomo.travaglini@arm.com
4612605Sgiacomo.travaglini@arm.com    pickValue();
4712605Sgiacomo.travaglini@arm.com    pickInitiatingNode();
4812605Sgiacomo.travaglini@arm.com    changeAddress(address);
4912605Sgiacomo.travaglini@arm.com    m_pc = pc;
5012605Sgiacomo.travaglini@arm.com    m_access_mode = RubyAccessMode(random_mt.random(0,
5112605Sgiacomo.travaglini@arm.com                                                    RubyAccessMode_NUM - 1));
5212605Sgiacomo.travaglini@arm.com    m_store_count = 0;
5312605Sgiacomo.travaglini@arm.com}
5412605Sgiacomo.travaglini@arm.com
5512605Sgiacomo.travaglini@arm.comvoid
5612605Sgiacomo.travaglini@arm.comCheck::initiate()
5712605Sgiacomo.travaglini@arm.com{
5812605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "initiating\n");
5912605Sgiacomo.travaglini@arm.com    debugPrint();
6012605Sgiacomo.travaglini@arm.com
6112605Sgiacomo.travaglini@arm.com    // currently no protocols support prefetches
6212605Sgiacomo.travaglini@arm.com    if (false && (random_mt.random(0, 0xf) == 0)) {
6312605Sgiacomo.travaglini@arm.com        initiatePrefetch(); // Prefetch from random processor
6412605Sgiacomo.travaglini@arm.com    }
6512605Sgiacomo.travaglini@arm.com
6612605Sgiacomo.travaglini@arm.com        if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
6712605Sgiacomo.travaglini@arm.com        initiateFlush(); // issue a Flush request from random processor
6812605Sgiacomo.travaglini@arm.com    }
6912605Sgiacomo.travaglini@arm.com
7012605Sgiacomo.travaglini@arm.com    if (m_status == TesterStatus_Idle) {
7112605Sgiacomo.travaglini@arm.com        initiateAction();
7212605Sgiacomo.travaglini@arm.com    } else if (m_status == TesterStatus_Ready) {
7312605Sgiacomo.travaglini@arm.com        initiateCheck();
7412605Sgiacomo.travaglini@arm.com    } else {
7512605Sgiacomo.travaglini@arm.com        // Pending - do nothing
7612605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest,
7712605Sgiacomo.travaglini@arm.com                "initiating action/check - failed: action/check is pending\n");
7812605Sgiacomo.travaglini@arm.com    }
7912605Sgiacomo.travaglini@arm.com}
8012605Sgiacomo.travaglini@arm.com
8112605Sgiacomo.travaglini@arm.comvoid
8212605Sgiacomo.travaglini@arm.comCheck::initiatePrefetch()
8312605Sgiacomo.travaglini@arm.com{
8412605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "initiating prefetch\n");
8512605Sgiacomo.travaglini@arm.com
8612605Sgiacomo.travaglini@arm.com    int index = random_mt.random(0, m_num_readers - 1);
8712605Sgiacomo.travaglini@arm.com    MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
8812605Sgiacomo.travaglini@arm.com
8912605Sgiacomo.travaglini@arm.com    Request::Flags flags;
9012605Sgiacomo.travaglini@arm.com    flags.set(Request::PREFETCH);
9112605Sgiacomo.travaglini@arm.com
9212605Sgiacomo.travaglini@arm.com    Packet::Command cmd;
9312605Sgiacomo.travaglini@arm.com
9412605Sgiacomo.travaglini@arm.com    // 1 in 8 chance this will be an exclusive prefetch
9512605Sgiacomo.travaglini@arm.com    if (random_mt.random(0, 0x7) != 0) {
9612605Sgiacomo.travaglini@arm.com        cmd = MemCmd::ReadReq;
9712605Sgiacomo.travaglini@arm.com
9812605Sgiacomo.travaglini@arm.com        // if necessary, make the request an instruction fetch
9912605Sgiacomo.travaglini@arm.com        if (m_tester_ptr->isInstOnlyCpuPort(index) ||
10012605Sgiacomo.travaglini@arm.com            (m_tester_ptr->isInstDataCpuPort(index) &&
10112605Sgiacomo.travaglini@arm.com             (random_mt.random(0, 0x1)))) {
10212605Sgiacomo.travaglini@arm.com            flags.set(Request::INST_FETCH);
10312605Sgiacomo.travaglini@arm.com        }
10412605Sgiacomo.travaglini@arm.com    } else {
10512605Sgiacomo.travaglini@arm.com        cmd = MemCmd::WriteReq;
10612605Sgiacomo.travaglini@arm.com        flags.set(Request::PF_EXCLUSIVE);
10712605Sgiacomo.travaglini@arm.com    }
10812605Sgiacomo.travaglini@arm.com
10912605Sgiacomo.travaglini@arm.com    // Prefetches are assumed to be 0 sized
11012605Sgiacomo.travaglini@arm.com    Request *req = new Request(m_address, 0, flags,
11112605Sgiacomo.travaglini@arm.com            m_tester_ptr->masterId(), curTick(), m_pc);
11212605Sgiacomo.travaglini@arm.com    req->setContext(index);
11312605Sgiacomo.travaglini@arm.com
11412605Sgiacomo.travaglini@arm.com    PacketPtr pkt = new Packet(req, cmd);
11512605Sgiacomo.travaglini@arm.com    // despite the oddity of the 0 size (questionable if this should
11612605Sgiacomo.travaglini@arm.com    // even be allowed), a prefetch is still a read and as such needs
11712605Sgiacomo.travaglini@arm.com    // a place to store the result
11812605Sgiacomo.travaglini@arm.com    uint8_t *data = new uint8_t[1];
11912605Sgiacomo.travaglini@arm.com    pkt->dataDynamic(data);
12012605Sgiacomo.travaglini@arm.com
12112605Sgiacomo.travaglini@arm.com    // push the subblock onto the sender state.  The sequencer will
12212605Sgiacomo.travaglini@arm.com    // update the subblock on the return
12312605Sgiacomo.travaglini@arm.com    pkt->senderState = new SenderState(m_address, req->getSize());
12412605Sgiacomo.travaglini@arm.com
12512605Sgiacomo.travaglini@arm.com    if (port->sendTimingReq(pkt)) {
12612605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "successfully initiated prefetch.\n");
12712605Sgiacomo.travaglini@arm.com    } else {
12812605Sgiacomo.travaglini@arm.com        // If the packet did not issue, must delete
12912605Sgiacomo.travaglini@arm.com        delete pkt->senderState;
13012605Sgiacomo.travaglini@arm.com        delete pkt->req;
13112605Sgiacomo.travaglini@arm.com        delete pkt;
13212605Sgiacomo.travaglini@arm.com
13312605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest,
13412605Sgiacomo.travaglini@arm.com                "prefetch initiation failed because Port was busy.\n");
13512605Sgiacomo.travaglini@arm.com    }
13612605Sgiacomo.travaglini@arm.com}
13712605Sgiacomo.travaglini@arm.com
13812605Sgiacomo.travaglini@arm.comvoid
13912605Sgiacomo.travaglini@arm.comCheck::initiateFlush()
14012605Sgiacomo.travaglini@arm.com{
14112605Sgiacomo.travaglini@arm.com
14212605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "initiating Flush\n");
14312605Sgiacomo.travaglini@arm.com
14412605Sgiacomo.travaglini@arm.com    int index = random_mt.random(0, m_num_writers - 1);
14512605Sgiacomo.travaglini@arm.com    MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
14612605Sgiacomo.travaglini@arm.com
14712605Sgiacomo.travaglini@arm.com    Request::Flags flags;
14812605Sgiacomo.travaglini@arm.com
14912605Sgiacomo.travaglini@arm.com    Request *req = new Request(m_address, CHECK_SIZE, flags,
15012605Sgiacomo.travaglini@arm.com            m_tester_ptr->masterId(), curTick(), m_pc);
15112605Sgiacomo.travaglini@arm.com
15212605Sgiacomo.travaglini@arm.com    Packet::Command cmd;
15312605Sgiacomo.travaglini@arm.com
15412605Sgiacomo.travaglini@arm.com    cmd = MemCmd::FlushReq;
15512605Sgiacomo.travaglini@arm.com
15612605Sgiacomo.travaglini@arm.com    PacketPtr pkt = new Packet(req, cmd);
15712605Sgiacomo.travaglini@arm.com
15812605Sgiacomo.travaglini@arm.com    // push the subblock onto the sender state.  The sequencer will
15912605Sgiacomo.travaglini@arm.com    // update the subblock on the return
16012605Sgiacomo.travaglini@arm.com    pkt->senderState = new SenderState(m_address, req->getSize());
16112605Sgiacomo.travaglini@arm.com
16212605Sgiacomo.travaglini@arm.com    if (port->sendTimingReq(pkt)) {
16312605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "initiating Flush - successful\n");
16412605Sgiacomo.travaglini@arm.com    }
16512605Sgiacomo.travaglini@arm.com}
16612605Sgiacomo.travaglini@arm.com
16712605Sgiacomo.travaglini@arm.comvoid
16812605Sgiacomo.travaglini@arm.comCheck::initiateAction()
16912605Sgiacomo.travaglini@arm.com{
17012605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "initiating Action\n");
17112605Sgiacomo.travaglini@arm.com    assert(m_status == TesterStatus_Idle);
17212605Sgiacomo.travaglini@arm.com
17312605Sgiacomo.travaglini@arm.com    int index = random_mt.random(0, m_num_writers - 1);
17412605Sgiacomo.travaglini@arm.com    MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
17512605Sgiacomo.travaglini@arm.com
17612605Sgiacomo.travaglini@arm.com    Request::Flags flags;
17712605Sgiacomo.travaglini@arm.com
17812605Sgiacomo.travaglini@arm.com    // Create the particular address for the next byte to be written
17912605Sgiacomo.travaglini@arm.com    Addr writeAddr(m_address + m_store_count);
18012605Sgiacomo.travaglini@arm.com
18112605Sgiacomo.travaglini@arm.com    // Stores are assumed to be 1 byte-sized
18212605Sgiacomo.travaglini@arm.com    Request *req = new Request(writeAddr, 1, flags, m_tester_ptr->masterId(),
18312605Sgiacomo.travaglini@arm.com                               curTick(), m_pc);
18412605Sgiacomo.travaglini@arm.com
18512605Sgiacomo.travaglini@arm.com    req->setContext(index);
18612605Sgiacomo.travaglini@arm.com    Packet::Command cmd;
18712605Sgiacomo.travaglini@arm.com
18812605Sgiacomo.travaglini@arm.com    // 1 out of 8 chance, issue an atomic rather than a write
18912605Sgiacomo.travaglini@arm.com    // if ((random() & 0x7) == 0) {
19012605Sgiacomo.travaglini@arm.com    //     cmd = MemCmd::SwapReq;
19112605Sgiacomo.travaglini@arm.com    // } else {
19212605Sgiacomo.travaglini@arm.com    cmd = MemCmd::WriteReq;
19312605Sgiacomo.travaglini@arm.com    // }
19412605Sgiacomo.travaglini@arm.com
19512605Sgiacomo.travaglini@arm.com    PacketPtr pkt = new Packet(req, cmd);
19612605Sgiacomo.travaglini@arm.com    uint8_t *writeData = new uint8_t[1];
19712605Sgiacomo.travaglini@arm.com    *writeData = m_value + m_store_count;
19812605Sgiacomo.travaglini@arm.com    pkt->dataDynamic(writeData);
19912605Sgiacomo.travaglini@arm.com
20012605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "Seq write: index %d data 0x%x check 0x%x\n", index,
20112605Sgiacomo.travaglini@arm.com            *(pkt->getConstPtr<uint8_t>()), *writeData);
20212605Sgiacomo.travaglini@arm.com
20312605Sgiacomo.travaglini@arm.com    // push the subblock onto the sender state.  The sequencer will
20412605Sgiacomo.travaglini@arm.com    // update the subblock on the return
20512605Sgiacomo.travaglini@arm.com    pkt->senderState = new SenderState(writeAddr, req->getSize());
20612605Sgiacomo.travaglini@arm.com
20712605Sgiacomo.travaglini@arm.com    if (port->sendTimingReq(pkt)) {
20812605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "initiating action - successful\n");
20912605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "status before action update: %s\n",
21012605Sgiacomo.travaglini@arm.com                (TesterStatus_to_string(m_status)).c_str());
21112605Sgiacomo.travaglini@arm.com        m_status = TesterStatus_Action_Pending;
21212605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "Check %s, State=Action_Pending\n", m_address);
21312605Sgiacomo.travaglini@arm.com    } else {
21412605Sgiacomo.travaglini@arm.com        // If the packet did not issue, must delete
21512605Sgiacomo.travaglini@arm.com        // Note: No need to delete the data, the packet destructor
21612605Sgiacomo.travaglini@arm.com        // will delete it
21712605Sgiacomo.travaglini@arm.com        delete pkt->senderState;
21812605Sgiacomo.travaglini@arm.com        delete pkt->req;
21912605Sgiacomo.travaglini@arm.com        delete pkt;
22012605Sgiacomo.travaglini@arm.com
22112605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
22212605Sgiacomo.travaglini@arm.com    }
22312605Sgiacomo.travaglini@arm.com
22412605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "status after action update: %s\n",
22512605Sgiacomo.travaglini@arm.com            (TesterStatus_to_string(m_status)).c_str());
22612605Sgiacomo.travaglini@arm.com}
22712605Sgiacomo.travaglini@arm.com
22812605Sgiacomo.travaglini@arm.comvoid
22912605Sgiacomo.travaglini@arm.comCheck::initiateCheck()
23012605Sgiacomo.travaglini@arm.com{
23112605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "Initiating Check\n");
23212605Sgiacomo.travaglini@arm.com    assert(m_status == TesterStatus_Ready);
23312605Sgiacomo.travaglini@arm.com
23412605Sgiacomo.travaglini@arm.com    int index = random_mt.random(0, m_num_readers - 1);
23512605Sgiacomo.travaglini@arm.com    MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
23612605Sgiacomo.travaglini@arm.com
23712605Sgiacomo.travaglini@arm.com    Request::Flags flags;
23812605Sgiacomo.travaglini@arm.com
23912605Sgiacomo.travaglini@arm.com    // If necessary, make the request an instruction fetch
24012605Sgiacomo.travaglini@arm.com    if (m_tester_ptr->isInstOnlyCpuPort(index) ||
24112605Sgiacomo.travaglini@arm.com        (m_tester_ptr->isInstDataCpuPort(index) &&
24212605Sgiacomo.travaglini@arm.com         (random_mt.random(0, 0x1)))) {
24312605Sgiacomo.travaglini@arm.com        flags.set(Request::INST_FETCH);
24412605Sgiacomo.travaglini@arm.com    }
24512605Sgiacomo.travaglini@arm.com
24612605Sgiacomo.travaglini@arm.com    // Checks are sized depending on the number of bytes written
24712605Sgiacomo.travaglini@arm.com    Request *req = new Request(m_address, CHECK_SIZE, flags,
24812605Sgiacomo.travaglini@arm.com                               m_tester_ptr->masterId(), curTick(), m_pc);
24912605Sgiacomo.travaglini@arm.com
25012605Sgiacomo.travaglini@arm.com    req->setContext(index);
25112605Sgiacomo.travaglini@arm.com    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
25212605Sgiacomo.travaglini@arm.com    uint8_t *dataArray = new uint8_t[CHECK_SIZE];
25312605Sgiacomo.travaglini@arm.com    pkt->dataDynamic(dataArray);
25412605Sgiacomo.travaglini@arm.com
25512605Sgiacomo.travaglini@arm.com    DPRINTF(RubyTest, "Seq read: index %d\n", index);
25612605Sgiacomo.travaglini@arm.com
25712605Sgiacomo.travaglini@arm.com    // push the subblock onto the sender state.  The sequencer will
25812605Sgiacomo.travaglini@arm.com    // update the subblock on the return
25912605Sgiacomo.travaglini@arm.com    pkt->senderState = new SenderState(m_address, req->getSize());
26012605Sgiacomo.travaglini@arm.com
26112605Sgiacomo.travaglini@arm.com    if (port->sendTimingReq(pkt)) {
26212605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "initiating check - successful\n");
26312605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "status before check update: %s\n",
26412605Sgiacomo.travaglini@arm.com                TesterStatus_to_string(m_status).c_str());
26512605Sgiacomo.travaglini@arm.com        m_status = TesterStatus_Check_Pending;
26612605Sgiacomo.travaglini@arm.com        DPRINTF(RubyTest, "Check %s, 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;
304            DPRINTF(RubyTest, "Check %s, State=Ready\n", m_address);
305        } else {
306            m_status = TesterStatus_Idle;
307            DPRINTF(RubyTest, "Check %s, 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)) {
317                panic("Action/check failure: proc: %d address: %s 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;
332        DPRINTF(RubyTest, "Check %s, 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;
352    DPRINTF(RubyTest, "Check %s, 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));
370    DPRINTF(RubyTest, "Check %s, 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}
395