/* -*- c++ -*- * * 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 * * Authors : Cesar Armando Fuguet Tortolero * Date : jul 2015 * Copyright: UPMC - LIP6 */ #include #include "synthetic_dspin_network.h" #include "dspin_router_config.h" #include "alloc_elems.h" namespace soclib { namespace caba { using namespace soclib::common; SyntheticDspinNetwork::SyntheticDspinNetwork(sc_module_name name, const size_t x_size, const size_t y_size, const size_t load) : BaseModule(name), p_clk("p_clk"), p_resetn("p_resetn"), m_x_size(x_size), m_y_size(y_size) { // DSPIN packet generator instantiation dspinGenerator = (DspinNetworkGenerator**) malloc(sizeof(DspinNetworkGenerator*) * m_x_size); for (size_t x = 0; x < m_x_size; ++x) { dspinGenerator[x] = (DspinNetworkGenerator*) malloc(sizeof(DspinNetworkGenerator) * m_y_size); for (size_t y = 0; y < m_y_size; ++y) { std::ostringstream generator_name; const int SRCID = (x << Y_WIDTH) | y; generator_name << "generator[" << x << "][" << y << "]"; new(&dspinGenerator[x][y]) DspinNetworkGenerator(generator_name.str().c_str(), m_x_size, m_y_size, SRCID, load, DSPIN_GENERATOR_FIFO_DEPTH); } } // DSPIN router instantiation dspinRouter = (DspinNetworkRouter**) malloc(sizeof(DspinNetworkRouter*) * m_x_size); for (size_t x = 0; x < m_x_size; ++x) { dspinRouter[x] = (DspinNetworkRouter*) malloc(sizeof(DspinNetworkRouter) * m_y_size); for (size_t y = 0; y < m_y_size; ++y) { std::ostringstream router_name; const bool BROADCAST_SUPPORTED = true; const bool CONFIGURATION_SUPPORTED = true; router_name << "router[" << x << "][" << y << "]"; new(&dspinRouter[x][y]) DspinNetworkRouter(router_name.str().c_str(), x, y, X_WIDTH, Y_WIDTH, DSPIN_ROUTER_FIFO_DEPTH, DSPIN_ROUTER_FIFO_DEPTH, BROADCAST_SUPPORTED, CONFIGURATION_SUPPORTED); } } // signals instantiation sL = alloc_elems("sL", m_x_size, m_y_size, 2); sH = alloc_elems("sH", m_x_size + 1, m_y_size, 2); sV = alloc_elems("sV", m_x_size, m_y_size + 1, 2); sConfigRouter = alloc_elems >("sConfigRouter", m_x_size, m_y_size); // netlist for (size_t x = 0; x < m_x_size; ++x) { for (size_t y = 0; y < m_y_size; ++y) { dspinRouter[x][y].p_clk(p_clk); dspinRouter[x][y].p_resetn(p_resetn); dspinRouter[x][y].p_in[DspinNetworkRouter::N](sV[x][y + 1][1]); dspinRouter[x][y].p_out[DspinNetworkRouter::N](sV[x][y + 1][0]); dspinRouter[x][y].p_in[DspinNetworkRouter::S](sV[x][y][0]); dspinRouter[x][y].p_out[DspinNetworkRouter::S](sV[x][y][1]); dspinRouter[x][y].p_in[DspinNetworkRouter::E](sH[x + 1][y][1]); dspinRouter[x][y].p_out[DspinNetworkRouter::E](sH[x + 1][y][0]); dspinRouter[x][y].p_in[DspinNetworkRouter::W](sH[x][y][0]); dspinRouter[x][y].p_out[DspinNetworkRouter::W](sH[x][y][1]); dspinRouter[x][y].p_in[DspinNetworkRouter::L](sL[x][y][0]); dspinRouter[x][y].p_out[DspinNetworkRouter::L](sL[x][y][1]); dspinRouter[x][y].bind_recovery_port(sConfigRouter[x][y]); dspinGenerator[x][y].p_clk(p_clk); dspinGenerator[x][y].p_resetn(p_resetn); dspinGenerator[x][y].p_out(sL[x][y][0]); dspinGenerator[x][y].p_in(sL[x][y][1]); } } } // end constructor() SyntheticDspinNetwork::~SyntheticDspinNetwork() { for (size_t x = 0; x < m_x_size; ++x) { for (size_t y = 0; y < m_y_size; ++y) { dspinGenerator[x][y].~DspinBroadcastGenerator(); dspinRouter[x][y].~DspinRouter(); } free(dspinGenerator[x]); free(dspinRouter[x]); } free(dspinGenerator); free(dspinRouter); dealloc_elems(sL, m_x_size, m_y_size, 2); dealloc_elems(sH, m_x_size + 1, m_y_size, 2); dealloc_elems(sV, m_x_size, m_y_size + 1, 2); dealloc_elems >(sConfigRouter, m_x_size, m_y_size); } static inline uint32_t configRouter(int bypass_mode, int reallocation_dir, int blackhole_pos) { return (bypass_mode << 7) | (reallocation_dir << 4) | blackhole_pos; } void SyntheticDspinNetwork::reset() { // initialize routers' configuration signals for (size_t x = 0; x < m_x_size; ++x) { for (size_t y = 0; y < m_y_size; ++y) { const uint32_t CONFIG_NONE = configRouter(0, REQ_NOP, BH_NONE); sConfigRouter[x][y].write(CONFIG_NONE); } } // initialize mesh's boundary signals for (size_t x = 0; x < m_x_size; ++x) { sV[x][0][0].write = false; sV[x][0][1].read = true; sV[x][m_y_size][0].read = true; sV[x][m_y_size][1].write = false; } for (size_t y = 0; y < m_y_size; ++y) { sH[0][y][0].write = false; sH[0][y][1].read = true; sH[m_x_size][y][0].read = true; sH[m_x_size][y][1].write = false; } } // end reset() void SyntheticDspinNetwork::set_faulty_router(const size_t faulty_x, const size_t faulty_y) { assert(faulty_x < m_x_size); assert(faulty_y < m_y_size); // transform the faulty router in a black-hole dspinRouter[faulty_x][faulty_y].set_disable_mask(0x1F); // reconfigure the faulty router's contour if (faulty_y < (m_y_size - 1)) { const uint32_t CONFIG_N = configRouter(1, REQ_SOUTH, BH_N); sConfigRouter[faulty_x][faulty_y + 1].write(CONFIG_N); if (faulty_x > 0) { const uint32_t CONFIG_NW = configRouter(1, REQ_EAST, BH_NW); sConfigRouter[faulty_x - 1][faulty_y + 1].write(CONFIG_NW); } if (faulty_x < (m_x_size - 1)) { const uint32_t CONFIG_NE = configRouter(1, REQ_WEST, BH_NE); sConfigRouter[faulty_x + 1][faulty_y + 1].write(CONFIG_NE); } } if (faulty_y > 0) { const uint32_t CONFIG_S = configRouter(1, REQ_NORTH, BH_S); sConfigRouter[faulty_x][faulty_y - 1].write(CONFIG_S); if (faulty_x > 0) { const uint32_t CONFIG_SW = configRouter(1, REQ_EAST, BH_SW); sConfigRouter[faulty_x - 1][faulty_y - 1].write(CONFIG_SW); } if (faulty_x < (m_x_size - 1)) { const uint32_t CONFIG_SE = configRouter(1, REQ_WEST, BH_SE); sConfigRouter[faulty_x + 1][faulty_y - 1].write(CONFIG_SE); } } if (faulty_x > 0) { const uint32_t CONFIG_W = configRouter(1, REQ_EAST, BH_W); sConfigRouter[faulty_x - 1][faulty_y].write(CONFIG_W); } if (faulty_x < (m_x_size - 1)) { const uint32_t CONFIG_E = configRouter(1, REQ_WEST, BH_E); sConfigRouter[faulty_x + 1][faulty_y].write(CONFIG_E); } } // end set_faulty_router() void SyntheticDspinNetwork::print_stats(const size_t x, const size_t y) { assert(x < m_x_size); assert(y < m_y_size); dspinGenerator[x][y].print_stats(); } } // end namespace caba } // end namespace soclib // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: