49#include "debug/RubyQueue.hh"
58using stl_helpers::operator<<;
61 :
SimObject(
p), m_stall_map_size(0), m_max_size(
p.buffer_size),
62 m_max_dequeue_rate(
p.max_dequeue_rate), m_dequeues_this_cy(0),
63 m_time_last_time_size_checked(0),
64 m_time_last_time_enqueue(0), m_time_last_time_pop(0),
65 m_last_arrival_time(0), m_last_message_strict_fifo_bypassed(false),
66 m_strict_fifo(
p.ordered),
67 m_randomization(
p.randomization),
68 m_allow_zero_latency(
p.allow_zero_latency),
69 m_routing_priority(
p.routing_priority),
70 ADD_STAT(m_not_avail_count, statistics::units::Count::get(),
71 "Number of times this buffer did not have N slots available"),
72 ADD_STAT(m_msg_count, statistics::units::Count::get(),
73 "Number of messages passed the buffer"),
74 ADD_STAT(m_buf_msgs, statistics::units::Rate<
75 statistics::units::Count, statistics::units::
Tick>::get(),
76 "Average number of messages in buffer"),
78 "Total number of ticks messages were stalled in this buffer"),
79 ADD_STAT(m_stall_count, statistics::units::Count::get(),
80 "Number of times messages were stalled"),
81 ADD_STAT(m_avg_stall_time, statistics::units::Rate<
82 statistics::units::
Tick, statistics::units::Count>::get(),
83 "Average stall ticks per message"),
84 ADD_STAT(m_occupancy, statistics::units::Rate<
85 statistics::units::Ratio, statistics::units::
Tick>::get(),
86 "Average occupancy of buffer capacity")
160 unsigned int current_size = 0;
161 unsigned int current_stall_size = 0;
182 if (current_size + current_stall_size +
n <=
m_max_size) {
185 DPRINTF(RubyQueue,
"n: %d, current_size: %d, heap size: %d, "
187 n, current_size + current_stall_size,
197 DPRINTF(RubyQueue,
"Peeking at head of queue.\n");
201 DPRINTF(RubyQueue,
"Message: %s\n", (*msg_ptr));
219 bool bypassStrictFIFO)
233 "Delta equals zero and allow_zero_latency is false during enqueue");
234 Tick arrival_time = 0;
242 arrival_time = current_time + delta;
256 assert(arrival_time >= current_time);
260 panic(
"FIFO ordering violated: %s name: %s current time: %d "
261 "delta: %d arrival_time: %d last arrival_time: %d\n",
262 *
this,
name(), current_time, delta, arrival_time,
275 Message* msg_ptr = message.get();
276 assert(msg_ptr != NULL);
279 "ensure we aren't dequeued early");
294 DPRINTF(RubyQueue,
"Enqueue arrival_time: %lld, Message: %s\n",
295 arrival_time, *(message.get()));
306 DPRINTF(RubyQueue,
"Popping\n");
313 message->updateDelayedTicks(current_time);
314 Tick delay = message->getDelayedTicks();
328 if (decrement_messages) {
374 DPRINTF(RubyQueue,
"Recycling.\n");
379 Tick future_time = current_time + recycle_latency;
380 node->setLastEnqueueTime(future_time);
390 while (!
lt.empty()) {
392 assert(
m->getLastEnqueueTime() <= schdTick);
396 std::greater<MsgPtr>());
400 DPRINTF(RubyQueue,
"Requeue arrival_time: %lld, Message: %s\n",
401 schdTick, *(
m.get()));
410 DPRINTF(RubyQueue,
"ReanalyzeMessages %#x\n",
addr);
428 DPRINTF(RubyQueue,
"ReanalyzeAllMessages\n");
476 DPRINTF(RubyQueue,
"Deferring enqueueing message: %s, Address %#x\n",
477 *(message.get()),
addr);
486 assert(msg_vec.size() > 0);
512 std::sort_heap(copy.begin(), copy.end(), std::greater<MsgPtr>());
524 (
m_prio_heap.front()->getLastEnqueueTime() <= current_time);
525 if (!can_dequeue && is_ready) {
529 return can_dequeue && is_ready;
544 DPRINTF(RubyQueue,
"functional %s for %#x\n",
545 is_read ?
"read" :
"write", pkt->
getAddr());
547 uint32_t num_functional_accesses = 0;
556 num_functional_accesses++;
558 num_functional_accesses++;
568 it != (map_iter->second).end(); ++it) {
574 num_functional_accesses++;
576 num_functional_accesses++;
580 return num_functional_accesses;
Cycles is a wrapper class for representing cycle counts, i.e.
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Abstract superclass for simulation objects.
void scheduleEventAbsolute(Tick timeAbs)
void scheduleEvent(Cycles timeDelta)
virtual void storeEventInfo(int info)
statistics::Scalar m_stall_count
bool isDeferredMsgMapEmpty(Addr addr) const
void recycle(Tick current_time, Tick recycle_latency)
MessageBuffer(const Params &p)
bool areNSlotsAvailable(unsigned int n, Tick curTime)
bool isReady(Tick current_time) const
Tick m_time_last_time_enqueue
const Message * peek() const
Function for extracting the message at the head of the message queue.
const bool m_allow_zero_latency
unsigned int m_size_last_time_size_checked
void unregisterDequeueCallback()
bool m_last_message_strict_fifo_bypassed
void enqueueDeferredMessages(Addr addr, Tick curTime, Tick delay)
void enqueue(MsgPtr message, Tick curTime, Tick delta, bool bypassStrictFIFO=false)
const unsigned int m_max_dequeue_rate
When != 0, isReady returns false once m_max_dequeue_rate messages have been dequeued in the same cycl...
MessageBufferParams Params
const unsigned int m_max_size
The maximum capacity.
void reanalyzeAllMessages(Tick current_time)
unsigned int m_stalled_at_cycle_start
unsigned int m_msgs_this_cycle
statistics::Formula m_avg_stall_time
Consumer * m_consumer
Consumer to signal a wakeup(), can be NULL.
Tick dequeue(Tick current_time, bool decrement_messages=true)
Updates the delay cycles of the message at the head of the queue, removes it from the queue and retur...
statistics::Average m_buf_msgs
statistics::Scalar m_stall_time
bool hasStalledMsg(Addr addr) const
std::vector< MsgPtr > m_prio_heap
Tick m_time_last_time_pop
void deferEnqueueingMessage(Addr addr, MsgPtr message)
void registerDequeueCallback(std::function< void()> callback)
StallMsgMapType m_stall_msg_map
A map from line addresses to lists of stalled messages for that line.
Tick m_time_last_time_size_checked
void stallMessage(Addr addr, Tick current_time)
statistics::Scalar m_msg_count
unsigned int m_size_at_cycle_start
statistics::Formula m_occupancy
unsigned int m_dequeues_this_cy
void print(std::ostream &out) const
void reanalyzeMessages(Addr addr, Tick current_time)
const MessageRandomization m_randomization
void reanalyzeList(std::list< MsgPtr > &, Tick)
unsigned int getSize(Tick curTime)
int m_stall_map_size
Current size of the stall map.
statistics::Scalar m_not_avail_count
std::function< void()> m_dequeue_callback
uint32_t functionalAccess(Packet *pkt, bool is_read, WriteMask *mask)
DeferredMsgMapType m_deferred_msg_map
virtual bool functionalRead(Packet *pkt)
The two functions below are used for reading / writing the message functionally.
Tick getLastEnqueueTime() const
virtual bool functionalWrite(Packet *pkt)
void updateDelayedTicks(Tick curTime)
Update the delay this message has experienced so far.
void setMsgCounter(uint64_t c)
void setLastEnqueueTime(const Tick &time)
static bool getWarmupEnabled()
static int getRandomization()
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::shared_ptr< Message > MsgPtr
Addr getOffset(Addr addr)
const FlagsType nonan
Don't print if this is NAN.
const FlagsType nozero
Don't print if this is zero.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
void ccprintf(cp::Print &print)