base.cc (12812:8f14879aebe1) base.cc (12844:c934a1338314)
1/*
2 * Copyright (c) 2012-2013, 2016-2018 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Thomas Grass
38 * Andreas Hansson
39 * Sascha Bischoff
40 */
41#include "cpu/testers/traffic_gen/base.hh"
42
43#include <sstream>
44
45#include "base/intmath.hh"
46#include "base/random.hh"
47#include "config/have_protobuf.hh"
48#include "cpu/testers/traffic_gen/base_gen.hh"
49#include "cpu/testers/traffic_gen/dram_gen.hh"
50#include "cpu/testers/traffic_gen/dram_rot_gen.hh"
51#include "cpu/testers/traffic_gen/exit_gen.hh"
52#include "cpu/testers/traffic_gen/idle_gen.hh"
53#include "cpu/testers/traffic_gen/linear_gen.hh"
54#include "cpu/testers/traffic_gen/random_gen.hh"
55#include "debug/Checkpoint.hh"
56#include "debug/TrafficGen.hh"
57#include "params/BaseTrafficGen.hh"
58#include "sim/sim_exit.hh"
59#include "sim/stats.hh"
60#include "sim/system.hh"
61
62#if HAVE_PROTOBUF
63#include "cpu/testers/traffic_gen/trace_gen.hh"
64#endif
65
66
67using namespace std;
68
69BaseTrafficGen::BaseTrafficGen(const BaseTrafficGenParams* p)
70 : MemObject(p),
71 system(p->system),
72 elasticReq(p->elastic_req),
73 progressCheck(p->progress_check),
74 noProgressEvent([this]{ noProgress(); }, name()),
75 nextTransitionTick(0),
76 nextPacketTick(0),
77 port(name() + ".port", *this),
78 retryPkt(NULL),
79 retryPktTick(0),
80 updateEvent([this]{ update(); }, name()),
81 numSuppressed(0),
82 masterID(system->getMasterId(this))
83{
84}
85
86BaseMasterPort&
87BaseTrafficGen::getMasterPort(const string& if_name, PortID idx)
88{
89 if (if_name == "port") {
90 return port;
91 } else {
92 return MemObject::getMasterPort(if_name, idx);
93 }
94}
95
96void
97BaseTrafficGen::init()
98{
99 MemObject::init();
100
101 if (!port.isConnected())
102 fatal("The port of %s is not connected!\n", name());
103}
104
105DrainState
106BaseTrafficGen::drain()
107{
108 if (!updateEvent.scheduled()) {
109 // no event has been scheduled yet (e.g. switched from atomic mode)
110 return DrainState::Drained;
111 }
112
113 if (retryPkt == NULL) {
114 // shut things down
115 nextPacketTick = MaxTick;
116 nextTransitionTick = MaxTick;
117 deschedule(updateEvent);
118 return DrainState::Drained;
119 } else {
120 return DrainState::Draining;
121 }
122}
123
124void
125BaseTrafficGen::serialize(CheckpointOut &cp) const
126{
127 DPRINTF(Checkpoint, "Serializing BaseTrafficGen\n");
128
129 // save ticks of the graph event if it is scheduled
130 Tick nextEvent = updateEvent.scheduled() ? updateEvent.when() : 0;
131
132 DPRINTF(TrafficGen, "Saving nextEvent=%llu\n", nextEvent);
133
134 SERIALIZE_SCALAR(nextEvent);
135
136 SERIALIZE_SCALAR(nextTransitionTick);
137
138 SERIALIZE_SCALAR(nextPacketTick);
139}
140
141void
142BaseTrafficGen::unserialize(CheckpointIn &cp)
143{
144 // restore scheduled events
145 Tick nextEvent;
146 UNSERIALIZE_SCALAR(nextEvent);
147 if (nextEvent != 0)
148 schedule(updateEvent, nextEvent);
149
150 UNSERIALIZE_SCALAR(nextTransitionTick);
151
152 UNSERIALIZE_SCALAR(nextPacketTick);
153}
154
155void
156BaseTrafficGen::update()
157{
158 // shift our progress-tracking event forward
159 reschedule(noProgressEvent, curTick() + progressCheck, true);
160
161 // if we have reached the time for the next state transition, then
162 // perform the transition
163 if (curTick() >= nextTransitionTick) {
164 transition();
165 } else {
166 assert(curTick() >= nextPacketTick);
167 // get the next packet and try to send it
168 PacketPtr pkt = activeGenerator->getNextPacket();
169
170 // suppress packets that are not destined for a memory, such as
171 // device accesses that could be part of a trace
172 if (pkt && system->isMemAddr(pkt->getAddr())) {
173 numPackets++;
174 if (!port.sendTimingReq(pkt)) {
175 retryPkt = pkt;
176 retryPktTick = curTick();
177 }
178 } else if (pkt) {
179 DPRINTF(TrafficGen, "Suppressed packet %s 0x%x\n",
180 pkt->cmdString(), pkt->getAddr());
181
182 ++numSuppressed;
183 if (numSuppressed % 10000)
184 warn("%s suppressed %d packets with non-memory addresses\n",
185 name(), numSuppressed);
186
187 delete pkt;
188 pkt = nullptr;
189 }
190 }
191
192 // if we are waiting for a retry, do not schedule any further
193 // events, in the case of a transition or a successful send, go
194 // ahead and determine when the next update should take place
195 if (retryPkt == NULL) {
196 nextPacketTick = activeGenerator->nextPacketTick(elasticReq, 0);
197 scheduleUpdate();
198 }
199}
200
201void
202BaseTrafficGen::transition()
203{
204 if (activeGenerator)
205 activeGenerator->exit();
206
207 activeGenerator = nextGenerator();
208
209 if (activeGenerator) {
210 const Tick duration = activeGenerator->duration;
211 if (duration != MaxTick && duration != 0) {
212 // we could have been delayed and not transitioned on the
213 // exact tick when we were supposed to (due to back
214 // pressure when sending a packet)
215 nextTransitionTick = curTick() + duration;
216 } else {
217 nextTransitionTick = MaxTick;
218 }
219
220 activeGenerator->enter();
221 nextPacketTick = activeGenerator->nextPacketTick(elasticReq, 0);
222 } else {
223 nextPacketTick = MaxTick;
224 nextTransitionTick = MaxTick;
225 assert(!updateEvent.scheduled());
226 }
227}
228
229void
230BaseTrafficGen::scheduleUpdate()
231{
232 // Has the generator run out of work? In that case, force a
233 // transition if a transition period hasn't been configured.
234 while (activeGenerator &&
235 nextPacketTick == MaxTick && nextTransitionTick == MaxTick) {
236 transition();
237 }
238
239 if (!activeGenerator)
240 return;
241
242 // schedule next update event based on either the next execute
243 // tick or the next transition, which ever comes first
244 const Tick nextEventTick = std::min(nextPacketTick, nextTransitionTick);
245
246 DPRINTF(TrafficGen, "Next event scheduled at %lld\n", nextEventTick);
247
248 // The next transition tick may be in the past if there was a
249 // retry, so ensure that we don't schedule anything in the past.
250 schedule(updateEvent, std::max(curTick(), nextEventTick));
251}
252
253void
254BaseTrafficGen::start()
255{
256 transition();
257 scheduleUpdate();
258}
259
260void
261BaseTrafficGen::recvReqRetry()
262{
263 assert(retryPkt != NULL);
264
265 DPRINTF(TrafficGen, "Received retry\n");
266 numRetries++;
267 // attempt to send the packet, and if we are successful start up
268 // the machinery again
269 if (port.sendTimingReq(retryPkt)) {
270 retryPkt = NULL;
271 // remember how much delay was incurred due to back-pressure
272 // when sending the request, we also use this to derive
273 // the tick for the next packet
274 Tick delay = curTick() - retryPktTick;
275 retryPktTick = 0;
276 retryTicks += delay;
277
278 if (drainState() != DrainState::Draining) {
279 // packet is sent, so find out when the next one is due
280 nextPacketTick = activeGenerator->nextPacketTick(elasticReq,
281 delay);
282 scheduleUpdate();
283 } else {
284 // shut things down
285 nextPacketTick = MaxTick;
286 nextTransitionTick = MaxTick;
287 signalDrainDone();
288 }
289 }
290}
291
292void
293BaseTrafficGen::noProgress()
294{
295 fatal("BaseTrafficGen %s spent %llu ticks without making progress",
296 name(), progressCheck);
297}
298
299void
300BaseTrafficGen::regStats()
301{
302 ClockedObject::regStats();
303
304 // Initialise all the stats
305 using namespace Stats;
306
307 numPackets
308 .name(name() + ".numPackets")
309 .desc("Number of packets generated");
310
311 numRetries
312 .name(name() + ".numRetries")
313 .desc("Number of retries");
314
315 retryTicks
316 .name(name() + ".retryTicks")
317 .desc("Time spent waiting due to back-pressure (ticks)");
318}
319
320std::shared_ptr<BaseGen>
321BaseTrafficGen::createIdle(Tick duration)
322{
1/*
2 * Copyright (c) 2012-2013, 2016-2018 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Thomas Grass
38 * Andreas Hansson
39 * Sascha Bischoff
40 */
41#include "cpu/testers/traffic_gen/base.hh"
42
43#include <sstream>
44
45#include "base/intmath.hh"
46#include "base/random.hh"
47#include "config/have_protobuf.hh"
48#include "cpu/testers/traffic_gen/base_gen.hh"
49#include "cpu/testers/traffic_gen/dram_gen.hh"
50#include "cpu/testers/traffic_gen/dram_rot_gen.hh"
51#include "cpu/testers/traffic_gen/exit_gen.hh"
52#include "cpu/testers/traffic_gen/idle_gen.hh"
53#include "cpu/testers/traffic_gen/linear_gen.hh"
54#include "cpu/testers/traffic_gen/random_gen.hh"
55#include "debug/Checkpoint.hh"
56#include "debug/TrafficGen.hh"
57#include "params/BaseTrafficGen.hh"
58#include "sim/sim_exit.hh"
59#include "sim/stats.hh"
60#include "sim/system.hh"
61
62#if HAVE_PROTOBUF
63#include "cpu/testers/traffic_gen/trace_gen.hh"
64#endif
65
66
67using namespace std;
68
69BaseTrafficGen::BaseTrafficGen(const BaseTrafficGenParams* p)
70 : MemObject(p),
71 system(p->system),
72 elasticReq(p->elastic_req),
73 progressCheck(p->progress_check),
74 noProgressEvent([this]{ noProgress(); }, name()),
75 nextTransitionTick(0),
76 nextPacketTick(0),
77 port(name() + ".port", *this),
78 retryPkt(NULL),
79 retryPktTick(0),
80 updateEvent([this]{ update(); }, name()),
81 numSuppressed(0),
82 masterID(system->getMasterId(this))
83{
84}
85
86BaseMasterPort&
87BaseTrafficGen::getMasterPort(const string& if_name, PortID idx)
88{
89 if (if_name == "port") {
90 return port;
91 } else {
92 return MemObject::getMasterPort(if_name, idx);
93 }
94}
95
96void
97BaseTrafficGen::init()
98{
99 MemObject::init();
100
101 if (!port.isConnected())
102 fatal("The port of %s is not connected!\n", name());
103}
104
105DrainState
106BaseTrafficGen::drain()
107{
108 if (!updateEvent.scheduled()) {
109 // no event has been scheduled yet (e.g. switched from atomic mode)
110 return DrainState::Drained;
111 }
112
113 if (retryPkt == NULL) {
114 // shut things down
115 nextPacketTick = MaxTick;
116 nextTransitionTick = MaxTick;
117 deschedule(updateEvent);
118 return DrainState::Drained;
119 } else {
120 return DrainState::Draining;
121 }
122}
123
124void
125BaseTrafficGen::serialize(CheckpointOut &cp) const
126{
127 DPRINTF(Checkpoint, "Serializing BaseTrafficGen\n");
128
129 // save ticks of the graph event if it is scheduled
130 Tick nextEvent = updateEvent.scheduled() ? updateEvent.when() : 0;
131
132 DPRINTF(TrafficGen, "Saving nextEvent=%llu\n", nextEvent);
133
134 SERIALIZE_SCALAR(nextEvent);
135
136 SERIALIZE_SCALAR(nextTransitionTick);
137
138 SERIALIZE_SCALAR(nextPacketTick);
139}
140
141void
142BaseTrafficGen::unserialize(CheckpointIn &cp)
143{
144 // restore scheduled events
145 Tick nextEvent;
146 UNSERIALIZE_SCALAR(nextEvent);
147 if (nextEvent != 0)
148 schedule(updateEvent, nextEvent);
149
150 UNSERIALIZE_SCALAR(nextTransitionTick);
151
152 UNSERIALIZE_SCALAR(nextPacketTick);
153}
154
155void
156BaseTrafficGen::update()
157{
158 // shift our progress-tracking event forward
159 reschedule(noProgressEvent, curTick() + progressCheck, true);
160
161 // if we have reached the time for the next state transition, then
162 // perform the transition
163 if (curTick() >= nextTransitionTick) {
164 transition();
165 } else {
166 assert(curTick() >= nextPacketTick);
167 // get the next packet and try to send it
168 PacketPtr pkt = activeGenerator->getNextPacket();
169
170 // suppress packets that are not destined for a memory, such as
171 // device accesses that could be part of a trace
172 if (pkt && system->isMemAddr(pkt->getAddr())) {
173 numPackets++;
174 if (!port.sendTimingReq(pkt)) {
175 retryPkt = pkt;
176 retryPktTick = curTick();
177 }
178 } else if (pkt) {
179 DPRINTF(TrafficGen, "Suppressed packet %s 0x%x\n",
180 pkt->cmdString(), pkt->getAddr());
181
182 ++numSuppressed;
183 if (numSuppressed % 10000)
184 warn("%s suppressed %d packets with non-memory addresses\n",
185 name(), numSuppressed);
186
187 delete pkt;
188 pkt = nullptr;
189 }
190 }
191
192 // if we are waiting for a retry, do not schedule any further
193 // events, in the case of a transition or a successful send, go
194 // ahead and determine when the next update should take place
195 if (retryPkt == NULL) {
196 nextPacketTick = activeGenerator->nextPacketTick(elasticReq, 0);
197 scheduleUpdate();
198 }
199}
200
201void
202BaseTrafficGen::transition()
203{
204 if (activeGenerator)
205 activeGenerator->exit();
206
207 activeGenerator = nextGenerator();
208
209 if (activeGenerator) {
210 const Tick duration = activeGenerator->duration;
211 if (duration != MaxTick && duration != 0) {
212 // we could have been delayed and not transitioned on the
213 // exact tick when we were supposed to (due to back
214 // pressure when sending a packet)
215 nextTransitionTick = curTick() + duration;
216 } else {
217 nextTransitionTick = MaxTick;
218 }
219
220 activeGenerator->enter();
221 nextPacketTick = activeGenerator->nextPacketTick(elasticReq, 0);
222 } else {
223 nextPacketTick = MaxTick;
224 nextTransitionTick = MaxTick;
225 assert(!updateEvent.scheduled());
226 }
227}
228
229void
230BaseTrafficGen::scheduleUpdate()
231{
232 // Has the generator run out of work? In that case, force a
233 // transition if a transition period hasn't been configured.
234 while (activeGenerator &&
235 nextPacketTick == MaxTick && nextTransitionTick == MaxTick) {
236 transition();
237 }
238
239 if (!activeGenerator)
240 return;
241
242 // schedule next update event based on either the next execute
243 // tick or the next transition, which ever comes first
244 const Tick nextEventTick = std::min(nextPacketTick, nextTransitionTick);
245
246 DPRINTF(TrafficGen, "Next event scheduled at %lld\n", nextEventTick);
247
248 // The next transition tick may be in the past if there was a
249 // retry, so ensure that we don't schedule anything in the past.
250 schedule(updateEvent, std::max(curTick(), nextEventTick));
251}
252
253void
254BaseTrafficGen::start()
255{
256 transition();
257 scheduleUpdate();
258}
259
260void
261BaseTrafficGen::recvReqRetry()
262{
263 assert(retryPkt != NULL);
264
265 DPRINTF(TrafficGen, "Received retry\n");
266 numRetries++;
267 // attempt to send the packet, and if we are successful start up
268 // the machinery again
269 if (port.sendTimingReq(retryPkt)) {
270 retryPkt = NULL;
271 // remember how much delay was incurred due to back-pressure
272 // when sending the request, we also use this to derive
273 // the tick for the next packet
274 Tick delay = curTick() - retryPktTick;
275 retryPktTick = 0;
276 retryTicks += delay;
277
278 if (drainState() != DrainState::Draining) {
279 // packet is sent, so find out when the next one is due
280 nextPacketTick = activeGenerator->nextPacketTick(elasticReq,
281 delay);
282 scheduleUpdate();
283 } else {
284 // shut things down
285 nextPacketTick = MaxTick;
286 nextTransitionTick = MaxTick;
287 signalDrainDone();
288 }
289 }
290}
291
292void
293BaseTrafficGen::noProgress()
294{
295 fatal("BaseTrafficGen %s spent %llu ticks without making progress",
296 name(), progressCheck);
297}
298
299void
300BaseTrafficGen::regStats()
301{
302 ClockedObject::regStats();
303
304 // Initialise all the stats
305 using namespace Stats;
306
307 numPackets
308 .name(name() + ".numPackets")
309 .desc("Number of packets generated");
310
311 numRetries
312 .name(name() + ".numRetries")
313 .desc("Number of retries");
314
315 retryTicks
316 .name(name() + ".retryTicks")
317 .desc("Time spent waiting due to back-pressure (ticks)");
318}
319
320std::shared_ptr<BaseGen>
321BaseTrafficGen::createIdle(Tick duration)
322{
323 return std::shared_ptr(new IdleGen(*this, duration));
323 return std::shared_ptr<BaseGen>(new IdleGen(*this, masterID, duration));
324}
325
326std::shared_ptr<BaseGen>
327BaseTrafficGen::createExit(Tick duration)
328{
324}
325
326std::shared_ptr<BaseGen>
327BaseTrafficGen::createExit(Tick duration)
328{
329 return std::shared_ptr(new ExitGen(*this, duration));
329 return std::shared_ptr<BaseGen>(new ExitGen(*this, masterID, duration));
330}
331
332std::shared_ptr<BaseGen>
333BaseTrafficGen::createLinear(Tick duration,
334 Addr start_addr, Addr end_addr, Addr blocksize,
335 Tick min_period, Tick max_period,
336 uint8_t read_percent, Addr data_limit)
337{
330}
331
332std::shared_ptr<BaseGen>
333BaseTrafficGen::createLinear(Tick duration,
334 Addr start_addr, Addr end_addr, Addr blocksize,
335 Tick min_period, Tick max_period,
336 uint8_t read_percent, Addr data_limit)
337{
338 return std::shared_ptr(new LinearGen(*this,
338 return std::shared_ptr<BaseGen>(new LinearGen(*this, masterID,
339 duration, start_addr,
340 end_addr, blocksize,
339 duration, start_addr,
340 end_addr, blocksize,
341 system->cacheLineSize(),
341 min_period, max_period,
342 read_percent, data_limit));
343}
344
345std::shared_ptr<BaseGen>
346BaseTrafficGen::createRandom(Tick duration,
347 Addr start_addr, Addr end_addr, Addr blocksize,
348 Tick min_period, Tick max_period,
349 uint8_t read_percent, Addr data_limit)
350{
342 min_period, max_period,
343 read_percent, data_limit));
344}
345
346std::shared_ptr<BaseGen>
347BaseTrafficGen::createRandom(Tick duration,
348 Addr start_addr, Addr end_addr, Addr blocksize,
349 Tick min_period, Tick max_period,
350 uint8_t read_percent, Addr data_limit)
351{
351 return std::shared_ptr(new RandomGen(*this,
352 return std::shared_ptr<BaseGen>(new RandomGen(*this, masterID,
352 duration, start_addr,
353 end_addr, blocksize,
353 duration, start_addr,
354 end_addr, blocksize,
355 system->cacheLineSize(),
354 min_period, max_period,
355 read_percent, data_limit));
356}
357
358std::shared_ptr<BaseGen>
359BaseTrafficGen::createDram(Tick duration,
360 Addr start_addr, Addr end_addr, Addr blocksize,
361 Tick min_period, Tick max_period,
362 uint8_t read_percent, Addr data_limit,
363 unsigned int num_seq_pkts, unsigned int page_size,
364 unsigned int nbr_of_banks_DRAM,
365 unsigned int nbr_of_banks_util,
366 unsigned int addr_mapping,
367 unsigned int nbr_of_ranks)
368{
356 min_period, max_period,
357 read_percent, data_limit));
358}
359
360std::shared_ptr<BaseGen>
361BaseTrafficGen::createDram(Tick duration,
362 Addr start_addr, Addr end_addr, Addr blocksize,
363 Tick min_period, Tick max_period,
364 uint8_t read_percent, Addr data_limit,
365 unsigned int num_seq_pkts, unsigned int page_size,
366 unsigned int nbr_of_banks_DRAM,
367 unsigned int nbr_of_banks_util,
368 unsigned int addr_mapping,
369 unsigned int nbr_of_ranks)
370{
369 return std::shared_ptr(new DramGen(*this,
371 return std::shared_ptr<BaseGen>(new DramGen(*this, masterID,
370 duration, start_addr,
371 end_addr, blocksize,
372 duration, start_addr,
373 end_addr, blocksize,
374 system->cacheLineSize(),
372 min_period, max_period,
373 read_percent, data_limit,
374 num_seq_pkts, page_size,
375 nbr_of_banks_DRAM,
376 nbr_of_banks_util,
377 addr_mapping,
378 nbr_of_ranks));
379}
380
381std::shared_ptr<BaseGen>
382BaseTrafficGen::createDramRot(Tick duration,
383 Addr start_addr, Addr end_addr, Addr blocksize,
384 Tick min_period, Tick max_period,
385 uint8_t read_percent, Addr data_limit,
386 unsigned int num_seq_pkts,
387 unsigned int page_size,
388 unsigned int nbr_of_banks_DRAM,
389 unsigned int nbr_of_banks_util,
390 unsigned int addr_mapping,
391 unsigned int nbr_of_ranks,
392 unsigned int max_seq_count_per_rank)
393{
375 min_period, max_period,
376 read_percent, data_limit,
377 num_seq_pkts, page_size,
378 nbr_of_banks_DRAM,
379 nbr_of_banks_util,
380 addr_mapping,
381 nbr_of_ranks));
382}
383
384std::shared_ptr<BaseGen>
385BaseTrafficGen::createDramRot(Tick duration,
386 Addr start_addr, Addr end_addr, Addr blocksize,
387 Tick min_period, Tick max_period,
388 uint8_t read_percent, Addr data_limit,
389 unsigned int num_seq_pkts,
390 unsigned int page_size,
391 unsigned int nbr_of_banks_DRAM,
392 unsigned int nbr_of_banks_util,
393 unsigned int addr_mapping,
394 unsigned int nbr_of_ranks,
395 unsigned int max_seq_count_per_rank)
396{
394 return std::shared_ptr(new DramRotGen(*this,
397 return std::shared_ptr<BaseGen>(new DramRotGen(*this, masterID,
395 duration, start_addr,
396 end_addr, blocksize,
398 duration, start_addr,
399 end_addr, blocksize,
400 system->cacheLineSize(),
397 min_period, max_period,
398 read_percent, data_limit,
399 num_seq_pkts, page_size,
400 nbr_of_banks_DRAM,
401 nbr_of_banks_util,
402 addr_mapping,
403 nbr_of_ranks,
404 max_seq_count_per_rank));
405}
406
407std::shared_ptr<BaseGen>
408BaseTrafficGen::createTrace(Tick duration,
409 const std::string& trace_file, Addr addr_offset)
410{
411#if HAVE_PROTOBUF
412 return std::shared_ptr<BaseGen>(
401 min_period, max_period,
402 read_percent, data_limit,
403 num_seq_pkts, page_size,
404 nbr_of_banks_DRAM,
405 nbr_of_banks_util,
406 addr_mapping,
407 nbr_of_ranks,
408 max_seq_count_per_rank));
409}
410
411std::shared_ptr<BaseGen>
412BaseTrafficGen::createTrace(Tick duration,
413 const std::string& trace_file, Addr addr_offset)
414{
415#if HAVE_PROTOBUF
416 return std::shared_ptr<BaseGen>(
413 new TraceGen(*this, duration, trace_file, addr_offset));
417 new TraceGen(*this, masterID, duration, trace_file, addr_offset));
414#else
415 panic("Can't instantiate trace generation without Protobuf support!\n");
416#endif
417}
418
419bool
420BaseTrafficGen::TrafficGenPort::recvTimingResp(PacketPtr pkt)
421{
422 delete pkt;
423
424 return true;
425}
418#else
419 panic("Can't instantiate trace generation without Protobuf support!\n");
420#endif
421}
422
423bool
424BaseTrafficGen::TrafficGenPort::recvTimingResp(PacketPtr pkt)
425{
426 delete pkt;
427
428 return true;
429}