Check.cc revision 11435
12817Sksewell@umich.edu/*
22817Sksewell@umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
32817Sksewell@umich.edu * Copyright (c) 2009 Advanced Micro Devices, Inc.
42817Sksewell@umich.edu * All rights reserved.
52817Sksewell@umich.edu *
62817Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
72817Sksewell@umich.edu * modification, are permitted provided that the following conditions are
82817Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
92817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
102817Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
112817Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
122817Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
132817Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
142817Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
152817Sksewell@umich.edu * this software without specific prior written permission.
162817Sksewell@umich.edu *
172817Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182817Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192817Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202817Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212817Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222817Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232817Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242817Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252817Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262817Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272817Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282817Sksewell@umich.edu */
292817Sksewell@umich.edu
302817Sksewell@umich.edu#include "base/random.hh"
312817Sksewell@umich.edu#include "cpu/testers/rubytest/Check.hh"
322817Sksewell@umich.edu#include "debug/RubyTest.hh"
332817Sksewell@umich.edu#include "mem/ruby/common/SubBlock.hh"
342935Sksewell@umich.edu
352817Sksewell@umich.edutypedef RubyTester::SenderState SenderState;
362817Sksewell@umich.edu
372834Sksewell@umich.eduCheck::Check(Addr address, Addr pc, int _num_writers, int _num_readers,
382834Sksewell@umich.edu             RubyTester* _tester)
392834Sksewell@umich.edu    : m_num_writers(_num_writers), m_num_readers(_num_readers),
402834Sksewell@umich.edu      m_tester_ptr(_tester)
412834Sksewell@umich.edu{
422834Sksewell@umich.edu    m_status = TesterStatus_Idle;
432834Sksewell@umich.edu
442817Sksewell@umich.edu    pickValue();
452817Sksewell@umich.edu    pickInitiatingNode();
462817Sksewell@umich.edu    changeAddress(address);
472817Sksewell@umich.edu    m_pc = pc;
482817Sksewell@umich.edu    m_access_mode = RubyAccessMode(random_mt.random(0,
492817Sksewell@umich.edu                                                    RubyAccessMode_NUM - 1));
502817Sksewell@umich.edu    m_store_count = 0;
512817Sksewell@umich.edu}
522817Sksewell@umich.edu
532817Sksewell@umich.eduvoid
542817Sksewell@umich.eduCheck::initiate()
552817Sksewell@umich.edu{
562817Sksewell@umich.edu    DPRINTF(RubyTest, "initiating\n");
572817Sksewell@umich.edu    debugPrint();
582817Sksewell@umich.edu
592817Sksewell@umich.edu    // currently no protocols support prefetches
602817Sksewell@umich.edu    if (false && (random_mt.random(0, 0xf) == 0)) {
612817Sksewell@umich.edu        initiatePrefetch(); // Prefetch from random processor
622817Sksewell@umich.edu    }
632817Sksewell@umich.edu
642817Sksewell@umich.edu        if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
652817Sksewell@umich.edu        initiateFlush(); // issue a Flush request from random processor
662817Sksewell@umich.edu    }
672817Sksewell@umich.edu
682817Sksewell@umich.edu    if (m_status == TesterStatus_Idle) {
693784Sgblack@eecs.umich.edu        initiateAction();
703789Sgblack@eecs.umich.edu    } else if (m_status == TesterStatus_Ready) {
713784Sgblack@eecs.umich.edu        initiateCheck();
723784Sgblack@eecs.umich.edu    } else {
733789Sgblack@eecs.umich.edu        // Pending - do nothing
743784Sgblack@eecs.umich.edu        DPRINTF(RubyTest,
752817Sksewell@umich.edu                "initiating action/check - failed: action/check is pending\n");
762817Sksewell@umich.edu    }
772817Sksewell@umich.edu}
782817Sksewell@umich.edu
792817Sksewell@umich.eduvoid
802817Sksewell@umich.eduCheck::initiatePrefetch()
812817Sksewell@umich.edu{
822817Sksewell@umich.edu    DPRINTF(RubyTest, "initiating prefetch\n");
832817Sksewell@umich.edu
842817Sksewell@umich.edu    int index = random_mt.random(0, m_num_readers - 1);
852817Sksewell@umich.edu    MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
862817Sksewell@umich.edu
872817Sksewell@umich.edu    Request::Flags flags;
882817Sksewell@umich.edu    flags.set(Request::PREFETCH);
892817Sksewell@umich.edu
902817Sksewell@umich.edu    Packet::Command cmd;
912817Sksewell@umich.edu
923548Sgblack@eecs.umich.edu    // 1 in 8 chance this will be an exclusive prefetch
932817Sksewell@umich.edu    if (random_mt.random(0, 0x7) != 0) {
942817Sksewell@umich.edu        cmd = MemCmd::ReadReq;
952817Sksewell@umich.edu
962817Sksewell@umich.edu        // if necessary, make the request an instruction fetch
975499Ssaidi@eecs.umich.edu        if (m_tester_ptr->isInstOnlyCpuPort(index) ||
983675Sktlim@umich.edu            (m_tester_ptr->isInstDataCpuPort(index) &&
995497Ssaidi@eecs.umich.edu             (random_mt.random(0, 0x1)))) {
1002817Sksewell@umich.edu            flags.set(Request::INST_FETCH);
1012817Sksewell@umich.edu        }
1022817Sksewell@umich.edu    } else {
1032817Sksewell@umich.edu        cmd = MemCmd::WriteReq;
1042817Sksewell@umich.edu        flags.set(Request::PF_EXCLUSIVE);
1052817Sksewell@umich.edu    }
1062817Sksewell@umich.edu
1072817Sksewell@umich.edu    // Prefetches are assumed to be 0 sized
1082817Sksewell@umich.edu    Request *req = new Request(m_address, 0, flags,
1092817Sksewell@umich.edu            m_tester_ptr->masterId(), curTick(), m_pc);
1102817Sksewell@umich.edu    req->setContext(index);
1112817Sksewell@umich.edu
1122817Sksewell@umich.edu    PacketPtr pkt = new Packet(req, cmd);
1132817Sksewell@umich.edu    // despite the oddity of the 0 size (questionable if this should
1142817Sksewell@umich.edu    // even be allowed), a prefetch is still a read and as such needs
1152817Sksewell@umich.edu    // a place to store the result
1162817Sksewell@umich.edu    uint8_t *data = new uint8_t[1];
1172817Sksewell@umich.edu    pkt->dataDynamic(data);
1185250Sksewell@umich.edu
1192817Sksewell@umich.edu    // push the subblock onto the sender state.  The sequencer will
1202817Sksewell@umich.edu    // update the subblock on the return
1212875Sksewell@umich.edu    pkt->senderState = new SenderState(m_address, req->getSize());
1222817Sksewell@umich.edu
1232817Sksewell@umich.edu    if (port->sendTimingReq(pkt)) {
1245250Sksewell@umich.edu        DPRINTF(RubyTest, "successfully initiated prefetch.\n");
1252817Sksewell@umich.edu    } else {
1262817Sksewell@umich.edu        // If the packet did not issue, must delete
1272817Sksewell@umich.edu        delete pkt->senderState;
1282817Sksewell@umich.edu        delete pkt->req;
1292817Sksewell@umich.edu        delete pkt;
1302817Sksewell@umich.edu
1312817Sksewell@umich.edu        DPRINTF(RubyTest,
1322817Sksewell@umich.edu                "prefetch initiation failed because Port was busy.\n");
1332817Sksewell@umich.edu    }
1342817Sksewell@umich.edu}
1352817Sksewell@umich.edu
1362817Sksewell@umich.eduvoid
1372817Sksewell@umich.eduCheck::initiateFlush()
1382817Sksewell@umich.edu{
1392817Sksewell@umich.edu
1402817Sksewell@umich.edu    DPRINTF(RubyTest, "initiating Flush\n");
1412817Sksewell@umich.edu
1422817Sksewell@umich.edu    int index = random_mt.random(0, m_num_writers - 1);
1432817Sksewell@umich.edu    MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
1442817Sksewell@umich.edu
1452817Sksewell@umich.edu    Request::Flags flags;
1462817Sksewell@umich.edu
1472817Sksewell@umich.edu    Request *req = new Request(m_address, CHECK_SIZE, flags,
1482817Sksewell@umich.edu            m_tester_ptr->masterId(), curTick(), m_pc);
1492817Sksewell@umich.edu
1502817Sksewell@umich.edu    Packet::Command cmd;
1512817Sksewell@umich.edu
1522817Sksewell@umich.edu    cmd = MemCmd::FlushReq;
1532817Sksewell@umich.edu
1542817Sksewell@umich.edu    PacketPtr pkt = new Packet(req, cmd);
1552817Sksewell@umich.edu
1562817Sksewell@umich.edu    // push the subblock onto the sender state.  The sequencer will
1572817Sksewell@umich.edu    // update the subblock on the return
1582817Sksewell@umich.edu    pkt->senderState = new SenderState(m_address, req->getSize());
1592817Sksewell@umich.edu
1602817Sksewell@umich.edu    if (port->sendTimingReq(pkt)) {
1612817Sksewell@umich.edu        DPRINTF(RubyTest, "initiating Flush - successful\n");
1622817Sksewell@umich.edu    }
1632817Sksewell@umich.edu}
1642817Sksewell@umich.edu
1652817Sksewell@umich.eduvoid
1662817Sksewell@umich.eduCheck::initiateAction()
1672817Sksewell@umich.edu{
1682817Sksewell@umich.edu    DPRINTF(RubyTest, "initiating Action\n");
1692817Sksewell@umich.edu    assert(m_status == TesterStatus_Idle);
1702817Sksewell@umich.edu
1712817Sksewell@umich.edu    int index = random_mt.random(0, m_num_writers - 1);
1722817Sksewell@umich.edu    MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
1732817Sksewell@umich.edu
1742817Sksewell@umich.edu    Request::Flags flags;
1752817Sksewell@umich.edu
1762817Sksewell@umich.edu    // Create the particular address for the next byte to be written
1772817Sksewell@umich.edu    Addr writeAddr(m_address + m_store_count);
1782817Sksewell@umich.edu
1792817Sksewell@umich.edu    // Stores are assumed to be 1 byte-sized
1802817Sksewell@umich.edu    Request *req = new Request(writeAddr, 1, flags, m_tester_ptr->masterId(),
1812817Sksewell@umich.edu                               curTick(), m_pc);
1822817Sksewell@umich.edu
1832817Sksewell@umich.edu    req->setContext(index);
1842817Sksewell@umich.edu    Packet::Command cmd;
1852817Sksewell@umich.edu
1862817Sksewell@umich.edu    // 1 out of 8 chance, issue an atomic rather than a write
1872817Sksewell@umich.edu    // if ((random() & 0x7) == 0) {
1882817Sksewell@umich.edu    //     cmd = MemCmd::SwapReq;
1892817Sksewell@umich.edu    // } else {
1902817Sksewell@umich.edu    cmd = MemCmd::WriteReq;
1912817Sksewell@umich.edu    // }
1922817Sksewell@umich.edu
1932817Sksewell@umich.edu    PacketPtr pkt = new Packet(req, cmd);
1942817Sksewell@umich.edu    uint8_t *writeData = new uint8_t[1];
1952817Sksewell@umich.edu    *writeData = m_value + m_store_count;
1962817Sksewell@umich.edu    pkt->dataDynamic(writeData);
1972817Sksewell@umich.edu
1982817Sksewell@umich.edu    DPRINTF(RubyTest, "Seq write: index %d data 0x%x check 0x%x\n", index,
1992817Sksewell@umich.edu            *(pkt->getConstPtr<uint8_t>()), *writeData);
2002817Sksewell@umich.edu
2012817Sksewell@umich.edu    // push the subblock onto the sender state.  The sequencer will
2022817Sksewell@umich.edu    // update the subblock on the return
2032817Sksewell@umich.edu    pkt->senderState = new SenderState(writeAddr, req->getSize());
2045259Sksewell@umich.edu
2055259Sksewell@umich.edu    if (port->sendTimingReq(pkt)) {
2065259Sksewell@umich.edu        DPRINTF(RubyTest, "initiating action - successful\n");
2075259Sksewell@umich.edu        DPRINTF(RubyTest, "status before action update: %s\n",
2085259Sksewell@umich.edu                (TesterStatus_to_string(m_status)).c_str());
2095259Sksewell@umich.edu        m_status = TesterStatus_Action_Pending;
2105259Sksewell@umich.edu        DPRINTF(RubyTest, "Check %s, State=Action_Pending\n", m_address);
2115259Sksewell@umich.edu    } else {
2125259Sksewell@umich.edu        // If the packet did not issue, must delete
2135259Sksewell@umich.edu        // Note: No need to delete the data, the packet destructor
2142817Sksewell@umich.edu        // will delete it
2154172Ssaidi@eecs.umich.edu        delete pkt->senderState;
2164172Ssaidi@eecs.umich.edu        delete pkt->req;
2174172Ssaidi@eecs.umich.edu        delete pkt;
2184172Ssaidi@eecs.umich.edu
2194172Ssaidi@eecs.umich.edu        DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
2202817Sksewell@umich.edu    }
2212817Sksewell@umich.edu
2222817Sksewell@umich.edu    DPRINTF(RubyTest, "status after action update: %s\n",
2232817Sksewell@umich.edu            (TesterStatus_to_string(m_status)).c_str());
2244172Ssaidi@eecs.umich.edu}
2252817Sksewell@umich.edu
2262817Sksewell@umich.eduvoid
2272817Sksewell@umich.eduCheck::initiateCheck()
2284172Ssaidi@eecs.umich.edu{
2292817Sksewell@umich.edu    DPRINTF(RubyTest, "Initiating Check\n");
2302817Sksewell@umich.edu    assert(m_status == TesterStatus_Ready);
2312817Sksewell@umich.edu
2322817Sksewell@umich.edu    int index = random_mt.random(0, m_num_readers - 1);
2332817Sksewell@umich.edu    MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
2342817Sksewell@umich.edu
2352817Sksewell@umich.edu    Request::Flags flags;
2362817Sksewell@umich.edu
2372817Sksewell@umich.edu    // If necessary, make the request an instruction fetch
2382817Sksewell@umich.edu    if (m_tester_ptr->isInstOnlyCpuPort(index) ||
2392817Sksewell@umich.edu        (m_tester_ptr->isInstDataCpuPort(index) &&
2402817Sksewell@umich.edu         (random_mt.random(0, 0x1)))) {
2412817Sksewell@umich.edu        flags.set(Request::INST_FETCH);
2422817Sksewell@umich.edu    }
2432817Sksewell@umich.edu
2442817Sksewell@umich.edu    // Checks are sized depending on the number of bytes written
2452817Sksewell@umich.edu    Request *req = new Request(m_address, CHECK_SIZE, flags,
2462817Sksewell@umich.edu                               m_tester_ptr->masterId(), curTick(), m_pc);
2472817Sksewell@umich.edu
2482817Sksewell@umich.edu    req->setContext(index);
2492817Sksewell@umich.edu    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
2502817Sksewell@umich.edu    uint8_t *dataArray = new uint8_t[CHECK_SIZE];
2512817Sksewell@umich.edu    pkt->dataDynamic(dataArray);
2522817Sksewell@umich.edu
2532817Sksewell@umich.edu    DPRINTF(RubyTest, "Seq read: index %d\n", index);
2542817Sksewell@umich.edu
2552817Sksewell@umich.edu    // push the subblock onto the sender state.  The sequencer will
2562817Sksewell@umich.edu    // update the subblock on the return
2572817Sksewell@umich.edu    pkt->senderState = new SenderState(m_address, req->getSize());
2582817Sksewell@umich.edu
2592817Sksewell@umich.edu    if (port->sendTimingReq(pkt)) {
2602817Sksewell@umich.edu        DPRINTF(RubyTest, "initiating check - successful\n");
2612817Sksewell@umich.edu        DPRINTF(RubyTest, "status before check update: %s\n",
2622817Sksewell@umich.edu                TesterStatus_to_string(m_status).c_str());
2635595Sgblack@eecs.umich.edu        m_status = TesterStatus_Check_Pending;
2645595Sgblack@eecs.umich.edu        DPRINTF(RubyTest, "Check %s, State=Check_Pending\n", m_address);
2655595Sgblack@eecs.umich.edu    } else {
2665595Sgblack@eecs.umich.edu        // If the packet did not issue, must delete
2675595Sgblack@eecs.umich.edu        // Note: No need to delete the data, the packet destructor
2685595Sgblack@eecs.umich.edu        // will delete it
2692817Sksewell@umich.edu        delete pkt->senderState;
2705595Sgblack@eecs.umich.edu        delete pkt->req;
2715595Sgblack@eecs.umich.edu        delete pkt;
2725595Sgblack@eecs.umich.edu
2735595Sgblack@eecs.umich.edu        DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
2745595Sgblack@eecs.umich.edu    }
2755595Sgblack@eecs.umich.edu
2765595Sgblack@eecs.umich.edu    DPRINTF(RubyTest, "status after check update: %s\n",
2775595Sgblack@eecs.umich.edu            TesterStatus_to_string(m_status).c_str());
2785595Sgblack@eecs.umich.edu}
2795595Sgblack@eecs.umich.edu
2805595Sgblack@eecs.umich.eduvoid
2815595Sgblack@eecs.umich.eduCheck::performCallback(NodeID proc, SubBlock* data, Cycles curTime)
2825595Sgblack@eecs.umich.edu{
2835595Sgblack@eecs.umich.edu    Addr address = data->getAddress();
2845595Sgblack@eecs.umich.edu
2855595Sgblack@eecs.umich.edu    // This isn't exactly right since we now have multi-byte checks
2865595Sgblack@eecs.umich.edu    //  assert(getAddress() == address);
2875595Sgblack@eecs.umich.edu
2885595Sgblack@eecs.umich.edu    assert(makeLineAddress(m_address) == makeLineAddress(address));
2895595Sgblack@eecs.umich.edu    assert(data != NULL);
2905595Sgblack@eecs.umich.edu
2915595Sgblack@eecs.umich.edu    DPRINTF(RubyTest, "RubyTester Callback\n");
2925595Sgblack@eecs.umich.edu    debugPrint();
2935595Sgblack@eecs.umich.edu
2945595Sgblack@eecs.umich.edu    if (m_status == TesterStatus_Action_Pending) {
2955595Sgblack@eecs.umich.edu        DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
2965595Sgblack@eecs.umich.edu                (m_value + m_store_count), data->getByte(0));
2975595Sgblack@eecs.umich.edu        // Perform store one byte at a time
2985595Sgblack@eecs.umich.edu        data->setByte(0, (m_value + m_store_count));
2995595Sgblack@eecs.umich.edu        m_store_count++;
3005595Sgblack@eecs.umich.edu        if (m_store_count == CHECK_SIZE) {
3015595Sgblack@eecs.umich.edu            m_status = TesterStatus_Ready;
3025595Sgblack@eecs.umich.edu            DPRINTF(RubyTest, "Check %s, State=Ready\n", m_address);
3035595Sgblack@eecs.umich.edu        } else {
3045595Sgblack@eecs.umich.edu            m_status = TesterStatus_Idle;
3055595Sgblack@eecs.umich.edu            DPRINTF(RubyTest, "Check %s, State=Idle store_count: %d\n",
3065595Sgblack@eecs.umich.edu                    m_address, m_store_count);
3075595Sgblack@eecs.umich.edu        }
3082817Sksewell@umich.edu        DPRINTF(RubyTest, "Action callback return data now %d\n",
3092817Sksewell@umich.edu                data->getByte(0));
3102817Sksewell@umich.edu    } else if (m_status == TesterStatus_Check_Pending) {
311        DPRINTF(RubyTest, "Check callback\n");
312        // Perform load/check
313        for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
314            if (uint8_t(m_value + byte_number) != data->getByte(byte_number)) {
315                panic("Action/check failure: proc: %d address: %s data: %s "
316                      "byte_number: %d m_value+byte_number: %d byte: %d %s"
317                      "Time: %d\n",
318                      proc, address, data, byte_number,
319                      (int)m_value + byte_number,
320                      (int)data->getByte(byte_number), *this, curTime);
321            }
322        }
323        DPRINTF(RubyTest, "Action/check success\n");
324        debugPrint();
325
326        // successful check complete, increment complete
327        m_tester_ptr->incrementCheckCompletions();
328
329        m_status = TesterStatus_Idle;
330        DPRINTF(RubyTest, "Check %s, State=Idle\n", m_address);
331        pickValue();
332
333    } else {
334        panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
335              "time: %d\n", *this, proc, data, m_status, curTime);
336    }
337
338    DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
339            makeLineAddress(m_address));
340    DPRINTF(RubyTest, "Callback done\n");
341    debugPrint();
342}
343
344void
345Check::changeAddress(Addr address)
346{
347    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
348    m_status = TesterStatus_Idle;
349    m_address = address;
350    DPRINTF(RubyTest, "Check %s, State=Idle\n", m_address);
351    m_store_count = 0;
352}
353
354void
355Check::pickValue()
356{
357    assert(m_status == TesterStatus_Idle);
358    m_value = random_mt.random(0, 0xff); // One byte
359    m_store_count = 0;
360}
361
362void
363Check::pickInitiatingNode()
364{
365    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
366    m_status = TesterStatus_Idle;
367    m_initiatingNode = (random_mt.random(0, m_num_writers - 1));
368    DPRINTF(RubyTest, "Check %s, State=Idle, picked initiating node %d\n",
369            m_address, m_initiatingNode);
370    m_store_count = 0;
371}
372
373void
374Check::print(std::ostream& out) const
375{
376    out << "["
377        << m_address << ", value: "
378        << (int)m_value << ", status: "
379        << m_status << ", initiating node: "
380        << m_initiatingNode << ", store_count: "
381        << m_store_count
382        << "]" << std::flush;
383}
384
385void
386Check::debugPrint()
387{
388    DPRINTF(RubyTest,
389        "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
390        m_address, (int)m_value, TesterStatus_to_string(m_status).c_str(),
391        m_initiatingNode, m_store_count);
392}
393