16#include "sparta/simulation/TreeNodePrivateAttorney.hpp"
22#include "sparta/events/GlobalOrderingPoint.hpp"
27 extern void onPipelineCollectionShutdown(Simulation* sim);
68 class CollectablesByClock
71 CollectablesByClock(
const Clock * clk,
75 switch(collection_phase)
77 case SchedulingPhase::Trigger:
79 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_trigger",
84 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_update",
89 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_portupdate",
94 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_flush",
99 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_collection",
104 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_tick",
109 (&ev_set_,
sparta::notNull(clk)->getName() +
"_auto_collection_event_posttick",
112 case SchedulingPhase::__last_scheduling_phase:
118 ev_collect_->setScheduleableClock(clk);
120 ev_collect_->setContinuing(
false);
124 enabled_ctns_.insert(ctn);
127 ev_collect_->schedule(sparta::Clock::Cycle(1));
131 enabled_ctns_.erase(ctn);
134 bool anyCollected()
const {
135 return !enabled_ctns_.empty();
138 void performCollection() {
144 for(
auto & ctn : enabled_ctns_) {
149 if(!enabled_ctns_.empty()) {
150 ev_collect_->schedule();
155 for(
auto ctn : enabled_ctns_) {
156 std::cout <<
'\t' << ctn->
getName() << std::endl;
162 std::unique_ptr<sparta::Scheduleable> ev_collect_;
163 std::set<CollectableTreeNode*> enabled_ctns_;
169 std::array<std::unique_ptr<CollectablesByClock>,
173 std::set<CollectableTreeNode*> registered_collectables_;
218 scheduler_(scheduler != nullptr ? scheduler : root_clk->
getScheduler())
223 sparta_assert(root !=
nullptr,
"Pipeline Collection will not be able to create location file because it was passed a nullptr root treenode.");
224 sparta_assert(root->
isFinalized(),
"Pipeline collection cannot be constructed until the sparta tree has been finalized.");
226 sparta_assert(root_clk !=
nullptr,
"Cannot construct PipelineCollector because root clock is a nullptr");
227 sparta_assert(scheduler_->
isFinalized() ==
false,
"Pipeline Collection cannot be instantiated after scheduler finalization -- it creates events");
232 addClks = [&addClks,
this, &fastest_clk] (
const sparta::Clock* clk)
235 auto & u_p = clock_ctn_map_[clk];
237 u_p[i].reset(
new CollectablesByClock(clk,
static_cast<SchedulingPhase>(i)));
242 auto clk_period = child_clk->
getPeriod();
249 if(clk_period != 1 && (!fastest_clk || (clk_period < fastest_clk->getPeriod()))) {
250 fastest_clk = child_clk;
258 if(fastest_clk ==
nullptr){
259 fastest_clk = root_clk;
265 static const uint32_t heartbeat_multiplier = 200;
267 if (heartbeat_interval == 0)
270 heartbeat_interval = fastest_clk->
getPeriod() * heartbeat_multiplier;
271 heartbeat_interval = heartbeat_interval + (100 - (heartbeat_interval % 100));
277 filepath_ = filepath;
278 root_clk_ = root_clk;
285 "The PipelineCollector was not torn down properly. Before "
286 "tearing down the simulation tree, you must call "
287 "destroy() on the collector");
298 if(collection_active_) {
299 for(
auto & ctn : registered_collectables_) {
300 if(ctn->isCollected()) {
301 ctn->closeRecord(
true);
305 registered_collectables_.clear();
306 collection_active_ =
false;
307 onPipelineCollectionShutdown(simulation_);
310 void reactivate(
const std::string& filepath)
313 "You can only reactivate the PipelineCollector after you destroy it");
314 filepath_ = filepath;
333 recursiveCollect = [&recursiveCollect,
this] (
sparta::TreeNode* starting_node)
337 if(c_node !=
nullptr) {
340 registered_collectables_.insert(c_node);
347 recursiveCollect(node);
351 recursiveCollect(starting_node);
363 recursiveStopCollect = [&recursiveStopCollect,
this] (
sparta::TreeNode* starting_node) {
366 if(c_node !=
nullptr)
369 registered_collectables_.erase(c_node);
375 recursiveStopCollect(node);
378 recursiveStopCollect(starting_node);
380 collection_active_ = !registered_collectables_.empty();
389 for(
auto & col : registered_collectables_) {
390 col->stopCollecting(
this);
392 registered_collectables_.clear();
393 onPipelineCollectionShutdown(simulation_);
411 auto ccm_pair = clock_ctn_map_.find(ctn->
getClock());
413 ccm_pair->second[
static_cast<uint32_t
>(collection_phase)]->enable(ctn);
429 auto ccm_pair = clock_ctn_map_.find(ctn->
getClock());
431 for(
auto & u_p : ccm_pair->second) {
447 return collection_active_;
467 std::string filepath_;
473 bool collection_active_ =
false;
File that defines the Clock class.
define a CollectableTreeNode type TreeNode.
Define a base Collector class.
File that defines the EventSet class.
A simple time-based, event precedence based scheduler.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_abort(...)
Simple variatic assertion that will print a message to std::cerr and call std::terminate()
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define CREATE_SPARTA_HANDLER(clname, meth)
Basic Node framework in sparta device tree composite pattern.
File that defines the UniqueEvent class.
A representation of simulated time.
Period getPeriod() const
Returns the period of this clock in scheduler ticks.
Scheduler * getScheduler() const
Set of Events that a unit (or sparta::TreeNode, sparta::Resource) contains and are visible through a ...
virtual bool isFinalized() const
Is this node (and thus the entire tree above it) "finalized".
A class that lets you schedule events now and in the future.
uint64_t Tick
Typedef for our unit of time.
bool isFinalized() const noexcept override
Is the scheduler finalized.
static const TreeNode::ChildrenVector & getAllChildren(const TreeNode &node)
Node in a composite tree representing a sparta Tree item.
const std::string & getName() const override
Gets the name of this node.
const Clock * getClock() override
Walks up parents (starting with self) until a parent with an associated local clock is found,...
A type of Event that uniquely schedules itself on the schedule within a single time quantum....
Simulator which builds a sparta DeviceTree.
An abstract type of TreeNode that has virtual calls to start collection on this node,...
void startCollecting(Collector *collector)
Method that tells this treenode that is now running collection.
bool isCollected() const
Determine whether or not this node has collection turned on or off.
void stopCollecting(Collector *collector)
Method that tells this treenode that is now not running collection.
bool isIterableCollectorBin() const
Check if this CollectableTreeNode is a Collectable inside an IterableCollector.
A non-templated base class that all Collectors should inherit from.
A class that facilitates all universal pipeline collection operations such as outputting finalized re...
void startCollection(sparta::TreeNode *starting_node)
Turn on collection for everything below a TreeNode. Recursively transverse the tree and turn on child...
PipelineCollector(const std::string &filepath, Scheduler::Tick heartbeat_interval, const sparta::Clock *root_clk, const sparta::TreeNode *root, Scheduler *scheduler=nullptr)
Instantiate the collector with required parameters before pipeline collection can occur.
void removeFromAutoCollection(CollectableTreeNode *ctn)
Remove the given CollectableTreeNode from collection.
bool isCollectionActive() const
Return true if the collector is actively collecting.
void stopCollection()
Stop pipeline collection on only those CollectableTreeNodes that this PipelineCollector was started w...
const std::string & getFilePath() const
void destroy()
Teardown the pipeline collector.
void addToAutoCollection(CollectableTreeNode *ctn, SchedulingPhase collection_phase=SchedulingPhase::Tick)
Add the CollectableTreeNode to auto collection.
Scheduler * getScheduler() const
void stopCollection(sparta::TreeNode *starting_node)
Stop pipeline collection on only those CollectableTreeNodes given.
Sparta Application framework.
Macros for handling exponential backoff.
T * notNull(T *p)
Ensures that a pointer is not null.
const uint32_t NUM_SCHEDULING_PHASES
The number of phases.
SchedulingPhase
The SchedulingPhases used for events (Tick, Update, PortUpdate, etc)
@ Update
Resources are updated in this phase.
@ PortUpdate
N-cycle Ports are updated in this phase.
@ Tick
Most operations (combinational logic) occurs in this phase.
@ Flush
Phase where flushing of pipelines, etc can occur.
@ PostTick
Operations such as post-tick pipeline collection occur here.
@ Collection
Pipeline collection occurs here.