/* -*- 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 : alain.greiner@lip6.fr * Date : july 2010 * Copyright: UPMC - LIP6 * * Modified by: Cesar Armando Fuguet Tortolero * Date : july 2015 */ #include "../include/dspin_broadcast_generator.h" #include namespace soclib { namespace caba { using namespace soclib::caba; using namespace soclib::common; #define tmpl(x) template x \ DspinBroadcastGenerator ////////////////////////////////////////////////////// tmpl(/**/)::DspinBroadcastGenerator( sc_module_name name, const size_t x_size, const size_t y_size, const size_t srcid, // srcid for random const size_t load, // requested load * 1000 const size_t fifo_depth) // Fifo depth : BaseModule(name), p_clk( "clk" ), p_resetn( "resetn" ), p_in( "p_in" ), p_out( "p_out" ), r_cycles( "r_cycles" ), r_fifo_posted( "r_fifo_posted" ), r_send_fsm( "r_send_fsm" ), r_send_length( "r_send_length" ), r_send_dest( "r_send_dest" ), r_send_date( "r_send_date" ), r_send_bc_packets( "r_send_bc_packets" ), r_receive_fsm( "r_receive_fsm" ), r_receive_bc_packets( "r_receive_bc_packets" ), r_receive_bc_latency( "r_receive_bc_latency" ), r_receive_bc_max_latency( "r_receive_bc_max_latency" ), r_max_fill_status( "r_max_fill_status" ), r_date_fifo( "r_date_fifo", fifo_depth ), m_x_size ( x_size ), m_y_size ( y_size ), m_load( load ), m_srcid( srcid ) { assert( (load <= 1000 ) and "DSPIN PACKET GENERATOR ERROR: The load should be between 0 and 1000" ); assert( (cmd_width >= 33) and "DSPIN PACKET GENERATOR ERROR: CMD flit width smaller than 33 bits"); SC_METHOD (transition); dont_initialize(); sensitive << p_clk.pos(); SC_METHOD (genMoore); dont_initialize(); sensitive << p_clk.neg(); } // end constructor //////////////////////// tmpl(void)::transition() { if ( not p_resetn.read() ) { r_send_fsm = SEND_IDLE; r_receive_fsm = RECEIVE_IDLE; r_cycles = 0; r_fifo_posted = 0; r_send_bc_packets = 0; r_receive_bc_packets = 0; r_receive_bc_latency = 0; r_receive_bc_max_latency = 0; r_max_fill_status = 0; srandom( m_srcid + cmd_width ); return; } // default values bool fifo_put = false; bool fifo_get = false; uint32_t alea = random(); ///////////////////////// GENERATOR FSM const size_t nflits = r_fifo_posted.read() * m_x_size * m_y_size * 2; size_t accepted_load = (nflits * 1000) / (r_cycles.read() + 1); if( (accepted_load + (alea>>16 & 0xF)) < (m_load) ) { fifo_put = true ; if( r_date_fifo.wok() ) r_fifo_posted = r_fifo_posted.read() + 1; } /////////////////////////// CMD FSM switch( r_send_fsm.read() ) { case SEND_IDLE: if ( r_date_fifo.rok() ) { fifo_get = true; r_send_length = 2; r_send_date = r_date_fifo.read(); r_send_bc_packets = r_send_bc_packets.read() + 1; r_send_fsm = SEND_BROADCAST; } break; case SEND_BROADCAST: if( p_out.read.read() ) { r_send_length = r_send_length.read() - 1; if( r_send_length.read() == 1 ) r_send_fsm = SEND_IDLE; } break; } // end SEND FSM ////////////////////////////// RECEIVE FSM switch( r_receive_fsm.read() ) { case RECEIVE_IDLE: if ( p_in.write.read() ) { assert (p_in.data.read() & sc_uint(1)); r_receive_fsm = RECEIVE_BROADCAST; } break; case RECEIVE_BROADCAST: if ( p_in.write.read() ) { uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read(); r_receive_bc_packets = r_receive_bc_packets.read() + 1; r_receive_bc_latency = r_receive_bc_latency.read() + latency; if (latency > r_receive_bc_max_latency.read()) r_receive_bc_max_latency = latency; r_receive_fsm = RECEIVE_IDLE; } break; } // `end RECEIVE FSM // increment date r_cycles = r_cycles.read() + 1; // update fifos r_date_fifo.update( fifo_get, fifo_put, r_cycles.read() ); if (r_date_fifo.filled_status() > r_max_fill_status.read()) r_max_fill_status.write(r_date_fifo.filled_status()); } // end transition ////////////////////// tmpl(void)::genMoore() { // p_out sc_uint data; bool write; bool eop; if ( r_send_fsm.read() == SEND_IDLE ) { data = 0; eop = false; write = false; } else { // SEND_BROADCAST (two flits) write = true; if ( r_send_length.read() == 2 ) { // first flit data = sc_uint(0x07C1F) << (cmd_width - 20) | sc_uint(1); eop = false; } else { // second flit data = (sc_uint)r_send_date.read() | (sc_uint(1)<<(cmd_width-1)); eop = true; } } p_out.data = data; p_out.eop = eop; p_out.write = write; p_in.read = true; } // end genMoore ///////////////////////// tmpl(void)::print_trace() { const char* cmd_str[] = { "IDLE", "SEND_BROADCAST" }; const char* rsp_str[] = { "IDLE", "RECEIVE_BROADCAST" }; std::cout << "DSPIN_GENERATOR " << name() << " : send_fsm = " << cmd_str[r_send_fsm.read()] << " / recv_fsm = " << rsp_str[r_receive_fsm.read()] << " / fifo_content = " << r_date_fifo.filled_status() << std::endl; } // end print_trace ///////////////////////// tmpl(void)::print_stats() { const size_t nflits = r_send_bc_packets.read() * m_x_size * m_y_size * 2; const size_t load = (nflits * 1000) / r_cycles.read(); const uint32_t bc_latency = r_receive_bc_latency.read() / (r_receive_bc_packets.read() + 1); std::cout << "DSPIN_GENERATOR " << name() << std::dec << std::endl << " - broadcast sent packets = " << r_send_bc_packets.read() << std::endl << " - offered load = " << m_load << std::endl << " - accepted load = " << load << std::endl << " - fifo max fill status = " << r_max_fill_status.read() << std::endl << " - broadcast received packets = " << r_receive_bc_packets.read() << std::endl << " - broadcast latency = " << bc_latency << std::endl << " - broadcast max latency = " << r_receive_bc_max_latency.read() << std::endl; } // end print_stats }} // end namespaces // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: