void TrafficManager::_Step() { Flit *f; Credit *cred; // Inject traffic if (_voqing) { _VOQInject(); } else { _ClassInject(); } // Advance network _net->ReadInputs(); _partial_internal_cycles += _internal_speedup; while (_partial_internal_cycles >= 1.0) { _net->InternalStep(); _partial_internal_cycles -= 1.0; } _net->WriteOutputs(); ++_time; // Eject traffic and send credits for (int output = 0; output < _dests; ++output) { f = _net->ReadFlit(output); if (f) { if (f->watch) { cout << "ejected flit " << f->id << " at output " << output << endl; cout << "sending credit for " << f->vc << endl; } cred = new Credit(1); cred->vc[0] = f->vc; cred->vc_cnt = 1; cred->head = f->head; cred->tail = f->tail; _net->WriteCredit(cred, output); if (f->head && (f->dest != output)) { cout << "At output " << output << endl; cout << *f; Error("Flit arrived at incorrect output"); } if (_reorder) { if (f->watch) { cout << "adding flit " << f->id << " to reorder buffer" << endl; cout << "flit's SN is " << f->sn << " buffer's SN is " << _rob_sqn[f->src][f->dest] << endl; } if (f->sn > _rob_sqn_max[f->src][f->dest]) { _rob_sqn_max[f->src][f->dest] = f->sn; } if (f->head) { _rob_size->AddSample(f->sn - _rob_sqn[f->src][f->dest]); } f->rob_time = _time; _rob[f->src][output].push(f); } else { _RetireFlit(f, output); if (!_empty_network) { _accepted_packets[output]->AddSample(1); } } } else { _net->WriteCredit(0, output); if (!_reorder && !_empty_network) { _accepted_packets[output]->AddSample(0); } } if (_reorder) { f = _ReadROB(output); if (f) { if (f->watch) { cout << "flit " << f->id << " removed from ROB at output " << output << endl; } _RetireFlit(f, output); if (!_empty_network) { _accepted_packets[output]->AddSample(1); } } else { if (!_empty_network) { _accepted_packets[output]->AddSample(0); } } } } }
void TrafficManager::_Step( ) { Flit *f; Credit *cred; // Inject traffic if ( _voqing ) { _VOQInject( ); } else { _ClassInject( ); } // Advance network _net->ReadInputs( ); _partial_internal_cycles += _internal_speedup; while ( _partial_internal_cycles >= 1.0 ) { _net->InternalStep( ); _partial_internal_cycles -= 1.0; } _net->WriteOutputs( ); ++_time; // Eject traffic and send credits Flit *last_valid_flit; //= new Flit; for ( int output = 0; output < _dests; ++output ) { f = _net->ReadFlit( output ); if ( f ) { if (1 || f->tail) { write_out_buf(output, f); // it should have space! if ( f->watch ) { cout << "Sent flit " << f->id << " to output buffer " << output << endl; cout << " Not sending the credit yet! " <<endl; } } else { if ( f->watch ) { cout << "ejected flit " << f->id << " at output " << output << endl; cout << "sending credit for " << f->vc << endl; } if ( _reorder ) { if ( f->watch ) { cout << "adding flit " << f->id << " to reorder buffer" << endl; cout << "flit's SN is " << f->sn << " buffer's SN is " << _rob_sqn[f->src][f->dest] << endl; } if ( f->sn > _rob_sqn_max[f->src][f->dest] ) { _rob_sqn_max[f->src][f->dest] = f->sn; } if ( f->head ) { _rob_size->AddSample( f->sn - _rob_sqn[f->src][f->dest] ); } f->rob_time = _time; _rob[f->src][output].push( f ); } else { _RetireFlit( f, output ); if ( !_empty_network ) { _accepted_packets[output]->AddSample( 1 ); } } } } transfer2boundary_buf( output ); if (!credit_return_queue[output].empty()) { last_valid_flit = credit_return_queue[output].front(); credit_return_queue[output].pop(); } else { last_valid_flit=NULL; } if (last_valid_flit) { cred = new Credit( 1 ); cred->vc[0] =last_valid_flit->vc; cred->vc_cnt = 1; cred->head = last_valid_flit->head; cred->tail =last_valid_flit->tail; _net->WriteCredit( cred, output ); if (last_valid_flit->watch) { cout <<"WE WROTE A CREDIT for flit "<<last_valid_flit->id<<"To output "<<output<< endl; } _RetireFlit(last_valid_flit, output ); if ( !_empty_network ) { _accepted_packets[output]->AddSample( 1 ); } } else { _net->WriteCredit( 0, output ); if ( !_reorder && !_empty_network) { _accepted_packets[output]->AddSample( 0 ); } } if ( _reorder ) { f = _ReadROB( output ); if ( f ) { if ( f->watch ) { cout << "flit " << f->id << " removed from ROB at output " << output << endl; } _RetireFlit( f, output ); if ( !_empty_network ) { _accepted_packets[output]->AddSample( 1 ); } } else { if ( !_empty_network ) { _accepted_packets[output]->AddSample( 0 ); } } } } }
void GPUTrafficManager::_Step() { bool flits_in_flight = false; for(int c = 0; c < _classes; ++c) { flits_in_flight |= !_total_in_flight_flits[c].empty(); } if(flits_in_flight && (_deadlock_timer++ >= _deadlock_warn_timeout)){ _deadlock_timer = 0; cout << "WARNING: Possible network deadlock.\n"; } vector<map<int, Flit *> > flits(_subnets); for ( int subnet = 0; subnet < _subnets; ++subnet ) { for ( int n = 0; n < _nodes; ++n ) { Flit * const f = _net[subnet]->ReadFlit( n ); if ( f ) { if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Ejecting flit " << f->id << " (packet " << f->pid << ")" << " from VC " << f->vc << "." << endl; } if(g_hpcl_comp_config.hpcl_comp_en == 0) { g_icnt_interface->WriteOutBuffer(subnet, n, f); //added by kh(030816) g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1); /// } else { //added by kh (030816) //(2.1.a) all reply flits (even write reply) are injected to decompressor for maintaining the order of flits. //coming from the same vc //Decompression: WRITE_REPLY should go through decomp, although no data is compressed. //READ_REPLY = {f1,f2,f3,f4,f5}, WRITE_REPLY = {f6} //Problematic case queue: f1,f2,f6,f3,f4,f5. if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY) { //only sm receives assert(g_hpcl_global_decomp_pl_2B[n]); //inject a flit to decompressor hpcl_comp_pl_data* pl_data = new hpcl_comp_pl_data; pl_data->add_comp_pl_data(f); g_hpcl_global_decomp_pl_2B[n]->set_input_data(pl_data); //added by kh (030316) //set vc info to compressed flits. for(int i = 0; i < f->compressed_other_flits.size(); i++) { Flit* cf = f->compressed_other_flits[i]; assert(cf); cf->vc = f->vc; } /// //delete pl_data; //added by kh (030816) g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1); if(f->compressed_other_flits.size() > 0) { g_hpcl_network_anal->add_sample(hpcl_network_anal::READ_REPLY_COMP_FLIT_NO, f->compressed_other_flits.size()+1); } else { g_hpcl_network_anal->add_sample(hpcl_network_anal::READ_REPLY_UNCOMP_FLIT_NO, 1); } /// } else if(f->type == Flit::CTRL_MSG) { //(2.2.a) all ctrl flits are injected to decompressor //std::cout << "f->id " << f->id << " f->src " << f->src << " f->dest " << f->dest << " node " << n << std::endl; hpcl_comp_pl_data* pl_data = new hpcl_comp_pl_data; pl_data->add_comp_pl_data(f); g_hpcl_global_decomp_pl_2B[n]->set_input_data(pl_data); //added by kh (030816) g_hpcl_network_anal->add_sample(hpcl_network_anal::CTRL_FLIT_NO,1); /// } else { g_icnt_interface->WriteOutBuffer(subnet, n, f); //added by kh (030816) g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1); /// } /// } } g_icnt_interface->Transfer2BoundaryBuffer(subnet, n); Flit* const ejected_flit = g_icnt_interface->GetEjectedFlit(subnet, n); if (ejected_flit) { if(ejected_flit->head) assert(ejected_flit->dest == n); if(ejected_flit->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Ejected flit " << ejected_flit->id << " (packet " << ejected_flit->pid << " VC " << ejected_flit->vc << ")" << "from ejection buffer." << endl; } flits[subnet].insert(make_pair(n, ejected_flit)); if((_sim_state == warming_up) || (_sim_state == running)) { ++_accepted_flits[ejected_flit->cl][n]; if(ejected_flit->tail) { ++_accepted_packets[ejected_flit->cl][n]; } } } // Processing the credit From the network Credit * const c = _net[subnet]->ReadCredit( n ); if ( c ) { #ifdef TRACK_FLOWS for(set<int>::const_iterator iter = c->vc.begin(); iter != c->vc.end(); ++iter) { int const vc = *iter; assert(!_outstanding_classes[n][subnet][vc].empty()); int cl = _outstanding_classes[n][subnet][vc].front(); _outstanding_classes[n][subnet][vc].pop(); assert(_outstanding_credits[cl][subnet][n] > 0); --_outstanding_credits[cl][subnet][n]; } #endif _buf_states[n][subnet]->ProcessCredit(c); c->Free(); } } _net[subnet]->ReadInputs( ); } if(g_hpcl_comp_config.hpcl_comp_en == 1) { //added by kh (030816) //(2.3) Decompressor for(int i = 0; i < g_hpcl_global_decomp_pl_2B.size(); i++) { if(!g_hpcl_global_decomp_pl_2B[i]) continue; g_hpcl_global_decomp_pl_2B[i]->run(getTime()+getTotalTime()); hpcl_comp_pl_data* comp_pl_data = g_hpcl_global_decomp_pl_2B[i]->get_output_data(); Flit* flit = comp_pl_data->get_flit_ptr(); if(flit) { int subnet = 0; assert(flit->const_dest == i); //std::cout << "Flit " << flit->id << " type " << flit->type << " is out from decomp" << std::endl; /* std::cout << GetSimTime() << "| MYEJECT | node " << i << " Flit " << flit->id << " type " << flit->type << " tail " << flit->tail << " vc " << flit->vc; if(flit->type == Flit::ANY_TYPE) std::cout << " ctrl " << std::endl; else std::cout << " mf " << ((mem_fetch*)flit->data)->get_request_uid() << std::endl; */ //std::cout << "Flit " << flit->id << " enc_status " << flit->m_enc_status; #ifdef CORRECTNESS_CHECK if(flit->m_enc_status == 1) { std::cout << "dec_status " << flit->check_correctness() << std::endl; if(flit->check_correctness() == false) { printf("flit %d has incorrect decoding!\n", flit->id); printf("\traw_data = "); for(int k = flit->raw_data.size()-1; k >=0; k--) { printf("%02x", flit->raw_data[k]); } printf("\n"); printf("\tdec_data = "); for(int k = flit->decomp_data.size()-1; k >=0; k--) { printf("%02x", flit->decomp_data[k]); } printf("\n"); } } #endif g_icnt_interface->WriteOutBuffer(subnet, i, flit); } //reset output data g_hpcl_global_decomp_pl_2B[i]->reset_output_data(); } /// //added by kh (030816) //(1.2.c) generate/inject ctrl flit is injected to NI injection buffer for(int i = 0; i < g_hpcl_global_comp_pl_2B.size(); i++) { if(!g_hpcl_global_comp_pl_2B[i]) continue; if(g_hpcl_global_comp_pl_2B[i]->has_out_dict_ctrl_msg() == false) continue; if(g_hpcl_global_comp_pl_2B[i]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN) continue; hpcl_dict_ctrl_msg<unsigned short>* ctrl_msg = g_hpcl_global_comp_pl_2B[i]->front_out_dict_ctrl_msg(); int packet_size = 1; //1 flit Flit::FlitType packet_type = Flit::CTRL_MSG; void* data = NULL; assert(ctrl_msg->get_dest_node()>=0); int subnet = 0; int response_size = 32; //32bytes //send ctrl from MC int sender_device_id = -1; if(g_mc_placement_config.is_mc_node(i)) { sender_device_id = g_mc_placement_config.get_mc_node_index(i) + 56; //56 SMs and 8 MCs } assert(sender_device_id >= 0); int sender_node_id = i; int receiver_node_id = ctrl_msg->get_dest_node(); int receiver_device_id = g_mc_placement_config.get_sm_node_index(receiver_node_id); assert(sender_node_id>=0); assert(receiver_node_id>=0); if(g_icnt_interface->HasBuffer(sender_device_id, response_size)) { //std::cout << getTime()+getTotalTime() << " | " << " PUSH2 | " << " input " << sender_device_id << " output " << receiver_device_id << " ctrl_msg " << ctrl_msg->get_id(); //std::cout << std::endl; _GeneratePacket(sender_node_id, -1, 0, getTime(), subnet, packet_size, packet_type, ctrl_msg, receiver_node_id); g_hpcl_global_comp_pl_2B[i]->pop_out_dict_ctrl_msg(); // std::cout << "ctrl_msg | id " << ctrl_msg->get_id(); // std::cout << " | src_node " << ctrl_msg->get_src_node(); // std::cout << " | dest_node " << ctrl_msg->get_dest_node(); // std::cout << " | word_index " << ctrl_msg->get_word_index(); // std::cout << " | word " << ctrl_msg->get_new_word() << std::endl;; // // g_hpcl_global_comp_pl_2B[i]->validate_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word()); } } /// } // GPGPUSim will generate/inject packets from interconnection interface #if 0 if ( !_empty_network ) { _Inject(); } #endif for(int subnet = 0; subnet < _subnets; ++subnet) { for(int n = 0; n < _nodes; ++n) { Flit * f = NULL; BufferState * const dest_buf = _buf_states[n][subnet]; int const last_class = _last_class[n][subnet]; int class_limit = _classes; if(_hold_switch_for_packet) { list<Flit *> const & pp = _input_queue[subnet][n][last_class]; if(!pp.empty() && !pp.front()->head && !dest_buf->IsFullFor(pp.front()->vc)) { f = pp.front(); assert(f->vc == _last_vc[n][subnet][last_class]); // if we're holding the connection, we don't need to check that class // again in the for loop --class_limit; } } for(int i = 1; i <= class_limit; ++i) { int const c = (last_class + i) % _classes; list<Flit *> const & pp = _input_queue[subnet][n][c]; if(pp.empty()) { continue; } Flit * const cf = pp.front(); assert(cf); assert(cf->cl == c); assert(cf->subnetwork == subnet); if(g_hpcl_comp_config.hpcl_comp_en == 1) { //added by kh (030816) //If compressor is busy with compressing flits of a packet, //don't inject a head flit of a new packet to the busy compressor //compressor is only for read reply, but write reply goes through the compressor to avoid intermixed flits from different packets //Thus, the following filtering is not restricted to read reply, thus we have no flit type checking to read reply. if(g_mc_placement_config.is_mc_node(n) == true && cf->head == true) { if(g_hpcl_global_comp_pl_2B[n] && g_hpcl_global_comp_pl_2B[n]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN) { f = NULL; break; } } /// } if(f && (f->pri >= cf->pri)) { continue; } //KH: routing output port is decided here. if(cf->head && cf->vc == -1) { // Find first available VC //std::cout << "_Step is called!!!!" << std::endl; //assert(1 == 0); OutputSet route_set; _rf(NULL, cf, -1, &route_set, true); set<OutputSet::sSetElement> const & os = route_set.GetSet(); assert(os.size() == 1); OutputSet::sSetElement const & se = *os.begin(); assert(se.output_port == -1); int vc_start = se.vc_start; int vc_end = se.vc_end; int vc_count = vc_end - vc_start + 1; if(_noq) { assert(_lookahead_routing); const FlitChannel * inject = _net[subnet]->GetInject(n); const Router * router = inject->GetSink(); assert(router); int in_channel = inject->GetSinkPort(); // NOTE: Because the lookahead is not for injection, but for the // first hop, we have to temporarily set cf's VC to be non-negative // in order to avoid seting of an assertion in the routing function. cf->vc = vc_start; _rf(router, cf, in_channel, &cf->la_route_set, false); cf->vc = -1; if(cf->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Generating lookahead routing info for flit " << cf->id << " (NOQ)." << endl; } set<OutputSet::sSetElement> const sl = cf->la_route_set.GetSet(); assert(sl.size() == 1); int next_output = sl.begin()->output_port; vc_count /= router->NumOutputs(); vc_start += next_output * vc_count; vc_end = vc_start + vc_count - 1; assert(vc_start >= se.vc_start && vc_start <= se.vc_end); assert(vc_end >= se.vc_start && vc_end <= se.vc_end); assert(vc_start <= vc_end); } if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Finding output VC for flit " << cf->id << ":" << endl; } for(int i = 1; i <= vc_count; ++i) { int const lvc = _last_vc[n][subnet][c]; int const vc = (lvc < vc_start || lvc > vc_end) ? vc_start : (vc_start + (lvc - vc_start + i) % vc_count); assert((vc >= vc_start) && (vc <= vc_end)); if(!dest_buf->IsAvailableFor(vc)) { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << " Output VC " << vc << " is busy." << endl; } } else { if(dest_buf->IsFullFor(vc)) { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << " Output VC " << vc << " is full." << endl; } } else { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << " Selected output VC " << vc << "." << endl; } cf->vc = vc; break; } } } } if(cf->vc == -1) { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "No output VC found for flit " << cf->id << "." << endl; } } else { if(dest_buf->IsFullFor(cf->vc)) { if(cf->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Selected output VC " << cf->vc << " is full for flit " << cf->id << "." << endl; } } else { f = cf; } } } if(f) { assert(f->subnetwork == subnet); int const c = f->cl; if(f->head) { if (_lookahead_routing) { if(!_noq) { const FlitChannel * inject = _net[subnet]->GetInject(n); const Router * router = inject->GetSink(); assert(router); int in_channel = inject->GetSinkPort(); _rf(router, f, in_channel, &f->la_route_set, false); if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Generating lookahead routing info for flit " << f->id << "." << endl; } } else if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Already generated lookahead routing info for flit " << f->id << " (NOQ)." << endl; } } else { f->la_route_set.Clear(); } dest_buf->TakeBuffer(f->vc); _last_vc[n][subnet][c] = f->vc; } _last_class[n][subnet] = c; _input_queue[subnet][n][c].pop_front(); #ifdef TRACK_FLOWS ++_outstanding_credits[c][subnet][n]; _outstanding_classes[n][subnet][f->vc].push(c); #endif if(g_hpcl_comp_config.hpcl_comp_en == 0) { dest_buf->SendingFlit(f); } else { //added by kh(030816) //(1.1.a) send a head flit first: update buffer state if(g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::READ_REPLY) { if(f->head) dest_buf->SendingFlit(f); //skip for other flits } else { dest_buf->SendingFlit(f); } /// } if(_pri_type == network_age_based) { f->pri = numeric_limits<int>::max() - _time; assert(f->pri >= 0); } if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Injecting flit " << f->id << " into subnet " << subnet << " at time " << _time << " with priority " << f->pri << "." << endl; } f->itime = _time; // Pass VC "back" if(!_input_queue[subnet][n][c].empty() && !f->tail) { Flit * const nf = _input_queue[subnet][n][c].front(); nf->vc = f->vc; } if((_sim_state == warming_up) || (_sim_state == running)) { ++_sent_flits[c][n]; //added by kh(070215) ++_sent_flits_net[subnet][n]; if(f->head) { ++_sent_packets[c][n]; //added by kh(030816) if(f->type < Flit::ANY_TYPE) { //added by kh(121715) if(g_mc_placement_config.is_sm_node(n)) { ((mem_fetch*)f->data)->set_status(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_SM, _time); //added by kh(122815) double req_queuing_lat_in_sm = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_NI_INPUT_BUF_IN_SM); g_hpcl_network_anal->add_sample(hpcl_network_anal::REQ_QUEUING_LAT_IN_SM, req_queuing_lat_in_sm); /// } else if(g_mc_placement_config.is_mc_node(n)) { ((mem_fetch*)f->data)->set_status(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_MEM, _time); //added by kh(122815) double rep_queuing_lat_in_mc = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_NI_INPUT_BUF_IN_MEM); g_hpcl_network_anal->add_sample(hpcl_network_anal::REP_QUEUING_LAT_IN_MC, rep_queuing_lat_in_mc); /// } /// } } } #ifdef TRACK_FLOWS ++_injected_flits[c][n]; #endif if(g_hpcl_comp_config.hpcl_comp_en == 0) { _net[subnet]->WriteFlit(f, n); } else { //added by kh (021416) //Compression //(1.1.b) flits but a head flit are injected to the compressor if(g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::READ_REPLY) { hpcl_comp_pl_data* pl_data = NULL; //A head flit is found. It means other flits are in _input_queue now. //flits move from _input_queue to compressor by force. //Those flits are sent to network in different paths such that we set info for //flit navigation here. if(f->head == true) { assert(!_input_queue[subnet][n][c].empty()); Flit * body_flit = _input_queue[subnet][n][c].front(); _input_queue[subnet][n][c].pop_front(); if(_pri_type == network_age_based) { body_flit->pri = numeric_limits<int>::max() - _time; assert(body_flit->pri >= 0); } body_flit->itime = _time; // Pass VC "back" for next flit if(!_input_queue[subnet][n][c].empty() && !body_flit->tail) { Flit * const nf = _input_queue[subnet][n][c].front(); nf->vc = body_flit->vc; } ++_sent_flits[c][n]; ++_sent_flits_net[subnet][n]; pl_data = new hpcl_comp_pl_data; pl_data->add_comp_pl_data(body_flit); g_hpcl_global_comp_pl_2B[n]->set_input_data(pl_data); //delete pl_data; //(1.1.a) send a head flit first _net[subnet]->WriteFlit(f, n); } else { pl_data = new hpcl_comp_pl_data; pl_data->add_comp_pl_data(f); g_hpcl_global_comp_pl_2B[n]->set_input_data(pl_data); //delete pl_data; } //(1.2.a) words in a flit are pushed to a queue in a compressor if(pl_data) { Flit* flit = pl_data->get_flit_ptr(); assert(flit); //Use receiver's id as global dict index int global_dict_index = flit->const_dest; //Push words to be updated to word_queue (this is done at zero-time) vector<unsigned short> word_list; g_hpcl_global_comp_pl_2B[n]->decompose(flit->raw_data, word_list); for(int i = 0; i < word_list.size(); i++) g_hpcl_global_comp_pl_2B[n]->push_word_to_queue(word_list[i], global_dict_index); delete pl_data; } } else if (g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::CTRL_MSG) { hpcl_dict_ctrl_msg<unsigned short>* ctrl_msg = (hpcl_dict_ctrl_msg<unsigned short>*)f->data; /* std::cout << "ctrl_msg | id " << ctrl_msg->get_id(); std::cout << " | src_node " << ctrl_msg->get_src_node(); std::cout << " | dest_node " << ctrl_msg->get_dest_node(); std::cout << " | word_index " << ctrl_msg->get_word_index(); std::cout << " | word " << ctrl_msg->get_new_word(); std::cout << " | n " << n; std::cout << std::endl;; */ g_hpcl_global_comp_pl_2B[n]->release_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word()); g_hpcl_global_comp_pl_2B[n]->validate_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word()); _net[subnet]->WriteFlit(f, n); } else { _net[subnet]->WriteFlit(f, n); } /// } } } } if(g_hpcl_comp_config.hpcl_comp_en == 1) { //added by kh(030816) //(1.3) Compression: Pipelined Compression for(int i = 0; i < g_hpcl_global_comp_pl_2B.size(); i++) { if(!g_hpcl_global_comp_pl_2B[i]) continue; //(1.2.b) words in the queue are updated to dictionary, when idle state //(1.2.d) ctrl msgs for words with frequency (>= threshold) are generated in compressor's run function, when idle state g_hpcl_global_comp_pl_2B[i]->run(getTime()+getTotalTime()); hpcl_comp_pl_data* comp_pl_rsl = g_hpcl_global_comp_pl_2B[i]->get_output_data(); Flit* flit = comp_pl_rsl->get_flit_ptr(); if(flit) { //std::cout << "node " << i << " flit->id " << flit->id << std::endl; //(1.1.c) flits are injected from the compressor to an input buffer if(HasBufferSpace(i, flit)) { SendFlitToBuffer(i, flit); //for credit management. SendFlitToNetwork(i, flit); //std::cout << "\t" << " send flit " << flit->id << std::endl; if(g_hpcl_global_comp_pl_2B[i]->get_comp_done() == true) { assert(g_hpcl_global_comp_pl_2B[i]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN); g_hpcl_global_comp_pl_2B[i]->set_state(hpcl_comp_pl<unsigned short>::HPCL_COMP_IDLE); g_hpcl_global_comp_pl_2B[i]->reset_comp_done(); } //reset output data g_hpcl_global_comp_pl_2B[i]->reset_output_data(); } else { //std::cout << "\t" << " cannot send flit " << flit->id << " due to no space!!!!!!!!!!" << std::endl; } } } /// } //Send the credit To the network for(int subnet = 0; subnet < _subnets; ++subnet) { for(int n = 0; n < _nodes; ++n) { map<int, Flit *>::const_iterator iter = flits[subnet].find(n); if(iter != flits[subnet].end()) { Flit * const f = iter->second; f->atime = _time; //added by kh(070715) if(f->tail) { //added by kh(030816) if(f->type < Flit::ANY_TYPE) { //added by kh(121715) if(g_mc_placement_config.is_sm_node(n)) { //std::cout << "mf's id: " << ((mem_fetch*)f->data)->get_request_uid() << ", time: " << _time << std::endl; ((mem_fetch*)f->data)->set_status(TAIL_FLIT_EJECTED_FROM_EJECT_BUF_IN_SM, _time); //added by kh(122815) double rep_net_lat = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_MEM); g_hpcl_network_anal->add_sample(hpcl_network_anal::REP_NET_LAT, rep_net_lat); /// } else if(g_mc_placement_config.is_mc_node(n)) { ((mem_fetch*)f->data)->set_status(TAIL_FLIT_EJECTED_FROM_EJECT_BUF_IN_MEM, _time); //added by kh(122815) double req_net_lat = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_SM); g_hpcl_network_anal->add_sample(hpcl_network_anal::REQ_NET_LAT, req_net_lat); /// } } } /// if(f->watch) { *gWatchOut << GetSimTime() << " | " << "node" << n << " | " << "Injecting credit for VC " << f->vc << " into subnet " << subnet << "." << endl; } if(g_hpcl_comp_config.hpcl_comp_en == 0) { Credit * const c = Credit::New(); c->vc.insert(f->vc); _net[subnet]->WriteCredit(c, n); } else { //added by kh(030816) if(f->type == Flit::READ_REPLY) { if(f->tail == false && f->m_enc_status == 1) { } else { Credit * const c = Credit::New(); c->vc.insert(f->vc); _net[subnet]->WriteCredit(c, n); //std::cout << "\tf->vc " << f->vc << " f->id " << f->id << std::endl; } } else { Credit * const c = Credit::New(); c->vc.insert(f->vc); _net[subnet]->WriteCredit(c, n); } /// } #ifdef TRACK_FLOWS ++_ejected_flits[f->cl][n]; #endif _RetireFlit(f, n); } } flits[subnet].clear(); // _InteralStep here _net[subnet]->Evaluate( ); //run router's pipeline _net[subnet]->WriteOutputs( ); //send flits.. } ++_time; assert(_time); if(gTrace){ cout<<"TIME "<<_time<<endl; } }