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_strict_fifo(
p.ordered),
66 m_randomization(
p.randomization),
67 m_allow_zero_latency(
p.allow_zero_latency),
68 m_routing_priority(
p.routing_priority),
69 ADD_STAT(m_not_avail_count, statistics::units::Count::get(),
70 "Number of times this buffer did not have N slots available"),
71 ADD_STAT(m_msg_count, statistics::units::Count::get(),
72 "Number of messages passed the buffer"),
73 ADD_STAT(m_buf_msgs, statistics::units::Rate<
74 statistics::units::Count, statistics::units::
Tick>::get(),
75 "Average number of messages in buffer"),
77 "Total number of ticks messages were stalled in this buffer"),
78 ADD_STAT(m_stall_count, statistics::units::Count::get(),
79 "Number of times messages were stalled"),
80 ADD_STAT(m_avg_stall_time, statistics::units::Rate<
81 statistics::units::
Tick, statistics::units::Count>::get(),
82 "Average stall ticks per message"),
83 ADD_STAT(m_occupancy, statistics::units::Rate<
84 statistics::units::Ratio, statistics::units::
Tick>::get(),
85 "Average occupancy of buffer capacity")
159 unsigned int current_size = 0;
160 unsigned int current_stall_size = 0;
181 if (current_size + current_stall_size +
n <=
m_max_size) {
184 DPRINTF(RubyQueue,
"n: %d, current_size: %d, heap size: %d, "
186 n, current_size + current_stall_size,
196 DPRINTF(RubyQueue,
"Peeking at head of queue.\n");
200 DPRINTF(RubyQueue,
"Message: %s\n", (*msg_ptr));
231 "Delta equals zero and allow_zero_latency is false during enqueue");
232 Tick arrival_time = 0;
240 arrival_time = current_time + delta;
254 assert(arrival_time >= current_time);
257 panic(
"FIFO ordering violated: %s name: %s current time: %d "
258 "delta: %d arrival_time: %d last arrival_time: %d\n",
259 *
this,
name(), current_time, delta, arrival_time,
270 Message* msg_ptr = message.get();
271 assert(msg_ptr != NULL);
274 "ensure we aren't dequeued early");
289 DPRINTF(RubyQueue,
"Enqueue arrival_time: %lld, Message: %s\n",
290 arrival_time, *(message.get()));
301 DPRINTF(RubyQueue,
"Popping\n");
308 message->updateDelayedTicks(current_time);
309 Tick delay = message->getDelayedTicks();
323 if (decrement_messages) {
369 DPRINTF(RubyQueue,
"Recycling.\n");
374 Tick future_time = current_time + recycle_latency;
375 node->setLastEnqueueTime(future_time);
385 while (!
lt.empty()) {
387 assert(
m->getLastEnqueueTime() <= schdTick);
391 std::greater<MsgPtr>());
395 DPRINTF(RubyQueue,
"Requeue arrival_time: %lld, Message: %s\n",
396 schdTick, *(
m.get()));
405 DPRINTF(RubyQueue,
"ReanalyzeMessages %#x\n",
addr);
423 DPRINTF(RubyQueue,
"ReanalyzeAllMessages\n");
471 DPRINTF(RubyQueue,
"Deferring enqueueing message: %s, Address %#x\n",
472 *(message.get()),
addr);
481 assert(msg_vec.size() > 0);
507 std::sort_heap(copy.begin(), copy.end(), std::greater<MsgPtr>());
519 (
m_prio_heap.front()->getLastEnqueueTime() <= current_time);
520 if (!can_dequeue && is_ready) {
524 return can_dequeue && is_ready;
539 DPRINTF(RubyQueue,
"functional %s for %#x\n",
540 is_read ?
"read" :
"write", pkt->
getAddr());
542 uint32_t num_functional_accesses = 0;
551 num_functional_accesses++;
553 num_functional_accesses++;
563 it != (map_iter->second).end(); ++it) {
569 num_functional_accesses++;
571 num_functional_accesses++;
575 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()
void enqueueDeferredMessages(Addr addr, Tick curTime, Tick delay)
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
void enqueue(MsgPtr message, Tick curTime, Tick delta)
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.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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)