void VC::UpdatePriority() { if(_buffer.empty()) return; if(_pri_type == queue_length_based) { _pri = _buffer.size(); } else if(_pri_type != none) { Flit * f = _buffer.front(); if((_pri_type != local_age_based) && _priority_donation) { Flit * df = f; for(size_t i = 1; i < _buffer.size(); ++i) { Flit * bf = _buffer[i]; if(bf->pri > df->pri) df = bf; } if((df != f) && (df->watch || f->watch)) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit " << df->id << " donates priority to flit " << f->id << "." << endl; } f = df; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit " << f->id << " sets priority to " << f->pri << "." << endl; _pri = f->pri; } }
void IQRouterBase::_OutputQueuing( ) { for ( int output = 0; output < _outputs; ++output ) { for ( int t = 0; t < _output_speedup; ++t ) { int expanded_output = _outputs*t + output; Flit * f = _crossbar_pipe->Read( expanded_output ); if ( f ) { _output_buffer[output].push( f ); if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Buffering flit " << f->id << " at output " << output << "." << endl; } } } for ( int input = 0; input < _inputs; ++input ) { Credit * c = _credit_pipe->Read( input ); if ( c ) { _in_cred_buffer[input].push( c ); } } }
//############################################################################// // // Function: FrameUpdate() // // Purpose: Perform frame update // //############################################################################// void FcRadar::FrameUpdate() { simTime = GetSimTime(); truPosX = pTgt->pxf; truPosY = pTgt->pyf; truVelX = pTgt->vxf - vxf; truVelY = pTgt->vyf - vyf; relPosX = truPosX - pxf; relPosY = truPosY - pyf; relVelX = truVelX; relVelY = truVelY; truAng = atan2( relPosY, relPosX ); truRng = sqrt( SQ(relPosX) + SQ(relPosY) ); truRdot = ( relVelX * relPosX + relVelY * relPosY ) / truRng; measAng = gaussian( truAng, rinAng, &pExec->seed ); measRdot = gaussian( truRdot, rinRdot, &pExec->seed ); measRng = gaussian( truRng, rinRng, &pExec->seed ); timeStamp = simTime; } // end FrameUpdate()
//############################################################################// // // Function: Output() // // Purpose: Print selected variables // //############################################################################// void Seeker::Output( bool printHeader, FILE *pOutFile ) { simTime = GetSimTime(); if ( printHeader ) { fprintf( pOutFile, "%20s", "skr.measAng"); fprintf( pOutFile, "%20s", "skr.measValid"); fprintf( pOutFile, "%20s", "skr.rinAng"); fprintf( pOutFile, "%20s", "skr.timeStamp"); fprintf( pOutFile, "%20s", "skr.truAng"); fprintf( pOutFile, "%20s", "skr.truRdot"); fprintf( pOutFile, "%20s", "skr.truRng"); fprintf( pOutFile, "%20s", "skr.vxf"); fprintf( pOutFile, "%20s", "skr.vyf"); } else { fprintf( pOutFile, "%20.6e", measAng ); fprintf( pOutFile, "%20.6d", measValid ); fprintf( pOutFile, "%20.6e", rinAng ); fprintf( pOutFile, "%20.6e", timeStamp ); fprintf( pOutFile, "%20.6e", truAng ); fprintf( pOutFile, "%20.6e", truRdot ); fprintf( pOutFile, "%20.6e", truRng ); fprintf( pOutFile, "%20.6e", vxf ); fprintf( pOutFile, "%20.6e", vyf ); } } // end Output()
void VC::AddFlit( Flit *f ) { assert(f); if(_expected_pid >= 0) { if(f->pid != _expected_pid) { ostringstream err; err << "Received flit " << f->id << " with unexpected packet ID: " << f->pid << " (expected: " << _expected_pid << ")"; Error(err.str()); } else if(f->tail) { _expected_pid = -1; } } else if(!f->tail) { _expected_pid = f->pid; } // update flit priority before adding to VC buffer if(_pri_type == local_age_based) { f->pri = numeric_limits<int>::max() - GetSimTime(); assert(f->pri >= 0); } else if(_pri_type == hop_count_based) { f->pri = f->hops; assert(f->pri >= 0); } _buffer.push_back(f); UpdatePriority(); }
void FlitChannel::WriteOutputs() { Channel<Flit>::WriteOutputs(); Flit const * const & f = _output; if(f && f->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Completed channel traversal for flit " << f->id << "." << endl; } }
void FlitChannel::ReadInputs() { Flit const * const & f = _input; if(f && f->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Beginning channel traversal for flit " << f->id << " with delay " << _delay << "." << endl; } Channel<Flit>::ReadInputs(); }
void IQRouterBase::_ReceiveFlits( ) { Flit *f; bufferMonitor.cycle() ; for ( int input = 0; input < _inputs; ++input ) { f = (*_input_channels)[input]->Receive(); if ( f ) { ++_received_flits[input]; VC * cur_vc = _vc[input][f->vc]; if ( cur_vc->GetState( ) == VC::idle ) { if ( !f->head ) { Error( "Received non-head flit at idle VC" ); } cur_vc->SetState( VC::routing ); _routing_vcs.push(input*_vcs+f->vc); } if(f->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Adding flit " << f->id << " to VC " << f->vc << " at input " << input << " (state: " << VC::VCSTATE[cur_vc->GetState()]; if(cur_vc->Empty()) { *gWatchOut << ", empty"; } else { assert(cur_vc->FrontFlit()); *gWatchOut << ", front: " << cur_vc->FrontFlit()->id; } *gWatchOut << ")." << endl; *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Received flit " << f->id << " from channel at input " << input << "." << endl; } if ( !cur_vc->AddFlit( f ) ) { Error( "VC buffer overflow" ); } bufferMonitor.write( input, f ) ; } } }
void writestage() { int job_num; job_num = ActivityArgSize(ME) - 1; while(1){ if (TRACE) printf("\nIn WRITE Stage at time %2.0f\n", GetSimTime()); do_write(); ProcessDelay(1.000); } }
void VC::SetState( eVCState s ) { Flit * f = FrontFlit(); if(f && f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Changing state from " << VC::VCSTATE[_state] << " to " << VC::VCSTATE[s] << "." << endl; _state = s; }
//############################################################################// // // Function: Initialize() // // Purpose: Initialize the model // //############################################################################// void FcRadar::Initialize() { ResetAll(); simTime = GetSimTime(); nextFrameTime = initFrameTime; pxf = initPxf; pyf = initPyf; } // end Initialize()
//############################################################################// // // Function: Initialize() // // Purpose: Initialize the model // //############################################################################// void Seeker::Initialize() { ResetAll(); simTime = GetSimTime(); initFrameTime = pMsl->launchTime; nextFrameTime = initFrameTime; pxf = pMsl->pxf; pyf = pMsl->pyf; } // end Initialize()
//############################################################################// // // Function: Output() // // Purpose: Print selected variables // //############################################################################// void FcRadar::Output( bool printHeader, FILE *pOutFile ) { simTime = GetSimTime(); if ( printHeader ) { fprintf( pOutFile, "%20s", "fcRdr.measAng"); fprintf( pOutFile, "%20s", "fcRdr.measRdot"); fprintf( pOutFile, "%20s", "fcRdr.measRng"); fprintf( pOutFile, "%20s", "fcRdr.timeStamp"); fprintf( pOutFile, "%20s", "fcRdr.pxf"); fprintf( pOutFile, "%20s", "fcRdr.pyf"); fprintf( pOutFile, "%20s", "fcRdr.rinAng"); fprintf( pOutFile, "%20s", "fcRdr.rinRdot"); fprintf( pOutFile, "%20s", "fcRdr.rinRng"); fprintf( pOutFile, "%20s", "fcRdr.truAng"); fprintf( pOutFile, "%20s", "fcRdr.truPosY"); fprintf( pOutFile, "%20s", "fcRdr.truRdot"); fprintf( pOutFile, "%20s", "fcRdr.truRng"); fprintf( pOutFile, "%20s", "fcRdr.vxf"); fprintf( pOutFile, "%20s", "fcRdr.vyf"); } else { fprintf( pOutFile, "%20.6e", measAng ); fprintf( pOutFile, "%20.6e", measRdot ); fprintf( pOutFile, "%20.6e", measRng ); fprintf( pOutFile, "%20.6e", timeStamp ); fprintf( pOutFile, "%20.6e", pxf ); fprintf( pOutFile, "%20.6e", pyf ); fprintf( pOutFile, "%20.6e", rinAng ); fprintf( pOutFile, "%20.6e", rinRdot ); fprintf( pOutFile, "%20.6e", rinRng ); fprintf( pOutFile, "%20.6e", truAng ); fprintf( pOutFile, "%20.6e", truPosY ); fprintf( pOutFile, "%20.6e", truRdot ); fprintf( pOutFile, "%20.6e", truRng ); fprintf( pOutFile, "%20.6e", vxf ); fprintf( pOutFile, "%20.6e", vyf ); } } // end Output()
//############################################################################// // // Function: Update // // Purpose: Update the state // //############################################################################// void Missile::Update() { simTime = GetSimTime(); if ( (simTime > launchTime) && !initialized ) { initialized = true; vxb = initVxb; vyb = 0.0; vxf = vxb; vyf = vyb; } } // end Update()
//############################################################################// // // Function: UpdateDerivatives() // // Purpose: Update the state // //############################################################################// void Missile::UpdateDerivatives() { double cth; double sth; simTime = GetSimTime(); ayb = pAp->ayb; theta = atan2( vyf, vxf ); cth = cos( theta ); sth = sin( theta ); axf = axb * cth - ayb * sth; ayf = axb * sth + ayb * cth; } // end UpdateDerivatives()
void min_dragonflynew( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { outputs->Clear( ); if(inject) { int inject_vc= RandomInt(gNumVCs-1); outputs->AddRange(0,inject_vc, inject_vc); return; } int _grp_num_routers= gA; int _grp_num_nodes =_grp_num_routers*gP; int dest = f->dest; int rID = r->GetID(); int grp_ID = int(rID / _grp_num_routers); int debug = f->watch; int out_port = -1; int out_vc = 0; int dest_grp_ID=-1; if ( in_channel < gP ) { out_vc = 0; f->ph = 0; if (dest_grp_ID == grp_ID) { f->ph = 1; } } out_port = dragonfly_port(rID, f->src, dest); //optical dateline if (out_port >=gP + (gA-1)) { f->ph = 1; } out_vc = f->ph; if (debug) *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " through output port : " << out_port << " out vc: " << out_vc << endl; outputs->AddRange( out_port, out_vc, out_vc ); }
//############################################################################// // // Function: Initialize() // // Purpose: Initialize the model // //############################################################################// void Missile::Initialize() { ResetAll(); simTime = GetSimTime(); nextFrameTime = initFrameTime; vxb = 0.0; vyb = 0.0; vxf = vxb; vyf = vxb; pxf = -( pExec->tFinal - launchTime ) * initVxb; pyf = 0.0; } // End Initialize()
//############################################################################// // // Function: FrameUpdate() // // Purpose: Perform frame update // //############################################################################// void Seeker::FrameUpdate() { simTime = GetSimTime(); pxf = pMsl->pxf; pyf = pMsl->pyf; vxf = pMsl->vxf; vyf = pMsl->vyf; truPosX = pTgt->pxf; truPosY = pTgt->pyf; truVelX = pTgt->vxf; truVelY = pTgt->vyf; relPosX = truPosX - pxf; relPosY = truPosY - pyf; relVelX = truVelX - vxf; relVelY = truVelY - vyf; truAng = atan2( relPosY, relPosX ); truRng = sqrt( SQ(relPosX) + SQ(relPosY) ); truRdot = ( relVelX * relPosX + relVelY * relPosY ) / truRng; if ( truRng < detRng ) { measAng = gaussian( truAng, rinAng, &pExec->seed ); measValid = true; } else { measAng = 0.0; measValid = false; } timeStamp = simTime; } // end FrameUpdate()
void min_dragonflynew( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { outputs->Clear( ); if(inject) { //injection && res_type_res means we are assigning VC for a speculative flow buffer int inject_vc= SRP_VC_CONVERTER(0,(f->res_type == RES_TYPE_RES)?RES_TYPE_SPEC:f->res_type); outputs->AddRange(0,inject_vc, inject_vc); return; } int dest = f->dest; int rID = r->GetID(); int grp_ID = int(rID / g_grp_num_routers); int dest_grp_ID = int(dest/g_grp_num_nodes); int debug = f->watch; int out_port = -1; int out_vc = 0; if ( in_channel < gP ) { f->ph = 0; if (dest_grp_ID == grp_ID) { f->ph = 1; } } out_port = dragonfly_port(rID, f->src, dest); //optical dateline if (out_port >=gP + (gA-1)) { f->ph = 1; } out_vc = SRP_VC_CONVERTER(f->ph,f->res_type); if (debug) *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " through output port : " << out_port << " out vc: " << out_vc << endl; outputs->AddRange( out_port, out_vc, out_vc ); }
//flow buffer status only change when in spec mode bool FlowBuffer::nack(int sn){ assert(_mode == RES_MODE); bool effective = false; if(_watch){ cout<<"flow "<<fl->flid <<" received nack "<<sn<<endl; } if(_flit_buffer.count(sn)!=0){ //change flit status for(int i = sn; _flit_buffer.count(i)!=0; ++i){ if(_watch){ cout<<"\tnack flit "<<i<<endl; } bool tail = (_flit_buffer[i]==NULL)?false:_flit_buffer[i]->tail; _flit_status[i] = FLIT_NACKED; _ready++; _reserved_slots++; _spec_outstanding--; TOTAL_SPEC_BUFFER--; if(tail) break; } _last_nack_time=GetSimTime(); #ifdef ENABLE_FLOW_STATS _stats[FLOW_STAT_FINAL_NOT_READY] += _no_retransmit_loss; #endif _no_retransmit_loss=0; //change buffer status if(_status == FLOW_STATUS_SPEC){ effective = true; if(_tail_sent){ _status = FLOW_STATUS_NACK; } else { _status = FLOW_STATUS_NACK_TRANSITION; } } } return effective; }
void IQRouterBase::_SendFlits( ) { Flit *f; for ( int output = 0; output < _outputs; ++output ) { if ( !_output_buffer[output].empty( ) ) { f = _output_buffer[output].front( ); f->from_router = this->GetID(); _output_buffer[output].pop( ); ++_sent_flits[output]; if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Sending flit " << f->id << " to channel at output " << output << "." << endl; } else { f = 0; } if(gTrace && f){cout<<"Outport "<<output<<endl;cout<<"Stop Mark"<<endl;} (*_output_channels)[output]->Send( f ); } }
bool FlowBuffer::send_spec_ready(){ switch(_status){ case FLOW_STATUS_GRANT_TRANSITION: case FLOW_STATUS_NACK_TRANSITION: case FLOW_STATUS_SPEC: if(RESERVATION_POST_WAIT && GetSimTime()<_sleep_time) return false; if(!_res_sent){ return true; } else if(!_tail_sent){ return true; } else{ if(RESERVATION_SPEC_OFF){ return false; } else { return (_ready>0 && _reserved_slots>0); } } default: return false; } }
//############################################################################// // // Function: Output() // // Purpose: Print selected variables // //############################################################################// void Missile::Output( bool printHeader, FILE *pOutFile ) { simTime = GetSimTime(); if ( printHeader ) { fprintf( pOutFile, "%20s", "msl.axb" ); fprintf( pOutFile, "%20s", "msl.axf" ); fprintf( pOutFile, "%20s", "msl.ayb" ); fprintf( pOutFile, "%20s", "msl.ayf" ); fprintf( pOutFile, "%20s", "msl.launchTime" ); fprintf( pOutFile, "%20s", "msl.pxf" ); fprintf( pOutFile, "%20s", "msl.pyf" ); fprintf( pOutFile, "%20s", "msl.theta" ); fprintf( pOutFile, "%20s", "msl.vxb" ); fprintf( pOutFile, "%20s", "msl.vxf" ); fprintf( pOutFile, "%20s", "msl.vyb" ); fprintf( pOutFile, "%20s", "msl.vyf" ); } else { fprintf(pOutFile, "%20.6e", axb); fprintf(pOutFile, "%20.6e", axf); fprintf(pOutFile, "%20.6e", ayb); fprintf(pOutFile, "%20.6e", ayf); fprintf(pOutFile, "%20.6e", launchTime); fprintf(pOutFile, "%20.6e", pxf); fprintf(pOutFile, "%20.6e", pyf); fprintf(pOutFile, "%20.6e", theta); fprintf(pOutFile, "%20.6e", vxb); fprintf(pOutFile, "%20.6e", vxf); fprintf(pOutFile, "%20.6e", vyb); fprintf(pOutFile, "%20.6e", vyf); } // end if ( printHeader ) else } // end Output()
void IQRouterSplit::_Alloc( ) { bool watched = false; int fast_path_vcs[_inputs]; _sw_allocator->Clear( ); for(int input = 0; input < _inputs; ++input) { fast_path_vcs[input] = -1; for(int s = 0; s < _input_speedup; ++s) { int expanded_input = s*_inputs + input; // Arbitrate (round-robin) between multiple requesting VCs at the same // input (handles the case when multiple VC's are requesting the same // output port) int vc = _sw_rr_offset[expanded_input]; for(int v = 0; v < _vcs; ++v) { // This continue acounts for the interleaving of VCs when input speedup // is used. // dub: Essentially, this skips loop iterations corresponding to those // VCs not in the current speedup set. The skipped iterations will be // handled in a different iteration of the enclosing loop over 's'. // dub: Furthermore, we skip this iteration if the current VC has only a // single, newly arrived flit. if(((vc % _input_speedup) != s) || _use_fast_path[input*_vcs+vc]) { vc = (vc + 1) % _vcs; continue; } VC * cur_vc = _vc[input][vc]; VC::eVCState vc_state = cur_vc->GetState(); if(cur_vc->FrontFlit() && cur_vc->FrontFlit()->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Saw flit " << cur_vc->FrontFlit()->id << " in slow path." << endl; if(!cur_vc->Empty()) { Flit * f = cur_vc->FrontFlit(); assert(f); if(((vc_state != VC::vc_alloc) && (vc_state != VC::active)) || (cur_vc->GetStateTime() < _sw_alloc_delay)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " is not ready for slow-path allocation (flit: " << f->id << ", state: " << VC::VCSTATE[vc_state] << ", state time: " << cur_vc->GetStateTime() << ")." << endl; vc = (vc + 1) % _vcs; continue; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " is requesting slow-path allocation (flit: " << f->id << ", state: " << VC::VCSTATE[vc_state] << ")." << endl; const OutputSet * route_set = cur_vc->GetRouteSet(); int output = _vc_rr_offset[input*_vcs+vc]; for(int output_index = 0; output_index < _outputs; ++output_index) { // in active state, we only care about our assigned output port if(vc_state == VC::active) { output = cur_vc->GetOutputPort(); } // When input_speedup > 1, the virtual channel buffers are // interleaved to create multiple input ports to the switch. // Similarily, the output ports are interleaved based on their // originating input when output_speedup > 1. assert(expanded_input == (vc%_input_speedup)*_inputs+input); int expanded_output = (input%_output_speedup)*_outputs + output; if((_switch_hold_in[expanded_input] == -1) && (_switch_hold_out[expanded_output] == -1)) { BufferState * dest_vc = _next_vcs[output]; bool do_request = false; int in_priority; // check if any suitable VCs are available and determine the // highest priority for this port int vc_cnt = route_set->NumVCs(output); assert(!((vc_state == VC::active) && (vc_cnt == 0))); for(int vc_index = 0; vc_index < vc_cnt; ++vc_index) { int vc_prio; int out_vc = route_set->GetVC(output, vc_index, &vc_prio); if((vc_state == VC::vc_alloc) && !dest_vc->IsAvailableFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is busy." << endl; continue; } else if((vc_state == VC::active) && (out_vc != cur_vc->GetOutputVC())) { continue; } if(dest_vc->IsFullFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " has no buffers available." << endl; continue; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is available." << endl; if(!do_request || (vc_prio > in_priority)) { do_request = true; in_priority = vc_prio; } } if(do_request) { if(f->watch) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " requests output " << output << " (flit: " << f->id << ", exp. input: " << expanded_input << ", exp. output: " << expanded_output << ")." << endl; watched = true; } // We could have requested this same input-output pair in a // previous iteration; only replace the previous request if the // current request has a higher priority (this is default // behavior of the allocators). Switch allocation priorities // are strictly determined by the packet priorities. _sw_allocator->AddRequest(expanded_input, expanded_output, vc, in_priority, cur_vc->GetPriority()); } } // in active state, we only care about our assigned output port if(vc_state == VC::active) { break; } output = (output + 1) % _outputs; } } vc = (vc + 1) % _vcs; } } // dub: handle fast-path flits separately so we know all switch requests // from other VCs that are on the regular path have been issued already for(int vc = 0; vc < _vcs; vc++) { if(_use_fast_path[input*_vcs+vc]) { VC * cur_vc = _vc[input][vc]; if(cur_vc->Empty()) { continue; } Flit * f = cur_vc->FrontFlit(); assert(f); if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Saw flit " << f->id << " in fast path." << endl; VC::eVCState vc_state = cur_vc->GetState(); if(((vc_state != VC::vc_alloc) && (vc_state != VC::active)) || (cur_vc->GetStateTime() < _sw_alloc_delay)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " is not ready for fast-path allocation (flit: " << f->id << ", state: " << VC::VCSTATE[vc_state] << ", state time: " << cur_vc->GetStateTime() << ")." << endl; continue; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " is requesting fast-path allocation (flit: " << f->id << ", state: " << VC::VCSTATE[vc_state] << ")." << endl; if(fast_path_vcs[input] >= 0) cout << "XXX" << endl << FullName() << endl << "VC: " << vc << ", input: " << input << ", flit: " << f->id << ", fast VC: " << fast_path_vcs[input] << ", fast flit: " << _vc[input][fast_path_vcs[input]]->FrontFlit()->id << endl << "XXX" << endl; assert(fast_path_vcs[input] < 0); fast_path_vcs[input] = vc; const OutputSet * route_set = cur_vc->GetRouteSet(); int expanded_input = (vc%_input_speedup)*_inputs+input; for(int output = 0; output < _outputs; ++output) { // dub: if we're done with VC allocation, we already know our output if(vc_state == VC::active) { output = cur_vc->GetOutputPort(); } BufferState * dest_vc = _next_vcs[output]; int expanded_output = (input%_output_speedup)*_outputs + output; if(_sw_allocator->ReadRequest(expanded_input, expanded_output) >= 0) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Crossbar slot is already in use by slow path " << "(exp. input: " << expanded_input << ", exp. output: " << expanded_output << ")." << endl; if(vc_state == VC::active) { break; } else { continue; } } bool do_request = false; int in_priority; int vc_cnt = route_set->NumVCs(output); assert((vc_state != VC::active) || (vc_cnt > 0)); for(int vc_index = 0; vc_index < vc_cnt; ++vc_index) { int vc_prio; int out_vc = route_set->GetVC(output, vc_index, &vc_prio); if((vc_state == VC::vc_alloc) && !dest_vc->IsAvailableFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is busy." << endl; continue; } else if((vc_state == VC::active) && (out_vc != cur_vc->GetOutputVC())) { continue; } if(dest_vc->IsFullFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " has no buffers available." << endl; continue; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is available." << endl; if(!do_request || (vc_prio > in_priority)) { do_request = true; in_priority = vc_prio; } } if(do_request) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << vc << " at input " << input << " requests output " << output << " (flit: " << f->id << ", exp. input: " << expanded_input << ", exp. output: " << expanded_output << ")." << endl; // We could have requested this same input-output pair in a // previous iteration; only replace the previous request if the // current request has a higher priority (this is default // behavior of the allocators). Switch allocation priorities // are strictly determined by the packet priorities. _sw_allocator->AddRequest(expanded_input, expanded_output, vc, in_priority, cur_vc->GetPriority()); } if(vc_state == VC::active) { break; } } } } } if(watched) { *gWatchOut << GetSimTime() << " | " << _sw_allocator->FullName() << " | "; _sw_allocator->PrintRequests(gWatchOut); } _sw_allocator->Allocate(); if(watched) { *gWatchOut << GetSimTime() << " | " << _sw_allocator->FullName() << " | " << "Grants = [ "; for(int input = 0; input < _inputs; ++input) for(int s = 0; s < _input_speedup; ++s) { int expanded_input = s * _inputs + input; int expanded_output = _sw_allocator->OutputAssigned(expanded_input); if(expanded_output > -1) { int output = expanded_output % _outputs; int vc = _sw_allocator->ReadRequest(expanded_input, expanded_output); *gWatchOut << input << " -> " << output << " (vc:" << vc << ") "; } } *gWatchOut << "]." << endl; } // Winning flits cross the switch _crossbar_pipe->WriteAll(NULL); ////////////////////////////// // Switch Power Modelling // - Record Total Cycles // switchMonitor.cycle() ; for(int input = 0; input < _inputs; ++input) { Credit * c = NULL; for(int s = 0; s < _input_speedup; ++s) { int expanded_input = s*_inputs + input; int expanded_output; VC * cur_vc; int vc; int fvc = fast_path_vcs[input]; if(_switch_hold_in[expanded_input] != -1) { assert(_switch_hold_in[expanded_input] >= 0); expanded_output = _switch_hold_in[expanded_input]; vc = _switch_hold_vc[expanded_input]; cur_vc = _vc[input][vc]; if(cur_vc->Empty()) { // Cancel held match if VC is empty expanded_output = -1; } } else { expanded_output = _sw_allocator->OutputAssigned(expanded_input); if(expanded_output >= 0) { vc = _sw_allocator->ReadRequest(expanded_input, expanded_output); cur_vc = _vc[input][vc]; } else { vc = -1; cur_vc = NULL; } } if(expanded_output >= 0) { int output = expanded_output % _outputs; Flit * f = cur_vc->FrontFlit(); assert(f); if(vc == fvc) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Fast-path allocation successful for VC " << vc << " at input " << input << " (flit: " << f->id << ")." << endl; } else { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Slow-path allocation successful for VC " << vc << " at input " << input << " (flit: " << f->id << ")." << endl; if(fvc >= 0) { assert(_use_fast_path[input*_vcs+fvc]); VC * fast_vc = _vc[input][fvc]; assert(fast_vc->FrontFlit()); if(fast_vc->FrontFlit()->watch) cout << GetSimTime() << " | " << FullName() << " | " << "Disabling fast-path allocation for VC " << fvc << " at input " << input << "." << endl; _use_fast_path[input*_vcs+fvc] = false; } } BufferState * dest_vc = _next_vcs[output]; switch(cur_vc->GetState()) { case VC::vc_alloc: { const OutputSet * route_set = cur_vc->GetRouteSet(); int sel_prio = -1; int sel_vc = -1; int vc_cnt = route_set->NumVCs(output); for(int vc_index = 0; vc_index < vc_cnt; ++vc_index) { int out_prio; int out_vc = route_set->GetVC(output, vc_index, &out_prio); if(!dest_vc->IsAvailableFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is busy." << endl; continue; } if(dest_vc->IsFullFor(out_vc)) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " has no buffers available." << endl; continue; } if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << out_vc << " at output " << output << " is available." << endl; if(out_prio > sel_prio) { sel_vc = out_vc; sel_prio = out_prio; } } if(sel_vc < 0) { cout << "XXX" << endl << "Flit " << f->id << ", VC " << vc << ", input " << input << ":" << endl << "None of " << vc_cnt << " VCs at output " << output << " were suitable and available." << endl << "XXX" << endl; } // we should only get to this point if some VC requested // allocation assert(sel_vc > -1); // dub: this is taken care of later on //cur_vc->SetState(VC::active); cur_vc->SetOutput(output, sel_vc); dest_vc->TakeBuffer(sel_vc); _vc_rr_offset[input*_vcs+vc] = (output + 1) % _outputs; if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "VC " << sel_vc << " at output " << output << " granted to VC " << vc << " at input " << input << " (flit: " << f->id << ")." << endl; } // NOTE: from here, we just fall through to the code for VC::active! case VC::active: if(_hold_switch_for_packet) { _switch_hold_in[expanded_input] = expanded_output; _switch_hold_vc[expanded_input] = vc; _switch_hold_out[expanded_output] = expanded_input; } //assert(cur_vc->GetState() == VC::active); assert(!cur_vc->Empty()); assert(cur_vc->GetOutputPort() == output); dest_vc = _next_vcs[output]; assert(!dest_vc->IsFullFor(cur_vc->GetOutputVC())); // Forward flit to crossbar and send credit back f = cur_vc->RemoveFlit(); if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Output " << output << " granted to VC " << vc << " at input " << input << " (flit: " << f->id << ", exp. input: " << expanded_input << ", exp. output: " << expanded_output << ")." << endl; f->hops++; // // Switch Power Modelling // switchMonitor.traversal(input, output, f); bufferMonitor.read(input, f); if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Forwarding flit " << f->id << " through crossbar " << "(exp. input: " << expanded_input << ", exp. output: " << expanded_output << ")." << endl; if (c == NULL) { c = _NewCredit(_vcs); } assert(vc == f->vc); c->vc[c->vc_cnt] = vc; c->vc_cnt++; c->dest_router = f->from_router; f->vc = cur_vc->GetOutputVC(); dest_vc->SendingFlit(f); _crossbar_pipe->Write(f, expanded_output); if(f->tail) { if(cur_vc->Empty()) { cur_vc->SetState(VC::idle); } else { cur_vc->Route(_rf, this, cur_vc->FrontFlit(), input); cur_vc->SetState(VC::vc_alloc); } _switch_hold_in[expanded_input] = -1; _switch_hold_vc[expanded_input] = -1; _switch_hold_out[expanded_output] = -1; } else { // reset state timer for next flit cur_vc->SetState(VC::active); } if(!_use_fast_path[input*_vcs+vc]) { _sw_rr_offset[expanded_input] = (vc + 1) % _vcs; } if(cur_vc->Empty() && !_use_fast_path[input*_vcs+vc]) { if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Enabling fast-path allocation for VC " << vc << " at input " << input << "." << endl; _use_fast_path[input*_vcs+vc] = true; } } } else if((fvc >= 0) && ((fvc % _input_speedup) == s)) { assert(_use_fast_path[input*_vcs+fvc]); VC * fast_vc = _vc[input][fvc]; Flit * f = fast_vc->FrontFlit(); assert(f); if(f->watch) *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Disabling fast-path allocation for VC " << fvc << " at input " << input << "." << endl; _use_fast_path[input*_vcs+fvc] = false; } } _credit_pipe->Write(c, input); } }
void Power_Module::run(){ totalTime = GetSimTime(); channelWirePower=0; channelClkPower=0; channelDFFPower=0; channelLeakPower=0; inputReadPower=0; inputWritePower=0; inputLeakagePower=0; switchPower=0; switchPowerCtrl=0; switchPowerLeak=0; outputPower=0; outputPowerClk=0; outputCtrlPower=0; channelArea=0; switchArea=0; inputArea=0; outputArea=0; maxInputPort = 0; maxOutputPort = 0; vector<FlitChannel *> inject = net->GetInject(); vector<FlitChannel *> eject = net->GetEject(); vector<FlitChannel *> chan = net->GetChannels(); for(int i = 0; i<net->NumNodes(); i++){ calcChannel(inject[i]); } for(int i = 0; i<net->NumNodes(); i++){ calcChannel(eject[i]); } for(int i = 0; i<net->NumChannels();i++){ calcChannel(chan[i]); } vector<Router*> routers = net->GetRouters(); for(size_t i = 0; i < routers.size(); i++){ IQRouter* temp = dynamic_cast<IQRouter*>(routers[i]); const BufferMonitor * bm = temp->GetBufferMonitor(); calcBuffer(bm); const SwitchMonitor * sm = temp->GetSwitchMonitor(); calcSwitch(sm); } double totalpower = channelWirePower+channelClkPower+channelDFFPower+channelLeakPower+ inputReadPower+inputWritePower+inputLeakagePower+ switchPower+switchPowerCtrl+switchPowerLeak+outputPower+outputPowerClk+outputCtrlPower; double totalarea = channelArea+switchArea+inputArea+outputArea; cout<< "-----------------------------------------\n" ; cout<< "- OCN Power Summary\n" ; cout<< "- Completion Time: "<<totalTime <<"\n" ; cout<< "- Flit Widths: "<<channel_width<<"\n" ; cout<< "- Channel Wire Power: "<<channelWirePower <<"\n" ; cout<< "- Channel Clock Power: "<<channelClkPower <<"\n" ; cout<< "- Channel Retiming Power: "<<channelDFFPower <<"\n" ; cout<< "- Channel Leakage Power: "<<channelLeakPower <<"\n" ; cout<< "- Input Read Power: "<<inputReadPower <<"\n" ; cout<< "- Input Write Power: "<<inputWritePower <<"\n" ; cout<< "- Input Leakage Power: "<<inputLeakagePower <<"\n" ; cout<< "- Switch Power: "<<switchPower <<"\n" ; cout<< "- Switch Control Power: "<<switchPowerCtrl <<"\n" ; cout<< "- Switch Leakage Power: "<<switchPowerLeak <<"\n" ; cout<< "- Output DFF Power: "<<outputPower <<"\n" ; cout<< "- Output Clk Power: "<<outputPowerClk <<"\n" ; cout<< "- Output Control Power: "<<outputCtrlPower <<"\n" ; cout<< "- Total Power: "<<totalpower <<"\n"; cout<< "-----------------------------------------\n" ; cout<< "\n" ; cout<< "-----------------------------------------\n" ; cout<< "- OCN Area Summary\n" ; cout<< "- Channel Area: "<<channelArea<<"\n" ; cout<< "- Switch Area: "<<switchArea<<"\n" ; cout<< "- Input Area: "<<inputArea<<"\n" ; cout<< "- Output Area: "<<outputArea<<"\n" ; cout<< "- Total Area: "<<totalarea<<endl; cout<< "-----------------------------------------\n" ; }
void ChaosRouter::_OutputAdvance( ) { Flit *f, *f2; Credit *c; bool advanced; int mq; _crossbar_pipe->WriteAll( 0 ); for ( int i = 0; i < _inputs; ++i ) { if ( ( ( _input_output_match[i] != -1 ) || ( _input_mq_match[i] != -1 ) ) && ( !_input_frame[i].empty( ) ) ) { advanced = false; f = _input_frame[i].front( ); /*if ( ! ) { } else { cout << "Input = " << i << ", input_output_match = " << _input_output_match[i] << ", input_mq_match = " << _input_mq_match[i] << endl; Error( "Input queue empty, but matched!" ); }*/ if ( _input_output_match[i] != -1 ) { if ( f->tail ) { _output_matched[_input_output_match[i]] = false; } _crossbar_pipe->Write( f, _input_output_match[i] ); if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit traversing crossbar from input queue " << i << " at " << FullName() << endl << *f; } advanced = true; } else if ( !_MultiQueueFull( _input_mq_match[i] ) ) { mq = _input_mq_match[i]; if ( f->head ) { _rf( this, f, i, _mq_route[mq], false ); _mq_age[mq] = 0; if ( _multi_state[mq] == empty ) { _multi_state[mq] = filling; } else if ( _multi_state[mq] == leaving ) { _multi_state[mq] = shared; } else { Error( "Multi-queue received head while not empty or leaving!" ); } } if ( f->tail ) { _mq_matched[mq] = false; if ( _multi_state[mq] == filling ) { _multi_state[mq] = full; } else if ( _multi_state[mq] == cut_through ) { _multi_state[mq] = leaving; } else { Error( "Multi-queue received tail while not filling or cutting-through!" ); } } _multi_queue[mq].push( f ); if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit stored in multiqueue at " << FullName() << endl << "State = " << _multi_state[mq] << endl << *f; } advanced = true; } if ( advanced ) { _input_frame[i].pop( ); if ( f->tail ) { // last in packet, update state if ( _input_state[i] == leaving ) { _input_state[i] = empty; } else if ( _input_state[i] == shared ) { _input_state[i] = filling; f2 = _input_frame[i].front( ); // update routes _rf( this, f2, i, _input_route[i], false ); } _input_output_match[i] = -1; _input_mq_match[i] = -1; } c = Credit::New( ); c->vc.insert(0); _credit_queue[i].push( c ); } } } for ( int m = 0; m < _multi_queue_size; ++m ) { if ( _multi_match[m] != -1 ) { if ( !_multi_queue[m].empty( ) ) { f = _multi_queue[m].front( ); _multi_queue[m].pop( ); } else { cout << "State = " << _multi_state[m] << endl; Error( "Multi queue empty, but matched!" ); } _crossbar_pipe->Write( f, _multi_match[m] ); if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit traversing crossbar from multiqueue slot " << m << " at " << FullName() << endl << *f; } if ( f->head ) { if ( _multi_state[m] == filling ) { _multi_state[m] = cut_through; } else if ( _multi_state[m] == full ) { _multi_state[m] = leaving; } else { Error( "Multi-queue sent head while not filling or full!" ); } } if ( f->tail ) { _output_matched[_multi_match[m]] = false; _multi_match[m] = -1; if ( _multi_state[m] == shared ) { _multi_state[m] = filling; } else if ( _multi_state[m] == leaving ) { _multi_state[m] = empty; } else { cout << "State = " << _multi_state[m] << endl; cout << *f; Error( "Multi-queue sent tail while not leaving or shared!" ); } } } _mq_age[m]++; } }
void ChaosRouter::ReadInputs( ) { Flit *f; Credit *c; for ( int input = 0; input < _inputs; ++input ) { f = _input_channels[input]->Receive(); if ( f ) { _input_frame[input].push( f ); if ( f->watch ) { *gWatchOut << GetSimTime() << " | " << FullName() << " | " << "Flit arriving at " << FullName() << " on channel " << input << endl << *f; } switch( _input_state[input] ) { case empty: if ( f->head ) { if ( f->tail ) { _input_state[input] = full; } else { _input_state[input] = filling; } _rf( this, f, input, _input_route[input], false ); } else { cout << *f; Error( "Empty buffer received non-head flit!" ); } break; case filling: if ( f->tail ) { _input_state[input] = full; } else if ( f->head ) { Error( "Input buffer received another head before previous tail!" ); } break; case full: Error( "Received flit while full!" ); break; case leaving: if ( f->head ) { _input_state[input] = shared; if ( f->tail ) { Error( "Received single-flit packet in leaving state!" ); } } else { cout << *f; Error( "Received non-head flit while packet leaving!" ); } break; case cut_through: if ( f->tail ) { _input_state[input] = leaving; } if ( f->head ) { cout << *f; Error( "Received head flit in cut through buffer!" ); } break; case shared: if ( f->head ) { Error( "Shared buffer received another head!" ); } else if ( f->tail ) { cout << "Input " << input << endl; cout << *f; Error( "Shared buffer received another tail!" ); } break; } } } // Process incoming credits for ( int output = 0; output < _outputs; ++output ) { c = _output_credits[output]->Receive(); if ( c ) { _next_queue_cnt[output]--; if ( _next_queue_cnt[output] < 0 ) { Error( "Next queue count fell below zero!" ); } c->Free(); } } }
//ugal now uses modified comparison, modefied getcredit void ugal_flatfly_onchip( const Router *r, const Flit *f, int in_channel, OutputSet *outputs, bool inject ) { // ( Traffic Class , Routing Order ) -> Virtual Channel Range int vcBegin = 0, vcEnd = gNumVCs-1; if ( f->type == Flit::READ_REQUEST ) { vcBegin = gReadReqBeginVC; vcEnd = gReadReqEndVC; } else if ( f->type == Flit::WRITE_REQUEST ) { vcBegin = gWriteReqBeginVC; vcEnd = gWriteReqEndVC; } else if ( f->type == Flit::READ_REPLY ) { vcBegin = gReadReplyBeginVC; vcEnd = gReadReplyEndVC; } else if ( f->type == Flit::WRITE_REPLY ) { vcBegin = gWriteReplyBeginVC; vcEnd = gWriteReplyEndVC; } assert(((f->vc >= vcBegin) && (f->vc <= vcEnd)) || (inject && (f->vc < 0))); int out_port; if(inject) { out_port = 0; } else { int dest = flatfly_transformation(f->dest); int rID = r->GetID(); int _concentration = gC; int found; int debug = 0; int tmp_out_port, _ran_intm; int _min_hop, _nonmin_hop, _min_queucnt, _nonmin_queucnt; int threshold = 2; if ( in_channel < gC ){ if(gTrace){ cout<<"New Flit "<<f->src<<endl; } f->ph = 0; } if(gTrace){ int load = 0; cout<<"Router "<<rID<<endl; cout<<"Input Channel "<<in_channel<<endl; //need to modify router to report the buffere depth load +=r->GetBuffer(in_channel); cout<<"Rload "<<load<<endl; } if (debug){ cout << " FLIT ID: " << f->id << " Router: " << rID << " routing from src : " << f->src << " to dest : " << dest << " f->ph: " <<f->ph << " intm: " << f->intm << endl; } // f->ph == 0 ==> make initial global adaptive decision // f->ph == 1 ==> route nonminimaly to random intermediate node // f->ph == 2 ==> route minimally to destination found = 0; if (f->ph == 1){ dest = f->intm; } if (dest >= rID*_concentration && dest < (rID+1)*_concentration) { if (f->ph == 1) { f->ph = 2; dest = flatfly_transformation(f->dest); if (debug) cout << " done routing to intermediate "; } else { found = 1; out_port = dest % gC; if (debug) cout << " final routing to destination "; } } if (!found) { if (f->ph == 0) { _min_hop = find_distance(flatfly_transformation(f->src),dest); _ran_intm = find_ran_intm(flatfly_transformation(f->src), dest); tmp_out_port = flatfly_outport(dest, rID); if (f->watch){ *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " MIN tmp_out_port: " << tmp_out_port; } _min_queucnt = r->GetCredit(tmp_out_port, -1, -1); _nonmin_hop = find_distance(flatfly_transformation(f->src),_ran_intm) + find_distance(_ran_intm, dest); tmp_out_port = flatfly_outport(_ran_intm, rID); if (f->watch){ *gWatchOut << GetSimTime() << " | " << r->FullName() << " | " << " NONMIN tmp_out_port: " << tmp_out_port << endl; } if (_ran_intm >= rID*_concentration && _ran_intm < (rID+1)*_concentration) { _nonmin_queucnt = numeric_limits<int>::max(); } else { _nonmin_queucnt = r->GetCredit(tmp_out_port, -1, -1); } if (debug){ cout << " _min_hop " << _min_hop << " _min_queucnt: " <<_min_queucnt << " _nonmin_hop: " << _nonmin_hop << " _nonmin_queucnt :" << _nonmin_queucnt << endl; } if (_min_hop * _min_queucnt <= _nonmin_hop * _nonmin_queucnt +threshold) { if (debug) cout << " Route MINIMALLY " << endl; f->ph = 2; } else { // route non-minimally f->minimal = 0; if (debug) { cout << " Route NONMINIMALLY int node: " <<_ran_intm << endl; } f->ph = 1; f->intm = _ran_intm; dest = f->intm; if (dest >= rID*_concentration && dest < (rID+1)*_concentration) { f->ph = 2; dest = flatfly_transformation(f->dest); } } } // find minimal correct dimension to route through out_port = flatfly_outport(dest, rID); // if we haven't reached our destination, restrict VCs appropriately to avoid routing deadlock if(out_port >= gC) { int const available_vcs = (vcEnd - vcBegin + 1) / 2; assert(available_vcs > 0); if(f->ph == 1) { vcEnd -= available_vcs; } else { assert(f->ph == 2); vcBegin += available_vcs; } } found = 1; } if (!found) { cout << " ERROR: output not found in routing. " << endl; cout << *f; exit (-1); } if (out_port >= gN*(gK-1) + gC) { cout << " ERROR: output port too big! " << endl; cout << " OUTPUT select: " << out_port << endl; cout << " router radix: " << gN*(gK-1) + gK << endl; exit (-1); } if (debug) cout << " through output port : " << out_port << endl; if(gTrace){cout<<"Outport "<<out_port<<endl;cout<<"Stop Mark"<<endl;} } outputs->Clear( ); outputs->AddRange( out_port , vcBegin, vcEnd ); }
//############################################################################// // // Function: Finalize() // // Purpose: Close out model // //############################################################################// void Missile::Finalize() { simTime = GetSimTime(); }
//############################################################################// // // Function: FrameUpdate // // Purpose: Perform frame update // //############################################################################// void Missile::FrameUpdate() { simTime = GetSimTime(); }