RubyTester.cc (11017:6ec228f6c143) | RubyTester.cc (11266:452e10b868ea) |
---|---|
1/* 2 * Copyright (c) 2012-2013 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 44 unchanged lines hidden (view full) --- 53 m_checkTable_ptr(nullptr), 54 m_num_cpus(p->num_cpus), 55 m_checks_to_complete(p->checks_to_complete), 56 m_deadlock_threshold(p->deadlock_threshold), 57 m_num_writers(0), 58 m_num_readers(0), 59 m_wakeup_frequency(p->wakeup_frequency), 60 m_check_flush(p->check_flush), | 1/* 2 * Copyright (c) 2012-2013 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 44 unchanged lines hidden (view full) --- 53 m_checkTable_ptr(nullptr), 54 m_num_cpus(p->num_cpus), 55 m_checks_to_complete(p->checks_to_complete), 56 m_deadlock_threshold(p->deadlock_threshold), 57 m_num_writers(0), 58 m_num_readers(0), 59 m_wakeup_frequency(p->wakeup_frequency), 60 m_check_flush(p->check_flush), |
61 m_num_inst_ports(p->port_cpuInstPort_connection_count) | 61 m_num_inst_only_ports(p->port_cpuInstPort_connection_count), 62 m_num_inst_data_ports(p->port_cpuInstDataPort_connection_count) |
62{ 63 m_checks_completed = 0; 64 65 // 66 // Create the requested inst and data ports and place them on the 67 // appropriate read and write port lists. The reason for the subtle 68 // difference between inst and data ports vs. read and write ports is 69 // from the tester's perspective, it only needs to know whether a port 70 // supports reads (checks) or writes (actions). Meanwhile, the protocol 71 // controllers have data ports (support read and writes) or inst ports 72 // (support only reads). 73 // Note: the inst ports are the lowest elements of the readPort vector, 74 // then the data ports are added to the readPort vector 75 // | 63{ 64 m_checks_completed = 0; 65 66 // 67 // Create the requested inst and data ports and place them on the 68 // appropriate read and write port lists. The reason for the subtle 69 // difference between inst and data ports vs. read and write ports is 70 // from the tester's perspective, it only needs to know whether a port 71 // supports reads (checks) or writes (actions). Meanwhile, the protocol 72 // controllers have data ports (support read and writes) or inst ports 73 // (support only reads). 74 // Note: the inst ports are the lowest elements of the readPort vector, 75 // then the data ports are added to the readPort vector 76 // |
77 int idx = 0; |
|
76 for (int i = 0; i < p->port_cpuInstPort_connection_count; ++i) { 77 readPorts.push_back(new CpuPort(csprintf("%s-instPort%d", name(), i), | 78 for (int i = 0; i < p->port_cpuInstPort_connection_count; ++i) { 79 readPorts.push_back(new CpuPort(csprintf("%s-instPort%d", name(), i), |
78 this, i)); | 80 this, i, idx)); 81 idx++; |
79 } | 82 } |
83 for (int i = 0; i < p->port_cpuInstDataPort_connection_count; ++i) { 84 CpuPort *port = new CpuPort(csprintf("%s-instDataPort%d", name(), i), 85 this, i, idx); 86 readPorts.push_back(port); 87 writePorts.push_back(port); 88 idx++; 89 } |
|
80 for (int i = 0; i < p->port_cpuDataPort_connection_count; ++i) { 81 CpuPort *port = new CpuPort(csprintf("%s-dataPort%d", name(), i), | 90 for (int i = 0; i < p->port_cpuDataPort_connection_count; ++i) { 91 CpuPort *port = new CpuPort(csprintf("%s-dataPort%d", name(), i), |
82 this, i); | 92 this, i, idx); |
83 readPorts.push_back(port); 84 writePorts.push_back(port); | 93 readPorts.push_back(port); 94 writePorts.push_back(port); |
95 idx++; |
|
85 } 86 87 // add the check start event to the event queue 88 schedule(checkStartEvent, 1); 89} 90 91RubyTester::~RubyTester() 92{ --- 10 unchanged lines hidden (view full) --- 103 104 m_last_progress_vector.resize(m_num_cpus); 105 for (int i = 0; i < m_last_progress_vector.size(); i++) { 106 m_last_progress_vector[i] = Cycles(0); 107 } 108 109 m_num_writers = writePorts.size(); 110 m_num_readers = readPorts.size(); | 96 } 97 98 // add the check start event to the event queue 99 schedule(checkStartEvent, 1); 100} 101 102RubyTester::~RubyTester() 103{ --- 10 unchanged lines hidden (view full) --- 114 115 m_last_progress_vector.resize(m_num_cpus); 116 for (int i = 0; i < m_last_progress_vector.size(); i++) { 117 m_last_progress_vector[i] = Cycles(0); 118 } 119 120 m_num_writers = writePorts.size(); 121 m_num_readers = readPorts.size(); |
122 assert(m_num_readers == m_num_cpus); |
|
111 112 m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this); 113} 114 115BaseMasterPort & 116RubyTester::getMasterPort(const std::string &if_name, PortID idx) 117{ | 123 124 m_checkTable_ptr = new CheckTable(m_num_writers, m_num_readers, this); 125} 126 127BaseMasterPort & 128RubyTester::getMasterPort(const std::string &if_name, PortID idx) 129{ |
118 if (if_name != "cpuInstPort" && if_name != "cpuDataPort") { | 130 if (if_name != "cpuInstPort" && if_name != "cpuInstDataPort" && 131 if_name != "cpuDataPort") { |
119 // pass it along to our super class 120 return MemObject::getMasterPort(if_name, idx); 121 } else { 122 if (if_name == "cpuInstPort") { | 132 // pass it along to our super class 133 return MemObject::getMasterPort(if_name, idx); 134 } else { 135 if (if_name == "cpuInstPort") { |
123 if (idx > m_num_inst_ports) { 124 panic("RubyTester::getMasterPort: unknown inst port idx %d\n", | 136 if (idx > m_num_inst_only_ports) { 137 panic("RubyTester::getMasterPort: unknown inst port %d\n", |
125 idx); 126 } 127 // | 138 idx); 139 } 140 // |
128 // inst ports directly map to the lowest readPort elements | 141 // inst ports map to the lowest readPort elements |
129 // 130 return *readPorts[idx]; | 142 // 143 return *readPorts[idx]; |
144 } else if (if_name == "cpuInstDataPort") { 145 if (idx > m_num_inst_data_ports) { 146 panic("RubyTester::getMasterPort: unknown inst+data port %d\n", 147 idx); 148 } 149 int read_idx = idx + m_num_inst_only_ports; 150 // 151 // inst+data ports map to the next readPort elements 152 // 153 return *readPorts[read_idx]; |
|
131 } else { 132 assert(if_name == "cpuDataPort"); 133 // | 154 } else { 155 assert(if_name == "cpuDataPort"); 156 // |
134 // add the inst port offset to translate to the correct read port 135 // index | 157 // data only ports map to the final readPort elements |
136 // | 158 // |
137 int read_idx = idx + m_num_inst_ports; 138 if (read_idx >= static_cast<PortID>(readPorts.size())) { 139 panic("RubyTester::getMasterPort: unknown data port idx %d\n", | 159 if (idx > (static_cast<int>(readPorts.size()) - 160 (m_num_inst_only_ports + m_num_inst_data_ports))) { 161 panic("RubyTester::getMasterPort: unknown data port %d\n", |
140 idx); 141 } | 162 idx); 163 } |
164 int read_idx = idx + m_num_inst_only_ports + m_num_inst_data_ports; |
|
142 return *readPorts[read_idx]; 143 } | 165 return *readPorts[read_idx]; 166 } |
167 // Note: currently the Ruby Tester does not support write only ports 168 // but that could easily be added here |
|
144 } 145} 146 147bool 148RubyTester::CpuPort::recvTimingResp(PacketPtr pkt) 149{ 150 // retrieve the subblock and call hitCallback 151 RubyTester::SenderState* senderState = 152 safe_cast<RubyTester::SenderState*>(pkt->senderState); 153 SubBlock& subblock = senderState->subBlock; 154 | 169 } 170} 171 172bool 173RubyTester::CpuPort::recvTimingResp(PacketPtr pkt) 174{ 175 // retrieve the subblock and call hitCallback 176 RubyTester::SenderState* senderState = 177 safe_cast<RubyTester::SenderState*>(pkt->senderState); 178 SubBlock& subblock = senderState->subBlock; 179 |
155 tester->hitCallback(id, &subblock); | 180 tester->hitCallback(globalIdx, &subblock); |
156 157 // Now that the tester has completed, delete the senderState 158 // (includes sublock) and the packet, then return 159 delete pkt->senderState; 160 delete pkt->req; 161 delete pkt; 162 return true; 163} 164 165bool | 181 182 // Now that the tester has completed, delete the senderState 183 // (includes sublock) and the packet, then return 184 delete pkt->senderState; 185 delete pkt->req; 186 delete pkt; 187 return true; 188} 189 190bool |
166RubyTester::isInstReadableCpuPort(int idx) | 191RubyTester::isInstOnlyCpuPort(int idx) |
167{ | 192{ |
168 return idx < m_num_inst_ports; | 193 return idx < m_num_inst_only_ports; |
169} 170 | 194} 195 |
196bool 197RubyTester::isInstDataCpuPort(int idx) 198{ 199 return ((idx >= m_num_inst_only_ports) && 200 (idx < (m_num_inst_only_ports + m_num_inst_data_ports))); 201} 202 |
|
171MasterPort* 172RubyTester::getReadableCpuPort(int idx) 173{ 174 assert(idx >= 0 && idx < readPorts.size()); 175 176 return readPorts[idx]; 177} 178 --- 6 unchanged lines hidden (view full) --- 185} 186 187void 188RubyTester::hitCallback(NodeID proc, SubBlock* data) 189{ 190 // Mark that we made progress 191 m_last_progress_vector[proc] = curCycle(); 192 | 203MasterPort* 204RubyTester::getReadableCpuPort(int idx) 205{ 206 assert(idx >= 0 && idx < readPorts.size()); 207 208 return readPorts[idx]; 209} 210 --- 6 unchanged lines hidden (view full) --- 217} 218 219void 220RubyTester::hitCallback(NodeID proc, SubBlock* data) 221{ 222 // Mark that we made progress 223 m_last_progress_vector[proc] = curCycle(); 224 |
193 DPRINTF(RubyTest, "completed request for proc: %d\n", proc); 194 DPRINTF(RubyTest, "addr: 0x%x, size: %d, data: ", | 225 DPRINTF(RubyTest, "completed request for proc: %d", proc); 226 DPRINTFR(RubyTest, " addr: 0x%x, size: %d, data: ", |
195 data->getAddress(), data->getSize()); 196 for (int byte = 0; byte < data->getSize(); byte++) { | 227 data->getAddress(), data->getSize()); 228 for (int byte = 0; byte < data->getSize(); byte++) { |
197 DPRINTF(RubyTest, "%d", data->getByte(byte)); | 229 DPRINTFR(RubyTest, "%d ", data->getByte(byte)); |
198 } | 230 } |
199 DPRINTF(RubyTest, "\n"); | 231 DPRINTFR(RubyTest, "\n"); |
200 201 // This tells us our store has 'completed' or for a load gives us 202 // back the data to make the check 203 Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress()); 204 assert(check_ptr != NULL); 205 check_ptr->performCallback(proc, data, curCycle()); 206} 207 --- 44 unchanged lines hidden --- | 232 233 // This tells us our store has 'completed' or for a load gives us 234 // back the data to make the check 235 Check* check_ptr = m_checkTable_ptr->getCheck(data->getAddress()); 236 assert(check_ptr != NULL); 237 check_ptr->performCallback(proc, data, curCycle()); 238} 239 --- 44 unchanged lines hidden --- |