/* -*- 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" 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, size_t length, // Packet length (flit numbers) float rho, // Packets ratio on the network size_t depth, // Fifo depth size_t xmesh, size_t ymesh, size_t bc_period = 0, // Broadcast period, if no broadcast => 0 size_t xmin = 0, size_t xmax = 0, size_t ymin = 0, size_t ymax = 0 ) : soclib::caba::BaseModule(name), p_clk("clk"), p_resetn("resetn"), p_vci("vci_ini"), m_srcid( mt.indexForId(vci_index) ), m_coord(vci_index[1]), // FIFOs m_length(length), m_rho(rho), m_depth(depth), m_x(x), m_y(y), 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() /////////////////////////////////// { size_t dest; do{ dest = (size_t) (rand() % (m_xmesh * m_ymesh)); } while(dest == m_srcid); return dest ; } /////////////////////////////////// // 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)::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; return; } bool date_fifo_put = false; bool date_fifo_get = false; switch ( r_vci_fsm.read() ) { ////////////////// case VCI_IDLE: { if (m_date_fifo.rok()){ if (r_broadcast_req.read()){ r_vci_fsm = VCI_BC_SEND ; } else { r_vci_fsm = VCI_SINGLE_SEND ; destAdress(); m_count = 0; } } break; } ////////////////// case VCI_SINGLE_SEND: { if (p_vci.cmdack.read()){ m_count++; 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 ; } } 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; r_vci_fsm = VCI_IDLE ; } break; } /////////////////// case VCI_BC_SEND: { m_address_to_send.broadcast_address.xmin = m_xmin; m_address_to_send.broadcast_address.xmax = m_xmax; m_address_to_send.broadcast_address.ymin = m_ymin; m_address_to_send.broadcast_address.ymax = m_ymax; m_address_to_send.broadcast_address.bc = 0x3; 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; r_vci_fsm = VCI_IDLE ; } else { m_bc_nrsp--; r_vci_fsm = VCI_BC_RECEIVE ; } } break; } } // end switch vci_fsm /////////////////// Filling fifo if( (rhos < m_rho) && (rand()/RAND_MAX) ){ if (m_date_fifo.wok()){ date_fifo_put = true ; } if (!r_broadcast_req.read() && (m_cpt_cycles % 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_rhos = (float) ((m_npackets * m_length) / m_cpt_cycles) ; 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 = (typename vci_param::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 = (typename vci_param::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