The Sparta Modeling Framework
Loading...
Searching...
No Matches
BIU.cpp
1// <BIU.cpp> -*- C++ -*-
2
4#include "BIU.hpp"
5
6namespace core_example
7{
8 const char BIU::name[] = "biu";
9
11 // Constructor
13
14 BIU::BIU(sparta::TreeNode *node, const BIUParameterSet *p) :
15 sparta::Unit(node),
16 biu_req_queue_size_(p->biu_req_queue_size),
17 biu_latency_(p->biu_latency)
18 {
19 in_biu_req_.registerConsumerHandler
20 (CREATE_SPARTA_HANDLER_WITH_DATA(BIU, getReqFromLSU_, ExampleInstPtr));
21
22 in_mss_ack_sync_.registerConsumerHandler
23 (CREATE_SPARTA_HANDLER_WITH_DATA(BIU, getAckFromMSS_, bool));
24 in_mss_ack_sync_.setPortDelay(static_cast<sparta::Clock::Cycle>(1));
25
26
27 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
28 info_logger_ << "BIU construct: #" << node->getGroupIdx();
29 }
30 }
31
32
34 // Callbacks
36
37 // Receive new BIU request from LSU
38 void BIU::getReqFromLSU_(const ExampleInstPtr & inst_ptr)
39 {
40 appendReqQueue_(inst_ptr);
41
42 // Schedule BIU request handling event only when:
43 // (1)BIU is not busy, and (2)Request queue is not empty
44 if (!biu_busy_) {
45 // NOTE:
46 // We could set this flag immediately here, but a better/cleaner way to do this is:
47 // (1)Schedule the handling event immediately;
48 // (2)Update flag in that event handler.
49
50 ev_handle_biu_req_.schedule(sparta::Clock::Cycle(0));
51 // NOTE:
52 // The handling event must be scheduled immediately (0 delay). Otherwise,
53 // BIU could potentially send another request to MSS before the busy flag is set
54 }
55 else {
56 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
57 info_logger_ << "This request cannot be serviced right now, MSS is already busy!";
58 }
59 }
60 }
61
62 // Handle BIU request
63 void BIU::handle_BIU_Req_()
64 {
65 biu_busy_ = true;
66 out_mss_req_sync_.send(biu_req_queue_.front(), biu_latency_);
67
68 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
69 info_logger_ << "BIU request is sent to MSS!";
70 }
71 }
72
73 // Handle MSS Ack
74 void BIU::handle_MSS_Ack_()
75 {
76 out_biu_ack_.send(biu_req_queue_.front());
77 biu_req_queue_.pop_front();
78 biu_busy_ = false;
79
80 // Schedule BIU request handling event only when:
81 // (1)BIU is not busy, and (2)Request queue is not empty
82 if (biu_req_queue_.size() > 0) {
83 ev_handle_biu_req_.schedule(sparta::Clock::Cycle(0));
84 }
85
86 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
87 info_logger_ << "MSS Ack is sent to LSU!";
88 }
89 }
90
91 // Receive MSS access acknowledge
92 void BIU::getAckFromMSS_(const bool & done)
93 {
94 if (done) {
95 ev_handle_mss_ack_.schedule(sparta::Clock::Cycle(0));
96
97 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
98 info_logger_ << "MSS Ack is received!";
99 }
100
101 return;
102 }
103
104 // Right now we expect MSS ack is always true
105 sparta_assert(false, "MSS is NOT done!");
106 }
107
108
110 // Regular Function/Subroutine Call
112
113 // Append BIU request queue
114 void BIU::appendReqQueue_(const ExampleInstPtr& inst_ptr)
115 {
116 sparta_assert(biu_req_queue_.size() <= biu_req_queue_size_ ,"BIU request queue overflows!");
117
118 // Push new requests from back
119 biu_req_queue_.emplace_back(inst_ptr);
120
121 if(SPARTA_EXPECT_FALSE(info_logger_.observed())) {
122 info_logger_ << "Append BIU request queue!";
123 }
124 }
125
126}
Set of macros for Sparta assertions. Caught by the framework.
#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)
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
group_idx_type getGroupIdx() const
Gets the group index of this node.
Macros for handling exponential backoff.