15 stat_ipc_(&unit_stat_set_,
17 "Instructions retired per cycle",
19 "total_number_retired/cycles",
24 {
"high", std::to_string(uint32_t(p->num_to_retire))},
25 {
"semantic",
"higher"}
28 num_retired_(&unit_stat_set_,
29 "total_number_retired",
30 "The total number of instructions retired by this core",
32 num_flushes_(&unit_stat_set_,
33 "total_number_of_flushes",
34 "The total number of flushes performed by the ROB",
36 num_to_retire_(p->num_to_retire),
37 num_insts_to_retire_(p->num_insts_to_retire),
38 reorder_buffer_(
"ReorderBuffer", p->retire_queue_depth,
39 node->getClock(), &unit_stat_set_)
42 ev_retire_.setDelay(1);
45 reorder_buffer_.enableCollection(node);
47 in_reorder_buffer_write_.
52 FlushManager::FlushingCriteria));
56 ev_ensure_forward_progress_.setContinuing(
false);
65 info_logger_ <<
"ROB is destructing now, but you can still see this message";
68 void ROB::sendInitialCredits_()
70 out_reorder_buffer_credits_.
send(reorder_buffer_.
capacity());
71 ev_ensure_forward_progress_.
schedule(retire_timeout_interval_);
74 void ROB::retireEvent_() {
75 retireInstructions_();
76 if (reorder_buffer_.
size() > 0) {
77 ev_retire_.
schedule(sparta::Clock::Cycle(1));
88 void ROB::robAppended_(
const InstGroup &) {
89 for(
auto & i : in_reorder_buffer_write_.
pullData()) {
90 reorder_buffer_.
push(i);
93 ev_retire_.
schedule(sparta::Clock::Cycle(0));
99 void ROB::handleFlush_(
const FlushManager::FlushingCriteria &)
102 out_reorder_buffer_credits_.
send(reorder_buffer_.
size());
103 reorder_buffer_.
clear();
106 void ROB::retireInstructions_() {
107 const uint32_t num_to_retire = std::min(reorder_buffer_.
size(), num_to_retire_);
110 info_logger_ <<
"Retire event, num to retire: " << num_to_retire;
113 uint32_t retired_this_cycle = 0;
114 for(uint32_t i = 0; i < num_to_retire; ++i)
116 auto & ex_inst_ptr = reorder_buffer_.
access(0);
117 auto & ex_inst = *ex_inst_ptr;
119 "Uh, oh! A speculative instruction is being retired: " << ex_inst);
120 if(ex_inst.getStatus() == ExampleInst::Status::COMPLETED)
123 ex_inst.setStatus(ExampleInst::Status::RETIRED);
124 if (ex_inst.isStoreInst()) {
125 out_rob_retire_ack_.send(ex_inst_ptr);
129 ++retired_this_cycle;
130 reorder_buffer_.
pop();
137 std::cout <<
"Retired " << num_retired_
138 <<
" instructions" << std::endl;
153 out_retire_flush_.
send(ex_inst.getUniqueID());
156 out_fetch_flush_redirect_.
send(ex_inst.getVAdr() + 4);
164 ex_inst.setLast(
true, &ev_retire_);
168 out_reorder_buffer_credits_.
send(retired_this_cycle);
173 void ROB::checkForwardProgress_()
175 if(
getClock()->currentCycle() - last_retirement_ >= retire_timeout_interval_)
178 e <<
"Been a while since we've retired an instruction. Is the pipe stalled indefinitely?";
181 ev_ensure_forward_progress_.
schedule(retire_timeout_interval_);
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SPARTA_EXPECT_FALSE(x)
A macro for hinting to the compiler a particular condition should be considered most likely false.
#define CREATE_SPARTA_HANDLER_WITH_DATA(clname, meth, dataT)
#define CREATE_SPARTA_HANDLER(clname, meth)
File that defines the StartupEvent class.
Parameters for ROB model.
ROB(sparta::TreeNode *node, const ROBParameterSet *p)
Constructor for ROB.
static const char name[]
Name of this resource. Required by sparta::UnitFactory.
Cycle currentCycle() const
Get the current cycle (uses current tick from the Scheduler)
@ COUNT_NORMAL
Counter counts the number of times something happens like one would expect. This is a weakly monotoni...
DataT pullData()
Return the last data received by the port, then clear it.
void send(const DataT &dat, sparta::Clock::Cycle rel_time=0)
Send data to bound receivers.
void schedule()
Schedule this event with its pre-set delay using the pre-set Clock.
bool observed() const noexcept
Is this NotificationSourceBase being observed at this node or an ancestor of any distance.
size_type size() const
Return the number of valid entries.
uint32_t capacity() const
Return the fixed size of this queue.
iterator push(const value_type &dat)
push data to the Queue.
value_type & access(uint32_t idx)
Read and return the data at the given index, reference, non-const method.
void clear()
Empty the queue.
void pop()
Pops the data at the front of the structure (oldest element) After pop iterator always points to the ...
Scheduler * getScheduler(const bool must_exist=true) const
const Clock * getClock() const
void stopRunning()
Tell the scheduler to stop running.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
StartupEvent is a simple class for scheduling a starting event on the Scheduler. It does not support ...
@ VS_ABSOLUTE
An absolute number having no units (typical default)
Node in a composite tree representing a sparta Tree item.
void schedule()
Schedule this event with its pre-set delay using the pre-set Clock.
log::MessageSource info_logger_
Default info logger.
Macros for handling exponential backoff.