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

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

Initiator with bug correction in latency computing

File size: 12.7 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
38namespace soclib { namespace caba {
39
40
41#define tmpl(x) template<typename vci_param> x VciSyntheticInitiator<vci_param>
42
43  //using soclib::common::uint32_log2; 
44 
45  ////////////////////////////////
46  //    Constructor
47  ////////////////////////////////
48
49  tmpl(/**/)::VciSyntheticInitiator( 
50      sc_module_name name,
51      const soclib::common::MappingTable &mt,
52      const soclib::common::IntTab       &vci_index,
53      const uint32_t length,    // Packet length (flit numbers)
54      const uint32_t rho,       // Offered load * 1000
55      const uint32_t depth,     // Fifo depth
56      const uint32_t xmesh,     
57      const uint32_t ymesh,
58      const uint32_t bc_period, // Broadcast period, if no broadcast => 0
59      const uint32_t xmin, 
60      const uint32_t xmax,
61      const uint32_t ymin,
62      const uint32_t ymax
63      )
64
65    : soclib::caba::BaseModule(name),
66
67    p_clk("clk"),
68    p_resetn("resetn"),
69    p_vci("vci_ini"),
70    //  FIFOs
71    m_srcid( mt.indexForId(vci_index) ),
72    m_length(length),
73    m_rho(rho),
74    m_depth(depth),
75    m_xmesh(xmesh),
76    m_ymesh(ymesh),
77    m_bc_period(bc_period),
78    m_xmin(xmin),
79    m_xmax(xmax),
80    m_ymin(ymin),
81    m_ymax(ymax),
82    r_date_fifo("r_date_fifo", m_depth),
83    r_bc_fifo("r_bc_fifo", m_depth),
84    r_cmd_fsm("r_cmd_fsm"),
85    r_cmd_address("r_cmd_address"),             
86    r_cmd_trdid("r_cmd_trdid"), 
87    r_cmd_count("r_cmd_count"),         
88    r_cmd_seed("r_cmd_seed"),   
89    r_bc_nrsp("r_bc_nrsp"),     
90    r_cpt_cycles("r_cpt_cycles"),               
91    r_cpt_period("r_cpt_period"),               
92    r_nb_single("r_nb_single"), 
93    r_latency_single("r_latency_single"),       
94    r_nb_bc("r_nb_bc"), 
95    r_latency_bc("r_latency_bc")               
96{
97
98      r_pending_fsm = new sc_signal<bool>[m_tab_size];
99      r_pending_date = new sc_signal<uint64_t>[m_tab_size];
100
101      SC_METHOD(transition);
102      dont_initialize();
103      sensitive << p_clk.pos();
104
105      SC_METHOD(genMoore);
106      dont_initialize();
107      sensitive << p_clk.neg();
108
109    } // end constructor
110
111
112  /////////////////////////////////
113  tmpl(/**/)::~VciSyntheticInitiator()
114    /////////////////////////////////
115  {
116        delete r_pending_fsm;
117        delete r_pending_date;
118  }
119
120  ///////////////////////////////////
121  tmpl(uint32_t)::destAdress()
122  ///////////////////////////////////
123  {
124    return (uint32_t) (rand() % (m_xmesh * m_ymesh)) ;
125  }
126
127
128  ///////////////////////////////////
129  tmpl(uint32_t)::destAdress(uint32_t *rand_seed)
130  ///////////////////////////////////
131  {
132    return (uint32_t) (rand_r(rand_seed) % (m_xmesh * m_ymesh)) ;
133  }
134
135 
136  //////////////////////////////////
137  tmpl(void)::print_trace()
138  //////////////////////////////////
139  {
140        const char* state_cmd_str[] = { "IDLE",
141                                        "SINGLE_SEND",
142                                        "BC_SEND"};
143
144        const char* state_bc_rsp_str[] = {"IDLE",
145                                          "WAIT_RSP"};
146
147        std::cout << "Vci_Synthetic_Initiator " << name()
148                  << " : " << std::dec << r_cpt_cycles.read() << " cycles " 
149                  << " : state_cmd_fsm = " << state_cmd_str[r_cmd_fsm] 
150                  << " : state_rsp_fsm = " << state_bc_rsp_str[r_pending_fsm[0].read()] 
151                  << " Adresse to send : " << std::hex << r_cmd_address.read()
152                  << " Number of broadcast to receive : " << std::dec << r_bc_nrsp.read() 
153                  << " Number of packets sent : " << std::dec << r_nb_single.read() << " " << r_cmd_trdid.read() << std::endl;
154        for(int i = 0; i < (1<<vci_param::T) ; i++){
155          std::cout << "ID : " << i << " " << (uint64_t)(r_pending_date[i].read()) << std::endl;
156        }
157  }
158
159  //////////////////////////////////
160  tmpl(void)::printStats()
161  //////////////////////////////////
162  {
163        std::cout << name() << " : "<< std::dec << r_cpt_cycles.read() << " cycles, " << r_nb_single.read() << " packets sent" << std::endl;
164        if (m_rho) 
165        {
166          std::cout << "Average latency : " << (double)(r_latency_single.read())/(double)(r_nb_single.read()) << std::endl;
167        }
168        if(m_bc_period)
169        {
170          std::cout << "Number of broadcast sent and received : " << r_nb_bc.read() << std::endl;
171          std::cout << "Average latency : " << ((double)r_latency_bc.read()/(double)r_nb_bc.read()) << std::endl;
172        }
173  }
174
175  //////////////////////////////////
176  tmpl(void)::transition()
177  //////////////////////////////////
178  {
179    //  RESET         
180    if ( ! p_resetn.read() ) 
181    {
182      // Initializing seed for random numbers generation
183
184#ifndef DETERMINISTIC
185      srand(time(NULL));
186#endif
187
188      // Initializing FSMs
189      r_cmd_fsm = VCI_IDLE;
190      for(size_t i=0 ; i<m_tab_size ; i++) r_pending_fsm[i] = false;
191
192      // Initializing FIFOs
193      r_date_fifo.init();
194      r_bc_fifo.init();
195
196      // Initializing the instrumentation registers
197      r_latency_single          = 0;
198      r_nb_single               = 0;
199      r_latency_bc              = 0;
200      r_nb_bc                   = 0;
201      r_cpt_cycles              = 0;
202      r_cpt_period              = 0;
203     
204      r_cmd_seed                = (uint32_t)m_srcid;
205
206      return;
207    }
208
209    bool    fifo_put = false;
210    bool    fifo_get = false;
211    bool    fifo_bc  = false;
212
213
214#ifdef DETERMINISTIC
215    uint32_t m_local_seed ;
216#endif
217
218    //////////////////
219    // VCI CMD FSM
220    //////////////////
221    switch ( r_cmd_fsm.read() ) {
222      case VCI_IDLE:
223        {
224          if (r_date_fifo.rok())
225          {
226            if ( r_bc_fifo.read() == true )     // its a broadcast request
227            {
228              if ( r_pending_fsm[0].read() == false )   // no current broadcast
229              {
230                r_cmd_fsm = VCI_BC_SEND ;
231                r_cmd_address = 0x3 | (0x7c1f << vci_param::N-20) ;
232              }
233            }
234            else                        // its a single request
235            {
236              int id = -1;
237              for(size_t i = 1; i < m_tab_size; i++){   // ID 0 reserved for broadcast transactions
238                if(r_pending_fsm[i].read() == false)
239                {
240                  id = (int)i;
241                  break;
242                }
243              }
244              if(id != -1){
245                r_cmd_fsm = VCI_SINGLE_SEND ;
246                r_cmd_count = 0;
247                r_cmd_trdid = id;
248              }
249#ifdef DETERMINISTIC
250              m_local_seed = r_cmd_seed.read();
251              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));
252              r_cmd_seed = m_local_seed;
253#else
254              r_cmd_address = destAdress() << (vci_param::N)-(soclib::common::uint32_log2((uint32_t)m_xmesh)+soclib::common::uint32_log2((uint32_t)m_ymesh));
255#endif
256            }
257          }
258          break;
259        }
260      case VCI_SINGLE_SEND:
261        {
262          if ( p_vci.cmdack.read())
263          {
264            r_cmd_count = r_cmd_count.read() + 1;
265            if (r_cmd_count.read() == m_length-1) 
266            {
267              //r_nb_single = r_nb_single.read() + 1;
268              r_cmd_fsm = VCI_SINGLE_REGISTER ;
269            }
270          }
271          break;
272        }
273      case VCI_SINGLE_REGISTER:
274        {
275          r_pending_date[r_cmd_trdid.read()] = (uint64_t)(r_date_fifo.read());
276          r_pending_fsm[r_cmd_trdid.read()] = true;
277          fifo_get = true;
278          r_cmd_fsm = VCI_IDLE;
279        }
280      case VCI_BC_SEND:
281        {
282          if (p_vci.cmdack.read()) 
283          {
284            r_bc_nrsp = (m_xmax - m_xmin) * (m_ymax - m_ymin) ;
285            r_pending_fsm[0] = true;
286            r_pending_date[0] = (uint64_t)(r_date_fifo.read());
287            fifo_get = true;
288            r_cmd_fsm = VCI_IDLE;
289            break;
290          }
291        }
292    } // end switch vci_fsm
293
294   
295    ///////////////////
296    // PENDING FSMs
297    //////////////////
298    if(p_vci.rspval.read())
299    {
300      if(p_vci.rtrdid.read() == 0)      // not a broadcast
301      {
302        assert( ( r_pending_fsm[0].read() == true ) && 
303                "illegal broadcast response received");
304        r_bc_nrsp = r_bc_nrsp.read() - 1 ;
305        if(r_bc_nrsp.read() == 1) 
306        {
307          r_pending_fsm[0] = false;
308          r_latency_bc = r_latency_bc.read() + (r_cpt_cycles.read() - r_pending_date[0].read());
309        }
310      }
311      else
312      {
313        assert( ( r_pending_fsm[(int)p_vci.rtrdid.read()] == true ) && 
314                "illegal single response received");
315        r_pending_fsm[p_vci.rtrdid.read()] = false;
316        r_latency_single = r_latency_single.read() + 
317                           (r_cpt_cycles.read() - r_pending_date[(int)p_vci.rtrdid.read()].read());
318      }
319    }
320
321    ////////////////////////
322    //  traffic regulator
323    ////////////////////////
324    if ( m_bc_period && (r_cpt_period.read() > m_bc_period) )
325    { 
326      fifo_put = true ;
327      fifo_bc  = true;
328      if (r_date_fifo.wok())   
329      {
330        r_nb_bc = r_nb_bc.read() + 1;
331        r_cpt_period = 0;
332      }
333    }
334    else if( ( (uint64_t)(m_rho*r_cpt_cycles.read()) > (uint64_t)(m_length*r_nb_single.read()*1000)) )
335    {
336      fifo_put = true ;
337      fifo_bc  = false;
338      if (r_date_fifo.wok())   r_nb_single = r_nb_single.read() + 1;
339    }
340
341    if ( m_bc_period && (r_cpt_period.read() > m_bc_period) && r_date_fifo.wok() ) 
342      r_cpt_period = 0;
343    else
344      r_cpt_period = r_cpt_period.read() + 1;
345
346    ////////////////////////
347    //  update fifos
348    ////////////////////////
349    if (fifo_put){
350      if (fifo_get){
351        r_date_fifo.put_and_get(r_cpt_cycles.read());
352        r_bc_fifo.put_and_get(fifo_bc);
353      } else {
354        r_date_fifo.simple_put(r_cpt_cycles.read());
355        r_bc_fifo.simple_put(fifo_bc);
356      }
357    } else {
358      if (fifo_get){
359        r_date_fifo.simple_get();
360        r_bc_fifo.simple_get();
361      }
362    }
363   
364    ///////////////////////////
365    //  increment local time
366    ///////////////////////////
367    r_cpt_cycles = r_cpt_cycles.read() + 1;
368
369    return;
370
371  } // end transition()
372
373  /////////////////////////////
374  tmpl(void)::genMoore()
375  /////////////////////////////
376  {
377    ////////////////////////////////////////////////////////////
378    // Command signals on the p_vci port
379    ////////////////////////////////////////////////////////////
380     p_vci.cmd        = vci_param::CMD_WRITE;   
381     p_vci.be         = 0xF;                             
382     p_vci.srcid      = m_srcid;   
383     p_vci.cons       = false;       
384     p_vci.wrap       = false;       
385     p_vci.contig     = true;       
386     p_vci.clen       = 0;         
387     p_vci.cfixed     = false;           
388     p_vci.rspack     = true;
389
390
391    switch ( r_cmd_fsm.read() ) {
392
393      //////////////////
394      case VCI_IDLE:
395        {
396          p_vci.cmdval  = false;                 
397          p_vci.address = 0; 
398          p_vci.plen    = 0;                                         
399          p_vci.wdata   = 0;                                       
400          p_vci.trdid   = 0;                 
401          p_vci.pktid      = 0;     
402          p_vci.eop     = false;                                   
403          break;
404        }
405        //////////////////
406      case VCI_SINGLE_SEND:
407        {
408          p_vci.cmdval  = true;                 
409          p_vci.address = (addr_t)(r_cmd_address.read() + (r_cmd_count.read()*4)); 
410          p_vci.plen    = m_length*4;                                         
411          p_vci.wdata   = 0;                                       
412          p_vci.trdid   = r_cmd_trdid.read();                 
413          p_vci.pktid   = 0;     
414          if (r_cmd_count.read() == m_length - 1 ) {
415            p_vci.eop     = true;                                   
416          } else {
417            p_vci.eop     = false;                                   
418          }
419          break;
420        }
421        ///////////////////
422      case VCI_BC_SEND:
423        {
424          p_vci.cmdval  = true;                 
425          p_vci.address = (addr_t) r_cmd_address.read(); 
426          p_vci.plen    = 4;                                         
427          p_vci.wdata   = 0;                                       
428          p_vci.trdid   = 0;                 
429          p_vci.pktid   = 0;     
430          p_vci.eop     = true;                                   
431          break;
432        }
433      //////////////////
434      case VCI_SINGLE_REGISTER:
435        {
436          p_vci.cmdval  = false;                 
437          p_vci.address = 0; 
438          p_vci.plen    = 0;                                         
439          p_vci.wdata   = 0;                                       
440          p_vci.trdid   = 0;                 
441          p_vci.pktid   = 0;     
442          p_vci.eop     = false;                                   
443          break;
444        }
445    } // end switch vci_cmd_fsm
446
447  } // end genMoore()
448
449}} // end name space
Note: See TracBrowser for help on using the repository browser.