mcFrontEnd.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _mcFrontEnd_cc_INC
00021 #define _mcFrontEnd_cc_INC
00022
00023 #include "mcFrontEnd.h"
00024 #include "../../../memctrl/MC.h"
00025 #include "../../../memctrl/response_handler.h"
00026
00027
00028
00029 using namespace std;
00030
00031 McFrontEnd::McFrontEnd()
00032 {
00033 name = "mcFrontEnd";
00034
00035 mc = (Component*)(new MC());
00036 ((MC*)mc)->parent = this;
00037 ((MC*)mc)->ni = this;
00038 ((MC*)mc)->Init();
00039 ni_recv = false;
00040 }
00041
00042 McFrontEnd::~McFrontEnd()
00043 {
00044 }
00045
00046 void
00047 McFrontEnd::set_no_vcs ( uint v)
00048 {
00049 vcs = v;
00050 }
00051
00052 void
00053 McFrontEnd::setup(uint n, uint v, uint time)
00054 {
00055
00056 vcs =v;
00057 max_sim_time = time;
00058 no_nodes = n;
00059 packets = 0;
00060 total_missed_time = 0;
00061 packets_out = 0;
00062 total_backward_time = 0;
00063 missed_time = 0;
00064 avg_resp_buff_occ = 0;
00065 resp_buff_occ_cycles = 0;
00066 address = myId();
00067 node_ip = address/3;
00068 last_vc = 0;
00069 flast_vc = 0;
00070 ((MC*)mc)->id = node_ip;
00071 ready.resize( vcs );
00072 outstanding_hlp.resize( vcs );
00073 ready.insert( ready.begin(), ready.size(), false );
00074 for(unsigned int i = 0; i < vcs; i++)
00075 ready[i] = true;
00076
00077
00078
00079
00080
00081
00082
00083 return ;
00084 }
00085
00086 void
00087 McFrontEnd::set_output_path( string name)
00088 {
00089
00090 stringstream str;
00091 str << name << "/ni_" << node_ip << "_trace_out.tr";
00092 out_filename = str.str();
00093 out_file.open(out_filename.c_str());
00094
00095
00096
00097
00098
00099
00100 }
00101
00102 void
00103 McFrontEnd::finish()
00104 {
00105 out_file.close();
00106 }
00107
00108
00109 void
00110 McFrontEnd::process_event(IrisEvent* e)
00111 {
00112 switch(e->type)
00113 {
00114 case NEW_PACKET_EVENT:
00115 handle_new_packet_event(e);
00116 break;
00117 case OUT_PULL_EVENT:
00118 handle_out_pull_event(e);
00119 break;
00120 case READY_EVENT:
00121 handle_ready_event(e);
00122 break;
00123
00124
00125
00126 default:
00127 cout << "McFrontEnd:: Unk event exception" << endl;
00128 break;
00129 }
00130 return ;
00131 }
00132
00133 void McFrontEnd::add_mc_bits(Request *req)
00134 {
00135
00136 ullint addr = req->address;
00137 unsigned int temp = MC_ADDR_BITS;
00138 ullint temp2 = temp-(int)log2(no_mcs);
00139
00140 ullint lower_mask = (uint)pow(2.0,temp2*1.0)-1;
00141 ullint upper_mask = ~lower_mask;
00142
00143 ullint lower_addr = (addr) & lower_mask;
00144 ullint upper_addr = ((addr) & upper_mask) << (int)log2(no_mcs);
00145
00146 vector<unsigned int>::iterator itr;
00147 itr = find(mc_positions.begin(), mc_positions.end(), node_ip);
00148
00149 ullint mc_addr =((itr-mc_positions.begin()) << temp2);
00150
00151 req->address = upper_addr | lower_addr | mc_addr;
00152 #ifdef _DEBUG
00153 cout << endl << hex << "Adding McBits 0x" << req->address << " upper_mask 0x" << upper_mask << " lower_mask 0x" << lower_mask << " Upper Addr 0x" << upper_addr << " Lower Addr 0x" << lower_addr << " mc_addr 0x" << mc_addr << " 0x" << (itr-mc_positions.begin()) << endl;
00154 #endif
00155 }
00156
00157
00158 void McFrontEnd::strip_mc_bits(Request *req)
00159 {
00160 ullint addr = req->address;
00161 ullint temp = MC_ADDR_BITS;
00162 ullint temp2 = temp-(int)log2(no_mcs);
00163 ullint lower_mask = (uint)pow(2.0,temp2*1.0)-1;
00164 #ifdef _64BIT
00165 ullint upper_mask = (ullint)((0xFFFFFFFFFFFF)-(pow(2.0,temp*1.0)-1));
00166 #else
00167 ullint upper_mask = (ullint)((0xFFFFFFFF)-(pow(2.0,temp*1.0)-1));
00168 #endif
00169 ullint lower_addr = (addr) & lower_mask;
00170 ullint upper_addr = ((addr) & upper_mask) >> (int)log2(no_mcs);
00171
00172 #ifdef GLOBAL_XOR
00173 short int tempBits = (int)log2(NO_OF_THREADS) - (int)log2(no_mcs);
00174 short int tempFactor = ((id >> tempBits) & (no_mcs-1));
00175 short int mc_addr = (((addr) >> temp2) & (no_mcs-1)) ^ tempFactor;
00176 #else
00177 short int mc_addr = ((addr) >> temp2) & (no_mcs-1);
00178 #endif
00179 vector<unsigned int>::iterator itr;
00180 itr = find(mc_positions.begin(), mc_positions.end(), node_ip);
00181
00182 req->address = upper_addr | lower_addr;
00183 #ifdef _DEBUG
00184 cout << endl << hex << "Stripping Address 0x" << req->address << " upper_mask 0x" << upper_mask << " lower_mask 0x" << lower_mask << " Upper Addr 0x" << upper_addr << " Lower Addr 0x" << lower_addr << " mc_addr 0x" << mc_addr << " 0x" << (itr-mc_positions.begin()) << endl;
00185 #endif
00186 assert(mc_addr== (itr-mc_positions.begin() ) );
00187 }
00188
00189
00190
00191 void
00192 McFrontEnd::handle_new_packet_event(IrisEvent* e)
00193 {
00194 ni_recv = false;
00195
00196
00197 #ifdef _DEBUG
00198 _DBG(" mcFrontEnd handle_new_packet_event %s \n Int from is %s %d", e->toString().c_str(), interface_connections[0]->toString().c_str(),e->vc);
00199 cout << endl;
00200 #endif
00201 HighLevelPacket* hlp = NULL;
00202 if(e->src_id == interface_connections[0]->address)
00203 {
00204 hlp = static_cast<HighLevelPacket*>(e->event_data.at(0));
00205 outstanding_hlp[hlp->virtual_channel] = hlp;
00206 }
00207
00208 bool found = false;;
00209 for( uint i=flast_vc+1; i<vcs; i++)
00210 if( outstanding_hlp[i]!=NULL)
00211 {
00212 hlp = outstanding_hlp[i];
00213 flast_vc = i;
00214 found = true;
00215 break;
00216 }
00217 if( !found)
00218 for( uint i=0; i<=flast_vc;i++)
00219 if( outstanding_hlp[i]!=NULL)
00220 {
00221 hlp = outstanding_hlp[i];
00222 flast_vc = i;
00223 found = true;
00224 break;
00225 }
00226
00227
00228 if (!((MC*)mc)->reqH->oneBufferFull && hlp!=NULL)
00229 {
00230
00231 Request* req = new Request();
00232 convertFromBitStream(req, hlp);
00233 req->startTime = hlp->req_start_time;
00234 req->hop_count = hlp->hop_count;
00235 req->avg_network_latency = hlp->avg_network_latency;
00236 req->arrivalTime = hlp->recv_time;
00237 total_missed_time += (ullint)(ceil(Simulator::Now()) - hlp->recv_time);
00238 packets++;
00239 last_pkt_out_cycle = (ullint)ceil(Simulator::Now());
00240
00241 strip_mc_bits(req);
00242
00243
00244 IrisEvent *e2 = new IrisEvent();
00245 e2->src = this;
00246 e2->dst = ((MC*)mc)->reqH;
00247 e2->event_data.push_back((void*)req);
00248 e2->type = START;
00249 Simulator::Schedule(ceil(Simulator::Now())+1, &RequestHandler::process_event, (RequestHandler*)e2->dst, e2);
00250
00251
00252 IrisEvent* event = new IrisEvent();
00253 event->type = READY_EVENT;
00254 event->vc = hlp->virtual_channel;
00255 Simulator::Schedule( ceil(Simulator::Now())+1, &NetworkComponent::process_event, interface_connections[0], event);
00256 outstanding_hlp[hlp->virtual_channel] = NULL;
00257 delete hlp;
00258 }
00259 else
00260 {
00261 if(hlp)
00262 {
00263 IrisEvent* event = new IrisEvent();
00264 event->type = NEW_PACKET_EVENT;
00265 event->event_data.push_back(hlp);
00266 event->src_id = address;
00267 event->vc = hlp->virtual_channel;
00268 Simulator::Schedule(floor(Simulator::Now())+ 1,
00269 &NetworkComponent::process_event, this, event);
00270 ni_recv = true;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 }
00290 delete e;
00291 return ;
00292 }
00293
00294 void
00295 McFrontEnd::handle_out_pull_event(IrisEvent* e)
00296 {
00297 bool found = false;
00298 uint sending_vc = -1;
00299 for( uint i=last_vc+1; i<vcs; i++)
00300 if( ready[i])
00301 {
00302 found = true;
00303 sending_vc = i;
00304 last_vc = i;
00305 break;
00306 }
00307 if ( !found)
00308 {
00309 for ( uint i=0; i<=last_vc; i++)
00310 if( ready[i])
00311 {
00312 found = true;
00313 sending_vc = i;
00314 last_vc = i;
00315 break;
00316 }
00317 }
00318
00319
00320 Request* req = new Request();
00321 if ( found && GetFrommcFrontEndQueue(req))
00322 {
00323 avg_resp_buff_occ += ((MC*)mc)->responseH->responseBuffer.size();
00324 resp_buff_occ_cycles++;
00325
00326
00327
00328
00329 vector<Request>::iterator queueIndex = niQueue.begin();
00330 IrisEvent* event = new IrisEvent();
00331 HighLevelPacket* hlp = new HighLevelPacket();
00332 event->type = NEW_PACKET_EVENT;
00333 hlp->virtual_channel = sending_vc;
00334 hlp->source = node_ip;
00335 hlp->recv_time = (ullint)Simulator::Now();
00336 add_mc_bits(req);
00337 hlp->addr = req->address;
00338 hlp->destination = req->threadId;
00339 hlp->transaction_id = 1000;
00340 hlp->msg_class = RESPONSE_PKT;
00341 hlp->req_start_time = req->startTime;
00342 hlp->hop_count = req->hop_count;
00343 hlp->avg_network_latency = req->avg_network_latency;
00344 hlp->waiting_in_ni = (ullint)Simulator::Now() - req->retireTime;
00345 hlp->stat_memory_serviced_time = req->retireTime - req->arrivalTime;
00346
00347 convertToBitStream(req, hlp);
00348 #ifdef _DEBUG
00349 cout << dec << "\n[" << Simulator::Now() << "] Sending packet from mcFrontEnd 0x" << hex << req->address << endl;
00350 #endif
00351 hlp->sent_time = (ullint)Simulator::Now();
00352 total_backward_time += ((ullint)Simulator::Now() - req->retireTime);
00353 packets_out++;
00354
00355 event->event_data.push_back(hlp);
00356 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event,interface_connections[0], event);
00357
00358 ready[sending_vc] = false;
00359 niQueue.erase(queueIndex);
00360
00361 IrisEvent* event3 = new IrisEvent();
00362 event3->type = SEND_TO_NI;
00363 event3->dst = ((MC*)mc)->responseH;
00364 Simulator::Schedule(Simulator::Now()+1, &ResponseHandler::process_event, (ResponseHandler*)event3->dst, event3);
00365
00366 last_out_pull_cycle = Simulator::Now();
00367 }
00368
00369 else
00370 sending = false;
00371
00372 delete req;
00373 delete e;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 void
00389 McFrontEnd::handle_ready_event(IrisEvent* e)
00390 {
00391 if ( e->vc > vcs )
00392 {
00393 _DBG(" Got ready for vc %d no_vcs %d ", e->vc, vcs);
00394 exit(1);
00395 }
00396
00397 if( ready[e->vc] )
00398 {
00399 cout << " Error Recv incorrect READY !" << endl;
00400 exit(1);
00401 }
00402 ready[e->vc] = true;
00403
00404 if( Simulator::Now() < max_sim_time )
00405 {
00406 IrisEvent* event = new IrisEvent();
00407 event->type = OUT_PULL_EVENT;
00408 event->vc = e->vc;
00409 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event);
00410 sending = true;
00411 }
00412 delete e;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 string
00459 McFrontEnd::toString() const
00460 {
00461 stringstream str;
00462 str << "mcFrontEnd"
00463 << "\t addr: " << address
00464 << "\tOutput File= " << out_filename
00465 << "\tInt is " << interface_connections[0]->address
00466 ;
00467 return str.str();
00468 }
00469
00470 bool
00471 McFrontEnd::GetFrommcFrontEndQueue(Request* req)
00472 {
00473
00474 if (!niQueue.empty())
00475 {
00476 *req = niQueue[0];
00477
00478 return true;
00479 }
00480 else
00481 return false;
00482 }
00483
00484 void
00485 McFrontEnd::convertToBitStream(Request* req, HighLevelPacket *hlp)
00486 {
00487
00488 for ( uint i=0 ; i < NETWORK_ADDRESS_BITS ; i++ )
00489 {
00490 bool bit = (bool)((req->address >> i) & 0x1);
00491 hlp->data.push_back(bit);
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 if (req->cmdType == CACHE_READ || req->cmdType == CACHE_WRITE || req->cmdType == CACHE_PREFETCH)
00507 for ( uint i= hlp->data.size(); i < (8*CACHE_BLOCK_SIZE - max_phy_link_bits); i++ )
00508 {
00509 bool bit = false;
00510 hlp->data.push_back(bit);
00511 }
00512
00513 hlp->data_payload_length = (ullint)ceil(hlp->data.size() *1.0 / max_phy_link_bits);
00514 hlp->data_payload_length = hlp->data_payload_length * max_phy_link_bits;
00515
00516 for ( uint i=hlp->data.size(); i < hlp->data_payload_length; i++ )
00517 {
00518 bool bit = false;
00519 hlp->data.push_back(bit);
00520 }
00521 }
00522
00523 void
00524 McFrontEnd::convertFromBitStream(Request* req, HighLevelPacket *hlp)
00525 {
00526 req->address = 0;
00527 for (unsigned int i=0; i < NETWORK_ADDRESS_BITS; i++)
00528 {
00529 ullint bit = hlp->data[i];
00530 req->address = req->address | (bit << i);
00531 }
00532 unsigned int temp = 0;
00533 for (unsigned int i = 0; i < NETWORK_COMMAND_BITS; i++)
00534 {
00535 temp = temp | (hlp->data[i+NETWORK_ADDRESS_BITS] << i);
00536 }
00537 req->cmdType = (cache_command)temp;
00538
00539 req->threadId = 0;
00540 for (unsigned int i=0; i < NETWORK_THREADID_BITS; i++)
00541 {
00542 req->threadId = req->threadId | (hlp->data[i+NETWORK_ADDRESS_BITS+NETWORK_COMMAND_BITS] << i);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 }
00552
00553 string
00554 McFrontEnd::print_stats() const
00555 {
00556 stringstream str;
00557
00558 ((MC*)mc)->stats->CalculateAggregateStats();
00559 str << ((MC*)mc)->stats->PrintAggregateStats(node_ip);
00560 str << "mcFrontEnd [" << node_ip << "] " << "last_pkt_out_cycle:\t" << last_pkt_out_cycle << endl;
00561 str << "mcFrontEnd [" << node_ip << "] " << "total_missed_time:\t" << total_missed_time<< endl;
00562 str << "mcFrontEnd [" << node_ip << "] " << "packets_in:\t" << packets << endl;
00563 str << "mcFrontEnd [" << node_ip << "] " << "packets_out:\t" << packets_out << endl;
00564 str << "mcFrontEnd [" << node_ip << "] " << "total_backward_time:\t" << total_backward_time << endl;
00565 str << "mcFrontEnd [" << node_ip << "] " << "avg_latency_waiting_in_ni(fwd path):\t" << (total_missed_time+0.0)/packets << endl;
00566 str << "mcFrontEnd [" << node_ip << "] " << "avg_latency_waiting_in_ni(bwd path):\t" << (total_backward_time+0.0)/packets_out << endl;
00567 if ( resp_buff_occ_cycles != 0)
00568 str << "mcFrontEnd [" << node_ip << "] " << "Resp buff occ:\t" << avg_resp_buff_occ/resp_buff_occ_cycles<< endl;
00569
00570 return str.str();
00571 }
00572
00573 #endif