source: trunk/modules/half_gateway_target_2/caba/source/include/half_gateway_target_2.h @ 11

Last change on this file since 11 was 11, checked in by simerabe, 14 years ago

adding trace for debugging

File size: 16.5 KB
Line 
1/* -*- c++ -*-
2 * SOCLIB_LGPL_HEADER_BEGIN
3 *
4 * This file is part of SoCLib, GNU LGPLv2.1.
5 *
6 * SoCLib is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; version 2.1 of the License.
9 *
10 * SoCLib is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with SoCLib; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 * SOCLIB_LGPL_HEADER_END
21 *
22 * Author   : Abdelmalek SI MERABET
23 * Date     : March 2010
24 *
25 * Copyright: UPMC - LIP6
26 */
27#include <systemc>
28#include "vci_initiator.h"
29#include "generic_fifo.h"
30#include "mapping_table.h"
31#include "ring_signals_2.h"
32#include "gate_ports_2.h"
33
34#define HT_DEBUG
35//#define HT_DEBUG_FSM
36
37namespace soclib { namespace caba {
38
39using soclib::common::IntTab;
40
41#ifdef HT_DEBUG_FSM
42namespace {
43        const char *ring_rsp_fsm_state_str_ht[] = {
44                "RSP_IDLE",
45                "DEFAULT",
46                "KEEP",
47        };
48        const char *ring_cmd_fsm_state_str_ht[] = {
49                "CMD_IDLE",
50                "BROADCAST_0",
51                "BROADCAST_1",
52                "LOCAL",
53                "RING",
54        };
55}
56#endif
57
58template<typename vci_param, int ring_cmd_data_size, int ring_rsp_data_size>
59class HalfGatewayTarget2
60{
61
62typedef typename vci_param::fast_addr_t vci_addr_t;
63typedef RingSignals2 ring_signal_t; 
64typedef soclib::caba::GateTarget2<ring_cmd_data_size, ring_rsp_data_size> gate_target_t;
65
66private:
67       
68        enum ring_cmd_fsm_state_e {
69                CMD_IDLE,        // waiting for first flit of a command packet
70                BROADCAST_0,
71                BROADCAST_1,
72                LOCAL,          // next flit of a local cmd packet
73                RING,          // next flit of a ring cmd packet
74        };
75       
76        // cmd token allocation fsm
77        enum ring_rsp_fsm_state_e {
78                RSP_IDLE,           
79                DEFAULT,       
80                KEEP,               
81        };
82       
83        // structural parameters
84        bool          m_alloc_target;
85        bool          m_local;
86        std::string   m_name;
87     
88        // internal registers
89        sc_signal<int>          r_ring_cmd_fsm;     // ring command packet FSM
90        sc_signal<int>          r_ring_rsp_fsm;     // ring response packet FSM
91       
92           
93        // internal fifos
94        GenericFifo<uint64_t > m_cmd_fifo;     // fifo for the local command paquet
95        GenericFifo<uint64_t > m_rsp_fifo;     // fifo for the local response paquet
96       
97        // locality table
98        soclib::common::AddressDecodingTable<vci_addr_t, bool> m_lt;
99        soclib::common::IntTab m_ringid;
100
101bool trace(int sc_time_stamp)
102{
103int time_stamp=0;
104char *ctime_stamp= getenv("FROM_CYCLE");
105
106if (ctime_stamp) time_stamp=atoi(ctime_stamp); 
107
108return sc_time_stamp >= time_stamp;
109
110}
111
112public :
113
114HalfGatewayTarget2(
115        const char     *name,
116        bool            alloc_target,
117        const int       &wrapper_fifo_depth,
118        const soclib::common::MappingTable &mt,
119        const soclib::common::IntTab &ringid,
120        bool  local) 
121    :   m_name(name), 
122        m_alloc_target(alloc_target),
123        m_cmd_fifo("m_cmd_fifo", wrapper_fifo_depth),
124        m_rsp_fifo("m_rsp_fifo", wrapper_fifo_depth),
125        m_lt(mt.getLocalityTable<typename vci_param::fast_addr_t>(ringid)),
126        m_ringid(ringid),
127        m_local(local),
128        r_ring_cmd_fsm("r_ring_cmd_fsm"),
129        r_ring_rsp_fsm("r_ring_rsp_fsm")
130{
131} //  end constructor
132
133void reset()
134{
135        if(m_alloc_target)
136                r_ring_rsp_fsm = DEFAULT;
137        else
138                r_ring_rsp_fsm = RSP_IDLE;
139       
140        r_ring_cmd_fsm = CMD_IDLE;
141        m_cmd_fifo.init();
142        m_rsp_fifo.init();       
143}
144////////////////////////////////
145//      transition
146////////////////////////////////
147void transition(const gate_target_t &p_gate_target, const ring_signal_t p_ring_in)       
148{
149
150//      bool      cmd_fifo_get = false;
151        bool      cmd_fifo_put = false;
152        uint64_t  cmd_fifo_data = 0;
153       
154        bool      rsp_fifo_get = false;
155        bool      rsp_fifo_put = false;
156        uint64_t  rsp_fifo_data = 0;
157
158#ifdef HT_DEBUG_FSM
159    std::cout << "--------------------------------------------" << std::endl;
160    std::cout             << " ring cmd fsm = " << ring_cmd_fsm_state_str_ht[r_ring_cmd_fsm] << std::endl
161                          << " ring rsp fsm = " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm] << std::endl;
162#endif
163       
164//////////// VCI CMD FSM /////////////////////////
165
166        if (p_gate_target.rsp_rok.read()) {
167                rsp_fifo_data = (uint64_t) p_gate_target.rsp_data.read();
168                rsp_fifo_put =  m_rsp_fifo.wok();
169        }
170
171        bool cmd_fifo_get = p_gate_target.cmd_wok.read();
172   
173//////////// RING RSP FSM (distributed) /////////////////////////
174       
175        switch( r_ring_rsp_fsm ) 
176        {
177                case RSP_IDLE:   
178#ifdef HT_DEBUG
179if( trace(sc_time_stamp()))
180std::cout << sc_time_stamp() << " -- " << m_name << " -- ring_rsp_fsm : RSP_IDLE"
181          << " -- fifo rok : " <<  m_rsp_fifo.rok()
182          << " -- ring rok : " <<  p_ring_in.rsp_w
183          << " -- ringin rsp grant : " << p_ring_in.rsp_grant
184          << " -- ringin rsp data  : " << p_ring_in.rsp_data
185          << std::endl;
186#endif   
187                        if ( p_ring_in.rsp_grant && m_rsp_fifo.rok() ) 
188
189                                r_ring_rsp_fsm = KEEP;           
190               
191                break;
192
193                case DEFAULT: 
194                       
195                        if ( m_rsp_fifo.rok()) // && p_ring_in.rsp_r )
196                        {
197#ifdef HT_DEBUG
198if( trace(sc_time_stamp()))
199std::cout << sc_time_stamp() << " -- " << m_name << " --  ring_rsp_fsm : DEFAULT " 
200          << " -- fifo_rsp_data : " << std::hex << m_rsp_fifo.read()
201          << std::endl;
202#endif
203                                rsp_fifo_get = p_ring_in.rsp_r; //true;
204                                r_ring_rsp_fsm = KEEP;
205                        }   
206                        else if ( !p_ring_in.rsp_grant )
207                                r_ring_rsp_fsm = RSP_IDLE; 
208                break;
209
210                case KEEP:   
211             
212                        if(m_rsp_fifo.rok() && p_ring_in.rsp_r) 
213                        {
214#ifdef HT_DEBUG
215if( trace(sc_time_stamp()))
216std::cout << sc_time_stamp() << " -- " << m_name << " -- ring_rsp_fsm : KEEP "
217          << " -- fifo_rok : " << m_rsp_fifo.rok()
218          << " -- ring_in_wok : " << p_ring_in.rsp_r
219          << " -- fifo_out_data : " << std::hex << m_rsp_fifo.read()
220          << std::endl;
221#endif
222                                rsp_fifo_get = true;             
223                                if ((int) ((m_rsp_fifo.read() >> 32 ) & 0x1) == 1) 
224                                {             
225                                        if ( p_ring_in.rsp_grant )
226                                                r_ring_rsp_fsm = DEFAULT; 
227                                        else   
228                                                r_ring_rsp_fsm = RSP_IDLE;               
229                                } 
230                        }           
231                break;
232
233        } // end switch ring cmd fsm
234
235/////////// RING CMD FSM ////////////////////////
236        switch( r_ring_cmd_fsm ) 
237        {
238
239                case CMD_IDLE: 
240                {
241                        vci_addr_t rtgtid = (vci_addr_t) ((p_ring_in.cmd_data >> 1) << 2);
242                        uint32_t cluster = (uint32_t) ((p_ring_in.cmd_data >> 24) & 0xF); // a voir FF
243                        bool brdcst = (IntTab(cluster) == m_ringid) && ((p_ring_in.cmd_data & 0x1) == 0X1) ;                       
244                        bool loc = !((p_ring_in.cmd_data & 0x1) == 0x1) && !m_lt[rtgtid] && !m_local;
245                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
246 
247#ifdef HT_DEBUG
248if( trace(sc_time_stamp())) {
249std::cout     << sc_time_stamp() << " -- " << m_name
250              << " -- ring_cmd_fsm -- CMD_IDLE "
251              << " -- in rok : " << p_ring_in.cmd_w
252              << " -- addr : " << std::hex << rtgtid
253              << " -- brdcst : " << brdcst
254              << " -- eop : " << eop
255              << " -- isloc : " << loc
256              << " -- in wok : " << p_ring_in.cmd_r
257              << " -- fifo wok : " << m_cmd_fifo.wok()
258//            << " -- cluster : " << std::hex << cluster
259//            << " -- intTab : " << IntTab(cluster)
260              << std::endl;
261}
262#endif
263                      if(p_ring_in.cmd_w && !eop && brdcst && !m_cmd_fifo.wok()) {
264                              r_ring_cmd_fsm = BROADCAST_0; 
265                      } 
266       
267                      if(p_ring_in.cmd_w && !eop && brdcst && m_cmd_fifo.wok()) {
268                              r_ring_cmd_fsm = BROADCAST_1;
269                              cmd_fifo_put  = true;
270                              cmd_fifo_data = p_ring_in.cmd_data;
271
272                      } 
273       
274                      if (p_ring_in.cmd_w && !eop && !brdcst && loc) {
275                              r_ring_cmd_fsm = LOCAL; 
276                              cmd_fifo_put   = m_cmd_fifo.wok();
277                              cmd_fifo_data  = p_ring_in.cmd_data; 
278
279                      } 
280       
281                      if (p_ring_in.cmd_w && !eop && !brdcst && !loc) {
282                              r_ring_cmd_fsm = RING;
283                      } 
284
285                      if (!p_ring_in.cmd_w || eop) {
286                              r_ring_cmd_fsm = CMD_IDLE;
287                      }
288
289                }
290
291                break;
292
293                case BROADCAST_0:
294
295#ifdef HT_DEBUG
296if( trace(sc_time_stamp()))
297         std::cout << sc_time_stamp() << " -- " << m_name 
298              << " -- ring_cmd_fsm -- BROADCAST_0 "
299              << " -- ringin cmd rok : " << p_ring_in.cmd_w
300              << " -- ringin cmd wok : " << p_ring_in.cmd_r
301              << " -- ringin data : " << std::hex << p_ring_in.cmd_data
302              << " -- fifo cmd wok : " << m_cmd_fifo.wok()
303              << std::endl;
304#endif
305                        if ( m_cmd_fifo.wok() )
306                        { 
307                                cmd_fifo_data = p_ring_in.cmd_data;
308                                r_ring_cmd_fsm = BROADCAST_1;
309
310                        } else {
311                                r_ring_cmd_fsm = BROADCAST_0;
312                        }
313
314                break;
315
316                case BROADCAST_1:
317                {
318#ifdef HT_DEBUG
319if( trace(sc_time_stamp()))
320         std::cout << sc_time_stamp() << " -- " << m_name
321              << " -- ring_cmd_fsm -- BROADCAST_1 "
322              << " -- ringin cmd rok : " << p_ring_in.cmd_w
323              << " -- ringin cmd wok : " << p_ring_in.cmd_r
324              << " -- ringin data : " << std::hex << p_ring_in.cmd_data
325              << " -- fifo cmd wok : " << m_cmd_fifo.wok()
326              << std::endl;
327#endif
328
329                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
330
331                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
332                        { 
333                                cmd_fifo_data = p_ring_in.cmd_data;
334                                cmd_fifo_put  = 1;
335                                r_ring_cmd_fsm = CMD_IDLE;
336
337                        }
338                        else {                   
339                                r_ring_cmd_fsm = BROADCAST_1;
340                        }
341                       
342                } 
343                break;
344
345                case LOCAL:   
346                {
347                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
348#ifdef HT_DEBUG
349if( trace(sc_time_stamp()))
350         std::cout << sc_time_stamp() << " -- " << m_name
351              << " -- ring_cmd_fsm -- LOCAL "
352              << " -- in cmd rok : " << p_ring_in.cmd_w
353              << " -- in cmd wok : " << p_ring_in.cmd_r
354              << " -- in data : " << std::hex << p_ring_in.cmd_data
355              << " -- fifo wok : " << m_cmd_fifo.wok() 
356              << " -- eop : " << eop
357              << std::endl;
358#endif
359
360                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
361                        { 
362
363                                cmd_fifo_put  = true;
364                                cmd_fifo_data = p_ring_in.cmd_data;
365                                r_ring_cmd_fsm = CMD_IDLE;
366                                       
367                        }
368                       
369                        if ( !p_ring_in.cmd_w || !m_cmd_fifo.wok() || !eop )
370                        { 
371
372                                cmd_fifo_put  = p_ring_in.cmd_w && m_cmd_fifo.wok();
373                                cmd_fifo_data = p_ring_in.cmd_data;
374                                r_ring_cmd_fsm = LOCAL;
375                                       
376                        }                       
377                } 
378                break;
379
380                case RING:   
381                { 
382 
383                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
384#ifdef HT_DEBUG
385if( trace(sc_time_stamp()))
386         std::cout << sc_time_stamp() << " -- " << m_name
387              << " -- ring_cmd_fsm -- RING "
388              << " -- in cmd rok : " << p_ring_in.cmd_w
389              << " -- in data : " << std::hex << p_ring_in.cmd_data
390              << " -- in wok : " << p_ring_in.cmd_r
391              << " -- eop : " << eop
392
393              << std::endl;
394#endif
395
396                        if ( p_ring_in.cmd_w && eop ) {       
397                                r_ring_cmd_fsm = CMD_IDLE;
398                        }
399                        else {
400                                r_ring_cmd_fsm = RING;
401                        }
402                }
403                break;
404        } // end switch cmd fsm
405
406    ////////////////////////
407    //  fifos update      //
408   ////////////////////////
409
410// local cmd fifo update
411        if ( cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
412        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
413        else if ( !cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.simple_get();
414// local rsp fifo update
415        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
416        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
417        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
418 
419}  // end Transition()
420 
421///////////////////////////////////////////////////////////////////
422void genMoore(gate_target_t &p_gate_target)
423///////////////////////////////////////////////////////////////////
424{
425        p_gate_target.cmd_w    = m_cmd_fifo.rok();
426        p_gate_target.cmd_data = (sc_uint<ring_cmd_data_size>) m_cmd_fifo.read();
427
428        p_gate_target.rsp_r= m_rsp_fifo.wok();
429} // end genMoore
430
431///////////////////////////////////////////////////////////////////
432void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out)
433///////////////////////////////////////////////////////////////////
434{
435
436        switch( r_ring_rsp_fsm ) 
437        {
438                case RSP_IDLE:
439                        p_ring_out.rsp_grant = p_ring_in.rsp_grant && !m_rsp_fifo.rok();
440
441                        p_ring_out.rsp_w    = p_ring_in.rsp_w;
442                        p_ring_out.rsp_data = p_ring_in.rsp_data;
443
444                        p_ring_out.rsp_r = p_ring_in.rsp_r;
445                break;
446
447                case DEFAULT:
448                        p_ring_out.rsp_grant = !( m_rsp_fifo.rok()); 
449
450                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
451                        p_ring_out.rsp_data =  m_rsp_fifo.read(); 
452
453                        p_ring_out.rsp_r = 1;
454                break;
455
456                case KEEP: 
457                        int rsp_fifo_eop = (int) ((m_rsp_fifo.read() >> 32) & 0x1);
458                        p_ring_out.rsp_grant = m_rsp_fifo.rok() && p_ring_in.rsp_r && (rsp_fifo_eop == 1);
459
460                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
461                        p_ring_out.rsp_data =  m_rsp_fifo.read();
462
463                        p_ring_out.rsp_r = 1;
464
465                break; 
466
467        } // end switch
468
469        p_ring_out.cmd_w    = p_ring_in.cmd_w;
470        p_ring_out.cmd_data = p_ring_in.cmd_data;
471
472        p_ring_out.cmd_grant = p_ring_in.cmd_grant;
473
474        switch( r_ring_cmd_fsm ) 
475        {
476                case CMD_IDLE:
477                {
478
479                        vci_addr_t rtgtid = (vci_addr_t) ((p_ring_in.cmd_data >> 1) << 2);
480                        uint32_t cluster = (uint32_t) ((p_ring_in.cmd_data >> 24) & 0xF); // a voir FF
481                        bool brdcst = (IntTab(cluster) == m_ringid) && ((p_ring_in.cmd_data & 0x1) == 0X1) ;
482                        bool loc = !((p_ring_in.cmd_data & 0x1) == 0x1) && !m_lt[rtgtid] && !m_local;
483                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
484
485                        if(p_ring_in.cmd_w && !eop && brdcst && !m_cmd_fifo.wok()) {
486                                p_ring_out.cmd_r = m_cmd_fifo.wok() && p_ring_in.cmd_r;
487                        } 
488                        if(p_ring_in.cmd_w && !eop && brdcst && m_cmd_fifo.wok()) {
489                                p_ring_out.cmd_r = m_cmd_fifo.wok() && p_ring_in.cmd_r;
490
491                        } 
492                        if (p_ring_in.cmd_w && !eop && !brdcst && loc) {
493                                p_ring_out.cmd_r =  m_cmd_fifo.wok();
494
495                        } 
496                        if (p_ring_in.cmd_w && !eop && !brdcst && !loc) {
497                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
498                        } 
499
500                        if (!p_ring_in.cmd_w || eop) {
501                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
502                        }
503                }
504                break;
505               case BROADCAST_0:
506                        p_ring_out.cmd_r =  m_cmd_fifo.wok() && p_ring_in.cmd_r; 
507                break;
508
509                case BROADCAST_1:
510                        p_ring_out.cmd_r =  m_cmd_fifo.wok() && p_ring_in.cmd_r; 
511                break;
512
513                case LOCAL:
514
515                        p_ring_out.cmd_r =  m_cmd_fifo.wok();   
516                break;
517
518                case RING:
519
520                        p_ring_out.cmd_r = p_ring_in.cmd_r;
521                break;
522
523        } // end switch
524
525} // end update_ring_signals
526 
527};
528
529}} // end namespace
530
531
Note: See TracBrowser for help on using the repository browser.