source: trunk/modules/vci_synthetic_initator/caba/sources/src/vci_synthetic_initiator.cpp @ 146

Last change on this file since 146 was 146, checked in by choichil, 13 years ago

Modifications to make the code easier to read

File size: 13.5 KB
RevLine 
[123]1
[77]2/* -*- c++ -*-
[123]3 * File         : vci_synthetic_initiator.cpp
4 * Date         : 23/12/2010
[77]5 * Copyright    : UPMC / LIP6
6 * Authors      : Christophe Choichillon
[131]7 * Version      : 2.1
[77]8 *
9 * SOCLIB_LGPL_HEADER_BEGIN
10 *
11 * This file is part of SoCLib, GNU LGPLv2.1.
12 *
13 * SoCLib is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published
15 * by the Free Software Foundation; version 2.1 of the License.
16 *
17 * SoCLib is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with SoCLib; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 *
27 * SOCLIB_LGPL_HEADER_END
28 *
29 * Maintainers: christophe.choichillon@lip6.fr
30 */
31
[78]32#include "../include/vci_synthetic_initiator.h"
[106]33#include <iostream>
[77]34
35
[135]36//#define DETERMINISTIC
[145]37#define RANDOM_PERIOD
[77]38
39namespace soclib { namespace caba {
40
41
[78]42#define tmpl(x) template<typename vci_param> x VciSyntheticInitiator<vci_param>
[77]43
[78]44  //using soclib::common::uint32_log2; 
45 
[77]46  ////////////////////////////////
47  //    Constructor
48  ////////////////////////////////
49
[78]50  tmpl(/**/)::VciSyntheticInitiator( 
[77]51      sc_module_name name,
[102]52      const soclib::common::MappingTable &mt,
53      const soclib::common::IntTab       &vci_index,
54      const uint32_t length,    // Packet length (flit numbers)
[128]55      const uint32_t rho,       // Offered load * 1000
[102]56      const uint32_t depth,     // Fifo depth
57      const uint32_t xmesh,     
58      const uint32_t ymesh,
59      const uint32_t bc_period, // Broadcast period, if no broadcast => 0
60      const uint32_t xmin, 
61      const uint32_t xmax,
62      const uint32_t ymin,
63      const uint32_t ymax
[78]64      )
[77]65
66    : soclib::caba::BaseModule(name),
67
68    p_clk("clk"),
69    p_resetn("resetn"),
70    p_vci("vci_ini"),
[135]71    //  FIFOs
[98]72    m_srcid( mt.indexForId(vci_index) ),
[81]73    m_length(length),
74    m_rho(rho),
75    m_depth(depth),
76    m_xmesh(xmesh),
77    m_ymesh(ymesh),
78    m_bc_period(bc_period),
79    m_xmin(xmin),
80    m_xmax(xmax),
81    m_ymin(ymin),
82    m_ymax(ymax),
[131]83    r_date_fifo("r_date_fifo", m_depth),
84    r_bc_fifo("r_bc_fifo", m_depth),
85    r_cmd_fsm("r_cmd_fsm"),
86    r_cmd_address("r_cmd_address"),             
87    r_cmd_trdid("r_cmd_trdid"), 
88    r_cmd_count("r_cmd_count"),         
89    r_cmd_seed("r_cmd_seed"),   
90    r_bc_nrsp("r_bc_nrsp"),     
91    r_cpt_cycles("r_cpt_cycles"),               
92    r_cpt_period("r_cpt_period"),               
93    r_nb_single("r_nb_single"), 
94    r_latency_single("r_latency_single"),       
95    r_nb_bc("r_nb_bc"), 
[146]96    r_latency_bc("r_latency_bc"),
97    r_time_to_next_bc("r_time_to_next_bc")
[126]98{
[77]99
[131]100      r_pending_fsm = new sc_signal<bool>[m_tab_size];
101      r_pending_date = new sc_signal<uint64_t>[m_tab_size];
[77]102
103      SC_METHOD(transition);
104      dont_initialize();
105      sensitive << p_clk.pos();
106
107      SC_METHOD(genMoore);
108      dont_initialize();
109      sensitive << p_clk.neg();
110
111    } // end constructor
112
113
114  /////////////////////////////////
[78]115  tmpl(/**/)::~VciSyntheticInitiator()
[77]116    /////////////////////////////////
117  {
[131]118        delete r_pending_fsm;
119        delete r_pending_date;
[77]120  }
121
[81]122  ///////////////////////////////////
[115]123  tmpl(uint32_t)::destAdress()
[81]124  ///////////////////////////////////
125  {
[115]126    return (uint32_t) (rand() % (m_xmesh * m_ymesh)) ;
[81]127  }
128
[98]129
130  ///////////////////////////////////
[115]131  tmpl(uint32_t)::destAdress(uint32_t *rand_seed)
[98]132  ///////////////////////////////////
[115]133  {
134    return (uint32_t) (rand_r(rand_seed) % (m_xmesh * m_ymesh)) ;
135  }
[98]136
[77]137  //////////////////////////////////
[145]138  tmpl(double)::getLatencySingle()
139  //////////////////////////////////
140  {
141        if (m_rho) 
142          return (double)(r_latency_single.read())/(double)(r_nb_single.read());
143        else
144          return 0;
145
146  }
147
148  //////////////////////////////////
149  tmpl(double)::getLatencyBC()
150  //////////////////////////////////
151  {
152        if(m_bc_period)
153          return ((double)r_latency_bc.read()/(double)r_nb_bc.read());
154        else
155          return 0;
156
157  }
158
159  //////////////////////////////////
[106]160  tmpl(void)::print_trace()
161  //////////////////////////////////
162  {
[123]163        const char* state_cmd_str[] = { "IDLE",
164                                        "SINGLE_SEND",
165                                        "BC_SEND"};
[106]166
[123]167        const char* state_bc_rsp_str[] = {"IDLE",
168                                          "WAIT_RSP"};
169
[106]170        std::cout << "Vci_Synthetic_Initiator " << name()
[131]171                  << " : " << std::dec << r_cpt_cycles.read() << " cycles " 
[123]172                  << " : state_cmd_fsm = " << state_cmd_str[r_cmd_fsm] 
[131]173                  << " : state_rsp_fsm = " << state_bc_rsp_str[r_pending_fsm[0].read()] 
[128]174                  << " Adresse to send : " << std::hex << r_cmd_address.read()
[146]175                  << " Number of BC_RSP to receive : " << std::dec << r_bc_nrsp.read() 
[145]176                  << " Number of packets sent : " << std::dec << r_nb_single.read() << " " << r_cmd_trdid.read() 
[146]177                  << " Number of BC sent : " << r_nb_bc.read()
178                  << " Cycles to the next BC : " << r_time_to_next_bc.read() << std::endl;
[123]179        for(int i = 0; i < (1<<vci_param::T) ; i++){
[131]180          std::cout << "ID : " << i << " " << (uint64_t)(r_pending_date[i].read()) << std::endl;
[123]181        }
[106]182  }
183
184  //////////////////////////////////
185  tmpl(void)::printStats()
186  //////////////////////////////////
187  {
[131]188        std::cout << name() << " : "<< std::dec << r_cpt_cycles.read() << " cycles, " << r_nb_single.read() << " packets sent" << std::endl;
[135]189        if (m_rho) 
190        {
191          std::cout << "Average latency : " << (double)(r_latency_single.read())/(double)(r_nb_single.read()) << std::endl;
192        }
[122]193        if(m_bc_period)
[132]194        {
195          std::cout << "Number of broadcast sent and received : " << r_nb_bc.read() << std::endl;
[135]196          std::cout << "Average latency : " << ((double)r_latency_bc.read()/(double)r_nb_bc.read()) << std::endl;
[132]197        }
[106]198  }
199
200  //////////////////////////////////
[77]201  tmpl(void)::transition()
[106]202  //////////////////////////////////
[77]203  {
204    //  RESET         
[128]205    if ( ! p_resetn.read() ) 
206    {
[98]207      // Initializing seed for random numbers generation
[128]208
[122]209#ifndef DETERMINISTIC
[98]210      srand(time(NULL));
[115]211#endif
[77]212
[98]213      // Initializing FSMs
[123]214      r_cmd_fsm = VCI_IDLE;
[128]215      for(size_t i=0 ; i<m_tab_size ; i++) r_pending_fsm[i] = false;
[77]216
[98]217      // Initializing FIFOs
[128]218      r_date_fifo.init();
219      r_bc_fifo.init();
[77]220
[128]221      // Initializing the instrumentation registers
[135]222      r_latency_single          = 0;
[128]223      r_nb_single               = 0;
[135]224      r_latency_bc              = 0;
[128]225      r_nb_bc                   = 0;
226      r_cpt_cycles              = 0;
227      r_cpt_period              = 0;
[122]228     
[135]229      r_cmd_seed                = (uint32_t)m_srcid;
[77]230
[146]231#ifndef RANDOM_PERIOD
232      r_time_to_next_bc         = m_bc_period;
233#endif
234
[77]235      return;
236    }
237
[128]238    bool    fifo_put = false;
239    bool    fifo_get = false;
[135]240    bool    fifo_bc  = false;
[77]241
[135]242
243#ifdef DETERMINISTIC
[127]244    uint32_t m_local_seed ;
[135]245#endif
[106]246
[128]247    //////////////////
248    // VCI CMD FSM
249    //////////////////
[123]250    switch ( r_cmd_fsm.read() ) {
[78]251      case VCI_IDLE:
[77]252        {
[128]253          if (r_date_fifo.rok())
254          {
[131]255            if ( r_bc_fifo.read() == true )     // its a broadcast request
[128]256            {
[131]257              if ( r_pending_fsm[0].read() == false )   // no current broadcast
[128]258              {
[131]259                r_cmd_fsm = VCI_BC_SEND ;
260                r_cmd_address = 0x3 | (0x7c1f << vci_param::N-20) ;
[128]261              }
262            }
263            else                        // its a single request
264            {
265              int id = -1;
[135]266              for(size_t i = 1; i < m_tab_size; i++){   // ID 0 reserved for broadcast transactions
[128]267                if(r_pending_fsm[i].read() == false)
268                {
[135]269                  id = (int)i;
[123]270                  break;
271                }
272              }
[128]273              if(id != -1){
[123]274                r_cmd_fsm = VCI_SINGLE_SEND ;
[128]275                r_cmd_count = 0;
276                r_cmd_trdid = id;
[123]277              }
[122]278#ifdef DETERMINISTIC
[128]279              m_local_seed = r_cmd_seed.read();
280              r_cmd_address = destAdress(&m_local_seed) << (vci_param::N)-(soclib::common::uint32_log2((uint32_t)m_xmesh)+soclib::common::uint32_log2((uint32_t)m_ymesh));
281              r_cmd_seed = m_local_seed;
[115]282#else
[128]283              r_cmd_address = destAdress() << (vci_param::N)-(soclib::common::uint32_log2((uint32_t)m_xmesh)+soclib::common::uint32_log2((uint32_t)m_ymesh));
[115]284#endif
[98]285            }
286          }
[77]287          break;
288        }
[78]289      case VCI_SINGLE_SEND:
[77]290        {
[128]291          if ( p_vci.cmdack.read())
292          {
[131]293            r_cmd_count = r_cmd_count.read() + 1;
[128]294            if (r_cmd_count.read() == m_length-1) 
295            {
[135]296              //r_nb_single = r_nb_single.read() + 1;
[128]297              r_cmd_fsm = VCI_SINGLE_REGISTER ;
[98]298            }
299          }
[77]300          break;
301        }
[128]302      case VCI_SINGLE_REGISTER:
303        {
[131]304          r_pending_date[r_cmd_trdid.read()] = (uint64_t)(r_date_fifo.read());
[128]305          r_pending_fsm[r_cmd_trdid.read()] = true;
306          fifo_get = true;
307          r_cmd_fsm = VCI_IDLE;
308        }
[123]309      case VCI_BC_SEND:
[77]310        {
[128]311          if (p_vci.cmdack.read()) 
312          {
[123]313            r_bc_nrsp = (m_xmax - m_xmin) * (m_ymax - m_ymin) ;
[131]314            r_pending_fsm[0] = true;
315            r_pending_date[0] = (uint64_t)(r_date_fifo.read());
[128]316            fifo_get = true;
317            r_cmd_fsm = VCI_IDLE;
[123]318            break;
[81]319          }
[77]320        }
[123]321    } // end switch vci_fsm
322
[132]323   
[128]324    ///////////////////
325    // PENDING FSMs
326    //////////////////
[131]327    if(p_vci.rspval.read())
[128]328    {
[131]329      if(p_vci.rtrdid.read() == 0)      // not a broadcast
[128]330      {
[131]331        assert( ( r_pending_fsm[0].read() == true ) && 
332                "illegal broadcast response received");
333        r_bc_nrsp = r_bc_nrsp.read() - 1 ;
334        if(r_bc_nrsp.read() == 1) 
335        {
336          r_pending_fsm[0] = false;
337          r_latency_bc = r_latency_bc.read() + (r_cpt_cycles.read() - r_pending_date[0].read());
338        }
339      }
340      else
341      {
[128]342        assert( ( r_pending_fsm[(int)p_vci.rtrdid.read()] == true ) && 
[131]343                "illegal single response received");
[128]344        r_pending_fsm[p_vci.rtrdid.read()] = false;
345        r_latency_single = r_latency_single.read() + 
346                           (r_cpt_cycles.read() - r_pending_date[(int)p_vci.rtrdid.read()].read());
[123]347      }
348    }
[77]349
[128]350    ////////////////////////
351    //  traffic regulator
352    ////////////////////////
[146]353    if ( m_bc_period && (r_cpt_period.read() > r_time_to_next_bc.read()) )
[128]354    { 
355      fifo_put = true ;
356      fifo_bc  = true;
[129]357      if (r_date_fifo.wok())   
358      {
359        r_nb_bc = r_nb_bc.read() + 1;
360        r_cpt_period = 0;
361      }
[81]362    }
[128]363    else if( ( (uint64_t)(m_rho*r_cpt_cycles.read()) > (uint64_t)(m_length*r_nb_single.read()*1000)) )
364    {
365      fifo_put = true ;
366      fifo_bc  = false;
367      if (r_date_fifo.wok())   r_nb_single = r_nb_single.read() + 1;
368    }
[81]369
[146]370    if ( m_bc_period && (r_cpt_period.read() > r_time_to_next_bc.read()) && r_date_fifo.wok() ) 
371    {
[145]372#ifdef RANDOM_PERIOD
[146]373      r_time_to_next_bc = (uint32_t)(rand()%(2*m_bc_period));
374#endif
[131]375      r_cpt_period = 0;
[146]376    }
[129]377    else
[131]378      r_cpt_period = r_cpt_period.read() + 1;
[129]379
[128]380    ////////////////////////
381    //  update fifos
382    ////////////////////////
[131]383    if (fifo_put){
384      if (fifo_get){
[128]385        r_date_fifo.put_and_get(r_cpt_cycles.read());
386        r_bc_fifo.put_and_get(fifo_bc);
[77]387      } else {
[131]388        r_date_fifo.simple_put(r_cpt_cycles.read());
[128]389        r_bc_fifo.simple_put(fifo_bc);
[77]390      }
391    } else {
[131]392      if (fifo_get){
[128]393        r_date_fifo.simple_get();
394        r_bc_fifo.simple_get();
[77]395      }
396    }
[98]397   
[128]398    ///////////////////////////
399    //  increment local time
400    ///////////////////////////
401    r_cpt_cycles = r_cpt_cycles.read() + 1;
[77]402
[81]403    return;
404
[77]405  } // end transition()
406
407  /////////////////////////////
408  tmpl(void)::genMoore()
[128]409  /////////////////////////////
[77]410  {
411    ////////////////////////////////////////////////////////////
[98]412    // Command signals on the p_vci port
[77]413    ////////////////////////////////////////////////////////////
[98]414     p_vci.cmd        = vci_param::CMD_WRITE;   
[81]415     p_vci.be         = 0xF;                             
[123]416     p_vci.srcid      = m_srcid;   
[81]417     p_vci.cons       = false;       
418     p_vci.wrap       = false;       
419     p_vci.contig     = true;       
420     p_vci.clen       = 0;         
421     p_vci.cfixed     = false;           
[123]422     p_vci.rspack     = true;
[77]423
424
[123]425    switch ( r_cmd_fsm.read() ) {
[77]426
[78]427      //////////////////
428      case VCI_IDLE:
429        {
[81]430          p_vci.cmdval  = false;                 
431          p_vci.address = 0; 
432          p_vci.plen    = 0;                                         
433          p_vci.wdata   = 0;                                       
434          p_vci.trdid   = 0;                 
[131]435          p_vci.pktid      = 0;     
[81]436          p_vci.eop     = false;                                   
[78]437          break;
438        }
439        //////////////////
440      case VCI_SINGLE_SEND:
441        {
[98]442          p_vci.cmdval  = true;                 
[131]443          p_vci.address = (addr_t)(r_cmd_address.read() + (r_cmd_count.read()*4)); 
[98]444          p_vci.plen    = m_length*4;                                         
445          p_vci.wdata   = 0;                                       
[131]446          p_vci.trdid   = r_cmd_trdid.read();                 
447          p_vci.pktid   = 0;     
448          if (r_cmd_count.read() == m_length - 1 ) {
[98]449            p_vci.eop     = true;                                   
450          } else {
451            p_vci.eop     = false;                                   
452          }
[78]453          break;
454        }
455        ///////////////////
456      case VCI_BC_SEND:
457        {
[98]458          p_vci.cmdval  = true;                 
[128]459          p_vci.address = (addr_t) r_cmd_address.read(); 
[98]460          p_vci.plen    = 4;                                         
461          p_vci.wdata   = 0;                                       
462          p_vci.trdid   = 0;                 
[131]463          p_vci.pktid   = 0;     
[98]464          p_vci.eop     = true;                                   
[78]465          break;
466        }
[131]467      //////////////////
468      case VCI_SINGLE_REGISTER:
469        {
470          p_vci.cmdval  = false;                 
471          p_vci.address = 0; 
472          p_vci.plen    = 0;                                         
473          p_vci.wdata   = 0;                                       
474          p_vci.trdid   = 0;                 
475          p_vci.pktid   = 0;     
476          p_vci.eop     = false;                                   
477          break;
478        }
[123]479    } // end switch vci_cmd_fsm
[77]480
481  } // end genMoore()
482
483}} // end name space
Note: See TracBrowser for help on using the repository browser.