gem5 v24.0.0.0
Loading...
Searching...
No Matches
buffers.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013-2014 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
44#ifndef __CPU_MINOR_BUFFERS_HH__
45#define __CPU_MINOR_BUFFERS_HH__
46
47#include <iostream>
48#include <queue>
49#include <sstream>
50#include <string>
51
52#include "base/logging.hh"
53#include "base/named.hh"
54#include "base/types.hh"
55#include "cpu/activity.hh"
56#include "cpu/minor/trace.hh"
57#include "cpu/timebuf.hh"
58
59namespace gem5
60{
61
62namespace minor
63{
64
70{
71 public:
74 virtual void reportData(std::ostream &os) const = 0;
75
76 virtual ~ReportIF() { }
77};
78
84{
85 public:
86 virtual bool isBubble() const = 0;
87};
88
95template <typename ElemType> /* ElemType should implement ReportIF */
97{
98 public:
99 static void
100 reportData(std::ostream &os, const ElemType &elem)
101 { elem.reportData(os); }
102};
103
106template <typename PtrType>
108{
109 public:
110 static void
111 reportData(std::ostream &os, const PtrType &elem)
112 { elem->reportData(os); }
113};
114
120template <typename ElemType>
122{
123 public:
124 static bool isBubble(const ElemType &) { return false; }
125 static ElemType
127 {
128 panic("bubble called but no bubble interface");
129 }
130};
131
133template <typename ElemType>
135{
136 public:
137 static bool isBubble(const ElemType &elem)
138 { return elem.isBubble(); }
139
140 static ElemType bubble() { return ElemType::bubble(); }
141};
142
144template <typename PtrType, typename ElemType>
146{
147 public:
148 static bool isBubble(const PtrType &elem)
149 { return elem->isBubble(); }
150
151 static PtrType bubble() { return ElemType::bubble(); }
152};
153
155template <typename ElemType,
156 typename ReportTraits = ReportTraitsAdaptor<ElemType>,
157 typename BubbleTraits = BubbleTraitsAdaptor<ElemType> >
158class MinorBuffer : public Named, public TimeBuffer<ElemType>
159{
160 protected:
163
165 std::string dataName;
166
167 public:
168 MinorBuffer(const std::string &name,
169 const std::string &data_name,
170 int num_past, int num_future,
171 int report_left = -1, int report_right = -1) :
172 Named(name), TimeBuffer<ElemType>(num_past, num_future),
173 reportLeft(report_left), reportRight(report_right),
174 dataName(data_name)
175 { }
176
177 public:
178 /* Is this buffer full of only bubbles */
179 bool
180 empty() const
181 {
182 bool ret = true;
183
184 for (int i = -this->past; i <= this->future; i++) {
185 if (!BubbleTraits::isBubble((*this)[i]))
186 ret = false;
187 }
188
189 return ret;
190 }
191
196 void
198 {
199 std::ostringstream data;
200
201 int step = (reportLeft > reportRight ? -1 : 1);
202 int end = reportRight + step;
203 int i = reportLeft;
204
205 while (i != end) {
206 const ElemType &datum = (*this)[i];
207
208 ReportTraits::reportData(data, datum);
209 i += step;
210 if (i != end)
211 data << ',';
212 }
213
214 minor::minorTrace("%s=%s\n", dataName, data.str());
215 }
216};
217
220template <typename Data>
221class Latch
222{
223 public:
225
226 protected:
230
232
233 public:
236 Latch(const std::string &name,
237 const std::string &data_name,
238 Cycles delay_ = Cycles(1),
239 bool report_backwards = false) :
240 delay(delay_),
241 buffer(name, data_name, delay_, 0, (report_backwards ? -delay_ : 0),
242 (report_backwards ? 0 : -delay_))
243 { }
244
245 public:
251 class Input
252 {
253 public:
254 typename Buffer::wire inputWire;
255
256 public:
257 Input(typename Buffer::wire input_wire) :
258 inputWire(input_wire)
259 { }
260 };
261
262 class Output
263 {
264 public:
265 typename Buffer::wire outputWire;
266
267 public:
268 Output(typename Buffer::wire output_wire) :
269 outputWire(output_wire)
270 { }
271 };
272
273 bool empty() const { return buffer.empty(); }
274
276 Input input() { return Input(buffer.getWire(0)); }
277
280
281 void minorTrace() const { buffer.minorTrace(); }
282
283 void evaluate() { buffer.advance(); }
284};
285
290template <typename ElemType,
291 typename ReportTraits,
292 typename BubbleTraits = BubbleTraitsAdaptor<ElemType> >
293class SelfStallingPipeline : public MinorBuffer<ElemType, ReportTraits>
294{
295 protected:
300
301 public:
304
306 unsigned int occupancy;
307
308 public:
309 SelfStallingPipeline(const std::string &name,
310 const std::string &data_name,
311 unsigned depth) :
312 MinorBuffer<ElemType, ReportTraits>
313 (name, data_name, depth, 0, -1, -depth),
314 pushWire(this->getWire(0)),
315 popWire(this->getWire(-depth)),
316 stalled(false),
317 occupancy(0)
318 {
319 assert(depth > 0);
320
321 /* Write explicit bubbles to get around the case where the default
322 * constructor for the element type isn't good enough */
323 for (unsigned i = 0; i <= depth; i++)
324 (*this)[-i] = BubbleTraits::bubble();
325 }
326
327 public:
332 void push(ElemType &elem)
333 {
334 assert(!alreadyPushed());
335 *pushWire = elem;
336 if (!BubbleTraits::isBubble(elem))
337 occupancy++;
338 }
339
341 ElemType &front() { return *popWire; }
342
343 const ElemType &front() const { return *popWire; }
344
346 bool alreadyPushed() { return !BubbleTraits::isBubble(*pushWire); }
347
349 bool isPopable() { return !BubbleTraits::isBubble(front()); }
350
354 void
356 {
357 bool data_at_end = isPopable();
358
359 if (!stalled) {
361 /* If there was data at the end of the pipe that has now been
362 * advanced out of the pipe, we've lost data */
363 if (data_at_end)
364 occupancy--;
365 /* Is there data at the end of the pipe now? */
366 stalled = isPopable();
367 /* Insert a bubble into the empty input slot to make sure that
368 * element is correct in the case where the default constructor
369 * for ElemType doesn't produce a bubble */
370 ElemType bubble = BubbleTraits::bubble();
371 *pushWire = bubble;
372 }
373 }
374};
375
378{
379 public:
381 virtual bool canReserve() const = 0;
382
384 virtual void reserve() = 0;
385
387 virtual void freeReservation() = 0;
388
389 virtual ~Reservable() {};
390};
391
400template <typename ElemType,
401 typename ReportTraits = ReportTraitsAdaptor<ElemType>,
402 typename BubbleTraits = BubbleTraitsAdaptor<ElemType> >
403class Queue : public Named, public Reservable
404{
405 private:
407
410 unsigned int numReservedSlots;
411
413 unsigned int capacity;
414
416 std::string dataName;
417
418 public:
419 Queue(const std::string &name, const std::string &data_name,
420 unsigned int capacity_) :
421 Named(name),
423 capacity(capacity_),
424 dataName(data_name)
425 { }
426
427 public:
431 void
432 push(ElemType &data)
433 {
434 if (!BubbleTraits::isBubble(data)) {
436 queue.push_back(data);
437
438 if (queue.size() > capacity) {
439 warn("%s: No space to push data into queue of capacity"
440 " %u, pushing anyway\n", name(), capacity);
441 }
442
443 }
444 }
445
448
451 {
452 if (numReservedSlots != 0)
454 }
455
459 void
461 {
462 /* Check reservable space */
463 if (unreservedRemainingSpace() == 0)
464 warn("%s: No space is reservable in queue", name());
465
467 }
468
469 bool canReserve() const { return unreservedRemainingSpace() != 0; }
470
472 unsigned int totalSpace() const { return capacity; }
473
475 unsigned int occupiedSpace() const { return queue.size(); }
476
478 unsigned int reservedSpace() const { return numReservedSlots; }
479
482 unsigned int
484 {
485 int ret = capacity - queue.size();
486
487 return (ret < 0 ? 0 : ret);
488 }
489
491 unsigned int
493 {
494 int ret = capacity - (queue.size() + numReservedSlots);
495
496 return (ret < 0 ? 0 : ret);
497 }
498
500 ElemType &front() { return queue.front(); }
501
502 const ElemType &front() const { return queue.front(); }
503
505 void pop() { queue.pop_front(); }
506
508 bool empty() const { return queue.empty(); }
509
510 void
512 {
513 std::ostringstream data;
514 /* If we become over-full, totalSpace() can actually be smaller than
515 * occupiedSpace(). Handle this */
516 unsigned int num_total = (occupiedSpace() > totalSpace() ?
518
519 unsigned int num_reserved = reservedSpace();
520 unsigned int num_occupied = occupiedSpace();
521
522 int num_printed = 1;
523 /* Bodge to rotate queue to report elements */
524 while (num_printed <= num_occupied) {
525 ReportTraits::reportData(data, queue[num_printed - 1]);
526 num_printed++;
527
528 if (num_printed <= num_total)
529 data << ',';
530 }
531
532 int num_printed_reserved = 1;
533 /* Show reserved slots */
534 while (num_printed_reserved <= num_reserved &&
535 num_printed <= num_total)
536 {
537 data << 'R';
538 num_printed_reserved++;
539 num_printed++;
540
541 if (num_printed <= num_total)
542 data << ',';
543 }
544
545 /* And finally pad with empty slots (if there are any) */
546 while (num_printed <= num_total) {
547 num_printed++;
548
549 if (num_printed <= num_total)
550 data << ',';
551 }
552
553 minor::minorTrace("%s=%s\n", dataName, data.str());
554 }
555};
556
568template <typename ElemType,
569 typename ReportTraits = ReportTraitsAdaptor<ElemType>,
570 typename BubbleTraits = BubbleTraitsAdaptor<ElemType> >
572{
573 protected:
576
578 mutable ElemType *elementPtr;
579
580 public:
581 InputBuffer(const std::string &name, const std::string &data_name,
582 unsigned int capacity_) :
583 queue(name, data_name, capacity_),
584 elementPtr(NULL)
585 { }
586
587 public:
591 void
592 setTail(ElemType &new_element)
593 {
594 assert(!elementPtr);
595 if (!BubbleTraits::isBubble(new_element)) {
596 if (queue.empty())
597 elementPtr = &new_element;
598 else
599 queue.push(new_element);
600 }
601 }
602
604 bool empty() const { return !elementPtr && queue.empty(); }
605
607 const ElemType &front() const
608 { return (elementPtr ? *elementPtr : queue.front()); }
609
610 ElemType &front()
611 { return (elementPtr ? *elementPtr : queue.front()); }
612
614 void
616 {
617 if (elementPtr) {
618 /* A popped element was expected to be pushed into queue
619 * and so take a reserved space */
620 elementPtr = NULL;
621 queue.freeReservation();
622 } else {
623 queue.pop();
624 }
625 }
626
630 void
631 pushTail() const
632 {
633 if (elementPtr)
634 queue.push(*elementPtr);
635 elementPtr = NULL;
636 }
637
639 void
641 {
642 pushTail();
643 queue.minorTrace();
644 }
645
647 bool canReserve() const { return queue.canReserve(); }
648 void reserve() { queue.reserve(); }
649 void freeReservation() { queue.freeReservation(); }
650
652 unsigned int
654 {
655 pushTail();
656 return queue.unreservedRemainingSpace();
657 }
658};
659
660} // namespace minor
661} // namespace gem5
662
663#endif /* __CPU_MINOR_BUFFERS_HH__ */
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
const char data[]
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
Interface for things with names.
Definition named.hh:39
virtual std::string name() const
Definition named.hh:47
wire getWire(int idx)
Definition timebuf.hh:232
Interface class for data with 'bubble' values.
Definition buffers.hh:84
virtual bool isBubble() const =0
Pass on call to the element.
Definition buffers.hh:135
static bool isBubble(const ElemType &elem)
Definition buffers.hh:137
Pass on call to the element where the element is a pointer.
Definition buffers.hh:146
static bool isBubble(const PtrType &elem)
Definition buffers.hh:148
Like a Queue but with a restricted interface and a setTail function which, when the queue is empty,...
Definition buffers.hh:572
bool empty() const
No single element or queue entries.
Definition buffers.hh:604
void reserve()
Reserve a slot in whatever structure this is attached to.
Definition buffers.hh:648
InputBuffer(const std::string &name, const std::string &data_name, unsigned int capacity_)
Definition buffers.hh:581
void setTail(ElemType &new_element)
Set the tail of the queue, this is like push but needs to be followed by pushTail for the new tail to...
Definition buffers.hh:592
const ElemType & front() const
Return the element, or the front of the queue.
Definition buffers.hh:607
void pop()
Pop either the head, or if none, the head of the queue.
Definition buffers.hh:615
void minorTrace() const
Report elements.
Definition buffers.hh:640
void freeReservation()
Free a reserved slot.
Definition buffers.hh:649
void pushTail() const
Push the single element (if any) into the queue proper.
Definition buffers.hh:631
ElemType * elementPtr
Pointer to the single element (if not NULL)
Definition buffers.hh:578
unsigned int unreservedRemainingSpace()
Like remainingSpace but does not count reserved spaces.
Definition buffers.hh:653
Queue< ElemType, ReportTraits, BubbleTraits > queue
Underlying queue.
Definition buffers.hh:575
bool canReserve() const
Reservable interface, passed on to queue.
Definition buffers.hh:647
Encapsulate wires on either input or output of the latch.
Definition buffers.hh:252
Input(typename Buffer::wire input_wire)
Definition buffers.hh:257
Output(typename Buffer::wire output_wire)
Definition buffers.hh:268
Wraps a MinorBuffer with Input/Output interfaces to ensure that units within the model can only see t...
Definition buffers.hh:222
Input input()
An interface to just the input of the buffer.
Definition buffers.hh:276
MinorBuffer< Data > Buffer
Definition buffers.hh:224
void minorTrace() const
Definition buffers.hh:281
Cycles delay
Delays, in cycles, writing data into the latch and seeing it on the latched wires.
Definition buffers.hh:229
bool empty() const
Definition buffers.hh:273
Output output()
An interface to just the output of the buffer.
Definition buffers.hh:279
Latch(const std::string &name, const std::string &data_name, Cycles delay_=Cycles(1), bool report_backwards=false)
forward/backwardDelay specify the delay from input to output in each direction.
Definition buffers.hh:236
TimeBuffer with MinorTrace and Named interfaces.
Definition buffers.hh:159
int reportLeft
The range of elements that should appear in trace lines.
Definition buffers.hh:162
std::string dataName
Name to use for the data in a MinorTrace line.
Definition buffers.hh:165
MinorBuffer(const std::string &name, const std::string &data_name, int num_past, int num_future, int report_left=-1, int report_right=-1)
Definition buffers.hh:168
void minorTrace() const
Report buffer states from 'slot' 'from' to 'to'.
Definition buffers.hh:197
... BubbleTraits are trait classes to add BubbleIF interface functionality to templates which process...
Definition buffers.hh:122
static ElemType bubble()
Definition buffers.hh:126
static bool isBubble(const ElemType &)
Definition buffers.hh:124
Wrapper for a queue type to act as a pipeline stage input queue.
Definition buffers.hh:404
Queue(const std::string &name, const std::string &data_name, unsigned int capacity_)
Definition buffers.hh:419
bool empty() const
Is the queue empty?
Definition buffers.hh:508
std::deque< ElemType > queue
Definition buffers.hh:406
void minorTrace() const
Definition buffers.hh:511
unsigned int reservedSpace() const
Number of slots which are reserved.
Definition buffers.hh:478
void clearReservedSpace()
Clear all allocated space.
Definition buffers.hh:447
void pop()
Pop the head item.
Definition buffers.hh:505
bool canReserve() const
Can a slot be reserved?
Definition buffers.hh:469
unsigned int unreservedRemainingSpace() const
Like remainingSpace but does not count reserved spaces.
Definition buffers.hh:492
unsigned int remainingSpace() const
Number of slots yet to fill in this buffer.
Definition buffers.hh:483
unsigned int occupiedSpace() const
Number of slots already occupied in this buffer.
Definition buffers.hh:475
void freeReservation()
Clear a single reserved slot.
Definition buffers.hh:450
std::string dataName
Name to use for the data in MinorTrace.
Definition buffers.hh:416
unsigned int capacity
Need this here as queues usually don't have a limited capacity.
Definition buffers.hh:413
ElemType & front()
Head value.
Definition buffers.hh:500
void reserve()
Reserve space in the queue for future pushes.
Definition buffers.hh:460
unsigned int totalSpace() const
Number of slots available in an empty buffer.
Definition buffers.hh:472
const ElemType & front() const
Definition buffers.hh:502
unsigned int numReservedSlots
Number of slots currently reserved for future (reservation respecting) pushes.
Definition buffers.hh:410
void push(ElemType &data)
Push an element into the buffer if it isn't a bubble.
Definition buffers.hh:432
Interface class for data with reporting/tracing facilities.
Definition buffers.hh:70
virtual void reportData(std::ostream &os) const =0
Print the data in a format suitable to be the value in "name=value" trace lines.
virtual ~ReportIF()
Definition buffers.hh:76
...ReportTraits are trait classes with the same functionality as ReportIF, but with elements explicit...
Definition buffers.hh:97
static void reportData(std::ostream &os, const ElemType &elem)
Definition buffers.hh:100
A similar adaptor but for elements held by pointer ElemType should implement ReportIF.
Definition buffers.hh:108
static void reportData(std::ostream &os, const PtrType &elem)
Definition buffers.hh:111
Base class for space reservation requestable objects.
Definition buffers.hh:378
virtual void freeReservation()=0
Free a reserved slot.
virtual void reserve()=0
Reserve a slot in whatever structure this is attached to.
virtual bool canReserve() const =0
Can a slot be reserved?
A pipeline simulating class that will stall (not advance when advance() is called) if a non-bubble va...
Definition buffers.hh:294
bool alreadyPushed()
Have we already pushed onto this pipe without advancing.
Definition buffers.hh:346
bool stalled
If true, advance will not advance the pipeline.
Definition buffers.hh:303
void advance()
Try to advance the pipeline.
Definition buffers.hh:355
SelfStallingPipeline(const std::string &name, const std::string &data_name, unsigned depth)
Definition buffers.hh:309
TimeBuffer< ElemType >::wire popWire
Wire at the output end of the pipeline (for convenience)
Definition buffers.hh:299
unsigned int occupancy
The number of slots with non-bubbles in them.
Definition buffers.hh:306
const ElemType & front() const
Definition buffers.hh:343
TimeBuffer< ElemType >::wire pushWire
Wire at the input end of the pipeline (for convenience)
Definition buffers.hh:297
bool isPopable()
There's data (not a bubble) at the end of the pipe.
Definition buffers.hh:349
void push(ElemType &elem)
Write an element to the back of the pipeline.
Definition buffers.hh:332
ElemType & front()
Peek at the end element of the pipe.
Definition buffers.hh:341
STL deque class.
Definition stl.hh:44
This file contains miscellaneous classes and functions for formatting general trace information and a...
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define warn(...)
Definition logging.hh:256
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 17 > os
Definition misc.hh:838
void minorTrace(const char *fmt, Args ...args)
DPRINTFN for MinorTrace reporting.
Definition trace.hh:66
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Minor contains all the definitions within the MinorCPU apart from the CPU class itself.
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0