diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/rubytest/Check.cc | 607 | ||||
-rw-r--r-- | src/cpu/rubytest/Check.hh | 98 | ||||
-rw-r--r-- | src/cpu/rubytest/CheckTable.cc | 145 | ||||
-rw-r--r-- | src/cpu/rubytest/CheckTable.hh | 74 | ||||
-rw-r--r-- | src/cpu/rubytest/RubyTester.cc | 189 | ||||
-rw-r--r-- | src/cpu/rubytest/RubyTester.hh | 190 |
6 files changed, 604 insertions, 699 deletions
diff --git a/src/cpu/rubytest/Check.cc b/src/cpu/rubytest/Check.cc index 3b358e633..ca7ca8457 100644 --- a/src/cpu/rubytest/Check.cc +++ b/src/cpu/rubytest/Check.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,370 +27,330 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "cpu/rubytest/Check.hh" +#include "mem/ruby/common/SubBlock.hh" #include "mem/ruby/system/Sequencer.hh" #include "mem/ruby/system/System.hh" -#include "mem/ruby/common/SubBlock.hh" -Check::Check(const Address& address, - const Address& pc, - int _num_cpu_sequencers, - RubyTester* _tester) - : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester) +typedef RubyTester::SenderState SenderState; + +Check::Check(const Address& address, const Address& pc, + int _num_cpu_sequencers, RubyTester* _tester) + : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester) { - m_status = TesterStatus_Idle; - - pickValue(); - pickInitiatingNode(); - changeAddress(address); - m_pc = pc; - m_access_mode = AccessModeType(random() % AccessModeType_NUM); - m_store_count = 0; + m_status = TesterStatus_Idle; + + pickValue(); + pickInitiatingNode(); + changeAddress(address); + m_pc = pc; + m_access_mode = AccessModeType(random() % AccessModeType_NUM); + m_store_count = 0; } -void Check::initiate() +void +Check::initiate() { - DPRINTF(RubyTest, "initiating\n"); - debugPrint(); - - // - // currently no protocols support prefetches - // - if (false && (random() & 0xf) == 0) { - initiatePrefetch(); // Prefetch from random processor - } - - if(m_status == TesterStatus_Idle) { - initiateAction(); - } else if(m_status == TesterStatus_Ready) { - initiateCheck(); - } else { - // Pending - do nothing - DPRINTF(RubyTest, "initiating action/check - failed: action/check is pending\n"); - } + DPRINTF(RubyTest, "initiating\n"); + debugPrint(); + + // currently no protocols support prefetches + if (false && (random() & 0xf) == 0) { + initiatePrefetch(); // Prefetch from random processor + } + + if (m_status == TesterStatus_Idle) { + initiateAction(); + } else if (m_status == TesterStatus_Ready) { + initiateCheck(); + } else { + // Pending - do nothing + DPRINTF(RubyTest, + "initiating action/check - failed: action/check is pending\n"); + } } -void Check::initiatePrefetch() +void +Check::initiatePrefetch() { - DPRINTF(RubyTest, "initiating prefetch\n"); - - RubyTester::CpuPort* port - = safe_cast<RubyTester::CpuPort*> \ - (m_tester_ptr->getCpuPort(random() % m_num_cpu_sequencers)); - - Request::Flags flags; - flags.set(Request::PREFETCH); - - // - // Prefetches are assumed to be 0 sized - // - Request *req = new Request(m_address.getAddress(), - 0, - flags, - curTick, - m_pc.getAddress()); - - Packet::Command cmd; - - // - // 1 in 8 chance this will be an exclusive prefetch - // - if ((random() & 0x7) != 0) { - cmd = MemCmd::ReadReq; - // - // 50% chance that the request will be an instruction fetch - // - if ((random() & 0x1) == 0) { - flags.set(Request::INST_FETCH); + DPRINTF(RubyTest, "initiating prefetch\n"); + + int index = random() % m_num_cpu_sequencers; + RubyTester::CpuPort* port = + safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index)); + + Request::Flags flags; + flags.set(Request::PREFETCH); + + // Prefetches are assumed to be 0 sized + Request *req = new Request(m_address.getAddress(), 0, flags, curTick, + m_pc.getAddress()); + + Packet::Command cmd; + + // 1 in 8 chance this will be an exclusive prefetch + if ((random() & 0x7) != 0) { + cmd = MemCmd::ReadReq; + + // 50% chance that the request will be an instruction fetch + if ((random() & 0x1) == 0) { + flags.set(Request::INST_FETCH); + } + } else { + cmd = MemCmd::WriteReq; + flags.set(Request::PF_EXCLUSIVE); + } + + PacketPtr pkt = new Packet(req, cmd, port->idx); + + // push the subblock onto the sender state. The sequencer will + // update the subblock on the return + pkt->senderState = + new SenderState(m_address, req->getSize(), pkt->senderState); + + if (port->sendTiming(pkt)) { + DPRINTF(RubyTest, "successfully initiated prefetch.\n"); + } else { + // If the packet did not issue, must delete + SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); + pkt->senderState = senderState->saved; + delete senderState; + delete pkt->req; + delete pkt; + + DPRINTF(RubyTest, + "prefetch initiation failed because Port was busy.\n"); } - } else { - cmd = MemCmd::WriteReq; - flags.set(Request::PF_EXCLUSIVE); - } - - PacketPtr pkt = new Packet(req, cmd, port->idx); - - // - // push the subblock onto the sender state. The sequencer will update the - // subblock on the return - // - pkt->senderState = new RubyTester::SenderState(m_address, - req->getSize(), - pkt->senderState); - - if (port->sendTiming(pkt)) { - DPRINTF(RubyTest, "successfully initiated prefetch.\n"); - } else { - // - // If the packet did not issue, must delete - // - RubyTester::SenderState* senderState = - safe_cast<RubyTester::SenderState*>(pkt->senderState); - pkt->senderState = senderState->saved; - delete senderState; - delete pkt->req; - delete pkt; - - DPRINTF(RubyTest, "prefetch initiation failed because Port was busy.\n"); - } } -void Check::initiateAction() +void +Check::initiateAction() { - DPRINTF(RubyTest, "initiating Action\n"); - assert(m_status == TesterStatus_Idle); - - RubyTester::CpuPort* port - = safe_cast<RubyTester::CpuPort*> \ - (m_tester_ptr->getCpuPort(random() % m_num_cpu_sequencers)); - - Request::Flags flags; - - // - // Create the particular address for the next byte to be written - // - Address writeAddr(m_address.getAddress() + m_store_count); - - // - // Stores are assumed to be 1 byte-sized - // - Request *req = new Request(writeAddr.getAddress(), - 1, - flags, - curTick, - m_pc.getAddress()); - - Packet::Command cmd; - - // - // 1 out of 8 chance, issue an atomic rather than a write - // -// if ((random() & 0x7) == 0) { -// cmd = MemCmd::SwapReq; -// } else { + DPRINTF(RubyTest, "initiating Action\n"); + assert(m_status == TesterStatus_Idle); + + int index = random() % m_num_cpu_sequencers; + RubyTester::CpuPort* port = + safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index)); + + Request::Flags flags; + + // Create the particular address for the next byte to be written + Address writeAddr(m_address.getAddress() + m_store_count); + + // Stores are assumed to be 1 byte-sized + Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick, + m_pc.getAddress()); + + Packet::Command cmd; + + // 1 out of 8 chance, issue an atomic rather than a write + // if ((random() & 0x7) == 0) { + // cmd = MemCmd::SwapReq; + // } else { cmd = MemCmd::WriteReq; -// } - - PacketPtr pkt = new Packet(req, cmd, port->idx); - uint8_t* writeData = new uint8_t; - *writeData = m_value + m_store_count; - pkt->dataDynamic(writeData); - - DPRINTF(RubyTest, - "data 0x%x check 0x%x\n", - *(pkt->getPtr<uint8_t>()), - *writeData); - - // - // push the subblock onto the sender state. The sequencer will update the - // subblock on the return - // - pkt->senderState = new RubyTester::SenderState(writeAddr, - req->getSize(), - pkt->senderState); - - if (port->sendTiming(pkt)) { - DPRINTF(RubyTest, "initiating action - successful\n"); - DPRINTF(RubyTest, - "status before action update: %s\n", + // } + + PacketPtr pkt = new Packet(req, cmd, port->idx); + uint8_t* writeData = new uint8_t; + *writeData = m_value + m_store_count; + pkt->dataDynamic(writeData); + + DPRINTF(RubyTest, "data 0x%x check 0x%x\n", + *(pkt->getPtr<uint8_t>()), *writeData); + + // push the subblock onto the sender state. The sequencer will + // update the subblock on the return + pkt->senderState = + new SenderState(writeAddr, req->getSize(), pkt->senderState); + + if (port->sendTiming(pkt)) { + DPRINTF(RubyTest, "initiating action - successful\n"); + DPRINTF(RubyTest, "status before action update: %s\n", + (TesterStatus_to_string(m_status)).c_str()); + m_status = TesterStatus_Action_Pending; + } else { + // If the packet did not issue, must delete + // Note: No need to delete the data, the packet destructor + // will delete it + SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); + pkt->senderState = senderState->saved; + delete senderState; + delete pkt->req; + delete pkt; + + DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n"); + } + + DPRINTF(RubyTest, "status after action update: %s\n", (TesterStatus_to_string(m_status)).c_str()); - m_status = TesterStatus_Action_Pending; - } else { - // - // If the packet did not issue, must delete - // Note: No need to delete the data, the packet destructor will delete it - // - RubyTester::SenderState* senderState = - safe_cast<RubyTester::SenderState*>(pkt->senderState); - pkt->senderState = senderState->saved; - delete senderState; - delete pkt->req; - delete pkt; - - DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n"); - } - - DPRINTF(RubyTest, - "status after action update: %s\n", - (TesterStatus_to_string(m_status)).c_str()); } -void Check::initiateCheck() +void +Check::initiateCheck() { - DPRINTF(RubyTest, "Initiating Check\n"); - assert(m_status == TesterStatus_Ready); - - RubyTester::CpuPort* port - = safe_cast<RubyTester::CpuPort*> \ - (m_tester_ptr->getCpuPort(random() % m_num_cpu_sequencers)); - - Request::Flags flags; - - // - // Checks are sized depending on the number of bytes written - // - Request *req = new Request(m_address.getAddress(), - CHECK_SIZE, - flags, - curTick, - m_pc.getAddress()); - - // - // 50% chance that the request will be an instruction fetch - // - if ((random() & 0x1) == 0) { - flags.set(Request::INST_FETCH); - } - - PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx); - uint8_t* dataArray = new uint8_t[CHECK_SIZE]; - pkt->dataDynamicArray(dataArray); - - // - // push the subblock onto the sender state. The sequencer will update the - // subblock on the return - // - pkt->senderState = new RubyTester::SenderState(m_address, - req->getSize(), - pkt->senderState); - - if (port->sendTiming(pkt)) { - DPRINTF(RubyTest, "initiating check - successful\n"); - DPRINTF(RubyTest, - "status before check update: %s\n", - (TesterStatus_to_string(m_status)).c_str()); - m_status = TesterStatus_Check_Pending; - } else { - // - // If the packet did not issue, must delete - // Note: No need to delete the data, the packet destructor will delete it - // - RubyTester::SenderState* senderState = - safe_cast<RubyTester::SenderState*>(pkt->senderState); - pkt->senderState = senderState->saved; - delete senderState; - delete pkt->req; - delete pkt; - - DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n"); - } - - DPRINTF(RubyTest, - "status after check update: %s\n", - (TesterStatus_to_string(m_status)).c_str()); + DPRINTF(RubyTest, "Initiating Check\n"); + assert(m_status == TesterStatus_Ready); + + int index = random() % m_num_cpu_sequencers; + RubyTester::CpuPort* port = + safe_cast<RubyTester::CpuPort*>(m_tester_ptr->getCpuPort(index)); + + Request::Flags flags; + + // Checks are sized depending on the number of bytes written + Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags, + curTick, m_pc.getAddress()); + + // 50% chance that the request will be an instruction fetch + if ((random() & 0x1) == 0) { + flags.set(Request::INST_FETCH); + } + + PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx); + uint8_t* dataArray = new uint8_t[CHECK_SIZE]; + pkt->dataDynamicArray(dataArray); + + // push the subblock onto the sender state. The sequencer will + // update the subblock on the return + pkt->senderState = + new SenderState(m_address, req->getSize(), pkt->senderState); + + if (port->sendTiming(pkt)) { + DPRINTF(RubyTest, "initiating check - successful\n"); + DPRINTF(RubyTest, "status before check update: %s\n", + TesterStatus_to_string(m_status).c_str()); + m_status = TesterStatus_Check_Pending; + } else { + // If the packet did not issue, must delete + // Note: No need to delete the data, the packet destructor + // will delete it + SenderState* senderState = safe_cast<SenderState*>(pkt->senderState); + pkt->senderState = senderState->saved; + delete senderState; + delete pkt->req; + delete pkt; + + DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n"); + } + + DPRINTF(RubyTest, "status after check update: %s\n", + TesterStatus_to_string(m_status).c_str()); } -void Check::performCallback(NodeID proc, SubBlock* data) +void +Check::performCallback(NodeID proc, SubBlock* data) { - Address address = data->getAddress(); - // assert(getAddress() == address); // This isn't exactly right since we now have multi-byte checks - assert(getAddress().getLineAddress() == address.getLineAddress()); - assert(data != NULL); - - DPRINTF(RubyTest, "RubyTester Callback\n"); - debugPrint(); - - if (m_status == TesterStatus_Action_Pending) { - DPRINTF(RubyTest, - "Action callback write value: %d, currently %d\n", - (m_value + m_store_count), - data->getByte(0)); - // - // Perform store one byte at a time - // - data->setByte(0, (m_value + m_store_count)); - m_store_count++; - if (m_store_count == CHECK_SIZE) { - m_status = TesterStatus_Ready; + Address address = data->getAddress(); + + // This isn't exactly right since we now have multi-byte checks + // assert(getAddress() == address); + + assert(getAddress().getLineAddress() == address.getLineAddress()); + assert(data != NULL); + + DPRINTF(RubyTest, "RubyTester Callback\n"); + debugPrint(); + + if (m_status == TesterStatus_Action_Pending) { + DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n", + (m_value + m_store_count), data->getByte(0)); + // Perform store one byte at a time + data->setByte(0, (m_value + m_store_count)); + m_store_count++; + if (m_store_count == CHECK_SIZE) { + m_status = TesterStatus_Ready; + } else { + m_status = TesterStatus_Idle; + } + DPRINTF(RubyTest, "Action callback return data now %d\n", + data->getByte(0)); + } else if (m_status == TesterStatus_Check_Pending) { + DPRINTF(RubyTest, "Check callback\n"); + // Perform load/check + for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) { + if (uint8(m_value + byte_number) != data->getByte(byte_number)) { + WARN_EXPR(proc); + WARN_EXPR(address); + WARN_EXPR(data); + WARN_EXPR(byte_number); + WARN_EXPR((int)m_value + byte_number); + WARN_EXPR((int)data->getByte(byte_number)); + WARN_EXPR(*this); + WARN_EXPR(g_eventQueue_ptr->getTime()); + ERROR_MSG("Action/check failure"); + } + } + DPRINTF(RubyTest, "Action/check success\n"); + debugPrint(); + + // successful check complete, increment complete + m_tester_ptr->incrementCheckCompletions(); + + m_status = TesterStatus_Idle; + pickValue(); + } else { - m_status = TesterStatus_Idle; - } - DPRINTF(RubyTest, - "Action callback return data now %d\n", - data->getByte(0)); - } else if (m_status == TesterStatus_Check_Pending) { - DPRINTF(RubyTest, "Check callback\n"); - // Perform load/check - for(int byte_number=0; byte_number<CHECK_SIZE; byte_number++) { - if (uint8(m_value+byte_number) != data->getByte(byte_number)) { + WARN_EXPR(*this); WARN_EXPR(proc); - WARN_EXPR(address); WARN_EXPR(data); - WARN_EXPR(byte_number); - WARN_EXPR((int)m_value+byte_number); - WARN_EXPR((int)data->getByte(byte_number)); - WARN_EXPR(*this); + WARN_EXPR(m_status); WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Action/check failure"); - } - } - DPRINTF(RubyTest, "Action/check success\n"); - debugPrint(); - - // successful check complete, increment complete - m_tester_ptr->incrementCheckCompletions(); - - m_status = TesterStatus_Idle; - pickValue(); + ERROR_MSG("Unexpected TesterStatus"); + } - } else { - WARN_EXPR(*this); - WARN_EXPR(proc); - WARN_EXPR(data); - WARN_EXPR(m_status); - WARN_EXPR(g_eventQueue_ptr->getTime()); - ERROR_MSG("Unexpected TesterStatus"); - } - - DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc, getAddress().getLineAddress()); - DPRINTF(RubyTest, "Callback done\n"); - debugPrint(); + DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc, + getAddress().getLineAddress()); + DPRINTF(RubyTest, "Callback done\n"); + debugPrint(); } -void Check::changeAddress(const Address& address) +void +Check::changeAddress(const Address& address) { - assert((m_status == TesterStatus_Idle) || (m_status == TesterStatus_Ready)); - m_status = TesterStatus_Idle; - m_address = address; - m_store_count = 0; + assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready); + m_status = TesterStatus_Idle; + m_address = address; + m_store_count = 0; } -void Check::pickValue() +void +Check::pickValue() { - assert(m_status == TesterStatus_Idle); - m_status = TesterStatus_Idle; - m_value = random() & 0xff; // One byte - m_store_count = 0; + assert(m_status == TesterStatus_Idle); + m_status = TesterStatus_Idle; + m_value = random() & 0xff; // One byte + m_store_count = 0; } -void Check::pickInitiatingNode() +void +Check::pickInitiatingNode() { - assert((m_status == TesterStatus_Idle) || (m_status == TesterStatus_Ready)); - m_status = TesterStatus_Idle; - m_initiatingNode = (random() % m_num_cpu_sequencers); - DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode); - m_store_count = 0; + assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready); + m_status = TesterStatus_Idle; + m_initiatingNode = (random() % m_num_cpu_sequencers); + DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode); + m_store_count = 0; } -void Check::print(ostream& out) const +void +Check::print(ostream& out) const { - out << "[" - << m_address << ", value: " - << (int) m_value << ", status: " - << m_status << ", initiating node: " - << m_initiatingNode << ", store_count: " - << m_store_count - << "]" << flush; + out << "[" + << m_address << ", value: " + << (int)m_value << ", status: " + << m_status << ", initiating node: " + << m_initiatingNode << ", store_count: " + << m_store_count + << "]" << flush; } -void Check::debugPrint() +void +Check::debugPrint() { - DPRINTF(RubyTest, - "[0x%x, value: %d, status: %s, initiating node: %d, store_count: %d]\n", - m_address.getAddress(), - (int)m_value, - (TesterStatus_to_string(m_status)).c_str(), - m_initiatingNode, - m_store_count); + DPRINTF(RubyTest, + "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n", + m_address.getAddress(), (int)m_value, + TesterStatus_to_string(m_status).c_str(), + m_initiatingNode, m_store_count); } diff --git a/src/cpu/rubytest/Check.hh b/src/cpu/rubytest/Check.hh index ce42ed376..5f621a018 100644 --- a/src/cpu/rubytest/Check.hh +++ b/src/cpu/rubytest/Check.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,78 +27,61 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CHECK_H -#define CHECK_H +#ifndef __CPU_RUBYTEST_CHECK_HH__ +#define __CPU_RUBYTEST_CHECK_HH__ -#include "mem/ruby/common/Global.hh" +#include "cpu/rubytest/RubyTester.hh" +#include "mem/protocol/AccessModeType.hh" +#include "mem/protocol/TesterStatus.hh" #include "mem/ruby/common/Address.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/system/NodeID.hh" -#include "mem/protocol/TesterStatus.hh" -#include "mem/protocol/AccessModeType.hh" -#include "cpu/rubytest/RubyTester.hh" + class SubBlock; const int CHECK_SIZE_BITS = 2; -const int CHECK_SIZE = (1<<CHECK_SIZE_BITS); +const int CHECK_SIZE = (1 << CHECK_SIZE_BITS); -class Check { -public: - // Constructors - Check(const Address& address, - const Address& pc, - int _num_cpu_sequencer, - RubyTester* _tester); +class Check +{ + public: + Check(const Address& address, const Address& pc, int _num_cpu_sequencer, + RubyTester* _tester); - // Default Destructor - //~Check(); - - // Public Methods + void initiate(); // Does Action or Check or nether + void performCallback(NodeID proc, SubBlock* data); + const Address& getAddress() { return m_address; } + void changeAddress(const Address& address); - void initiate(); // Does Action or Check or nether - void performCallback(NodeID proc, SubBlock* data); - const Address& getAddress() { return m_address; } - void changeAddress(const Address& address); + void print(ostream& out) const; - void print(ostream& out) const; -private: - // Private Methods - void initiatePrefetch(); - void initiateAction(); - void initiateCheck(); + private: + void initiatePrefetch(); + void initiateAction(); + void initiateCheck(); - void pickValue(); - void pickInitiatingNode(); + void pickValue(); + void pickInitiatingNode(); - void debugPrint(); + void debugPrint(); - // Using default copy constructor and assignment operator - // Check(const Check& obj); - // Check& operator=(const Check& obj); - - // Data Members (m_ prefix) - TesterStatus m_status; - uint8 m_value; - int m_store_count; - NodeID m_initiatingNode; - Address m_address; - Address m_pc; - AccessModeType m_access_mode; - int m_num_cpu_sequencers; - RubyTester* m_tester_ptr; + TesterStatus m_status; + uint8 m_value; + int m_store_count; + NodeID m_initiatingNode; + Address m_address; + Address m_pc; + AccessModeType m_access_mode; + int m_num_cpu_sequencers; + RubyTester* m_tester_ptr; }; -// Output operator declaration -ostream& operator<<(ostream& out, const Check& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const Check& obj) +inline ostream& +operator<<(ostream& out, const Check& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //CHECK_H +#endif // __CPU_RUBYTEST_CHECK_HH__ diff --git a/src/cpu/rubytest/CheckTable.cc b/src/cpu/rubytest/CheckTable.cc index a589fbdd3..875b4b31e 100644 --- a/src/cpu/rubytest/CheckTable.cc +++ b/src/cpu/rubytest/CheckTable.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,103 +27,105 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#include "cpu/rubytest/Check.hh" #include "cpu/rubytest/CheckTable.hh" #include "cpu/rubytest/CheckTable.hh" -#include "cpu/rubytest/Check.hh" #include "mem/gems_common/Map.hh" CheckTable::CheckTable(int _num_cpu_sequencers, RubyTester* _tester) - : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester) + : m_num_cpu_sequencers(_num_cpu_sequencers), m_tester_ptr(_tester) { - m_lookup_map_ptr = new Map<Address, Check*>; - physical_address_t physical = 0; - Address address; - - const int size1 = 32; - const int size2 = 100; - - // The first set is to get some false sharing - physical = 1000; - for (int i=0; i<size1; i++) { - // Setup linear addresses - address.setAddress(physical); - addCheck(address); - physical += CHECK_SIZE; - } + m_lookup_map_ptr = new Map<Address, Check*>; + physical_address_t physical = 0; + Address address; + + const int size1 = 32; + const int size2 = 100; + + // The first set is to get some false sharing + physical = 1000; + for (int i = 0; i < size1; i++) { + // Setup linear addresses + address.setAddress(physical); + addCheck(address); + physical += CHECK_SIZE; + } - // The next two sets are to get some limited false sharing and cache conflicts - physical = 1000; - for (int i=0; i<size2; i++) { - // Setup linear addresses - address.setAddress(physical); - addCheck(address); - physical += 256; - } + // The next two sets are to get some limited false sharing and + // cache conflicts + physical = 1000; + for (int i = 0; i < size2; i++) { + // Setup linear addresses + address.setAddress(physical); + addCheck(address); + physical += 256; + } - physical = 1000 + CHECK_SIZE; - for (int i=0; i<size2; i++) { - // Setup linear addresses - address.setAddress(physical); - addCheck(address); - physical += 256; - } + physical = 1000 + CHECK_SIZE; + for (int i = 0; i < size2; i++) { + // Setup linear addresses + address.setAddress(physical); + addCheck(address); + physical += 256; + } } CheckTable::~CheckTable() { - int size = m_check_vector.size(); - for (int i=0; i<size; i++) { - delete m_check_vector[i]; - } - delete m_lookup_map_ptr; + int size = m_check_vector.size(); + for (int i = 0; i < size; i++) + delete m_check_vector[i]; + delete m_lookup_map_ptr; } -void CheckTable::addCheck(const Address& address) +void +CheckTable::addCheck(const Address& address) { - if (log_int(CHECK_SIZE) != 0) { - if (address.bitSelect(0,CHECK_SIZE_BITS-1) != 0) { - ERROR_MSG("Check not aligned"); + if (log_int(CHECK_SIZE) != 0) { + if (address.bitSelect(0, CHECK_SIZE_BITS - 1) != 0) { + ERROR_MSG("Check not aligned"); + } } - } - for (int i=0; i<CHECK_SIZE; i++) { - if (m_lookup_map_ptr->exist(Address(address.getAddress()+i))) { - // A mapping for this byte already existed, discard the entire check - return; + for (int i = 0; i < CHECK_SIZE; i++) { + if (m_lookup_map_ptr->exist(Address(address.getAddress()+i))) { + // A mapping for this byte already existed, discard the + // entire check + return; + } } - } - Check* check_ptr = new Check(address, - Address(100+m_check_vector.size()), - m_num_cpu_sequencers, - m_tester_ptr); - for (int i=0; i<CHECK_SIZE; i++) { - // Insert it once per byte - m_lookup_map_ptr->add(Address(address.getAddress()+i), check_ptr); - } - m_check_vector.insertAtBottom(check_ptr); + Check* check_ptr = new Check(address, Address(100 + m_check_vector.size()), + m_num_cpu_sequencers, m_tester_ptr); + for (int i = 0; i < CHECK_SIZE; i++) { + // Insert it once per byte + m_lookup_map_ptr->add(Address(address.getAddress() + i), check_ptr); + } + m_check_vector.insertAtBottom(check_ptr); } -Check* CheckTable::getRandomCheck() +Check* +CheckTable::getRandomCheck() { - return m_check_vector[random() % m_check_vector.size()]; + return m_check_vector[random() % m_check_vector.size()]; } -Check* CheckTable::getCheck(const Address& address) +Check* +CheckTable::getCheck(const Address& address) { - DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address"); - DEBUG_EXPR(TESTER_COMP, MedPrio, address); - - if (m_lookup_map_ptr->exist(address)) { - Check* check = m_lookup_map_ptr->lookup(address); - assert(check != NULL); - return check; - } else { - return NULL; - } + DEBUG_MSG(TESTER_COMP, MedPrio, "Looking for check by address"); + DEBUG_EXPR(TESTER_COMP, MedPrio, address); + + if (m_lookup_map_ptr->exist(address)) { + Check* check = m_lookup_map_ptr->lookup(address); + assert(check != NULL); + return check; + } else { + return NULL; + } } -void CheckTable::print(ostream& out) const +void +CheckTable::print(ostream& out) const { } diff --git a/src/cpu/rubytest/CheckTable.hh b/src/cpu/rubytest/CheckTable.hh index 8b05e6541..a22fa7f73 100644 --- a/src/cpu/rubytest/CheckTable.hh +++ b/src/cpu/rubytest/CheckTable.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,66 +27,55 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CHECKTABLE_H -#define CHECKTABLE_H +#ifndef __CPU_RUBYTEST_CHECKTABLE_HH__ +#define __CPU_RUBYTEST_CHECKTABLE_HH__ #include <iostream> -#include "mem/ruby/common/Global.hh" #include "mem/gems_common/Vector.hh" +#include "mem/ruby/common/Global.hh" class Address; class Check; class RubyTester; template <class KEY_TYPE, class VALUE_TYPE> class Map; -class CheckTable { -public: - // Constructors - CheckTable(int _num_cpu_sequencers, RubyTester* _tester); - - // Destructor - ~CheckTable(); - - // Public Methods +class CheckTable +{ + public: + CheckTable(int _num_cpu_sequencers, RubyTester* _tester); + ~CheckTable(); - Check* getRandomCheck(); - Check* getCheck(const Address& address); + Check* getRandomCheck(); + Check* getCheck(const Address& address); - // bool isPresent(const Address& address) const; - // void removeCheckFromTable(const Address& address); - // bool isTableFull() const; - // Need a method to select a check or retrieve a check + // bool isPresent(const Address& address) const; + // void removeCheckFromTable(const Address& address); + // bool isTableFull() const; + // Need a method to select a check or retrieve a check - void print(std::ostream& out) const; -private: - // Private Methods - void addCheck(const Address& address); + void print(std::ostream& out) const; - // Private copy constructor and assignment operator - CheckTable(const CheckTable& obj); - CheckTable& operator=(const CheckTable& obj); - - // Data Members (m_ prefix) - Vector<Check*> m_check_vector; - Map<Address, Check*>* m_lookup_map_ptr; + private: + void addCheck(const Address& address); - int m_num_cpu_sequencers; - RubyTester* m_tester_ptr; -}; + // Private copy constructor and assignment operator + CheckTable(const CheckTable& obj); + CheckTable& operator=(const CheckTable& obj); -// Output operator declaration -std::ostream& operator<<(std::ostream& out, const CheckTable& obj); + Vector<Check*> m_check_vector; + Map<Address, Check*>* m_lookup_map_ptr; -// ******************* Definitions ******************* + int m_num_cpu_sequencers; + RubyTester* m_tester_ptr; +}; -// Output operator definition -extern inline -std::ostream& operator<<(std::ostream& out, const CheckTable& obj) +inline std::ostream& +operator<<(std::ostream& out, const CheckTable& obj) { - obj.print(out); - out << std::flush; - return out; + obj.print(out); + out << std::flush; + return out; } -#endif //CHECKTABLE_H +#endif // __CPU_RUBYTEST_CHECKTABLE_HH__ diff --git a/src/cpu/rubytest/RubyTester.cc b/src/cpu/rubytest/RubyTester.cc index 547b0eb17..b2af22a6e 100644 --- a/src/cpu/rubytest/RubyTester.cc +++ b/src/cpu/rubytest/RubyTester.cc @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,54 +27,51 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "mem/ruby/common/Global.hh" -#include "mem/ruby/system/System.hh" +#include "cpu/rubytest/Check.hh" #include "cpu/rubytest/RubyTester.hh" -#include "mem/ruby/eventqueue/RubyEventQueue.hh" +#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/SubBlock.hh" -#include "cpu/rubytest/Check.hh" +#include "mem/ruby/eventqueue/RubyEventQueue.hh" +#include "mem/ruby/system/System.hh" #include "sim/sim_exit.hh" RubyTester::RubyTester(const Params *p) - : MemObject(p), - checkStartEvent(this), + : MemObject(p), checkStartEvent(this), m_checks_to_complete(p->checks_to_complete), m_deadlock_threshold(p->deadlock_threshold), m_wakeup_frequency(p->wakeup_frequency) { - m_checks_completed = 0; - - // add the check start event to the event queue - schedule(checkStartEvent, 1); + m_checks_completed = 0; + // add the check start event to the event queue + schedule(checkStartEvent, 1); } RubyTester::~RubyTester() { - delete m_checkTable_ptr; - for (int i = 0; i < ports.size(); i++) { - delete ports[i]; - } + delete m_checkTable_ptr; + for (int i = 0; i < ports.size(); i++) + delete ports[i]; } -void RubyTester::init() +void +RubyTester::init() { - assert(ports.size() > 0); + assert(ports.size() > 0); - m_last_progress_vector.setSize(ports.size()); - for (int i = 0; i < m_last_progress_vector.size(); i++) { - m_last_progress_vector[i] = 0; - } + m_last_progress_vector.setSize(ports.size()); + for (int i = 0; i < m_last_progress_vector.size(); i++) { + m_last_progress_vector[i] = 0; + } - m_num_cpu_sequencers = ports.size(); + m_num_cpu_sequencers = ports.size(); - m_checkTable_ptr = new CheckTable(m_num_cpu_sequencers, this); + m_checkTable_ptr = new CheckTable(m_num_cpu_sequencers, this); } Port * RubyTester::getPort(const std::string &if_name, int idx) { - if (if_name != "cpuPort") { panic("RubyTester::getPort: unknown port %s requested", if_name); } @@ -97,102 +93,99 @@ RubyTester::getPort(const std::string &if_name, int idx) Tick RubyTester::CpuPort::recvAtomic(PacketPtr pkt) { - panic("RubyTester::CpuPort::recvAtomic() not implemented!\n"); - return 0; + panic("RubyTester::CpuPort::recvAtomic() not implemented!\n"); + return 0; } bool RubyTester::CpuPort::recvTiming(PacketPtr pkt) { - // - // retrieve the subblock and call hitCallback - // - RubyTester::SenderState* senderState = - safe_cast<RubyTester::SenderState*>(pkt->senderState); - SubBlock* subblock = senderState->subBlock; - assert(subblock != NULL); - - // pop the sender state from the packet - pkt->senderState = senderState->saved; - - tester->hitCallback(idx, subblock); - - // - // Now that the tester has completed, delete the senderState - // (includes sublock) and the packet, then return - // - delete senderState; - delete pkt->req; - delete pkt; - return true; + // retrieve the subblock and call hitCallback + RubyTester::SenderState* senderState = + safe_cast<RubyTester::SenderState*>(pkt->senderState); + SubBlock* subblock = senderState->subBlock; + assert(subblock != NULL); + + // pop the sender state from the packet + pkt->senderState = senderState->saved; + + tester->hitCallback(idx, subblock); + + // Now that the tester has completed, delete the senderState + // (includes sublock) and the packet, then return + delete senderState; + delete pkt->req; + delete pkt; + return true; } -Port* +Port* RubyTester::getCpuPort(int idx) { - assert(idx >= 0 && idx < ports.size()); + assert(idx >= 0 && idx < ports.size()); - return ports[idx]; + return ports[idx]; } -void RubyTester::hitCallback(NodeID proc, SubBlock* data) +void +RubyTester::hitCallback(NodeID proc, SubBlock* data) { - // Mark that we made progress - m_last_progress_vector[proc] = g_eventQueue_ptr->getTime(); - - DPRINTF(RubyTest, "completed request for proc: %d\n", proc); - DPRINTF(RubyTest, - "addr: 0x%x, size: %d, data: ", - data->getAddress(), - data->getSize()); - for (int byte = 0; byte < data->getSize(); byte++) { - DPRINTF(RubyTest, "%d", data->getByte(byte)); - } - DPRINTF(RubyTest, "\n"); - - // - // This tells us our store has 'completed' or for a load gives us - // back the data to make the check - // - Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress()); - assert(check_ptr != NULL); - check_ptr->performCallback(proc, data); -} + // Mark that we made progress + m_last_progress_vector[proc] = g_eventQueue_ptr->getTime(); + + DPRINTF(RubyTest, "completed request for proc: %d\n", proc); + DPRINTF(RubyTest, "addr: 0x%x, size: %d, data: ", + data->getAddress(), data->getSize()); + for (int byte = 0; byte < data->getSize(); byte++) { + DPRINTF(RubyTest, "%d", data->getByte(byte)); + } + DPRINTF(RubyTest, "\n"); -void RubyTester::wakeup() -{ - if (m_checks_completed < m_checks_to_complete) { - // Try to perform an action or check - Check* check_ptr = m_checkTable_ptr->getRandomCheck(); + // This tells us our store has 'completed' or for a load gives us + // back the data to make the check + Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress()); assert(check_ptr != NULL); - check_ptr->initiate(); - - checkForDeadlock(); - - schedule(checkStartEvent, curTick + m_wakeup_frequency); - } else { - exitSimLoop("Ruby Tester completed"); - } + check_ptr->performCallback(proc, data); +} + +void +RubyTester::wakeup() +{ + if (m_checks_completed < m_checks_to_complete) { + // Try to perform an action or check + Check* check_ptr = m_checkTable_ptr->getRandomCheck(); + assert(check_ptr != NULL); + check_ptr->initiate(); + + checkForDeadlock(); + + schedule(checkStartEvent, curTick + m_wakeup_frequency); + } else { + exitSimLoop("Ruby Tester completed"); + } } -void RubyTester::checkForDeadlock() +void +RubyTester::checkForDeadlock() { - int size = m_last_progress_vector.size(); - Time current_time = g_eventQueue_ptr->getTime(); - for (int processor = 0; processor < size; processor++) { - if ((current_time - m_last_progress_vector[processor]) > m_deadlock_threshold) { - WARN_EXPR(current_time); - WARN_EXPR(m_last_progress_vector[processor]); - WARN_EXPR(current_time - m_last_progress_vector[processor]); - WARN_EXPR(processor); - ERROR_MSG("Deadlock detected."); + int size = m_last_progress_vector.size(); + Time current_time = g_eventQueue_ptr->getTime(); + for (int processor = 0; processor < size; processor++) { + if ((current_time - m_last_progress_vector[processor]) > + m_deadlock_threshold) { + WARN_EXPR(current_time); + WARN_EXPR(m_last_progress_vector[processor]); + WARN_EXPR(current_time - m_last_progress_vector[processor]); + WARN_EXPR(processor); + ERROR_MSG("Deadlock detected."); + } } - } } -void RubyTester::print(ostream& out) const +void +RubyTester::print(ostream& out) const { - out << "[RubyTester]" << endl; + out << "[RubyTester]" << endl; } RubyTester * diff --git a/src/cpu/rubytest/RubyTester.hh b/src/cpu/rubytest/RubyTester.hh index f1ed7e34e..f4cf4a04d 100644 --- a/src/cpu/rubytest/RubyTester.hh +++ b/src/cpu/rubytest/RubyTester.hh @@ -1,4 +1,3 @@ - /* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * Copyright (c) 2009 Advanced Micro Devices, Inc. @@ -28,135 +27,118 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RUBY_TESTER_H -#define RUBY_TESTER_H +#ifndef __CPU_RUBYTEST_RUBYTESTER_HH__ +#define __CPU_RUBYTEST_RUBYTESTER_HH__ -#include "mem/ruby/common/Global.hh" -#include "mem/mem_object.hh" #include "cpu/rubytest/CheckTable.hh" -#include "mem/ruby/system/RubyPort.hh" -#include "mem/ruby/common/SubBlock.hh" -#include "mem/ruby/common/DataBlock.hh" +#include "mem/mem_object.hh" #include "mem/packet.hh" +#include "mem/ruby/common/DataBlock.hh" +#include "mem/ruby/common/Global.hh" +#include "mem/ruby/common/SubBlock.hh" +#include "mem/ruby/system/RubyPort.hh" #include "params/RubyTester.hh" -class RubyTester : public MemObject +class RubyTester : public MemObject { + public: + class CpuPort : public SimpleTimingPort + { + private: + RubyTester *tester; + + public: + CpuPort(const std::string &_name, RubyTester *_tester, int _idx) + : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx) + {} - public: + int idx; - class CpuPort : public SimpleTimingPort - { - RubyTester *tester; + protected: + virtual bool recvTiming(PacketPtr pkt); + virtual Tick recvAtomic(PacketPtr pkt); + }; - public: - - CpuPort(const std::string &_name, - RubyTester *_tester, - int _idx) - : SimpleTimingPort(_name, _tester), tester(_tester), idx(_idx) - {} + struct SenderState : public Packet::SenderState + { + SubBlock* subBlock; + Packet::SenderState *saved; - int idx; - - protected: - - virtual bool recvTiming(PacketPtr pkt); + SenderState(Address addr, int size, + Packet::SenderState *sender_state = NULL) + : saved(sender_state) + { + subBlock = new SubBlock(addr, size); + } - virtual Tick recvAtomic(PacketPtr pkt); - - }; + ~SenderState() + { + delete subBlock; + } + }; - struct SenderState : public Packet::SenderState - { - SubBlock* subBlock; - Packet::SenderState *saved; - - SenderState(Address addr, - int size, - Packet::SenderState *sender_state = NULL) - : saved(sender_state) - {subBlock = new SubBlock(addr, size);} + typedef RubyTesterParams Params; + RubyTester(const Params *p); + ~RubyTester(); - ~SenderState() {delete subBlock;} - }; + virtual Port *getPort(const std::string &if_name, int idx = -1); - typedef RubyTesterParams Params; - // Constructors - RubyTester(const Params *p); + Port* getCpuPort(int idx); - // Destructor - ~RubyTester(); - - // Public Methods - - virtual Port *getPort(const std::string &if_name, int idx = -1); + virtual void init(); - Port* getCpuPort(int idx); + void wakeup(); - void virtual init(); + void incrementCheckCompletions() { m_checks_completed++; } - void wakeup(); + void printStats(ostream& out) const {} + void clearStats() {} + void printConfig(ostream& out) const {} - void incrementCheckCompletions() { m_checks_completed++; } + void print(ostream& out) const; - void printStats(ostream& out) const {} - void clearStats() {} - void printConfig(ostream& out) const {} + protected: + class CheckStartEvent : public Event + { + private: + RubyTester *tester; - void print(ostream& out) const; + public: + CheckStartEvent(RubyTester *_tester) + : Event(CPU_Tick_Pri), tester(_tester) + {} + void process() { tester->wakeup(); } + virtual const char *description() const { return "RubyTester tick"; } + }; + + CheckStartEvent checkStartEvent; - protected: - class CheckStartEvent : public Event - { private: - RubyTester *tester; - - public: - CheckStartEvent(RubyTester *_tester) : Event(CPU_Tick_Pri), tester(_tester) {} - void process() { tester->wakeup(); } - virtual const char *description() const { return "RubyTester tick"; } - }; - - CheckStartEvent checkStartEvent; - - - private: - // Private Methods - - void hitCallback(NodeID proc, SubBlock* data); - - void checkForDeadlock(); - - // Private copy constructor and assignment operator - RubyTester(const RubyTester& obj); - RubyTester& operator=(const RubyTester& obj); - - // Data Members (m_ prefix) - - CheckTable* m_checkTable_ptr; - Vector<Time> m_last_progress_vector; - - uint64 m_checks_completed; - std::vector<CpuPort*> ports; - uint64 m_checks_to_complete; - int m_deadlock_threshold; - int m_num_cpu_sequencers; - int m_wakeup_frequency; -}; + void hitCallback(NodeID proc, SubBlock* data); + + void checkForDeadlock(); -// Output operator declaration -ostream& operator<<(ostream& out, const RubyTester& obj); + // Private copy constructor and assignment operator + RubyTester(const RubyTester& obj); + RubyTester& operator=(const RubyTester& obj); -// ******************* Definitions ******************* + CheckTable* m_checkTable_ptr; + Vector<Time> m_last_progress_vector; + + uint64 m_checks_completed; + std::vector<CpuPort*> ports; + uint64 m_checks_to_complete; + int m_deadlock_threshold; + int m_num_cpu_sequencers; + int m_wakeup_frequency; +}; -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const RubyTester& obj) +inline ostream& +operator<<(ostream& out, const RubyTester& obj) { - obj.print(out); - out << flush; - return out; + obj.print(out); + out << flush; + return out; } -#endif //RUBY_TESTER_H +#endif // __CPU_RUBYTEST_RUBYTESTER_HH__ |