00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _SAMPA_COMPONENT_CACHE_H_
00020 #define _SAMPA_COMPONENT_CACHE_H_
00021
00022 #include "sampa/core/module.h"
00023
00024 namespace Sampa {
00025
00026 class Cache : public Module {
00027 public:
00028 Cache(const Name&);
00029
00030 void bind_inst_initiator(Initiator*);
00031 void bind_data_initiator(Initiator*);
00032 Target* get_inst_target() { return &p_inst_slave; }
00033 Target* get_data_target() { return &p_data_slave; }
00034
00035 void bind_inst_target(Target*);
00036 void bind_data_target(Target*);
00037 Initiator* get_inst_initiator() { return &p_inst_master; }
00038 Initiator* get_data_initiator() { return &p_data_master; }
00039
00040 private:
00041 bool recieve_inst_response(const Response&);
00042 {
00043 if (m_inst_responses_pipe.is_empty())
00044 e_inst_response.notify_in_n_rising(m_response_pipeline_depth);
00045 short idx = m_inst_response_pipe.push();
00046 m_inst_response[idx] = response;
00047 m_inst_response_date[idx] = get_rising_count();
00048 return true;
00049 }
00050
00051 bool recieve_data_response(const Response& response)
00052 {
00053 if (m_data_responses_pipe.is_empty())
00054 e_data_response.notify_in_n_rising(m_response_pipeline_depth);
00055 short idx = m_inst_response_pipe.push();
00056 m_data_response[idx] = response;
00057 m_data_response_date[idx] = get_rising_count();
00058 return true;
00059 }
00060
00061 bool recieve_inst_request(const Request& req) {
00062 if (m_burst-- == 0) {
00063 m_inst_req.schedule(req);
00064 m_burst += req.get_burst();
00065 }
00066 return true;
00067 }
00068
00069 bool recieve_data_request(const Request&);
00070
00071 void fill_instruction() {
00072 if (m_inst_line_fill_pending) {
00073 m_inst_line_fill_pending = false;
00074 m_inst_req_out = m_inst_req;
00075 if (inst_miss()) {
00076 e_inst_request.notify_in_n_rising(2);
00077 }
00078 } else {
00079
00080
00081 }
00082 if (m_pending_inst_resp > 0) {
00083 m_pending_inst_resp--;
00084 p_inst_slave->send_response(m_inst_req);
00085 }
00086 }
00087
00088 void forward_data_request()
00089 {
00090 if (read_pending > 0) {
00091 } else if (eviction) {
00092 }
00093 }
00094
00095 void forward_data_response()
00096 {
00097 short idx = m_inst_response_pipe.pop();
00098 p_inst_slave->send_response(m_inst_responses[idx]);
00099 if (!m_inst_response_pipe.is_empty())
00100 e_inst_response.notify_in_n_rising(m_inst_responses_date[m_inst_response_pipe.peek()]+m_response_pipeline_depth- get_rising_count());
00101 }
00102
00103 void forward_inst_response()
00104 {
00105 short idx = m_inst_response_pipe.pop();
00106 p_inst_slave->send_response(m_inst_responses[idx]);
00107 if (!m_inst_response_pipe.is_empty())
00108 e_inst_response.notify_in_n_rising(m_inst_responses_date[m_inst_response_pipe.peek()]+m_response_pipeline_depth- get_rising_count());
00109 }
00110
00111 AdaptingTarget p_inst_slave;
00112 AdaptingTarget p_data_slave;
00113 AdaptingInitiator p_inst_master;
00114 AdaptingInitiator p_data_master;
00115
00116 EventSingle e_inst_response;
00117 EventSingle e_data_response;
00118 IntParameter m_response_pipeline_depth;
00119 Array<Response> m_inst_responses;
00120 Array<Response> m_data_responses;
00121 Gated<Request> m_inst_req;
00122 Gated<Request> m_data_req;
00123 };
00124 }
00125
00126 #endif
00127 bool read_hit(const Address& address)
00128 {
00129 return (cacheable(address) && sampa_rand01() >= m_read_miss_ratio);
00130 }
00131
00132 bool inst_hit(const Address& address)
00133 {
00134 return (cacheable(address) && sampa_rand01() >= m_inst_miss_ratio);
00135 }
00136
00137 bool write_hit(const Address& address)
00138 {
00139 return (cacheable(address) && sampa_rand01() >= m_write_miss_ratio);
00140 }
00141
00142 bool eviction_hit(const Address& address)
00143 {
00144 return (cacheable(address) && sampa_rand01() >= m_eviction_miss_ratio);
00145 }
00146
00147 void process_data()
00148 {
00149 switch (state) {
00150 case EVALUATE:
00151 if (request.get_command() == READ) {
00152
00153 if (read_hit(request.get_address())) {
00154 state = READ_HIT;
00155 e_forward.notify_in_n_rising(2);
00156 set_next_trigger(e_forward);
00157 } else {
00158 state = READ_MISS;
00159 e_forward.notify_in_n_rising(1);
00160 set_next_trigger(e_forward);
00161 }
00162 } else if (request.get_burst() > 1) {
00163
00164 e_forward.notify_in_n_rising(1);
00165 set_next_trigger(e_forward);
00166 if (eviction_hit(request.get_address())) {
00167 state = EVICTION_HIT;
00168 } else if (m_write_though) {
00169
00170 state = EVICTION_MISS;
00171 } else if (eviction()) {
00172
00173 state = EVICTION_BACK_EVICTION;
00174 } else {
00175
00176 state = STALL_EVICTION;
00177 }
00178 } else {
00179
00180 e_forward.notify_in_n_rising(1);
00181 set_next_trigger(e_forward);
00182 if (hit()) {
00183 state = WRITE_HIT;
00184 } else if (m_write_through) {
00185 state = WRITE_MISS;
00186 } else {
00187
00188 m_write_pending = true;
00189 state = MISS;
00190 }
00191 }
00192 m_burst += req.get_burst();
00193 if (hit()) {
00194 state = HIT;
00195 e_forward.notify_in_n_rising(2);
00196 set_next_trigger(e_forward);
00197 } else {
00198 state = MISS;
00199 e_forward.notify_in_n_rising(1);
00200 }
00201 break;
00202 case READ_HIT:
00203 set_next_trigger(p_data_slave->get_response_accepted_event());
00204 state = READ_HIT_NEXT;
00205
00206 case READ_HIT_NEXT:
00207 p_inst_slave->send_response();
00208 if (m_burst-- = 0) {
00209 state = EVALUATE;
00210 p_data_slave->accept_request();
00211 set_next_trigger(p_data_slave->get_request_accepted_event());
00212 }
00213 break;
00214 case MISS:
00215 if (m_pending_eviction) {
00216
00217 set_next_trigger();
00218 break;
00219 }
00220 set_next_trigger(p_inst_master->get_request_accepted_event());
00221 state = MISS_NEXT;
00222
00223 case MISS_NEXT:
00224 p_inst_master->send_request();
00225 if (m_burst-- != 0) break;
00226 if (eviction()) {
00227 m_eviction_requested |= 1<<INST;
00228 if (m_eviction_pending > 0) {
00229 state = STALL_EVICTION;
00230 set_next_trigger(e_eviction_granted[INST]);
00231 break;
00232 }
00233 }
00234
00235 case STALL_EVICTION:
00236 state = EVALUATE;
00237 p_inst_slave->accept_request();
00238 set_next_trigger(p_inst_slave->get_request_accepted_event());
00239 break;
00240 }
00241 }
00242
00243 void forward_data_request()
00244 {
00245 if (m_linefill_pending) {
00246 p_data_master->send_request();
00247 if (--m_linefill_pending == 0) {
00248 set_next_trigger(e_data_req_forward);
00249 if (m_eviction_requested != NONE)
00250 e_data_req_forward.notify_next_cycle();
00251 }
00252 } else if (m_eviction_pending > 0) {
00253 p_data_master->send_request();
00254 if (--m_eviction_pending == 0) {
00255 set_next_trigger(e_data_req_forward);
00256 if (m_eviction_requested != NONE)
00257 e_data_req_forward.notify_next_cycle();
00258 }
00259 } else if (m_linefill_requested) {
00260 m_linefill_pending = m_linefill_req.get_burst() - 1;
00261 p_data_master->send_request(m_linefill_req);
00262 set_next_trigger(p_data_master->get_request_accepted_event());
00263 } else if (m_eviction_requested) {
00264 m_eviction_elected = 1 - m_eviction_elected;
00265 if (!(m_eviction_requested&(1+m_eviction_elected)))
00266 m_eviction_elected = 1 - m_eviction_elected);
00267 m_eviction_requested &= ~(1+m_eviction_elected);
00268 e_eviction_granted[m_eviction_elected].notify_next_cycle();
00269 m_eviction_pending = m_eviction_req.get_burst() - 1;
00270 p_data_master->send_request(m_eviction_req);
00271 set_next_trigger(p_data_master->get_request_accepted_event());
00272 }
00273 }
00274
00275 void process_inst()
00276 {
00277 switch (state) {
00278 case EVALUATE:
00279 m_burst += req.get_burst();
00280 if (hit()) {
00281 state = HIT;
00282 e_forward.notify_in_n_rising(2);
00283 set_next_trigger(e_forward);
00284 } else {
00285 state = MISS;
00286 e_forward.notify_in_n_rising(1);
00287 }
00288 break;
00289 case HIT:
00290 set_next_trigger(p_inst_slave->get_response_accepted_event());
00291 state = HIT_NEXT;
00292
00293 case HIT_NEXT:
00294 p_inst_slave->send_response();
00295 if (m_burst-- = 0) {
00296 state = EVALUATE;
00297 p_inst_master->accept_request();
00298 set_next_trigger(p_inst_master->get_request_accepted_event());
00299 }
00300 break;
00301 case MISS:
00302 set_next_trigger(p_inst_master->get_request_accepted_event());
00303 state = MISS_NEXT;
00304
00305 case MISS_NEXT:
00306 p_inst_master->send_request();
00307 if (m_burst-- != 0) break;
00308 if (eviction()) {
00309 m_eviction_requested |= 1<<INST;
00310 if (m_eviction_pending > 0) {
00311 state = STALL_EVICTION;
00312 set_next_trigger(e_eviction_granted[INST]);
00313 break;
00314 }
00315 }
00316
00317 case STALL_EVICTION:
00318 state = EVALUATE;
00319 p_inst_slave->accept_request();
00320 set_next_trigger(p_inst_slave->get_request_accepted_event());
00321 break;
00322 }
00323 }
00324