/* -*- c++ -*- * File : vci_traffic_generator.cpp * Date : 26/08/2010 * Copyright : UPMC / LIP6 * Authors : Christophe Choichillon * * 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 * * Maintainers: christophe.choichillon@lip6.fr */ #include "../include/vci_synthetic_initiator.h" #include namespace soclib { namespace caba { #define tmpl(x) template x VciSyntheticInitiator //using soclib::common::uint32_log2; //////////////////////////////// // Constructor //////////////////////////////// tmpl(/**/)::VciSyntheticInitiator( sc_module_name name, const soclib::common::MappingTable &mt, const soclib::common::IntTab &vci_index, const uint32_t length, // Packet length (flit numbers) const uint32_t rho, // Packets ratio on the network // const float rho, // Packets ratio on the network const uint32_t depth, // Fifo depth const uint32_t xmesh, const uint32_t ymesh, const uint32_t bc_period, // Broadcast period, if no broadcast => 0 const uint32_t xmin, const uint32_t xmax, const uint32_t ymin, const uint32_t ymax ) : soclib::caba::BaseModule(name), p_clk("clk"), p_resetn("resetn"), p_vci("vci_ini"), m_srcid( mt.indexForId(vci_index) ), // FIFOs m_length(length), m_rho(rho), m_depth(depth), m_xmesh(xmesh), m_ymesh(ymesh), m_bc_period(bc_period), m_xmin(xmin), m_xmax(xmax), m_ymin(ymin), m_ymax(ymax), m_date_fifo("m_date_fifo", depth), r_vci_fsm("r_vci_fsm") { SC_METHOD(transition); dont_initialize(); sensitive << p_clk.pos(); SC_METHOD(genMoore); dont_initialize(); sensitive << p_clk.neg(); } // end constructor ///////////////////////////////// tmpl(/**/)::~VciSyntheticInitiator() ///////////////////////////////// { } /////////////////////////////////// tmpl(size_t)::destAdress() /////////////////////////////////// { return (size_t) (rand() % (m_xmesh * m_ymesh)) ; } /////////////////////////////////// // tmpl(void)::destAdress(/*size_t X_local, size_t Y_local,*/ size_t &X_dest, size_t &Y_dest) /////////////////////////////////// // { // size_t x_dest_calc, y_dest_calc; // do{ // x_dest_calc = (rand()%m_xmesh); // y_dest_calc = (rand()%m_ymesh); // } while((x_dest_calc = m_x) && (y_dest_calc == m_y)); // } ////////////////////////////////// tmpl(void)::print_trace() ////////////////////////////////// { const char* state_str[] = { "IDLE", "SINGLE_SEND", "SINGLE_RECEIVE", "BC_SEND", "BC_RECEIVE" }; std::cout << "Vci_Synthetic_Initiator " << name() << " : " << m_cpt_cycles << " cycles " << " : state = " << state_str[r_vci_fsm] << " Adresse to send : " << m_address_to_send << std::endl; } ////////////////////////////////// tmpl(void)::printStats() ////////////////////////////////// { std::cout << m_cpt_cycles << " cycles, " << m_npackets << " packets sent" << std::endl; } ////////////////////////////////// tmpl(void)::transition() ////////////////////////////////// { // RESET if ( ! p_resetn.read() ) { // Initializing seed for random numbers generation srand(time(NULL)); // Initializing FSMs r_vci_fsm = VCI_IDLE; // Initializing FIFOs m_date_fifo.init(); // Activity counters m_cpt_cycles = 0; m_npackets = 0; r_broadcast_req = false; return; } bool date_fifo_put = false; bool date_fifo_get = false; // if (m_cpt_cycles == 0) { // m_rhos = 0.0 ; // } else { // m_rhos = static_cast(m_npackets * m_length) / static_cast(m_cpt_cycles) ; // } switch ( r_vci_fsm.read() ) { std::cout << m_cpt_cycles << " cycles, " << m_npackets << " packets sent" << std::endl; //printStats(); ////////////////// case VCI_IDLE: { if (m_date_fifo.rok()){ if (r_broadcast_req.read()){ m_address_to_send = (((((((((m_xmin << 5) | m_xmax ) << 5 ) | m_ymin ) << 5 ) | m_ymax ) << 5 ) << vci_param::N-(4*5) ) | 0x3) | 0 ; r_vci_fsm = VCI_BC_SEND ; } else { r_vci_fsm = VCI_SINGLE_SEND ; m_address_to_send = destAdress() << 32-10; m_count = 0; } } break; } ////////////////// case VCI_SINGLE_SEND: { if (p_vci.cmdack.read()){ if (m_count == m_length-1) { m_start_latency1 = m_date_fifo.read(); m_start_latency2 = m_cpt_cycles; r_vci_fsm = VCI_SINGLE_RECEIVE ; } else { r_vci_fsm = VCI_SINGLE_SEND ; m_count++; } } break; } ////////////////////// case VCI_SINGLE_RECEIVE: { if (p_vci.rspval.read()) { m_start_latency1 = m_date_fifo.read(); m_start_latency2 = m_cpt_cycles; m_npackets++; date_fifo_get = true; m_address_to_send = 0; r_vci_fsm = VCI_IDLE ; } break; } /////////////////// case VCI_BC_SEND: { m_bc_nrsp = (m_xmax - m_xmin) * (m_ymax - m_ymin); r_vci_fsm = VCI_BC_SEND; break; } //////////////////// case VCI_BC_RECEIVE: { if (p_vci.rspval.read()){ if (m_bc_nrsp == 0) { r_broadcast_req = false; m_address_to_send = 0; r_vci_fsm = VCI_IDLE ; } else { m_bc_nrsp--; r_vci_fsm = VCI_BC_RECEIVE ; } } break; } } // end switch vci_fsm /////////////////// Filling fifo if( ( (uint64_t)(m_rho*m_cpt_cycles) >= (uint64_t)(m_length*m_npackets*1000)) ){ if (m_date_fifo.wok()){ date_fifo_put = true ; } if (m_bc_period){ if (!r_broadcast_req.read() && (m_cpt_cycles % m_bc_period)){ r_broadcast_req = true; } } } if (date_fifo_put){ if (date_fifo_get){ m_date_fifo.put_and_get(m_cpt_cycles); } else { m_date_fifo.simple_put(m_cpt_cycles); } } else { if (date_fifo_get){ m_date_fifo.simple_get(); } } m_cpt_cycles++; return; } // end transition() ///////////////////////////// tmpl(void)::genMoore() ///////////////////////////// { //////////////////////////////////////////////////////////// // Command signals on the p_vci port //////////////////////////////////////////////////////////// p_vci.cmd = vci_param::CMD_WRITE; p_vci.be = 0xF; p_vci.pktid = 0; p_vci.srcid = m_srcid; p_vci.cons = false; p_vci.wrap = false; p_vci.contig = true; p_vci.clen = 0; p_vci.cfixed = false; switch ( r_vci_fsm.read() ) { ////////////////// case VCI_IDLE: { p_vci.cmdval = false; p_vci.address = 0; p_vci.plen = 0; p_vci.wdata = 0; p_vci.trdid = 0; p_vci.eop = false; p_vci.rspack = false; break; } ////////////////// case VCI_SINGLE_SEND: { p_vci.cmdval = true; p_vci.address = (addr_t)(m_address_to_send + (m_count*4)); p_vci.plen = m_length*4; p_vci.wdata = 0; p_vci.trdid = 0; if (m_count == m_length - 1 ) { p_vci.eop = true; } else { p_vci.eop = false; } p_vci.rspack = false; break; } ////////////////////// case VCI_SINGLE_RECEIVE: { p_vci.cmdval = false; p_vci.address = 0; p_vci.plen = 0; p_vci.wdata = 0; p_vci.trdid = 0; p_vci.eop = false; p_vci.rspack = true; break; } /////////////////// case VCI_BC_SEND: { p_vci.cmdval = true; p_vci.address = (addr_t) m_address_to_send; p_vci.plen = 4; p_vci.wdata = 0; p_vci.trdid = 0; p_vci.eop = true; p_vci.rspack = false; break; } //////////////////// case VCI_BC_RECEIVE: { p_vci.cmdval = false; p_vci.address = 0; p_vci.plen = 0; p_vci.wdata = 0; p_vci.trdid = 0; p_vci.eop = false; p_vci.rspack = true; break; } } // end switch vci_fsm } // end genMoore() }} // end name space