TPZComponent* TPZBuilder :: createComponentWithId( const TPZString& id, TPZComponent* owner ) { INDEX indice = getTagIndex(id); TPZTag* tag = getTagWithIndex(indice); if( ! tag ) { TPZString err; tag = getTagWithIndex(1); err.sprintf(ERR_TPZBLDR_002, (char*)id ); err=err+TPZString("(cont...)\n Help= Avaliable ")+tag->tagName()+TPZString(" (")+showTagArray(tag->tagName())+TPZString(" )"); EXIT_PROGRAM(err); } TPZComponent* rComponent = parseComponentDefinition(tag,owner,indice); if( ! rComponent ) { tag = getTagWithIndex(1); TPZString err; err.sprintf(ERR_TPZBLDR_002, (char*)id ); err=err+TPZString("(cont...)\n Help= Avaliable ")+tag->tagName()+TPZString(" (")+showTagArray(tag->tagName())+TPZString(" )"); EXIT_PROGRAM(err); } return rComponent; }
void TPZNetworkSquareMidimew :: initialize() { if( isInitializated() ) return; /* Check consistency of parameters */ if(getSizeY()!=1 ||getSizeZ()!=1) { TPZString err; err.sprintf( ERR_TPZTONET_002, (char*)getRouterId() ); err.sprintf("\nSquare Midimew Network Ysize and Zsize must be 1. Al nodes in Xsize!"); EXIT_PROGRAM(err); } if((int)ceil(sqrt((float)getSizeX()))%2 || getSizeX() < 4 ) { TPZString err; err.sprintf( ERR_TPZTONET_002, (char*)getRouterId() ); err.sprintf("\n Square Midimew Network Xsize must be an even 2's power(4,16,64,256,1024,4096...)"); EXIT_PROGRAM(err); } if( !getSizeX() || !getSizeY() || !getSizeZ() ) { TPZString err; err.sprintf(ERR_TPZTONET_001, getSizeX(), getSizeY(), getSizeZ() ); EXIT_PROGRAM(err); } /* Create the routers for each node */ int i; for( i=0; i<getSizeX(); i++ ) { TPZPosition pos(i,0,0); TPZRouter* newRouter = (TPZRouter*) (TPZRouter::routerBuilder->createComponentWithId(getRouterId(),this)); if( ! newRouter ) { TPZString err; err.sprintf( ERR_TPZTONET_002, (char*)getRouterId() ); EXIT_PROGRAM(err); } newRouter->setPosition(pos); addRouter(newRouter); } /* Connect the routers together */ for( i=0; i<getSizeX(); i++ ) { initializeConnectionsFor(TPZPosition(i,0,0)); } /* Other initialization tasks */ generateRoutingTable(); setInitializated(true); setSimulation(getSimulation()); }
TPZNetworkSquareMidimew* TPZNetworkSquareMidimew :: newFrom( const TPZTag* tag, TPZComponent* owner ) { TPZComponentId idNetwork(*tag); TPZString sizeX, sizeY, sizeZ; unsigned x, y=1, z=1; /* Read network size from tag attributes */ if( !(tag->getAttributeValueWithName(TPZ_TAG_SIZEX, sizeX)) ) { TPZString err; err.sprintf(ERR_TPZTONET_003, (char*)TPZ_TAG_SIZEX ); EXIT_PROGRAM(err); } x = sizeX.asInteger(); /* if( tag->getAttributeValueWithName(TPZ_TAG_SIZEY, sizeY) ) { y = sizeY.asInteger(); } if( tag->getAttributeValueWithName(TPZ_TAG_SIZEZ, sizeZ) ) { z = sizeZ.asInteger(); } */ /* Check size consistency */ if( !x /*|| !y || !z*/ ) { TPZString err; err.sprintf(ERR_TPZTONET_004, x, 0, 0 ); EXIT_PROGRAM(err); } /* Read the router identifier */ TPZString routerId; if( ! (tag->getAttributeValueWithName(TPZ_TAG_REFROUTER, routerId)) ) { TPZString err; err.sprintf(ERR_TPZTONET_003, (char*)TPZ_TAG_REFROUTER ); EXIT_PROGRAM(err); } /* Read the connection delay */ TPZString connectionDelay; unsigned delay=0; if( tag->getAttributeValueWithName(TPZ_TAG_DELAY, connectionDelay) ) { delay = connectionDelay.asInteger(); } /* Instantiation of the network class */ TPZNetworkSquareMidimew* net = new TPZNetworkSquareMidimew( idNetwork, routerId, x, y, z ); net->setConnectionDelay(delay); net -> setSimulation(owner); net -> initialize(); return net; }
static void reconnect(conn_t *conn) { if(++tries > 3) { EXIT_PROGRAM(RECONNECT_FAIL); } if (conn->sd != -1) close(conn->sd); if (make_connection(conn->remote, conn) < 0) { print_con_info(conn, "Unable to reconnect to %s: %s", conn->remote, strerror(errno)); EXIT_PROGRAM(RECONNECT_FAIL); } tries = 0; }
TPZComponent* TPZNetworkBuilder::parseComponentDefinition( const TPZTag* tag, TPZComponent* owner, INDEX& index ) { TPZString tagName = tag->tagName(); TPZComponent* rComponent = 0; if( tagName == TPZ_TAG_TORUSNET ) { rComponent = TPZNetworkTorus::newFrom(tag,owner); } else if( tagName == TPZ_TAG_MESHNET ) { rComponent = TPZNetworkMesh::newFrom(tag,owner); } else if (tagName == TPZ_TAG_MIDIMEWNET ) { rComponent = TPZNetworkMidimew::newFrom(tag,owner); } else if (tagName == TPZ_TAG_SQUAREMIDIMEWNET ) { rComponent = TPZNetworkSquareMidimew::newFrom(tag,owner); } else { TPZString err; err.sprintf( ERR_TPZNBLDR_001, (char*)tagName ); EXIT_PROGRAM(err); } return rComponent; }
Boolean TPZRunnableComponent :: onStopDown(unsigned interfaz, unsigned cv) { if( ! getFlowControl() ) { TPZString err; err.sprintf(ERR_TPZRUNCO_001, (char*)asString() ); EXIT_PROGRAM(err); } return getFlowControl() -> onStopDown(interfaz,cv); }
TPZBuilder :: TPZBuilder(const TPZString& sgmlFile) : m_FileName(sgmlFile), m_TagArray(0) { m_SgmlFile = new ifstream(sgmlFile); if( ! m_SgmlFile->good() ) { TPZString err; err.sprintf(ERR_TPZBLDR_001, (char*)sgmlFile); EXIT_PROGRAM(err); } }
void TPZRunnableComponent :: postRun(uTIME time) { if( m_Flow ) { m_Flow -> postRun(time); } else { TPZString err; err.sprintf(ERR_TPZRUNCO_001, (char*)asString() ); EXIT_PROGRAM(err); } }
unsigned TPZCrossbarFlowCTMux :: extractOutputPortNumber( TPZROUTINGTYPE dir, unsigned channel ) { unsigned oPort = ((TPZCrossbar&)getComponent()).getOutputWith( dir,1 ); if( !oPort ) { TPZString err; err.sprintf( ERR_TPZCMFLO_003, (char*)getComponent().asString(), (char*)_routingType2string(dir) ); EXIT_PROGRAM(err); } if( ((TPZCrossbar&)getComponent()).isLocalNodeOutput(oPort) ) oPort += ( channel - 1 ); return oPort; }
unsigned TPZCrossbarFlowCTMux :: extractOutputPortNumber(TPZMessage* msg) { unsigned oPort = ((TPZCrossbar&)getComponent()).getOutputWith( msg->getRoutingPort(),1 ); if( !oPort ) { TPZString err; err.sprintf( ERR_TPZCMFLO_003, (char*)getComponent().asString(), (char*)msg->asString(), (char*)_routingType2string(msg->getRoutingPort()) ); EXIT_PROGRAM(err); } if( ((TPZCrossbar&)getComponent()).isLocalNodeOutput(oPort) ) oPort += ( msg->getChannel() - 1 ); return oPort; }
//************************************************************************* //: // f: Boolean updateMessageInfo (TPZmessage * msg); // // d: //: //************************************************************************* Boolean TPZCrossbarFlowWH :: updateMessageInfo( TPZMessage* msg ) { //update hop-count for current direction int deltaX = msg->delta(0); int deltaY = msg->delta(1); int deltaZ = msg->delta(2); TPZROUTINGTYPE tipo=msg->getRoutingPort(); switch(tipo) { case _Xplus_: msg->setDelta(deltaX-1,0); return true; case _Xminus_: msg->setDelta(deltaX+1,0); return true; case _Yplus_: msg->setDelta(deltaY-1,1); return true; case _Yminus_: msg->setDelta(deltaY+1,1); return true; case _Zplus_: msg->setDelta(deltaZ-1,2); return true; case _Zminus_: msg->setDelta(deltaZ+1,2); return true; case _LocalNode_: return true; default: EXIT_PROGRAM("error"); } }
static void sigint(int a) { EXIT_PROGRAM(SIGINT_REASON); }
//************************************************************************* //: // f: virtual Boolean inputReading (); // // d: //: //************************************************************************* Boolean TPZSimpleRouterFlowLigero :: inputReading() { unsigned outPort; unsigned inPort; unsigned virtualChannel=1; cleanOutputInterfaces(); TPZNetwork* net = ((TPZSimulation*)(getComponent().getSimulation()))->getNetwork(); #ifndef NO_TRAZA TPZString txt_comp= getComponent().asString() + TPZString(" TIME: ") + TPZString(getOwnerRouter().getCurrentTime()); #endif //********************************************************************************************************** //********************************************************************************************************** // PART 0: ESCAPE PATH //********************************************************************************************************** //********************************************************************************************************** //********************************************************************************** // Part 0-a: fifo escape //********************************************************************************** if( (! m_latch_escape ) && (m_fifo_escape.numberOfElements()!=0) ) { m_fifo_escape.dequeue(m_latch_escape); } m_clearEscConnection=false; if(m_latch_escape) { #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-ESCAPE " + m_latch_escape->asString(); texto += TPZString(" Occupation:") + TPZString(m_fifo_escape.numberOfElements()); TPZWRITE2LOG(texto); #endif Boolean checkFlow=true; if (m_latch_escape->isHeader() || m_latch_escape->isHeadTail()) { m_escape_ctrl= getOutputDirection(m_latch_escape); outPort=extractOutputPortNumber(m_escape_ctrl); if ( (m_escape_ctrl==_LocalNode_) && (checkFlowControl(0, m_fifos_cons, 1, m_bufferSize)==false) ) { checkFlow=false; } if ( (m_escape_ctrl!=_LocalNode_) && ( (checkEscapePath(m_escape_ctrl)==false) || (m_linkAvailable[outPort]==false) ) ) { checkFlow=false; } } if (checkFlow==true) { if (m_escape_ctrl==_LocalNode_) { #ifndef NO_TRAZA TPZString texto = txt_comp + " ESCAPE->CONS " + m_latch_escape->asString(); TPZWRITE2LOG(texto); #endif m_fifos_cons[0].enqueue(m_latch_escape); m_escape_ctrl=_LocalNode_; m_latch_escape=0; } else { #ifndef NO_TRAZA TPZString texto2 = txt_comp + " LINK TRAVERSAL (ESCAPE) " + TPZString(outPort) + m_latch_escape->asString(); TPZWRITE2LOG(texto2); #endif outPort=extractOutputPortNumber(m_escape_ctrl); if (m_latch_escape->isHeader() || m_latch_escape->isHeadTail()) m_linkAvailable[outPort]=false; outputInterfaz(outPort)->sendData(m_latch_escape,virtualChannel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::OStageTraversal); getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); // Clear the latch and the connection if necessary if( m_latch_escape->isHeadTail() || m_latch_escape->isTail()) m_clearEscConnection=true; m_latch_escape=0; } } } //********************************************************************************** // Part 0-b: fifo reading to fill latches //********************************************************************************** if( (! m_latch_pre_escape ) && (m_fifo_pre_escape.numberOfElements()!=0) ) { m_fifo_pre_escape.dequeue(m_latch_pre_escape); } if( (! m_latch_inj_escape ) && (m_fifo_inj_escape.numberOfElements()!=0) ) { m_fifo_inj_escape.dequeue(m_latch_inj_escape); } //********************************************************************************** // Part 0-c: arbitration to access escape fifo //********************************************************************************** //first messages trying to access escape path for the first time if(m_latch_inj_escape) { #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-INJ-ESCAPE " + m_latch_inj_escape->asString(); texto += TPZString(" Occupation:") + TPZString(m_fifo_inj_escape.numberOfElements()); TPZWRITE2LOG(texto); #endif Boolean checkFlow=true; if (m_latch_inj_escape->isHeader() || m_latch_inj_escape->isHeadTail()) { //bubble check to access the escape path if( (checkEscapeFlowControl()==false) || m_escAvailable==false) checkFlow=false; else m_escAvailable=false; } if (checkFlow==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " INJ-ESCAPE->ESCAPE " + m_latch_inj_escape->asString(); TPZWRITE2LOG(texto); #endif m_fifo_escape.enqueue(m_latch_inj_escape); if (m_latch_inj_escape->isTail() || m_latch_inj_escape->isHeadTail()) m_clearPreEsc=true; m_latch_inj_escape=0; } } //Then we arbitrate messages in transit through escape path if(m_latch_pre_escape) { #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-PRE-ESCAPE " + m_latch_pre_escape->asString(); texto += TPZString(" Occupation:") + TPZString(m_fifo_pre_escape.numberOfElements()); TPZWRITE2LOG(texto); #endif Boolean checkFlow=true; if (m_latch_pre_escape->isHeader() || m_latch_pre_escape->isHeadTail()) { //simple CT check for messages in transit if( (m_fifo_escape.numberOfElements()>2) || m_escAvailable==false) checkFlow=false; else m_escAvailable=false; } if (checkFlow==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " PRE-ESCAPE->ESCAPE " + m_latch_pre_escape->asString(); TPZWRITE2LOG(texto); #endif m_fifo_escape.enqueue(m_latch_pre_escape); if (m_latch_pre_escape->isTail() || m_latch_pre_escape->isHeadTail()) m_clearPreEsc=true; m_latch_pre_escape=0; } } //Finally, we check mux status if (m_clearPreEsc==true) { m_escAvailable=true; m_clearPreEsc=false; } //********************************************************************************************************** //********************************************************************************************************** // PART 1: CONSUMPTION //********************************************************************************************************** //********************************************************************************************************** //in the case of consumption, for index starts with 0 because the zero position //is employed for escape path. the rest of for loops start with 1. for( inPort = 0; inPort < m_ports; inPort++) { // Injection buffers if( (! m_latch_cons[inPort] ) && (m_fifos_cons[inPort].numberOfElements()!=0) ) { m_fifos_cons[inPort].dequeue(m_latch_cons[inPort]); } } // Clear connection m_clearConsConnection=false; for( inPort = 0; inPort < m_ports; inPort++) { if( ! m_latch_cons[inPort] ) continue; if( m_latch_cons[inPort]->isHeader() || m_latch_cons[inPort]->isHeadTail() ) { //First we check if the link is in use if(m_consAvailable==false) continue; if( outputInterfaz(m_ports)->isStopActive(virtualChannel) ) continue; //reserve the link for the remaining flits m_consAvailable=false; } //send the message outputInterfaz(m_ports)->sendData(m_latch_cons[inPort],virtualChannel); #ifndef NO_TRAZA TPZString texto = txt_comp + " TO CONSUMER " + m_latch_cons[inPort]->asString(); TPZWRITE2LOG(texto); #endif // Clear the latch and the connection if necessary if( m_latch_cons[inPort]->isHeadTail() || m_latch_cons[inPort]->isTail() ) m_clearConsConnection=true; m_latch_cons[inPort]=0; } if (m_clearConsConnection==true) m_consAvailable=true; //********************************************************************************************************** //********************************************************************************************************** // PART 2: OUTPUT STAGE //********************************************************************************************************** //********************************************************************************************************** //********************************************************************************** // Part 2-a: from buffers to latches //********************************************************************************** for( outPort = 1; outPort < m_ports; outPort++) { // Bypass buffers if( (! m_latch_out_byp[outPort] ) && (m_fifos_out_byp[outPort].numberOfElements()!=0) ) { m_fifos_out_byp[outPort].dequeue(m_latch_out_byp[outPort]); } // From-Ring buffers if( (! m_latch_out_turn[outPort] ) && (m_fifos_out_turn[outPort].numberOfElements()!=0) ) { m_fifos_out_turn[outPort].dequeue(m_latch_out_turn[outPort]); } // Injection buffers if( (! m_latch_out_inj[outPort] ) && (m_fifos_out_inj[outPort].numberOfElements()!=0) ) { m_fifos_out_inj[outPort].dequeue(m_latch_out_inj[outPort]); } // Clear connection m_clearConnection[outPort]=false; } //********************************************************************************** // Part 2-b: Request the Output link for Bypass buffers //********************************************************************************** for( outPort = 1; outPort < m_ports; outPort++) { if( ! m_latch_out_byp[outPort] ) continue; #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-OUT-BYPASS " + m_latch_out_byp[outPort]->asString(); texto += TPZString(" outPort:") + TPZString(outPort); texto += TPZString(" Occupation:") + TPZString(m_fifos_out_byp[outPort].numberOfElements()); TPZWRITE2LOG(texto); #endif if( m_latch_out_byp[outPort]->isHeader() || m_latch_out_byp[outPort]->isHeadTail() ) { //First we check if the link is in use and if the next router has buffers available if(m_linkAvailable[outPort]==false) continue; if( outputInterfaz(outPort)->isStopActive(virtualChannel) ) continue; //reserve the link for the remaining flits m_linkAvailable[outPort]=false; } //send the message updateMessageInfo(m_latch_out_byp[outPort], outPort); outputInterfaz(outPort)->sendData(m_latch_out_byp[outPort],virtualChannel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::OStageTraversal); if ( ((TPZSimpleRouter&)getComponent()).getTypeForOutput(outPort) != _LocalNode_ ) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } #ifndef NO_TRAZA TPZString texto2 = txt_comp + " LINK TRAVERSAL (BYPASS) " + m_latch_out_byp[outPort]->asString(); TPZWRITE2LOG(texto2); #endif // Clear the latch and the connection if necessary if( m_latch_out_byp[outPort]->isHeadTail() || m_latch_out_byp[outPort]->isTail() ) { m_clearConnection[outPort]=true; //If the message is ordered, clear the input port restriction if(m_latch_out_byp[outPort]->isOrdered()) m_interfazInOrder[m_latch_out_byp[outPort]->getInputInterfaz()]=false; } m_latch_out_byp[outPort]=0; } //********************************************************************************** // PART 2-c: Request the Output link for From-Ring buffers //********************************************************************************** for( outPort = 1; outPort < m_ports; outPort++) { if( ! m_latch_out_turn[outPort] ) continue; #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-OUT-TURN " + m_latch_out_turn[outPort]->asString(); texto += TPZString(" outPort:") + TPZString(outPort); texto += TPZString(" Occupation:") + TPZString(m_fifos_out_turn[outPort].numberOfElements()); TPZWRITE2LOG(texto); #endif if( m_latch_out_turn[outPort]->isHeader() || m_latch_out_turn[outPort]->isHeadTail() ) { //First we check if the link is in use if(m_linkAvailable[outPort]==false) continue; if( outputInterfaz(outPort)->isStopActive(virtualChannel) ) continue; //If the msg is on Escape, bubble must be checked if ( (m_latch_out_turn[outPort]->isOnScape()==true) && (checkEscapeFlowControl()==false) ) continue; //reserve the link for the remaining flits m_linkAvailable[outPort]=false; } //send the message updateMessageInfo(m_latch_out_turn[outPort], outPort); outputInterfaz(outPort)->sendData(m_latch_out_turn[outPort],virtualChannel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::OStageTraversal); if ( ((TPZSimpleRouter&)getComponent()).getTypeForOutput(outPort) != _LocalNode_ ) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } #ifndef NO_TRAZA TPZString texto2 = txt_comp + " LINK TRAVERSAL (RING) " + m_latch_out_turn[outPort]->asString(); TPZWRITE2LOG(texto2); #endif // Clear the latch and the connection if necessary if( m_latch_out_turn[outPort]->isHeadTail() || m_latch_out_turn[outPort]->isTail() ) { m_clearConnection[outPort]=true; //If the message is ordered, clear the input port restriction if(m_latch_out_turn[outPort]->isOrdered()) m_interfazInOrder[m_latch_out_turn[outPort]->getInputInterfaz()]=false; } m_latch_out_turn[outPort]=0; } //********************************************************************************** // PART 2-d: Request the Output link for Injection buffers //********************************************************************************** for( outPort = 1; outPort <= m_ports; outPort++) { if( ! m_latch_out_inj[outPort] ) continue; #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-OUT-INJ " + m_latch_out_inj[outPort]->asString(); texto += TPZString(" outPort:") + TPZString(outPort); texto += TPZString(" Occupation:") + TPZString(m_fifos_out_inj[outPort].numberOfElements()); TPZWRITE2LOG(texto); #endif if( m_latch_out_inj[outPort]->isHeader() || m_latch_out_inj[outPort]->isHeadTail() ) { //First we check if the link is in use if(m_linkAvailable[outPort]==false) continue; if( outputInterfaz(outPort)->isStopActive(virtualChannel) ) continue; //reserve the link for the remaining flits m_linkAvailable[outPort]=false; } //send the message updateMessageInfo(m_latch_out_inj[outPort], outPort); outputInterfaz(outPort)->sendData(m_latch_out_inj[outPort],virtualChannel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::OStageTraversal); if ( ((TPZSimpleRouter&)getComponent()).getTypeForOutput(outPort) != _LocalNode_ ) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } #ifndef NO_TRAZA TPZString texto2 = txt_comp + " LINK TRAVERSAL (INJ) " + m_latch_out_inj[outPort]->asString(); TPZWRITE2LOG(texto2); #endif // Clear the latch and the connection if necessary if( m_latch_out_inj[outPort]->isHeadTail() || m_latch_out_inj[outPort]->isTail() ) m_clearConnection[outPort]=true; m_latch_out_inj[outPort]=0; } //********************************************************************************** // PART 2-e: Clear all the links (tail flit) occupied this cycle //********************************************************************************** for( outPort = 1; outPort <= m_ports; outPort++) { if (m_clearConnection[outPort]==true) m_linkAvailable[outPort]=true; } if (m_clearEscConnection==true) { outPort=extractOutputPortNumber(m_escape_ctrl); m_linkAvailable[outPort]=true; } //********************************************************************************************************** //********************************************************************************************************** // PART 3: MULTIPORT BUFFERS (INTERNAL RING) //********************************************************************************************************** //********************************************************************************************************** //********************************************************************************** // Part 3-a: from buffers to latches //********************************************************************************** for( inPort = 1; inPort < m_ports; inPort++) { if( (! m_latch_mp_one[inPort] ) && (m_fifos_mp_one[inPort].numberOfElements()!=0) ) { m_fifos_mp_one[inPort].dequeue(m_latch_mp_one[inPort]); } if( (! m_latch_mp_two[inPort] ) && (m_fifos_mp_two[inPort].numberOfElements()!=0) ) { m_fifos_mp_two[inPort].dequeue(m_latch_mp_two[inPort]); } m_clearRingExit[inPort]=false; m_clearRingAdvance[inPort]=false; } //********************************************************************************** // Part 3-b: Arbitrate buffer one (the one comming from input stage) //********************************************************************************** for( inPort = 1; inPort < m_ports; inPort++) { if( !m_latch_mp_one[inPort] ) continue; //******************************************************** // BORRAR, INJECTION ON SCAPE ALWAYS //******************************************************** //m_latch_mp_one[inPort]->setOnScape(); //******************************************************** if( m_latch_mp_one[inPort]->isHeader() || m_latch_mp_one[inPort]->isHeadTail() ) { //First we check if the message can leave the ring if(m_ringExitAvailable[inPort]==true && checkFlowControl((inPort%(m_ports-1))+1, m_fifos_out_turn, 1, m_OSSize)==true) { Boolean checkHead=checkHeader(inPort, m_latch_mp_one[inPort]); if ( checkHead==true ) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->OSTAGE " + m_latch_mp_one[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_out_turn[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_one[inPort]); m_mp_one_ctrl[inPort]=Leave; m_ringExitAvailable[inPort]=false; if(m_latch_mp_one[inPort]->isHeadTail()) m_clearRingExit[inPort]=true; m_latch_mp_one[inPort]=0; continue; } } //If not, we request the next multiport. As we are entering the internal router ring //two conditions: two holes on mp_two[inPort] and one hole on mp_two[(inPort%(m_ports-1))+1] Boolean BubbleFlowControl=checkFlowControl(inPort, m_fifos_mp_two, 2, m_MPSize ); Boolean CTFlowControl=checkFlowControl((inPort%(m_ports-1))+1, m_fifos_mp_two, 1, m_MPSize); if(m_ringAdvanceAvailable[inPort]==true && BubbleFlowControl==true && CTFlowControl==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->MP " + m_latch_mp_one[inPort]->asString(); texto += TPZString(" NextMP= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_mp_two[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_one[inPort]); m_mp_one_ctrl[inPort]=Advance; m_ringAdvanceAvailable[inPort]=false; if(m_latch_mp_one[inPort]->isHeadTail()) m_clearRingAdvance[inPort]=true; m_latch_mp_one[inPort]=0; continue; } } else { if ( m_mp_one_ctrl[inPort]==Leave) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->OSTAGE " + m_latch_mp_one[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_out_turn[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_one[inPort]); if(m_latch_mp_one[inPort]->isTail()) m_clearRingExit[inPort]=true; m_latch_mp_one[inPort]=0; } else { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->MP " + m_latch_mp_one[inPort]->asString(); texto += TPZString(" NextMP= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_mp_two[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_one[inPort]); if(m_latch_mp_one[inPort]->isTail()) m_clearRingAdvance[inPort]=true; m_latch_mp_one[inPort]=0; } } } //********************************************************************************** // Part 3-c: Arbitrate buffer two (the one forming the ring) //********************************************************************************** for( inPort = 1; inPort < m_ports; inPort++) { if( !m_latch_mp_two[inPort] ) continue; if( m_latch_mp_two[inPort]->isHeader() || m_latch_mp_two[inPort]->isHeadTail() ) { //First we check if the message must go to escape path if( (inPort==1) && m_latch_mp_two[inPort]->isOnScape() ) { if(m_fifo_inj_escape.numberOfElements()<=2) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->ESCAPE " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifo_inj_escape.enqueue(m_latch_mp_two[inPort]); m_mp_two_ctrl[inPort]=Escape; m_latch_mp_two[inPort]=0; continue; } } //Then we check if the message can leave the ring if(m_ringExitAvailable[inPort]==true && checkFlowControl((inPort%(m_ports-1))+1, m_fifos_out_turn, 1, m_OSSize)==true) { Boolean checkHead=checkHeader(inPort, m_latch_mp_two[inPort]); if ( checkHead==true ) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->OSTAGE " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_out_turn[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_two[inPort]); m_mp_two_ctrl[inPort]=Leave; m_ringExitAvailable[inPort]=false; if(m_latch_mp_two[inPort]->isHeadTail()) m_clearRingExit[inPort]=true; m_latch_mp_two[inPort]=0; continue; } } //If not, we request the next multiport if(m_ringAdvanceAvailable[inPort]==true && checkFlowControl((inPort%(m_ports-1))+1, m_fifos_mp_two, 1, m_MPSize)==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->MP " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" NextMP= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_mp_two[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_two[inPort]); m_mp_two_ctrl[inPort]=Advance; m_ringAdvanceAvailable[inPort]=false; if(m_latch_mp_two[inPort]->isHeadTail()) m_clearRingAdvance[inPort]=true; //Normal messages must check the number of multiports to move to missrtg or escape if (!m_latch_mp_two[inPort]->isOrdered()) { if (m_latch_mp_two[inPort]->getLastMissRouted()==false && m_latch_mp_two[inPort]->isOnScape()==false) { m_latch_mp_two[inPort]->incrMultiportNumber(); if (m_latch_mp_two[inPort]->getMultiportNumber() >= (m_ports-1)*m_missLoops) { m_latch_mp_two[inPort]->incrTimesMiss(); if (m_latch_mp_two[inPort]->getTimesMiss() >= m_missLimit) m_latch_mp_two[inPort]->setOnScape(); else m_latch_mp_two[inPort]->setLastMissRouted(true); } } } m_latch_mp_two[inPort]=0; continue; } } else { if ( m_mp_two_ctrl[inPort]==Escape) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->ESCAPE " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifo_inj_escape.enqueue(m_latch_mp_two[inPort]); m_latch_mp_two[inPort]=0; } else if ( m_mp_two_ctrl[inPort]==Leave) { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->OSTAGE " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" OutPort= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_out_turn[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_two[inPort]); if(m_latch_mp_two[inPort]->isTail()) m_clearRingExit[inPort]=true; m_latch_mp_two[inPort]=0; } else { #ifndef NO_TRAZA TPZString texto = txt_comp + " MP->MP " + m_latch_mp_two[inPort]->asString(); texto += TPZString(" NextMP= ") + TPZString((inPort%(m_ports-1))+1); TPZWRITE2LOG(texto); #endif m_fifos_mp_two[(inPort%(m_ports-1))+1].enqueue(m_latch_mp_two[inPort]); if(m_latch_mp_two[inPort]->isTail()) m_clearRingAdvance[inPort]=true; m_latch_mp_two[inPort]=0; } } } //********************************************************************************** // Part 3-d: Clear finished connections //********************************************************************************** for( inPort = 1; inPort < m_ports; inPort++) { if (m_clearRingExit[inPort]==true) m_ringExitAvailable[inPort]= true; if (m_clearRingAdvance[inPort]==true) m_ringAdvanceAvailable[inPort]= true; } //**************************************************************************************************************** //**************************************************************************************************************** // PART 4: INPUT STAGE //**************************************************************************************************************** //**************************************************************************************************************** //********************************************************************************** // Part 4-a: from buffers to latches //********************************************************************************** for(inPort = 1; inPort <= m_ports; inPort++) { // If the routing is empty, Take the next message from the corresponding fifo if( (! m_routing[inPort] ) && (m_fifos[inPort].numberOfElements()!=0) ) { m_fifos[inPort].dequeue(m_routing[inPort]); } } //********************************************************************************** // PART 4-b: Then arbitrate msg access to the next stage //********************************************************************************** for(inPort = 1; inPort < m_ports; inPort++) //The last port is arbitrated different, is injection { // If the routing is empty, go to the next if( ! m_routing[inPort] ) continue; #ifndef NO_TRAZA TPZString texto = txt_comp + " LATCH-ISTAGE " + m_routing[inPort]->asString(); texto += TPZString(" inPort: ") + TPZString(inPort); texto += TPZString(" Occupation: ") + TPZString(m_fifos[inPort].numberOfElements()); TPZWRITE2LOG(texto); #endif if( m_routing[inPort]->isHeader() || m_routing[inPort]->isHeadTail() ) { TPZROUTINGTYPE direction= getOutputDirection(m_routing[inPort]); outPort = extractOutputPortNumber(direction); // First we check if it must be consumed if( outPort == m_ports ) { if(checkFlowControl(inPort, m_fifos_cons, 1, m_bufferSize)==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " ISTAGE->CONS " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto); #endif m_fifos_cons[inPort].enqueue(m_routing[inPort]); m_istage_ctrl[inPort]= Consume; m_routing[inPort]=0; } continue; } //At this point we check inOrder restrictions if( m_routing[inPort]->isOrdered() && m_interfazInOrder[inPort]==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " STOP-ORDERED " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto); #endif continue; } //Second we try the bypass path if( (outPort == inPort) && (checkFlowControl(outPort, m_fifos_out_byp, 1, m_OSSize)==true) && !m_routing[inPort]->isOnScape() ) { #ifndef NO_TRAZA TPZString texto = txt_comp + " ISTAGE->OSTAGE " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto); #endif m_fifos_out_byp[outPort].enqueue(m_routing[inPort]); m_istage_ctrl[inPort]= Bypass; if(m_routing[inPort]->isOrdered()) { m_interfazInOrder[inPort]=true; m_routing[inPort]->setInputInterfaz(inPort); } m_routing[inPort]=0; continue; } //Next we try to enter the internal router ring if( checkFlowControl(inPort, m_fifos_mp_one, 1, m_MPSize)==true ) { #ifndef NO_TRAZA TPZString texto = txt_comp + " ISTAGE->MP " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto); #endif m_fifos_mp_one[inPort].enqueue(m_routing[inPort]); m_istage_ctrl[inPort]= Turn; if(m_routing[inPort]->isOrdered()) { m_interfazInOrder[inPort]=true; m_routing[inPort]->setInputInterfaz(inPort); } m_routing[inPort]=0; continue; } } else { if(m_istage_ctrl[inPort]==Bypass) { #ifndef NO_TRAZA TPZString texto1 = txt_comp + " ISTAGE->OSTAGE " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto1); #endif m_routing[inPort]->setInputInterfaz(inPort); m_fifos_out_byp[inPort].enqueue(m_routing[inPort]); m_routing[inPort]=0; } else if(m_istage_ctrl[inPort]==Turn) { #ifndef NO_TRAZA TPZString texto2 = txt_comp + " ISTAGE->MP " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto2); #endif m_routing[inPort]->setInputInterfaz(inPort); m_fifos_mp_one[inPort].enqueue(m_routing[inPort]); m_routing[inPort]=0; } else if (m_istage_ctrl[inPort]==Consume) { #ifndef NO_TRAZA TPZString texto3 = txt_comp + " ISTAGE->CONS " + m_routing[inPort]->asString(); TPZWRITE2LOG(texto3); #endif m_fifos_cons[inPort].enqueue(m_routing[inPort]); m_routing[inPort]=0; } else { TPZString err; err.sprintf( "Wrong value of I-Stage control for Body flits"); EXIT_PROGRAM(err); } } } //**************************************************************************************************************** //**************************************************************************************************************** // PART 5: INJECTION //**************************************************************************************************************** //**************************************************************************************************************** if( m_routing[m_ports] !=0 ) { if( m_routing[m_ports]->isHeader() || m_routing[m_ports]->isHeadTail() ) { //ordered messages are routed through a mesh if( m_routing[m_ports]->isOrdered()) { int deltaX; int deltaY; TPZPosition src = getOwnerRouter().getPosition(); TPZPosition dst = m_routing[m_ports]->destiny(); TPZPosition deltaPos = dst - src; deltaX = deltaPos.valueForCoordinate(TPZPosition::X); deltaY = deltaPos.valueForCoordinate(TPZPosition::Y); deltaX = (deltaX>=0) ? deltaX+1 : deltaX-1; deltaY = (deltaY>=0) ? deltaY+1 : deltaY-1; m_routing[m_ports]->setDelta(deltaX,0); m_routing[m_ports]->setDelta(deltaY,1); } TPZROUTINGTYPE direction= getInjectionDirection(m_routing[m_ports]); outPort= extractOutputPortNumber(direction); if (checkFlowControl(outPort, m_fifos_out_inj, 1, m_bufferSize)==true) { #ifndef NO_TRAZA TPZString texto = txt_comp + " INJECTION " + m_routing[inPort]->asString(); texto += TPZString(" O-PORT: ") + TPZString(outPort); TPZWRITE2LOG(texto); #endif m_fifos_out_inj[outPort].enqueue(m_routing[m_ports]); m_injection_ctrl=outPort; m_routing[m_ports]=0; } } else { m_fifos_out_inj[m_injection_ctrl].enqueue(m_routing[m_ports]); m_routing[m_ports]=0; } } return true; }
Boolean TPZFifoMemoryFlowWH::inputReading() { TPZMessage* msg; inputInterfaz()->getData(&msg); if (!inputInterfaz()->isReadyActive() && m_tail==false) { uTIME delayTime = getOwnerRouter().getCurrentTime() ; TPZString err= "A tail flit was expected but transmission has been interrupted"; err=err+msg->asString()+ "Time crash=" + TPZString(delayTime); EXIT_PROGRAM(err); } if (inputInterfaz()->isReadyActive() ) { msg->incDistance(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::BufferWrite); if (msg->isTail() || msg->isHeadTail()) { m_tail=true; setControlTail(true); } if (msg->isHeader() || msg->isHeadTail()) { getOwnerRouter().incrContadorTotal(); } if (msg->isHeader() && m_tail==false) { uTIME delayTime = getOwnerRouter().getCurrentTime() ; TPZString err= "A head flit arrives before previous tail flit"; err=err+msg->asString()+ "Time crash=" + TPZString(delayTime); EXIT_PROGRAM(err); } if ( !bufferHoles()) { uTIME delayTime = getOwnerRouter().getCurrentTime() ; TPZString err; err.sprintf(ERR_TPZFFLOW_001, (char*)getComponent().asString()); err=err+msg->asString()+ "Time crash=" + TPZString(delayTime); EXIT_PROGRAM(err); } uTIME delay = getOwnerRouter().getCurrentTime() + getDataDelay(); TPZEvent event(_BufferData_, msg); getEventQueue().enqueue(event, delay); #ifndef NO_TRAZA uTIME delayTime = getOwnerRouter().getCurrentTime() ; TPZString texto = getComponent().asString() + " Flit Rx on Time" + TPZString(delayTime) + " # " + msg->asString() + ") holes= " + TPZString(bufferHoles()); TPZWRITE2LOG(texto); #endif stateChange(); if (m_SendStop) { inputInterfaz()->sendStopRightNow(); #ifndef NO_TRAZA uTIME time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().asString() + ": Full Buffer->Stop "; texto += TPZString(time); TPZWRITE2LOG(texto); #endif } else { inputInterfaz()->clearStopRightNow(); } return true; } return false; }
//************************************************************************* //: // f: virtual Boolean dispatchEvent (const TPZEvent & event); // // d: //: //************************************************************************* Boolean TPZCrossbarFlowWH :: dispatchEvent(const TPZEvent& event) { uTIME delayTime = getOwnerRouter().getCurrentTime(); //********************************************************************** // EVENT= ROUTING //********************************************************************** if( event.type() == _RoutingVC_ ) { //update the header and select output port TPZMessage *msg; unsigned iPort = event.source(); m_MessageReceivedTable->valueAt(iPort,&msg); if( (!(msg->isHeader())) && (!(msg->isHeadTail()))) { TPZString err; err.sprintf( "%s :Data flits should not pass through this event",(char*)getComponent().asString() ); EXIT_PROGRAM(err); } #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event ROUTING. TIME = "; texto += TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # " + msg->asString() ; TPZWRITE2LOG( texto ); #endif if (!msg->isMulticast())//multicast messages are proceesed at FIFO buffer, avoid re-routing { int deltaX = msg->delta(0); int deltaY = msg->delta(1); int deltaZ = msg->delta(2); if( deltaX > 1 ) msg->setRoutingPort(_Xplus_); else if( deltaX < -1 ) msg->setRoutingPort(_Xminus_); else if( deltaY > +1 ) msg->setRoutingPort(_Yplus_); else if( deltaY < -1 ) msg->setRoutingPort(_Yminus_); else if( deltaZ > +1 ) msg->setRoutingPort(_Zplus_); else if( deltaZ < -1 ) msg->setRoutingPort(_Zminus_); else msg->setRoutingPort(_LocalNode_); } unsigned portout = extractOutputPortNumber(msg); m_InOutPortTable->setValueAt(iPort, portout); TPZEvent SWAllocEvent(_SwitchAllocator_, iPort, portout, 1, msg); getEventQueue().enqueue(SWAllocEvent, delayTime+m_routingDelay); } //********************************************************************** // EVENT= SWITCH ALLOCATION //********************************************************************** else if( event.type() == _SwitchAllocator_ ) { unsigned iPort = event.source(); unsigned oPort = event.destiny(); TPZMessage* msg; m_MessageReceivedTable->valueAt(iPort,&msg); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event SW ALLOCATION. TIME = " + TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # oPort=" + TPZString(oPort) + msg->asString() ; TPZWRITE2LOG( texto ); #endif if (getStateForOutputPort(oPort)==FREE) { #ifndef NO_TRAZA TPZString texto2 = getComponent().asString() + " Free port=" + TPZString(oPort); TPZWRITE2LOG( texto2); #endif setStateForOutputPort(oPort, ASIGNED); TPZEvent SWTravEvent(_SwitchTraversal_, iPort, oPort, 1, msg); getEventQueue().enqueue(SWTravEvent, delayTime+1); } else { #ifndef NO_TRAZA TPZString texto3 = getComponent().asString() + "Occupied port"; TPZWRITE2LOG( texto3 ); #endif TPZEvent SWAllocEvent(_SwitchAllocator_,iPort, oPort, 1, msg); getEventQueue().enqueue(SWAllocEvent, delayTime+m_SWArbitrationDelay); } ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWArbitration); } //********************************************************************** // EVENT= SWITCH TRAVERSAL //********************************************************************** else if( event.type() == _SwitchTraversal_ ) { unsigned iPort = event.source(); unsigned oPort = event.destiny(); TPZMessage* msg; m_MessageReceivedTable->valueAt(iPort,&msg); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event SW TRAVERSAL. TIME = " + TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # oPort=" + TPZString(oPort) + msg->asString() ; TPZWRITE2LOG( texto ); #endif if ( (!outputInterfaz(oPort)->isStopActive())) { inputInterfaz(iPort)->clearStopRightNow(); if (!msg->isMulticast()) updateMessageInfo(msg); //again, MC messages already processed outputInterfaz(oPort)->sendData(msg); if ( msg->isTail() || msg->isHeadTail() ) { setStateForOutputPort(oPort, FREE); } ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWTraversal); if ( ((TPZCrossbar&)getComponent()).getTypeForOutput(oPort,1) != _LocalNode_) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } } else { uTIME delayTime = getOwnerRouter().getCurrentTime() ; TPZEvent SWTravEvent(_SwitchTraversal_,iPort, oPort, 1, msg); getEventQueue().enqueue(SWTravEvent, delayTime+m_SWTraversalDelay); } } return true; }
//************************************************************************* //: // f: virtual Boolean inputReading (); // // d: //: //************************************************************************* Boolean TPZSimpleRouterFlowWH :: inputReading() { unsigned outPort; unsigned inPort; unsigned virtualChannel; cleanOutputInterfaces(); TPZNetwork* net = ((TPZSimulation*)(getComponent().getSimulation()))->getNetwork(); //********************************************************************************************************** // PART 4: Loop through all output ports. // We move the data flits for already established connections //********************************************************************************************************** for( outPort = 1; outPort <= m_ports; outPort++) { // Find the input port assigned to outport. // If not assigned, go to the next. if( ! (inPort = m_connections[outPort] ) ) { continue; } // If no message at routing, go to the next if( ! m_routing[inPort] ) { TPZString err = getComponent().asString() + " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); err+=" connection indicates that input: "; err+= TPZString(inPort)+"is connected to output: "; err+= TPZString(outPort); err+=" but the routing unit is empty (Packet fragmented at the link?)"; //EXIT_PROGRAM (err); continue; } virtualChannel=(inPort-1)/m_ports+1; if( inPort % m_ports == 0 ) { virtualChannel=m_routing[inPort]->getVnet(); if(inPort>m_ports)continue; } if(outPort == m_ports) virtualChannel=1; if( outputInterfaz(outPort)->isStopActive(virtualChannel) ) { continue; } // If there is a message at routing and delay is over if( ! ( m_routingtime[inPort]-- ) ) { TPZMessage* mess=m_routing[inPort]; if (mess->isMulticast()) { unsigned long long messageMask=mess->getMsgmask(); unsigned long long portMask=getOwnerRouter().getMask(mess->getRoutingPort()); //The last message, no replication is needed if ( (messageMask & (~portMask))== 0) { mess->setMsgmask(messageMask & portMask); m_routing[inPort] = 0; #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " NO-REPLICATION "; texto += TPZString( " Leaving MSG= ") + mess->asString(); texto += TPZString( " Leaving Mask= ") + TPZString(mess->getMsgmask()); texto += TPZString( " OPORT= ") + TPZString(outPort); TPZWRITE2LOG(texto); #endif } //need to replicate, destinations remaining else { if((mess = getMessagePool().allocate())==0) { TPZString err; err.sprintf(ERR_TPZPOOL_001); EXIT_PROGRAM(err); } *mess=*m_routing[inPort]; //New message mask mess->setMulticast(); mess->setMsgmask(messageMask & portMask); #ifdef PTOPAZ unsigned pool_index=net->getThreadID(pthread_self()); mess->setPoolIndex(pool_index); #endif // Statistics functions net->incrementTx(TPZNetwork::Message); net->incrementTx(TPZNetwork::Packet,mess->messageSize()); net->incrementTx(TPZNetwork::Flit,mess->messageSize()*mess->packetSize()); m_routing[inPort]->setMsgmask(messageMask & (~portMask)); updateMessageInfo(m_routing[inPort]); m_routingtime[inPort] = getHeaderDelay(); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " REPLICATION "; texto += TPZString( " Leaving Mask= ") + TPZString(mess->getMsgmask()); texto += TPZString(" Remaining Mask= ") + TPZString(m_routing[inPort]->getMsgmask()); TPZWRITE2LOG(texto); #endif } } else { m_routing[inPort] = 0; } outputInterfaz(outPort)->sendData(mess,virtualChannel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWTraversal); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::BufferRead); if ( ((TPZSimpleRouter&)getComponent()).getTypeForOutput(outPort) != _LocalNode_ ) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " SW TRAVERSAL "; texto += " From "; texto += mess->asString() + " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); texto += TPZString(" inPort: ") + TPZString(inPort) + TPZString(" outPort: ") + TPZString(outPort); texto += TPZString(" VChannel: ") + TPZString(virtualChannel); TPZWRITE2LOG(texto); #endif // If end of message if( mess->isTail() || mess->isHeadTail() ) { m_connections[outPort] = 0; #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " CLEARING "; texto += " From "; texto += mess->asString() + " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); texto += TPZString(" inPort: ") + TPZString(inPort) + TPZString(" outPort: ") + TPZString(outPort); texto += TPZString(" VChannel: ") + TPZString(virtualChannel); TPZWRITE2LOG(texto); #endif } } } //****************************************************************************************************************** // PART 3: Process the connection of the crossbar // the token is to be round robin arbitration //****************************************************************************************************************** inPort = m_ports*m_vnets; m_token = 0; int i; for(i = 0; i < m_ports*m_vnets ; i++, inPort = inPort - 1) { virtualChannel=(inPort-1)/m_ports+1; // If the routing is empty, go to the next if( ! m_routing[inPort] ) { continue; } // If it is not a header, go to the next if( (! m_routing[inPort]->isHeader()) && (! m_routing[inPort]->isHeadTail()) ) { continue; } // Extract the output port outPort = extractOutputPortNumber(m_routing[inPort]); if(inPort == m_ports) { virtualChannel=m_routing[inPort]->getVnet(); if(inPort>m_ports)continue; } if(outPort == m_ports) virtualChannel=1; if( outputInterfaz(outPort)->isStopActive(virtualChannel) ) { if( ! m_token ) m_token = inPort; continue; } if( ! m_connections[outPort] ) { // Reserve the port m_connections[outPort] = inPort; #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " SW ARB [GRANT] "; texto += " From "; texto += m_routing[inPort]->asString() + " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); texto += TPZString(" inPort: ") + TPZString(inPort) + TPZString(" outPort: ") + TPZString(outPort); texto += TPZString(" VChannel: ") + TPZString(virtualChannel); TPZWRITE2LOG(texto); #endif } else { #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " SW ARB {REJECT] "; texto += " From "; texto += m_routing[inPort]->asString() + " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); texto += TPZString(" inPort: ") + TPZString(inPort) + TPZString(" outPort: ") + TPZString(outPort); texto += TPZString(" VChannel: ") + TPZString(virtualChannel); TPZWRITE2LOG(texto); #endif // If this is the first port rejected in this round // keep it to serve first in the following if( ! m_token ) { m_token = inPort; } } } // No ports were rejected. if( ! m_token ) m_token = inPort; //**************************************************************************************************************** // PART 2: Loop through all the routing // Filling those that are empty with data from the fifo //**************************************************************************************************************** for(inPort = 1; inPort <= m_ports*m_vnets; inPort++) { // If the routing is not empty if( ! m_routing[inPort] ) { // Take the next message from the corresponding fifo if(m_fifos[inPort].numberOfElements()!=0) { m_fifos[inPort].dequeue(m_routing[inPort]); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " BUFFER-READ "; texto += m_routing[inPort]->asString()+ " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); TPZWRITE2LOG(texto); #endif // If the message is header if( m_routing[inPort]->isHeader() || m_routing[inPort]->isHeadTail() ) { // Calculate the output port updateMessageInfo(m_routing[inPort]); m_routingtime[inPort] = getHeaderDelay(); } else { m_routingtime[inPort] = 0; } } } } //********************************************************************************************************** // PART 1: Loop through all sync. //********************************************************************************************************** for( inPort = 1; inPort <= m_ports*m_vnets; inPort++) { // If there is a message at syncronizer, if( m_sync[inPort] ) { #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " BUFFER-WRITE "; texto += m_sync[inPort]->asString()+ " TIME: " + TPZString(getOwnerRouter().getCurrentTime()); TPZWRITE2LOG(texto); #endif // Put it in the corresponding buffer m_fifos[inPort].enqueue(m_sync[inPort]); // and remove it from syncs m_sync[inPort]=0; } } return true; }
Boolean TPZConsumerFlowReactive :: stateChange() { if( (!inputInterfaz()->isStopActive()) && m_DataReceived ) { #ifndef NO_TRAZA TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto= getComponent().asString() + " Flit Rx. TIME = " + time + ". " + m_InputData->asString(); #endif if(m_State == Information && m_InputData->isHeader()) { TPZString err; err.sprintf( "%s : I detect a Header flit before previous message Tail flit: %s", (char*)getComponent().asString(), (char*)m_InputData->asString() ); EXIT_PROGRAM(err); } if( m_State == Header ) { if (m_InputData->isHeadTail()) m_State = Header; else m_State = Information; if( m_InputData->destiny() != getOwnerRouter().getPosition() && !m_InputData->isMulticast() ) { TPZString err; err.sprintf( ERR_TPZCOFLO_001,(char*)getComponent().asString(),(char*)m_InputData->asString() ); EXIT_PROGRAM(err); } if(m_InputData->isHeadTail()) { #ifndef NO_TRAZA texto += " PACKET RX"; #endif m_InputData->setDestiny(getOwnerRouter().getPosition()); getOwnerRouter().onPacketReceived(m_InputData); uTIME lastTime = getOwnerRouter().getCurrentTime(); ((TPZSimulation*)(getComponent().getSimulation()))->setLastMessage ( lastTime ); } } if( m_InputData->isTail() ) { #ifndef NO_TRAZA texto += " PACKET RX"; #endif getOwnerRouter().onPacketReceived(m_InputData); m_State = Header; uTIME lastTime = getOwnerRouter().getCurrentTime(); ((TPZSimulation*)(getComponent().getSimulation()))->setLastMessage ( lastTime ); //reinjection of the packet, in order to emulate reactive nature //injectProtocolMessage emulates traffic where messages travel back to their source node //injectProtocolRandomMessage function can also be employed. In this case, destination of //re-injected packet is chosen randomly. int order = m_InputData-> getVnet (); unsigned mess_types= ((TPZSimulation*)(getComponent().getSimulation()))->getProtocolMessTypes(); if (order < mess_types) ((TPZSimulation *)(getComponent().getSimulation()))->injectProtocolMessage(m_InputData->destiny(), m_InputData->source(), order+1); } #ifndef NO_TRAZA TPZWRITE2LOG(texto); #endif } return true; }
Boolean TPZCrossbarFlowCTMux :: onReadyUp(unsigned interfaz, unsigned cv) { unsigned i = interfaz; TPZMessage* msg; TPZMessage* lastMessage; inputInterfaz(i)->getData(&msg); m_MessageReceivedTable->valueAt(i,&lastMessage); if(lastMessage) if( *msg == *lastMessage ) return true; m_MessageReceivedTable->setValueAt(i,msg); uTIME delayTime = getOwnerRouter().getCurrentTime() ; #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Flit Rx. TIME = "; texto += TPZString(delayTime) + " # " + msg->asString(); TPZWRITE2LOG( texto ); #endif if( getOutputForInput(i).left() == 0 ) { // This is to run the TPZCrossbarFlowCTMux if(!msg->isHeader()) { return true; } // This from the head. unsigned outPort = extractOutputPortNumber(msg); unsigned outChannel = extractOutputChannel(msg); if( outChannel==0) { EXIT_PROGRAM("Message without output VC"); } TPZEvent requestEvent(_CrossbarRequest_,i,outPort,outChannel); setStateForInput(i,Waiting); if( isOutputPortFree(outPort,outChannel) ) { // You must assign an output delayTime += getHeaderDelay(); if( ((TPZCrossbar&)getComponent()).isLocalNodeOutput(outPort) ) { if( getHeaderDelay() > 1 ) delayTime -= 1; } getEventQueue().enqueue(requestEvent,delayTime); } else { // The output port is busy. A request is queued #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Esperando una SALIDA !"; texto += TPZString(delayTime) + " iport= " + TPZString(i); TPZWRITE2LOG( texto ); #endif addConnectionRequest(i,uPAIR(outPort,outChannel)); } #ifndef NO_TRAZA TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().getName() + " Stop Tx. TIME = "; texto += time + " iport= " + TPZString(i); TPZWRITE2LOG( texto ); #endif inputInterfaz(i)->sendStopRightNow(); } else { delayTime += getDataDelay(); TPZEvent passEvent(_CrossbarPass_,i); getEventQueue().enqueue(passEvent,delayTime); } return true; }
Boolean TPZCrossbarFlowCTMux :: dispatchEvent(const TPZEvent& event) { if( ( event.type() == _CrossbarRequest_ ) || ( event.type() == _CrossbarPass_ ) ) { TPZCrossbar& crossbar = (TPZCrossbar&)(getComponent()); unsigned iPort = event.source(); unsigned oPort = getOutputForInput(iPort).left(); unsigned channel = getOutputForInput(iPort).right(); if(event.type() == _CrossbarRequest_) { oPort=event.destiny(); channel=event.channel(); } TPZMessage *msg; m_MessageReceivedTable->valueAt(iPort,&msg); if(!msg) return true; if(!channel) { if(_CrossbarRequest_) { EXIT_PROGRAM("Channel set to 0 in request Not allowed"); } else { EXIT_PROGRAM("Channel set to 0 in data Not allowed"); } } else if( ! iPort ) { TPZString err; err.sprintf( ERR_TPZCFLOC_001, (char*)getComponent().asString(), (char*)msg->asString() ); EXIT_PROGRAM(err); } else if(!oPort) { TPZString err; err.sprintf( ERR_TPZCFLOC_002, (char*)getComponent().asString(), (char*)msg->asString() ); EXIT_PROGRAM(err); } //Here's the difference with the normal version if( event.type() == _CrossbarRequest_) { for(int i=1; i<=crossbar.numberOfInputs(); i++) { uPAIR temp; m_PortAsignamentTable->valueAt(i,temp); if(i!=iPort && (temp.left()==oPort) ) { inputInterfaz(iPort)->sendStop(); uTIME delayTime = getOwnerRouter().getCurrentTime() + 1; getEventQueue().enqueue(event,delayTime); #ifndef NO_TRAZA TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().asString() + " CONTENTION STOP TIME = "; texto += time + msg->asString() + " i=" + TPZString(iPort) + ", o=" + TPZString(oPort) + ", OPORT used by i=" + TPZString(i); TPZWRITE2LOG( texto ); #endif return true; } } if( (outputInterfaz(oPort)->isStopActive(channel))) { inputInterfaz(iPort)->sendStop(); uTIME delayTime = getOwnerRouter().getCurrentTime() + 1; getEventQueue().enqueue(event,delayTime); #ifndef NO_TRAZA TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().asString() + " QUEUES STOP TIME = "; texto += time + msg->asString() + " i=" + TPZString(iPort) + ", o=" + TPZString(oPort); TPZWRITE2LOG( texto ); #endif return true; } establishConnection(iPort,oPort,channel); setStateForInput(iPort,Connect); } inputInterfaz(iPort)->clearStopRightNow(); outputInterfaz(oPort)->sendData(msg,channel); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWTraversal); if (msg->getRoutingPort()!=_LocalNode_) ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); #ifndef NO_TRAZA TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().asString() + " Flit Tx. TIME = "; texto += time + msg->asString() + " i=" + TPZString(iPort) + ", o=" + TPZString(oPort); TPZWRITE2LOG( texto ); #endif if( msg->isTail() ) { clearConnection(iPort); uPAIR temp; temp = getConnectionRequestForWith(oPort); iPort=temp.left(); channel=temp.right(); if( iPort != 0 ) { establishConnection(iPort,oPort,channel); TPZEvent requestEvent(_CrossbarRequest_,iPort,oPort,channel); uTIME delayTime = getOwnerRouter().getCurrentTime() + MAXIMO(1,getHeaderDelay()); if( ((TPZCrossbar&)getComponent()).isLocalNodeOutput(oPort) ) { if( getHeaderDelay() > 1 ) delayTime -= 1; } getEventQueue().enqueue(requestEvent,delayTime); } } } return true; }
/* -------------------------- Initialization ---------------- */ static void setup_connections(int argc, char *argv[]) { struct optstruct *opts; struct optstruct *clamd_opts; unsigned i; char *conn = NULL; opts = optparse(NULL, argc, argv, 1, OPT_CLAMDTOP, 0, NULL); if (!opts) { fprintf(stderr, "ERROR: Can't parse command line options\n"); EXIT_PROGRAM(FAIL_CMDLINE); } if(optget(opts, "help")->enabled) { optfree(opts); help(); normal_exit = 1; exit(0); } if(optget(opts, "version")->enabled) { printf("Clam AntiVirus Monitoring Tool %s\n", get_version()); optfree(opts); normal_exit = 1; exit(0); } if(optget(opts, "defaultcolors")->enabled) default_colors = 1; memset(&global, 0, sizeof(global)); if (!opts->filename || !opts->filename[0]) { const struct optstruct *opt; const char *clamd_conf = optget(opts, "config-file")->strarg; if ((clamd_opts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) { fprintf(stderr, "Can't parse clamd configuration file %s\n", clamd_conf); EXIT_PROGRAM(FAIL_CMDLINE); } if((opt = optget(clamd_opts, "LocalSocket"))->enabled) { conn = strdup(opt->strarg); if (!conn) { fprintf(stderr, "Can't strdup LocalSocket value\n"); EXIT_PROGRAM(FAIL_INITIAL_CONN); } } else if ((opt = optget(clamd_opts, "TCPSocket"))->enabled) { char buf[512]; const struct optstruct *opt_addr; const char *host = "localhost"; if ((opt_addr = optget(clamd_opts, "TCPAddr"))->enabled) { host = opt_addr->strarg; } snprintf(buf, sizeof(buf), "%lld", opt->numarg); conn = make_ip(host, buf); } else { fprintf(stderr, "Can't find how to connect to clamd\n"); EXIT_PROGRAM(FAIL_INITIAL_CONN); } optfree(clamd_opts); global.num_clamd = 1; } else { unsigned i = 0; while (opts->filename[i]) { i++; } global.num_clamd = i; } #ifdef _WIN32 WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { fprintf(stderr, "Error at WSAStartup(): %d\n", WSAGetLastError()); EXIT_PROGRAM(FAIL_INITIAL_CONN); } #endif /* clamdtop */ puts( " __ ____"); puts(" _____/ /___ _____ ___ ____/ / /_____ ____"); puts(" / ___/ / __ `/ __ `__ \\/ __ / __/ __ \\/ __ \\"); puts("/ /__/ / /_/ / / / / / / /_/ / /_/ /_/ / /_/ /"); puts("\\___/_/\\__,_/_/ /_/ /_/\\__,_/\\__/\\____/ .___/"); puts(" /_/"); global.all_stats = calloc(global.num_clamd, sizeof(*global.all_stats)); OOM_CHECK(global.all_stats); global.conn = calloc(global.num_clamd, sizeof(*global.conn)); OOM_CHECK(global.conn); for (i=0;i < global.num_clamd;i++) { const char *soname = conn ? conn : opts->filename[i]; global.conn[i].line = i+1; if (make_connection(soname, &global.conn[i]) < 0) { EXIT_PROGRAM(FAIL_INITIAL_CONN); } } optfree(opts); free(conn); #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); signal(SIGINT, sigint); #endif }
//************************************************************************* //: // f: virtual Boolean dispatchEvent (const TPZEvent & event); // // d: //: //************************************************************************* Boolean TPZCrossbarFlowVC::dispatchEvent(const TPZEvent& event) { uTIME delayTime = getOwnerRouter().getCurrentTime(); //********************************************************************** // EVENT= ROUTING //********************************************************************** if (event.type() == _RoutingVC_) { //update the header and select output port TPZMessage *msg; unsigned iPort = event.source(); m_MessageReceivedTable->valueAt(iPort, &msg); if ( (!(msg->isHeader())) && (!(msg->isHeadTail())) ) { TPZString err; err.sprintf("%s :Body flits should not pass through this state", (char*)getComponent().asString() ); EXIT_PROGRAM(err); } #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event ROUTING. TIME = "; texto += TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # " + msg->asString() ; TPZWRITE2LOG(texto); #endif if (!msg->isMulticast()) //MC messages have been already processed { int deltaX = msg->delta(0); int deltaY = msg->delta(1); int deltaZ = msg->delta(2); if (deltaX > 1) msg->setRoutingPort(_Xplus_); else if (deltaX < -1) msg->setRoutingPort(_Xminus_); else if (deltaY > +1) msg->setRoutingPort(_Yplus_); else if (deltaY < -1) msg->setRoutingPort(_Yminus_); else if (deltaZ > +1) msg->setRoutingPort(_Zplus_); else if (deltaZ < -1) msg->setRoutingPort(_Zminus_); else msg->setRoutingPort(_LocalNode_); } unsigned portout = extractOutputPortNumber(msg); //***************************************************************** //Ideal assignation of the first VC to request //***************************************************************** unsigned msgtype=msg->getVnet(); unsigned VCFirstReq; //Oredered messages must request the same VC to avoid message forwarding if (msg->isOrdered()) VCFirstReq=1; else VCFirstReq= getFirstVCReqFor(iPort, portout, msgtype); m_InOutVCTable->setValueAt(iPort, VCFirstReq); //***************************************************************** TPZEvent VCAllocEvent(_VCAllocator_, iPort, portout, VCFirstReq, msg); getEventQueue().enqueue(VCAllocEvent, delayTime+m_routingDelay); } //********************************************************************** // EVENT= VIRTUAL CHANNEL ARBITRATION //********************************************************************** else if (event.type() == _VCAllocator_) { unsigned iPort = event.source(); unsigned oPort = event.destiny(); unsigned VChannel = event.channel(); TPZMessage* msg; m_MessageReceivedTable->valueAt(iPort, &msg); if ( ( (!(msg->isHeader())) && (!(msg->isHeadTail())) ) || (!iPort) || (!oPort) ) { TPZString err; err.sprintf("%s :Some kind of error at this point", (char*)getComponent().asString() ); EXIT_PROGRAM(err); } #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event VC ALLOCATION. TIME = "; texto += TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # oPort=" + TPZString(oPort) + " # VChannel =" + TPZString(VChannel) + msg->asString() ; TPZWRITE2LOG(texto); #endif //The absolute port value corresponding to the message must be calculated unsigned messtype=msg->getVnet(); unsigned oVirtualChannel=getAbsolutValueForOutputVC(oPort, VChannel, messtype); TPZState state=getStateForOutputVC(oVirtualChannel); if (state!=FREE) { //On the next VC arbitration event we request a different Virtual Channel unsigned mux = ((TPZCrossbar&)(getComponent())).getOutputMux(); unsigned msgtypes = ((TPZCrossbar&)(getComponent())).getNumberMT(); unsigned VCNextRequest; if (msg->isOrdered()) VCNextRequest=VChannel; else VCNextRequest=((VChannel)%(mux/msgtypes))+1; m_InOutVCTable->setValueAt(iPort, VCNextRequest); #ifndef NO_TRAZA TPZString texto3 = getComponent().asString() + " VC Occupied" + " # New VC Requested = " + TPZString(VCNextRequest); TPZWRITE2LOG(texto3); #endif TPZEvent VCAllocEvent(_VCAllocator_, iPort, oPort, VCNextRequest); getEventQueue().enqueue(VCAllocEvent, delayTime+m_VCArbitrationDelay); } else { #ifndef NO_TRAZA TPZString texto2 = getComponent().asString() + " Found Free VC" + " # OutputVC = " + TPZString(oVirtualChannel); TPZWRITE2LOG(texto2); #endif setStateForOutputVC(oVirtualChannel, ASIGNED); TPZEvent SWAllocEvent(_SwitchAllocator_, iPort, oPort, VChannel, msg); getEventQueue().enqueue(SWAllocEvent, delayTime+m_VCArbitrationDelay); } ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::VCArbitration); } //********************************************************************** // EVENT= SWITCH ARBITRATION //********************************************************************** else if (event.type() == _SwitchAllocator_) { unsigned iPort = event.source(); unsigned oPort = event.destiny(); unsigned VChannel = event.channel(); TPZMessage* msg; m_MessageReceivedTable->valueAt(iPort, &msg); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event SW ALLOCATION. TIME = " + TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # oPort=" + TPZString(oPort) + " # VChannel =" + TPZString(VChannel) + msg->asString() ; TPZWRITE2LOG(texto); #endif unsigned mux = ((TPZCrossbar&)(getComponent())).getOutputMux(); unsigned msgtypes = ((TPZCrossbar&)(getComponent())).getNumberMT(); unsigned messtype=msg->getVnet(); unsigned outputVChannel= (messtype-1)*(mux/msgtypes) + VChannel; if (oPort == m_outputs) outputVChannel=1; TPZState state=getStateForOutputPort(oPort); if ( (!outputInterfaz(oPort)->isStopActive(outputVChannel)) && state==FREE) { #ifndef NO_TRAZA TPZString texto2 = getComponent().asString() + " Free Port=" + TPZString(oPort) + "turns into ASIGNED"; TPZWRITE2LOG(texto2); #endif setStateForOutputPort(oPort, ASIGNED); m_InOutPortTable->setValueAt(iPort, oPort); TPZEvent SWTravEvent(_SwitchTraversal_, iPort, oPort, VChannel, msg); getEventQueue().enqueue(SWTravEvent, delayTime+m_SWArbitrationDelay); } else { #ifndef NO_TRAZA TPZString texto3 = getComponent().asString() + "already occupied port"; TPZWRITE2LOG(texto3); #endif TPZEvent SWAllocEvent(_SwitchAllocator_, iPort, oPort, VChannel, msg); getEventQueue().enqueue(SWAllocEvent, delayTime+m_SWArbitrationDelay); } ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWArbitration); } //********************************************************************** // EVENT= SWITCH TRAVERSAL //********************************************************************** else if (event.type() == _SwitchTraversal_) { unsigned iPort = event.source(); unsigned oPort = event.destiny(); unsigned VChannel = event.channel(); TPZMessage* msg; m_MessageReceivedTable->valueAt(iPort, &msg); #ifndef NO_TRAZA TPZString texto = getComponent().asString() + " Event SW TRAVERSAL. TIME = " + TPZString(getOwnerRouter().getCurrentTime()) + " # " + "iPort=" + TPZString(iPort) + " # oPort=" + TPZString(oPort) + " # VChannel =" + TPZString(VChannel) + msg->asString() ; TPZWRITE2LOG(texto); #endif unsigned mux = ((TPZCrossbar&)(getComponent())).getOutputMux(); unsigned msgtypes = ((TPZCrossbar&)(getComponent())).getNumberMT(); unsigned messtype=msg->getVnet(); unsigned outputVChannel= (messtype-1)*(mux/msgtypes) + VChannel; if (oPort == m_outputs) outputVChannel=1; inputInterfaz(iPort)->clearStopRightNow(); if (!msg->isMulticast() )updateMessageInfo(msg);//only unicast message need to update their contents. outputInterfaz(oPort)->sendData(msg, outputVChannel); #ifndef NO_TRAZA TPZString texto2 = getComponent().asString() + "Port liberation =" + TPZString(oPort); TPZWRITE2LOG(texto2); #endif setStateForOutputPort(oPort, FREE); if (msg->isTail() || msg->isHeadTail() ) { unsigned oVirtualChannel= getAbsolutValueForOutputVC(oPort, VChannel, messtype); #ifndef NO_TRAZA TPZString texto3 = getComponent().asString() + "Channel liberation =" + TPZString(oVirtualChannel); TPZWRITE2LOG(texto3); #endif setStateForOutputVC(oVirtualChannel, FREE); } ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::SWTraversal); if ( ((TPZCrossbar&)getComponent()).getTypeForOutput(oPort,1) != _LocalNode_) { getOwnerRouter().incrLinkUtilization(); ((TPZNetwork*)(getOwnerRouter().getOwner()))->incrEventCount( TPZNetwork::LinkTraversal); } } return true; }
Boolean TPZConsumerFlowRespTimeSim::stateChange() { if (m_DataReceived) { #ifndef NO_TRAZA //Log: lectura del buffer: flit a procesar TPZString time = getOwnerRouter().getCurrentTime(); TPZString texto = getComponent().asString() + " BUFFER-READ. TIME = " + time + ". " + m_InputData->asString(); #endif if (m_State == Information && m_InputData->isHeader()) { TPZString err; err.sprintf( "%s : I detect a Header flit before previous message Tail flit: %s", (char*) getComponent().asString(), (char*) m_InputData->asString()); EXIT_PROGRAM(err); } if (m_State == Header) { if (m_InputData->isHeadTail()) m_State = Header; else m_State = Information; if (m_InputData->destiny() != getOwnerRouter().getPosition() && !m_InputData->isMulticast()) { TPZString err; err.sprintf(ERR_TPZCOFLO_001, (char*) getComponent().asString(), (char*) m_InputData->asString()); EXIT_PROGRAM(err); } if (m_InputData->isHeadTail()) { #ifndef NO_TRAZA texto += " PACKET RX"; #endif m_InputData->setDestiny(getOwnerRouter().getPosition()); getOwnerRouter().onPacketReceived(m_InputData); uTIME lastTime = getOwnerRouter().getCurrentTime(); ((TPZSimulation*) (getComponent().getSimulation()))->setLastMessage( lastTime); //Emulacion de contencion en el acceso a L2. Cuando se finaliza el envio del mensaje //(lleva el ultimo flit) se completa la peticion de acceso a memoria, por lo que //hay que esperar a que la memoria "devuelva el dato" (no se envia nada al consumidor hasta //que transcurran t_acceso(L2) ns //Cuando el mensaje es 1 solo flit: read request (no lleva dato). if (getOwnerRouter().getPosition().valueForCoordinate( TPZPosition::Z) == 1){ m_wasReadNotWrite = true; m_stopCycles = 0; #ifndef NO_TRAZA texto += " (Memory read request)"; #endif } } } if (m_InputData->isTail()) { #ifndef NO_TRAZA texto += " PACKET RX"; #endif getOwnerRouter().onPacketReceived(m_InputData); m_State = Header; uTIME lastTime = getOwnerRouter().getCurrentTime(); ((TPZSimulation*) (getComponent().getSimulation()))->setLastMessage( lastTime); //Emulacion de contencion en el acceso a L2. //Cuando el mensaje es de mas de un flit: write request (lleva dato). if (getOwnerRouter().getPosition().valueForCoordinate( TPZPosition::Z) == 1){ m_wasReadNotWrite = false; m_stopCycles = 0; #ifndef NO_TRAZA texto += " (Memory write request)"; #endif } } #ifndef NO_TRAZA TPZWRITE2LOG(texto); #endif } //emulacion de contencion en acceso a L2, control de flujo //se envia una senal de stop emulando el tiempo de acceso a memoria, //provocando que los demas mensajes esperen a la finalizacion de la peticion if(getOwnerRouter().getPosition().valueForCoordinate(TPZPosition::Z)==1) { m_stopCycles++; if(m_wasReadNotWrite){ if (m_stopCycles < ((TPZConsumer&) getComponent()).getReadLatency()) m_readBuffer = false; else m_readBuffer = true; } else { if (m_stopCycles < ((TPZConsumer&) getComponent()).getWriteLatency())m_readBuffer = false; else m_readBuffer = true; } } else { m_readBuffer = true; } return true; }