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

Last change on this file since 190 was 190, checked in by zzhang, 12 years ago

fix some bugs in vdspin platform

File size: 14.4 KB
Line 
1
2/* -*- c++ -*-
3 * File         : vci_synthetic_initiator.cpp
4 * Date         : 23/12/2010
5 * Copyright    : UPMC / LIP6
6 * Authors      : Christophe Choichillon
7 * Version      : 2.1
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
32#include "../include/vci_synthetic_initiator.h"
33#include <iostream>
34
35
36//#define DETERMINISTIC
37#define RANDOM_PERIOD
38
39namespace soclib { namespace caba {
40
41
42#define tmpl(x) template<typename vci_param> x VciSyntheticInitiator<vci_param>
43
44  //using soclib::common::uint32_log2; 
45 
46  ////////////////////////////////
47  //    Constructor
48  ////////////////////////////////
49
50  tmpl(/**/)::VciSyntheticInitiator( 
51      sc_module_name name,
52      const soclib::common::MappingTable &mt,
53      const soclib::common::IntTab       &vci_index,
54      const uint32_t length,    // Packet length (flit numbers)
55      const uint32_t rho,       // Offered load * 1000
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
64      )
65
66    : soclib::caba::BaseModule(name),
67
68    p_clk("clk"),
69    p_resetn("resetn"),
70    p_vci("vci_ini"),
71    //  FIFOs
72    m_srcid( mt.indexForId(vci_index) ),
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),
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"), 
96    r_latency_bc("r_latency_bc"),
97    r_time_to_next_bc("r_time_to_next_bc")
98{
99
100      r_pending_fsm = new sc_signal<bool>[m_tab_size];
101      r_pending_date = new sc_signal<uint64_t>[m_tab_size];
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  /////////////////////////////////
115  tmpl(/**/)::~VciSyntheticInitiator()
116    /////////////////////////////////
117  {
118        delete r_pending_fsm;
119        delete r_pending_date;
120  }
121
122  ///////////////////////////////////
123  tmpl(uint32_t)::destAdress()
124  ///////////////////////////////////
125  {
126    return (uint32_t) (rand() % (m_xmesh * m_ymesh)) ;
127  }
128
129
130  ///////////////////////////////////
131  tmpl(uint32_t)::destAdress(uint32_t *rand_seed)
132  ///////////////////////////////////
133  {
134    return (uint32_t) (rand_r(rand_seed) % (m_xmesh * m_ymesh)) ;
135  }
136
137  //////////////////////////////////
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        double latency = (double)r_latency_bc.read();
153        double nb      = (double)r_nb_bc.read();
154        std::cout << "Latency BC : " <<std::dec << latency << " nb_bc : " << nb << std::endl;
155        if(m_bc_period)
156          return (latency/nb);
157        else
158          return 0;
159
160  }
161
162  //////////////////////////////////
163  tmpl(void)::print_trace()
164  //////////////////////////////////
165  {
166        const char* state_cmd_str[] = { "IDLE",
167                                        "SINGLE_SEND",
168                                        "BC_SEND"};
169
170        const char* state_bc_rsp_str[] = {"IDLE",
171                                          "WAIT_RSP"};
172
173        std::cout << "Vci_Synthetic_Initiator " << name()
174                  << " : " << std::dec << r_cpt_cycles.read() << " cycles " 
175                  << " : state_cmd_fsm = " << state_cmd_str[r_cmd_fsm] 
176                  << " : state_rsp_fsm = " << state_bc_rsp_str[r_pending_fsm[0].read()] 
177                  << " Adresse to send : " << std::hex << r_cmd_address.read()
178                  << " Number of BC_RSP to receive : " << std::dec << r_bc_nrsp.read() 
179                  << " Number of packets sent : " << std::dec << r_nb_single.read() << " " << r_cmd_trdid.read() 
180                  << " Number of BC sent : " << r_nb_bc.read()
181                  << " Cycles to the next BC : " << r_time_to_next_bc.read() 
182                  << " FIFO status : " << r_date_fifo.filled_status() << std::endl;
183        for(int i = 0; i < (1<<vci_param::T) ; i++){
184          std::cout << "ID : " << i << " " << (uint64_t)(r_pending_date[i].read()) << std::endl;
185        }
186  }
187
188  //////////////////////////////////
189  tmpl(void)::printStats()
190  //////////////////////////////////
191  {
192        std::cout << name() << " : "<< std::dec << r_cpt_cycles.read() << " cycles, " << r_nb_single.read() << " packets sent" << std::endl;
193        if (m_rho) 
194        {
195          std::cout << "Average latency : " << (double)(r_latency_single.read())/(double)(r_nb_single.read()) << std::endl;
196        }
197        if(m_bc_period)
198        {
199          std::cout << "Number of broadcast sent and received : " << r_nb_bc.read() << std::endl;
200          std::cout << "Average latency : " << ((double)r_latency_bc.read()/(double)r_nb_bc.read()) << std::endl;
201        }
202  }
203
204  //////////////////////////////////
205  tmpl(void)::transition()
206  //////////////////////////////////
207  {
208    //  RESET         
209    if ( ! p_resetn.read() ) 
210    {
211      // Initializing seed for random numbers generation
212
213//#ifndef DETERMINISTIC
214//      srand(time(NULL));
215//#endif
216
217      // Initializing FSMs
218      r_cmd_fsm = VCI_IDLE;
219      for(size_t i=0 ; i<m_tab_size ; i++) r_pending_fsm[i] = false;
220
221      // Initializing FIFOs
222      r_date_fifo.init();
223      r_bc_fifo.init();
224
225      // Initializing the instrumentation registers
226      r_latency_single          = 0;
227      r_nb_single               = 0;
228      r_latency_bc              = 0;
229      r_nb_bc                   = 0;
230      r_cpt_cycles              = 0;
231      r_cpt_period              = 0;
232     
233      r_cmd_seed                = (uint32_t)m_srcid;
234     
235      //std::cout << name() << " " << std::dec << m_bc_period << std::endl;
236
237      if (m_bc_period){
238        uint32_t a = (uint32_t)(rand()%(2*m_bc_period));
239        //std::cout << name() << " " << std::dec << a << std::endl;
240        r_time_to_next_bc               = a;
241      } else {
242        //std::cout << "c'est 0 " << std::endl;
243        r_time_to_next_bc               = 0;
244      }
245
246      return;
247    }
248
249    bool    fifo_put = false;
250    bool    fifo_get = false;
251    bool    fifo_bc  = false;
252
253
254#ifdef DETERMINISTIC
255    uint32_t m_local_seed ;
256#endif
257
258    //////////////////
259    // VCI CMD FSM
260    //////////////////
261    switch ( r_cmd_fsm.read() ) {
262      case VCI_IDLE:
263        {
264          if (r_date_fifo.rok())
265          {
266            if ( r_bc_fifo.read() == true )     // its a broadcast request
267            {
268              if ( r_pending_fsm[0].read() == false )   // no current broadcast
269              {
270                //std::cout << name() << "SENDING BC" << std::endl;
271                r_cmd_fsm = VCI_BC_SEND ;
272                r_cmd_address = 0x3 | (0x7c1f << vci_param::N-20) ;
273              }
274            }
275            else                        // its a single request
276            {
277              int id = -1;
278              for(size_t i = 1; i < m_tab_size; i++){   // ID 0 reserved for broadcast transactions
279                if( r_pending_fsm[i].read() == false )
280                {
281                  id = (int)i;
282                  break;
283                }
284              }
285              if(id != -1){
286                r_cmd_fsm = VCI_SINGLE_SEND ;
287                r_cmd_count = 0;
288                r_cmd_trdid = id;
289              }
290#ifdef DETERMINISTIC
291              m_local_seed = r_cmd_seed.read();
292              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));
293              r_cmd_seed = m_local_seed;
294#else
295              r_cmd_address = destAdress() << (vci_param::N)-(soclib::common::uint32_log2((uint32_t)m_xmesh)+soclib::common::uint32_log2((uint32_t)m_ymesh));
296#endif
297            }
298          }
299          break;
300        }
301      case VCI_SINGLE_SEND:
302        {
303          if ( p_vci.cmdack.read())
304          {
305            r_cmd_count = r_cmd_count.read() + 1;
306            if (r_cmd_count.read() == m_length-1) 
307            {
308              //r_nb_single = r_nb_single.read() + 1;
309              r_cmd_fsm = VCI_SINGLE_REGISTER ;
310            }
311          }
312          break;
313        }
314      case VCI_SINGLE_REGISTER:
315        {
316          r_pending_date[r_cmd_trdid.read()] = (uint64_t)(r_date_fifo.read());
317          r_pending_fsm[r_cmd_trdid.read()] = true;
318          fifo_get = true;
319          r_cmd_fsm = VCI_IDLE;
320          break;
321        }
322      case VCI_BC_SEND:
323        {
324          if (p_vci.cmdack.read()) 
325          {
326            //std::cout << std::dec << r_cpt_cycles.read() << "ns " << name() << " BC SEND " << r_nb_bc.read() << " " << r_time_to_next_bc.read() << std::endl;
327            r_bc_nrsp = (m_xmax - m_xmin) * (m_ymax - m_ymin) ;
328            r_pending_fsm[0] = true;
329            r_pending_date[0] = (uint64_t)(r_date_fifo.read());
330            fifo_get = true;
331            r_cmd_fsm = VCI_IDLE;
332            break;
333          }
334        }
335    } // end switch vci_fsm
336
337   
338    ///////////////////
339    // PENDING FSMs
340    //////////////////
341    if(p_vci.rspval.read())
342    {
343      if(p_vci.rtrdid.read() == 0)      // not a broadcast
344      {
345        assert( ( r_pending_fsm[0].read() == true ) && 
346                "illegal broadcast response received");
347        r_bc_nrsp = r_bc_nrsp.read() - 1 ;
348        if(r_bc_nrsp.read() == 1) 
349        {
350          r_pending_fsm[0] = false;
351          r_latency_bc = r_latency_bc.read() + (r_cpt_cycles.read() - r_pending_date[0].read());
352          //std::cout << std::dec << r_cpt_cycles.read() << "ns " << name() << " BC done " << std::endl;
353        }
354      }
355      else
356      {
357        assert( ( r_pending_fsm[(int)p_vci.rtrdid.read()] == true ) && 
358                "illegal single response received");
359        r_pending_fsm[p_vci.rtrdid.read()] = false;
360        r_latency_single = r_latency_single.read() + 
361                           (r_cpt_cycles.read() - r_pending_date[(int)p_vci.rtrdid.read()].read());
362      }
363    }
364
365    ////////////////////////
366    //  traffic regulator
367    ////////////////////////
368    if ( m_bc_period && (r_cpt_period.read() > r_time_to_next_bc.read()) )
369    { 
370      fifo_put = true ;
371      fifo_bc  = true;
372      if (r_date_fifo.wok())   
373      {
374        r_nb_bc = r_nb_bc.read() + 1;
375//        r_cpt_period = 0;
376//#ifdef RANDOM_PERIOD
377//      r_time_to_next_bc = (uint32_t)(rand()%(2*m_bc_period));
378//#endif
379      }
380    }
381    else if( ( (uint64_t)(m_rho*r_cpt_cycles.read()) > (uint64_t)(m_length*r_nb_single.read()*1000)) )
382    {
383      fifo_put = true ;
384      fifo_bc  = false;
385      if (r_date_fifo.wok())   r_nb_single = r_nb_single.read() + 1;
386    }
387
388    if ( m_bc_period && (r_cpt_period.read() > r_time_to_next_bc.read()) && r_date_fifo.wok() ) 
389    {
390#ifdef RANDOM_PERIOD
391      r_time_to_next_bc = (uint32_t)(rand()%(2*m_bc_period));
392#endif
393      r_cpt_period = 0;
394    }
395    else
396      r_cpt_period = r_cpt_period.read() + 1;
397
398    ////////////////////////
399    //  update fifos
400    ////////////////////////
401    if (fifo_put){
402      if (fifo_get){
403        r_date_fifo.put_and_get(r_cpt_cycles.read());
404        r_bc_fifo.put_and_get(fifo_bc);
405      } else {
406        r_date_fifo.simple_put(r_cpt_cycles.read());
407        r_bc_fifo.simple_put(fifo_bc);
408      }
409    } else {
410      if (fifo_get){
411        r_date_fifo.simple_get();
412        r_bc_fifo.simple_get();
413      }
414    }
415   
416    ///////////////////////////
417    //  increment local time
418    ///////////////////////////
419    r_cpt_cycles = r_cpt_cycles.read() + 1;
420
421    return;
422
423  } // end transition()
424
425  /////////////////////////////
426  tmpl(void)::genMoore()
427  /////////////////////////////
428  {
429    ////////////////////////////////////////////////////////////
430    // Command signals on the p_vci port
431    ////////////////////////////////////////////////////////////
432     p_vci.cmd        = vci_param::CMD_WRITE;   
433     p_vci.be         = 0xF;                             
434     p_vci.srcid      = m_srcid;   
435     p_vci.cons       = false;       
436     p_vci.wrap       = false;       
437     p_vci.contig     = true;       
438     p_vci.clen       = 0;         
439     p_vci.cfixed     = false;           
440     p_vci.rspack     = true;
441
442
443    switch ( r_cmd_fsm.read() ) {
444
445      //////////////////
446      case VCI_IDLE:
447        {
448          p_vci.cmdval  = false;                 
449          p_vci.address = 0; 
450          p_vci.plen    = 0;                                         
451          p_vci.wdata   = 0;                                       
452          p_vci.trdid   = 0;                 
453          p_vci.pktid      = 0;     
454          p_vci.eop     = false;                                   
455          break;
456        }
457        //////////////////
458      case VCI_SINGLE_SEND:
459        {
460          p_vci.cmdval  = true;                 
461          p_vci.address = (addr_t)(r_cmd_address.read() + (r_cmd_count.read()*4)); 
462          p_vci.plen    = m_length*4;                                         
463          p_vci.wdata   = 0;                                       
464          p_vci.trdid   = r_cmd_trdid.read();                 
465          p_vci.pktid   = 0;     
466          if (r_cmd_count.read() == m_length - 1 ) {
467            p_vci.eop     = true;                                   
468          } else {
469            p_vci.eop     = false;                                   
470          }
471          break;
472        }
473        ///////////////////
474      case VCI_BC_SEND:
475        {
476          p_vci.cmdval  = true;                 
477          p_vci.address = (addr_t) r_cmd_address.read(); 
478          p_vci.plen    = 4;                                         
479          p_vci.wdata   = 0;                                       
480          p_vci.trdid   = 0;                 
481          p_vci.pktid   = 0;     
482          p_vci.eop     = true;                                   
483          break;
484        }
485      //////////////////
486      case VCI_SINGLE_REGISTER:
487        {
488          p_vci.cmdval  = false;                 
489          p_vci.address = 0; 
490          p_vci.plen    = 0;                                         
491          p_vci.wdata   = 0;                                       
492          p_vci.trdid   = 0;                 
493          p_vci.pktid   = 0;     
494          p_vci.eop     = false;                                   
495          break;
496        }
497    } // end switch vci_cmd_fsm
498
499  } // end genMoore()
500
501}} // end name space
Note: See TracBrowser for help on using the repository browser.