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 ---