/* -*- c++ -*- * * File : dspin_router.cpp * Copyright (c) UPMC, Lip6 * Authors : Alain Greiner, Abbas Sheibanyrad, Ivan Miro, Zhen Zhang * * SOCLIB_LGPL_HEADER_BEGIN * * This file is part of SoCLib, GNU LGPLv2.1. * * SoCLib is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; version 2.1 of the License. * * SoCLib is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with SoCLib; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * SOCLIB_LGPL_HEADER_END * */ #include "../include/dspin_router.h" #include "dspin_router_config.h" #include namespace soclib { namespace caba { using namespace soclib::common; using namespace soclib::caba; #define tmpl(x) template x DspinRouter //////////////////////////////////////////////// // constructor //////////////////////////////////////////////// tmpl(/**/)::DspinRouter( sc_module_name name, const size_t x, const size_t y, const size_t x_width, const size_t y_width, const size_t in_fifo_depth, const size_t out_fifo_depth, const bool broadcast_supported, const bool configuration_supported) : soclib::caba::BaseModule(name), p_clk( "p_clk" ), p_resetn( "p_resetn" ), p_in( alloc_elems >("p_in", 5) ), p_out( alloc_elems >("p_out", 5) ), p_recovery_cfg(NULL), r_alloc_out( alloc_elems >("r_alloc_out", 5)), r_index_out( soclib::common::alloc_elems >("r_index_out", 5)), r_fsm_in( alloc_elems >("r_fsm_in", 5)), r_index_in( alloc_elems >("r_index_in", 5)), m_local_x( x ), m_local_y( y ), m_x_width( x_width ), m_x_shift( flit_width - x_width ), m_x_mask( (0x1 << x_width) - 1 ), m_y_width( y_width ), m_y_shift( flit_width - x_width - y_width ), m_y_mask( (0x1 << y_width) - 1 ), m_broadcast_supported( broadcast_supported ), m_disable_mask( 0 ) { std::cout << " - Building DspinRouter : " << name << std::endl; SC_METHOD (transition); dont_initialize(); sensitive << p_clk.pos(); SC_METHOD (genMoore); dont_initialize(); sensitive << p_clk.neg(); r_fifo_in = (GenericFifo*) malloc(sizeof(GenericFifo) * 5); r_fifo_out = (GenericFifo*) malloc(sizeof(GenericFifo) * 5); r_buf_in = (internal_flit_t*) malloc(sizeof(internal_flit_t) * 5); for( size_t i = 0 ; i < 5 ; i++ ) { std::ostringstream stri; stri << "r_in_fifo_" << i; new(&r_fifo_in[i]) GenericFifo(stri.str(), in_fifo_depth); std::ostringstream stro; stro << "r_out_fifo_" << i; new(&r_fifo_out[i]) GenericFifo(stro.str(), out_fifo_depth); } if (configuration_supported) { p_recovery_cfg = new sc_core::sc_in ("p_recovery_cfg"); } } // end constructor /////////////////////////////////////////////////// tmpl(/**/)::~DspinRouter() { if ( is_reconfigurable() ) delete p_recovery_cfg; } /////////////////////////////////////////////////// tmpl(int)::blackhole_position() { assert( is_reconfigurable() ); return p_recovery_cfg->read() & 0xF; } /////////////////////////////////////////////////// tmpl(void)::bind_recovery_port(sc_signal &s) { if ( not is_reconfigurable() ) { std::cerr << "Error in " << name() << ": router configuration not supported." << std::endl << "Enable it during router instantiation." << std::endl; exit(1); } (*p_recovery_cfg)(s); } tmpl(bool)::is_recovery_routing_enabled() { assert( is_reconfigurable() ); return (((p_recovery_cfg->read() >> 4) & 0x1) != 0); } tmpl(bool)::is_reallocation_enabled() { assert( is_reconfigurable() ); return (blackhole_position() != NORMAL); } tmpl(int)::reallocation_route() { assert( is_reconfigurable() ); return ((p_recovery_cfg->read() >> 5) & 0x7); } tmpl(bool)::is_reconfigurable() { return (p_recovery_cfg != NULL); } /////////////////////////////////////////////////// tmpl(bool)::is_destination_blackhole( size_t xdest, size_t ydest ) { assert ( is_reconfigurable() ); const int bhpos = blackhole_position(); const bool is_n = (bhpos == N_OF_X); const bool is_s = (bhpos == S_OF_X); const bool is_w = (bhpos == W_OF_X); const bool is_e = (bhpos == E_OF_X); const bool is_nw = (bhpos == NW_OF_X); const bool is_ne = (bhpos == NE_OF_X); const bool is_sw = (bhpos == SW_OF_X); const bool is_se = (bhpos == SE_OF_X); if ( bhpos == NORMAL ) return false; size_t xhole; if (is_nw || is_w || is_sw) xhole = m_local_x + 1; else if (is_ne || is_se || is_e ) xhole = m_local_x - 1; else xhole = m_local_x; size_t yhole; if (is_sw || is_s || is_se) yhole = m_local_y + 1; else if (is_nw || is_n || is_ne) yhole = m_local_y - 1; else yhole = m_local_y; return ((xdest == xhole) && (ydest == yhole)); } /////////////////////////////////////////////////// tmpl(int)::recovery_route( size_t dx, size_t dy ) { // use normal routing (X-first) when the recovery routing is disabled int bhpos = NORMAL; bool normal = true; if (is_reconfigurable()) { assert(not is_reallocation_enabled() or not is_destination_blackhole(dx, dy)); bhpos = blackhole_position(); normal = (bhpos == NORMAL) or (not is_recovery_routing_enabled() and not is_destination_blackhole(dx, dy)); } const bool is_n = not normal and (bhpos == N_OF_X); const bool is_s = not normal and (bhpos == S_OF_X); const bool is_w = not normal and (bhpos == W_OF_X); const bool is_e = not normal and (bhpos == E_OF_X); const bool is_nw = not normal and (bhpos == NW_OF_X); const bool is_ne = not normal and (bhpos == NE_OF_X); const bool is_sw = not normal and (bhpos == SW_OF_X); const bool is_se = not normal and (bhpos == SE_OF_X); const size_t lx = m_local_x; const size_t ly = m_local_y; if ( dx > lx ) { if ( is_ne || is_e || is_se || is_s || normal ) return REQ_EAST; else if ( is_n ) { if ( (ly == 1) || (lx == 0) || (dy >= ly) || (dx > (lx + 1)) ) return REQ_EAST; else return REQ_WEST; } else if ( is_nw ) { if ( (ly == 1) || (dy >= ly) || (dx > (lx + 2)) ) return REQ_EAST; else return REQ_SOUTH; } else if ( is_w ) { if ( (ly == 0) || (dy > ly)) return REQ_NORTH; else return REQ_SOUTH; } else if ( is_sw ) { if ( (dy <= ly) || (dx > (lx + 1)) ) return REQ_EAST; else return REQ_NORTH; } std::cout << "error: unexpected condition in function " << __FILE__ << ":" << __func__ << " +" << __LINE__ << std::endl; exit(1); } // end if (dx > lx) else if ( dx < lx ) { if ( is_n || is_nw || is_w || is_sw || is_s || normal ) return REQ_WEST; else if ( is_ne ) { if ( (dx < (lx - 1)) || (dy >= ly) ) return REQ_WEST; else return REQ_SOUTH; } else if ( is_se ) { if ( (lx == 1) && (dy > (ly + 1)) ) return REQ_NORTH; else return REQ_WEST; } else if ( is_e ) { if ( (ly == 0) || ((lx == 1) && (dy > ly)) ) return REQ_NORTH; else return REQ_SOUTH; } std::cout << "error: unexpected condition in function " << __FILE__ << ":" << __func__ << " +" << __LINE__ << std::endl; exit(1); } // end if (dx < lx) else if ( dy > ly ) { if ( ! is_s ) return REQ_NORTH; else if ( lx != 0 ) return REQ_WEST; else return REQ_EAST; } else if ( dy < ly ) { if ( ! is_n ) return REQ_SOUTH; else if ( lx != 0) return REQ_WEST; else return REQ_EAST; } return REQ_LOCAL; } /////////////////////////////////////////////////// tmpl(int)::route( sc_uint data ) { const size_t dx = (size_t)(data >> m_x_shift) & m_x_mask; const size_t dy = (size_t)(data >> m_y_shift) & m_y_mask; if ( is_reconfigurable() ) { // reroute requests whose destination is the blackhole (this is to // implement the segment reallocation mechanism) if ( is_reallocation_enabled() and is_destination_blackhole(dx, dy)) { return reallocation_route(); } } // use the recovery routing return recovery_route(dx, dy); } /////////////////////////////////////////////////// tmpl(int)::broadcast_route(int step, int source, sc_uint data) { const size_t lx = m_local_x; const size_t ly = m_local_y; const size_t xmin = (data >> (flit_width - 5 )) & 0x1F; const size_t xmax = (data >> (flit_width - 10)) & 0x1F; const size_t ymin = (data >> (flit_width - 15)) & 0x1F; const size_t ymax = (data >> (flit_width - 20)) & 0x1F; const int bhpos = is_reconfigurable() ? blackhole_position() : NORMAL; const bool is_n = (bhpos == N_OF_X); const bool is_s = (bhpos == S_OF_X); const bool is_w = (bhpos == W_OF_X); const bool is_e = (bhpos == E_OF_X); const bool is_nw = (bhpos == NW_OF_X); const bool is_ne = (bhpos == NE_OF_X); const bool is_sw = (bhpos == SW_OF_X); const bool is_se = (bhpos == SE_OF_X); const bool special = ((data & 0x2) != 0) and (bhpos != NORMAL); int sel = REQ_NOP; switch(source) { case REQ_LOCAL : if ( step == 1 ) sel = REQ_NORTH; else if ( step == 2 ) sel = REQ_SOUTH; else if ( step == 3 ) { if ( is_n && (lx != 0) && (ly != 1) ) sel = REQ_NOP; else sel = REQ_EAST; } else if ( step == 4 ) { if ( is_ne && (lx != 1) && (ly != 1) ) sel = REQ_NOP; else sel = REQ_WEST; } break; case REQ_NORTH : if ( step == 1 ) sel = REQ_SOUTH; else if ( step == 2 ) sel = REQ_LOCAL; else if ( step == 3 ) { if ( is_sw ) sel = REQ_EAST; else sel = REQ_NOP; } else if ( step == 4 ) { if ( is_se && (!special || (lx == 1))) sel = REQ_WEST; else sel = REQ_NOP; } break; case REQ_SOUTH : if ( step == 1 ) sel = REQ_NORTH; else if ( step == 2 ) sel = REQ_LOCAL; else if ( step == 3 ) { if ( is_nw ) sel = REQ_EAST; else if ( is_ne && ((lx == 1) || (ly == 1)) ) sel = REQ_WEST; else sel = REQ_NOP; } else if ( step == 4 ) sel = REQ_NOP; break; case REQ_EAST : if ( step == 1 ) { if ( is_ne && (lx != 1) && (ly != 1) ) sel = REQ_NOP; else sel = REQ_WEST; } else if ( step == 2 ) sel = REQ_NORTH; else if ( step == 3 ) sel = REQ_SOUTH; else if ( step == 4 ) sel = REQ_LOCAL; break; case REQ_WEST : if ( step == 1 ) { if ( is_n && (ly != 1) ) sel = REQ_NOP; else if ( is_s && special ) sel = REQ_NOP; else sel = REQ_EAST; } else if ( step == 2 ) sel = REQ_NORTH; else if ( step == 3 ) sel = REQ_SOUTH; else if ( step == 4 ) sel = REQ_LOCAL; break; } // inhibit requests to the blackhole or beyond the mesh boundaries. if ( (sel == REQ_NORTH) && (!(ly < ymax) || is_s)) sel = REQ_NOP; else if ( (sel == REQ_SOUTH) && (!(ly > ymin) || is_n)) sel = REQ_NOP; else if ( (sel == REQ_EAST ) && (!(lx < xmax) || is_w)) sel = REQ_NOP; else if ( (sel == REQ_WEST ) && (!(lx > xmin) || is_e)) sel = REQ_NOP; return sel; } ///////////////////////////////////////////////////////// tmpl(bool)::is_broadcast(sc_uint data) { return ( (data & 0x1) != 0); } ///////////////////////////////////////////////////////// tmpl(typename DspinRouter::internal_flit_t):: compute_broadcast_header(int source) { const int bhpos = blackhole_position(); const int is_nw = (bhpos == NW_OF_X); const int is_ne = (bhpos == NE_OF_X); internal_flit_t header; header.eop = false; header.data = r_fifo_in[source].read().data; const int SPECIAL = 0x2; switch (source) { case REQ_NORTH: if ( is_nw || is_ne ) header.data |= SPECIAL; break; /* Make sure that broadcast transactions do not enter the DSPIN * network with the special bit set. This can arrive if an initiator * or a local interconnect uses the broadcast header reserved bits * internally */ case REQ_LOCAL: header.data &= ~SPECIAL; break; } return header; } ///////////////////////// tmpl(void)::print_trace() { const char* port_name[] = { "N", "S", "E", "W", "L" }; const char* infsm_str[] = { "IDLE", "REQ", "ALLOC", "REQ_FIRST", "ALLOC_FIRST", "REQ_SECOND", "ALLOC_SECOND", "REQ_THIRD", "ALLOC_THIRD", "REQ_FOURTH", "ALLOC_FOURTH" }; const char* bh_str[] = { "N_OF_X", "NE_OF_X", "E_OF_X", "SE_OF_X", "S_OF_X", "SW_OF_X", "W_OF_X", "NW_OF_X" }; std::cout << "DSPIN_ROUTER " << name(); if ( is_reconfigurable() ) { std::cout << " / bh = " << bh_str[blackhole_position()]; if (is_recovery_routing_enabled()) std::cout << " / recovery_routing "; if (is_reallocation_enabled()) std::cout << " / reallocation dir = " << port_name[reallocation_route()]; } for( size_t i = 0 ; i < 5 ; i++) // loop on input ports { std::cout << " / infsm[" << port_name[i] << "] " << infsm_str[r_fsm_in[i].read()]; } for ( size_t out=0 ; out<5 ; out++) // loop on output ports { if ( r_alloc_out[out].read() ) { int in = r_index_out[out]; std::cout << " / " << port_name[in] << " -> " << port_name[out] ; } } std::cout << std::endl; } //////////////////////// tmpl(void)::transition() { // Long wires connecting input and output ports size_t req_in[5]; // input ports -> output ports size_t get_out[5]; // output ports -> input ports bool put_in[5]; // input ports -> output ports internal_flit_t data_in[5]; // input ports -> output ports // control signals for the input fifos bool fifo_in_write[5]; bool fifo_in_read[5]; internal_flit_t fifo_in_wdata[5]; // control signals for the output fifos bool fifo_out_write[5]; bool fifo_out_read[5]; internal_flit_t fifo_out_wdata[5]; // Reset if ( p_resetn == false ) { for(size_t i = 0 ; i < 5 ; i++) { r_alloc_out[i] = false; r_index_out[i] = 0; r_index_in[i] = 0; r_fsm_in[i] = INFSM_IDLE; r_fifo_in[i].init(); r_fifo_out[i].init(); } return; } // fifos signals default values for(size_t i = 0 ; i < 5 ; i++) { fifo_in_read[i] = false; // do not write into the FIFO of disabled interfaces fifo_in_write[i] = p_in[i].write.read() && (((m_disable_mask >> i) & 1) == 0); fifo_in_wdata[i].data = p_in[i].data.read(); fifo_in_wdata[i].eop = p_in[i].eop.read(); fifo_out_read[i] = p_out[i].read.read() || (((m_disable_mask >> i) & 1) == 1); fifo_out_write[i] = false; } // loop on the output ports: // compute get_out[j] depending on the output port state // and combining fifo_out[j].wok and r_alloc_out[j] for ( size_t j = 0 ; j < 5 ; j++ ) { if( r_alloc_out[j].read() and (r_fifo_out[j].wok()) ) { get_out[j] = r_index_out[j].read(); } else { get_out[j] = 0xFFFFFFFF; } } // loop on the input ports : // The port state is defined by r_fsm_in[i], r_index_in[i] & r_buf_in[i] // The req_in[i] computation implements the X-FIRST algorithm. // data_in[i], put_in[i] and req_in[i] depend on the input port state. // The fifo_in_read[i] is computed further... for ( size_t i = 0 ; i < 5 ; i++ ) { switch ( r_fsm_in[i].read() ) { case INFSM_IDLE: // no output port allocated { put_in[i] = false; if ( r_fifo_in[i].rok() ) // packet available in input fifo { if ( is_broadcast( r_fifo_in[i].read().data ) and m_broadcast_supported ) // broadcast { if ( r_fifo_in[i].read().eop ) { std::cout << "ERROR in DSPIN_ROUTER " << name() << " : broadcast packet must be 2 flits" << std::endl; exit(1); } const internal_flit_t& header = compute_broadcast_header(i); fifo_in_read[i] = true; req_in[i] = broadcast_route(1, i, header.data); r_buf_in[i] = header; r_index_in[i] = req_in[i]; if ( req_in[i] == REQ_NOP ) r_fsm_in[i] = INFSM_REQ_SECOND; else r_fsm_in[i] = INFSM_REQ_FIRST; } else // unicast { req_in[i] = route(r_fifo_in[i].read().data); r_index_in[i] = req_in[i]; r_fsm_in[i] = INFSM_REQ; } } else { req_in[i] = REQ_NOP; } break; } case INFSM_REQ: // not a broadcast / waiting output port allocation { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = r_index_in[i]; fifo_in_read[i] = (get_out[r_index_in[i].read()] == i); if ( get_out[r_index_in[i].read()] == i ) // first flit transfered { if ( r_fifo_in[i].read().eop ) r_fsm_in[i] = INFSM_IDLE; else r_fsm_in[i] = INFSM_ALLOC; } break; } case INFSM_ALLOC: // not a broadcast / output port allocated { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = REQ_NOP; // no request fifo_in_read[i] = (get_out[r_index_in[i].read()] == i); if ( r_fifo_in[i].read().eop and r_fifo_in[i].rok() and (get_out[r_index_in[i].read()] == i) ) // last flit transfered { r_fsm_in[i] = INFSM_IDLE; } break; } case INFSM_REQ_FIRST: // broacast / waiting first output port allocation { data_in[i] = r_buf_in[i]; put_in[i] = true; req_in[i] = broadcast_route(1, i, r_buf_in[i].data); r_index_in[i] = req_in[i]; if ( req_in[i] == REQ_NOP ) // no transfer for this step { r_fsm_in[i] = INFSM_REQ_SECOND; } else { if( get_out[req_in[i]] == i ) // header flit transfered { r_fsm_in[i] = INFSM_ALLOC_FIRST; } } break; } case INFSM_ALLOC_FIRST: // broadcast / first output port allocated { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = REQ_NOP; if( (get_out[r_index_in[i].read()] == i) and r_fifo_in[i].rok() ) // data flit transfered { if ( not r_fifo_in[i].read().eop ) { std::cout << "ERROR in DSPIN_ROUTER " << name() << " : broadcast packet must be 2 flits" << std::endl; } r_fsm_in[i] = INFSM_REQ_SECOND; } break; } case INFSM_REQ_SECOND: // broacast / waiting second output port allocation { data_in[i] = r_buf_in[i]; put_in[i] = true; req_in[i] = broadcast_route(2, i, r_buf_in[i].data); r_index_in[i] = req_in[i]; if ( req_in[i] == REQ_NOP ) // no transfer for this step { r_fsm_in[i] = INFSM_REQ_THIRD; } else { if( get_out[req_in[i]] == i ) // header flit transfered { r_fsm_in[i] = INFSM_ALLOC_SECOND; } } break; } case INFSM_ALLOC_SECOND: // broadcast / second output port allocated { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = REQ_NOP; if( (get_out[r_index_in[i].read()] == i ) and r_fifo_in[i].rok() ) // data flit transfered { if ( not r_fifo_in[i].read().eop ) { std::cout << "ERROR in DSPIN_ROUTER " << name() << " : broadcast packet must be 2 flits" << std::endl; } r_fsm_in[i] = INFSM_REQ_THIRD; } break; } case INFSM_REQ_THIRD: // broacast / waiting third output port allocation { data_in[i] = r_buf_in[i]; put_in[i] = true; req_in[i] = broadcast_route(3, i, r_buf_in[i].data); r_index_in[i] = req_in[i]; if ( req_in[i] == REQ_NOP ) // no transfer for this step { r_fsm_in[i] = INFSM_REQ_FOURTH; } else { if( get_out[req_in[i]] == i ) // header flit transfered { r_fsm_in[i] = INFSM_ALLOC_THIRD; } } break; } case INFSM_ALLOC_THIRD: // broadcast / third output port allocated { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = REQ_NOP; if( (get_out[r_index_in[i].read()] == i ) and r_fifo_in[i].rok() ) // data flit transfered { if ( not r_fifo_in[i].read().eop ) { std::cout << "ERROR in DSPIN_ROUTER " << name() << " : broadcast packet must be 2 flits" << std::endl; } r_fsm_in[i] = INFSM_REQ_FOURTH; } break; } case INFSM_REQ_FOURTH: // broacast / waiting fourth output port allocation { data_in[i] = r_buf_in[i]; put_in[i] = true; req_in[i] = broadcast_route(4, i, r_buf_in[i].data); r_index_in[i] = req_in[i]; if ( req_in[i] == REQ_NOP ) // no transfer for this step { fifo_in_read[i] = true; r_fsm_in[i] = INFSM_IDLE; } else { if( get_out[req_in[i]] == i ) // header flit transfered { r_fsm_in[i] = INFSM_ALLOC_FOURTH; } } break; } case INFSM_ALLOC_FOURTH: // broadcast / fourth output port allocated { data_in[i] = r_fifo_in[i].read(); put_in[i] = r_fifo_in[i].rok(); req_in[i] = REQ_NOP; if( (get_out[r_index_in[i].read()] == i ) and r_fifo_in[i].rok() ) // data flit transfered { if ( not r_fifo_in[i].read().eop ) { std::cout << "ERROR in DSPIN_ROUTER " << name() << " : broadcast packet must be 2 flits" << std::endl; } fifo_in_read[i] = true; r_fsm_in[i] = INFSM_IDLE; } break; } } // end switch } // end for input ports // loop on the output ports : // The r_alloc_out[j] and r_index_out[j] computation // implements the round-robin allocation policy. // These two registers implement a 10 states FSM. for( size_t j = 0 ; j < 5 ; j++ ) { if( not r_alloc_out[j].read() ) // not allocated: possible new allocation { for( size_t k = r_index_out[j].read() + 1 ; k < (r_index_out[j] + 6) ; k++) { size_t i = k % 5; if( req_in[i] == j ) { r_alloc_out[j] = true; r_index_out[j] = i; break; } } // end loop on input ports } else // allocated: possible desallocation { if ( data_in[r_index_out[j]].eop and r_fifo_out[j].wok() and put_in[r_index_out[j]] ) { r_alloc_out[j] = false; } } } // end loop on output ports // loop on the output ports : // The fifo_out_write[j] and fifo_out_wdata[j] computation // implements the output port mux. for( size_t j = 0 ; j < 5 ; j++ ) { if( r_alloc_out[j] ) // output port allocated { fifo_out_write[j] = put_in[r_index_out[j]]; fifo_out_wdata[j] = data_in[r_index_out[j]]; } } // end loop on the output ports // FIFOS update for(size_t i = 0 ; i < 5 ; i++) { r_fifo_in[i].update(fifo_in_read[i], fifo_in_write[i], fifo_in_wdata[i]); r_fifo_out[i].update(fifo_out_read[i], fifo_out_write[i], fifo_out_wdata[i]); } } // end transition //////////////////////////////// // genMoore //////////////////////////////// tmpl(void)::genMoore() { for(size_t i = 0 ; i < 5 ; i++) { // input ports : READ signals p_in[i].read = r_fifo_in[i].wok() || (((m_disable_mask >> i) & 1) == 1); // output ports : DATA & WRITE signals p_out[i].data = r_fifo_out[i].read().data; p_out[i].eop = r_fifo_out[i].read().eop; p_out[i].write = r_fifo_out[i].rok() && (((m_disable_mask >> i) & 1) == 0); } } // end genMoore }} // end namespace // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4