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

Last change on this file since 64 was 64, checked in by nipo, 14 years ago

Use proper namespaces

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