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

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

Initiator with only one FSM for responses

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