DirectedGenerator.cc revision 6386
1/* 2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * $Id$ 31 * 32 */ 33 34// This Deterministic Generator generates GETX requests for all nodes in the system 35// The GETX requests are generated one at a time in round-robin fashion 0...1...2...etc. 36 37#include "mem/ruby/tester/DetermGETXGenerator.hh" 38#include "mem/protocol/DetermGETXGeneratorStatus.hh" 39#include "mem/ruby/tester/DeterministicDriver.hh" 40#include "mem/ruby/tester/Tester_Globals.hh" 41#include "mem/ruby/common/Global.hh" 42#include "mem/ruby/tester/SpecifiedGenerator.hh" 43//#include "DMAController.hh" 44#include "mem/ruby/libruby.hh" 45 46 47DetermGETXGenerator::DetermGETXGenerator(NodeID node, DeterministicDriver * driver) 48{ 49 m_status = DetermGETXGeneratorStatus_Thinking; 50 m_last_transition = 0; 51 counter = 0; 52 m_node = node; 53 m_address = Address(1); // initialize to null value 54 m_counter = 0; 55 issued_load = false; 56 parent_driver = driver; 57 // don't know exactly when this node needs to request so just guess randomly 58 parent_driver->eventQueue->scheduleEvent(this, 1+(random() % 200)); 59} 60 61DetermGETXGenerator::~DetermGETXGenerator() 62{ 63} 64 65void DetermGETXGenerator::wakeup() 66{ 67 DEBUG_EXPR(TESTER_COMP, MedPrio, m_node); 68 DEBUG_EXPR(TESTER_COMP, MedPrio, m_status); 69 70 // determine if this node is next for the GETX round robin request 71 if (m_status == DetermGETXGeneratorStatus_Thinking) { 72 if (parent_driver->isStoreReady(m_node)) { 73 if (!issued_load) { 74 pickAddress(); 75 } 76 m_status = DetermGETXGeneratorStatus_Store_Pending; // Store Pending 77 m_last_transition = parent_driver->eventQueue->getTime(); 78 initiateStore(); // GETX 79 } else { // I'll check again later 80 parent_driver->eventQueue->scheduleEvent(this, thinkTime()); 81 } 82 } else { 83 WARN_EXPR(m_status); 84 ERROR_MSG("Invalid status"); 85 } 86 87} 88 89void DetermGETXGenerator::performCallback(NodeID proc, Address address) 90{ 91 assert(proc == m_node); 92 assert(address == m_address); 93 94 DEBUG_EXPR(TESTER_COMP, LowPrio, proc); 95 DEBUG_EXPR(TESTER_COMP, LowPrio, m_status); 96 DEBUG_EXPR(TESTER_COMP, LowPrio, address); 97 98 if (m_status == DetermGETXGeneratorStatus_Store_Pending) { 99 parent_driver->recordStoreLatency(parent_driver->eventQueue->getTime() - m_last_transition); 100 parent_driver->storeCompleted(m_node, address); // advance the store queue 101 102 m_counter++; 103 if (m_counter < parent_driver->m_tester_length) { 104 m_status = DetermGETXGeneratorStatus_Thinking; 105 m_last_transition = parent_driver->eventQueue->getTime(); 106 parent_driver->eventQueue->scheduleEvent(this, waitTime()); 107 } else { 108 parent_driver->reportDone(); 109 m_status = DetermGETXGeneratorStatus_Done; 110 m_last_transition = parent_driver->eventQueue->getTime(); 111 } 112 113 } else { 114 WARN_EXPR(m_status); 115 ERROR_MSG("Invalid status"); 116 } 117} 118 119int DetermGETXGenerator::thinkTime() const 120{ 121 return parent_driver->m_think_time; 122} 123 124int DetermGETXGenerator::waitTime() const 125{ 126 return parent_driver->m_wait_time; 127} 128 129void DetermGETXGenerator::pickAddress() 130{ 131 assert(m_status == DetermGETXGeneratorStatus_Thinking); 132 133 m_address = parent_driver->getNextStoreAddr(m_node); 134} 135 136void DetermGETXGenerator::initiateStore() 137{ 138 DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Store"); 139 uint8_t *write_data = new uint8_t[64]; 140 for(int i=0; i < 64; i++) { 141 write_data[i] = m_node; 142 } 143 144 char name [] = "Sequencer_"; 145 char port_name [13]; 146 sprintf(port_name, "%s%d", name, m_node); 147 int64_t request_id; 148 if (counter%10 == 0) { 149 if (!issued_load) { 150 cerr << m_node << " RMW_Read to address: " << m_address.getAddress() << endl << flush; 151 request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Read, RubyAccessMode_Supervisor)); 152 issued_load = true; 153 } 154 else { 155 cerr << m_node << " RMW_Write to address: " << m_address.getAddress() << endl << flush; 156 request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_RMW_Write, RubyAccessMode_Supervisor)); 157 issued_load = false; 158 counter++; 159 } 160 } 161 else { 162 cerr << m_node << " ST to address: " << m_address.getAddress() << endl << flush; 163 request_id = libruby_issue_request(libruby_get_port_by_name(port_name), RubyRequest(m_address.getAddress(), write_data, 64, 0, RubyRequestType_ST, RubyAccessMode_Supervisor)); 164 counter++; 165 } 166 167 // delete [] write_data; 168 169 ASSERT(parent_driver->requests.find(request_id) == parent_driver->requests.end()); 170 parent_driver->requests.insert(make_pair(request_id, make_pair(m_node, m_address))); 171} 172 173void DetermGETXGenerator::print(ostream& out) const 174{ 175} 176 177