mcFrontEnd.cc

Go to the documentation of this file.
00001 /*
00002  * =====================================================================================
00003  *
00004  *       Filename:  mcFrontEnd.cc
00005  *
00006  *    Description: Implements the interface to the memory controller module.
00007  *    Can be used as an example of how to interface other cycle accurate
00008  *    simulators to IRIS
00009  *
00010  *        Version:  1.0
00011  *        Created:  03/11/2010 05:12:58 PM
00012  *       Revision:  none
00013  *       Compiler:  gcc
00014  *
00015  *         Author:  Mitchelle Rasquinha (), mitchelle.rasquinha@gatech.edu
00016  *        Company:  Georgia Institute of Technology
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 //#include      "../frontend/impl/mesh.h"
00027 
00028 //#define SEND_ONE_PACKET 1
00029 using namespace std;
00030 
00031 McFrontEnd::McFrontEnd()
00032 {
00033     name = "mcFrontEnd";
00034     //interface_connections.resize(1);
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    //  send ready events for each virtual channel
00079 
00080       //  IrisEvent* event = new IrisEvent();
00081       //  event->type = DETECT_DEADLOCK_EVENT;
00082       //  Simulator::Schedule( floor(Simulator::Now())+1, &NetworkComponent::process_event, this, event);
00083     return ;
00084 } /* ----- end of function GenericTPG::setup ----- */
00085 
00086 void
00087 McFrontEnd::set_output_path( string name)
00088 {
00089     // open the output trace file
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     if( !out_file.is_open() )
00096     {
00097         cout << "Could not open output trace file " << out_filename << ".\n";
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         //case DETECT_DEADLOCK_EVENT:
00124           //  handle_detect_deadlock_event(e);
00125             //break;
00126         default:
00127             cout << "McFrontEnd:: Unk event exception" << endl;
00128             break;
00129     }
00130     return ;
00131 } /* ----- end of function GenericTPG::process_event ----- */
00132 
00133 void McFrontEnd::add_mc_bits(Request *req)
00134 {
00135     //cout << "Address before adding mcbits 0x" << hex << req->address << endl; 
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;//(ullint)((0xFFFFFFFF)-(pow(2.0,temp*1.0)-1));
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     //cout << "Before stripping address 0x" << hex << req->address;
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         //cout << "Interface size " << interface_connections.size() << endl;
00196 //    _DBG_NOARG("I reached here");
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; //static_cast<HighLevelPacket*>(e->event_data.at(0));
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 //      cout << "\n[" << Simulator::Now() << "] mcFrontEnd got packet " << hex << req->address << dec << " from Uncore" << req->threadId << endl;
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         // send back a ready event
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 /*        if(hlp!=NULL)
00274         {
00275                 if (e->src_id != interface_connections[0]->address)
00276                         cout << Simulator::Now() << " minhaj" << endl;  
00277                 else
00278                         cout << Simulator::Now() << " mitch" << endl;
00279             outstanding_hlp[hlp->virtual_channel] = hlp; //static_cast<HighLevelPacket*>(e->event_data.at(0));
00280         }
00281         else
00282         {
00283             cout << Simulator::Now() << " Dhruv" << endl;
00284             assert(e->src_id != interface_connections[0]->address);     
00285             for( uint i=0; i<vcs; i++)
00286                 outstanding_hlp[i] = NULL;
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         //        if( ((MC*)mc)->responseH->responseBuffer.size() > 64)
00326         //            cout << " Resp buffer exceeded Time: " << Simulator::Now() << " size: " << ((MC*)mc)->responseH->responseBuffer.size()<< endl;
00327 
00328         //  Send a high level packet now 
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; //ask response handler for more
00363             event3->dst = ((MC*)mc)->responseH; //e->vc;
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    void 
00377    McFrontEnd::handle_detect_deadlock_event(IrisEvent* e)
00378    {
00379    if( (Simulator::Now() - last_out_pull_cycle) > 30000 )
00380    {
00381    cout << "ERROR IN mcFrontEnd" << endl;
00382    exit(1);
00383    }
00384    e->type = DETECT_DEADLOCK_EVENT;
00385    Simulator::Schedule( floor(Simulator::Now())+50, &NetworkComponent::process_event, this, e);
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     //    _DBG(" mcFrontEnd GOT READY %d",e->vc);
00397     if( ready[e->vc] )
00398     {
00399         cout << " Error Recv incorrect READY !" << endl;
00400         exit(1);
00401     }
00402     ready[e->vc] = true;
00403     // send the next packet if it is less than the current time
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    void 
00418    McFrontEnd::handle_old_packet_event(IrisEvent* e)
00419    {
00420 #ifdef _DEBUG
00421 cout << "mcFrontEnd " << address << " handle_old_packet_event " << e->vc ;
00422 #endif
00423 
00424 if (!((MC*)mc)->reqH->oneBufferFull)
00425 {
00426 HighLevelPacket* hlp = static_cast<HighLevelPacket*>(e->event_data.at(0));
00427 Request* req = new Request();
00428 convertFromBitStream(req, hlp);
00429 req->arrivalTime = hlp->recv_time; 
00430 IrisEvent *e2 = new IrisEvent();
00431 e2->src = this;
00432 e2->dst = (Component*)((MC*)mc)->reqH;
00433 e2->event_data.push_back((void*)req);
00434 e2->type = START;       
00435 Simulator::Schedule(Simulator::Now()+1, &RequestHandler::process_event, (RequestHandler*)e2->dst, e2);
00436 
00437 IrisEvent* event = new IrisEvent();
00438 event->type = READY_EVENT;
00439 VirtualChannelDescription* vc = new VirtualChannelDescription();
00440 event->vc = 0;
00441 event->event_data.push_back(vc);
00442 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, interface_connections[0], event);
00443 delete hlp;
00444 }
00445 else
00446 {
00447 IrisEvent* event2 = new IrisEvent();
00448 event2->type = OLD_PACKET_EVENT;
00449 event2->event_data.push_back(e->event_data.at(0));
00450 Simulator::Schedule(Simulator::Now()+1, &NetworkComponent::process_event, this, event2);
00451 }
00452 
00453 // Send ready event back 
00454 delete e;
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     //    vector<Request>::iterator queueIndex = niQueue.begin();
00474     if (!niQueue.empty())
00475     {   
00476         *req = niQueue[0];
00477         //        niQueue.erase(queueIndex);
00478         return true;
00479     }
00480     else
00481         return false;
00482 }
00483 
00484 void 
00485 McFrontEnd::convertToBitStream(Request* req, HighLevelPacket *hlp)
00486 {
00487     //cout << "HLP data " << endl;
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     //cout << endl;
00494     /*    for ( uint i=0 ; i < NETWORK_COMMAND_BITS ; i++ )
00495           {
00496           bool bit = (bool)((req->cmdType >> i) & 0x1); 
00497           hlp->data.push_back(bit);
00498           }
00499           for( uint i=0 ; i < NETWORK_THREADID_BITS ; i++ )
00500           {
00501           bool bit = (bool)((req->threadId >> i) & 0x1); 
00502           hlp->data.push_back(bit);
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;   // sending 0's as data 
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     /*     req->data.value = 0;
00545            if (req->cmdType == CACHE_WRITEBACK)
00546            for ( uint i=0 ; i < 8*WRITEBACK_SIZE ; i++ )
00547            {
00548            req->data.value = req->data.value | (hlp->data[i+NETWORK_ADDRESS_BITS+NETWORK_COMMAND_BITS+NETWORK_THREADID_BITS] << i);
00549            req->data.size = WRITEBACK_SIZE;
00550            }*/
00551 }
00552 
00553 string
00554 McFrontEnd::print_stats() const
00555 {
00556     stringstream str;
00557     //    str << "\n mcFrontEnd addr: " << address <<endl;
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   /* ----- #ifndef _mcFrontEnd_cc_INC  ----- */

Generated on Tue Oct 19 17:22:00 2010 for IRIS by  doxygen 1.5.8