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

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

fixing bug related to broadcast

File size: 16.6 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
159if( trace(sc_time_stamp()))
160    std::cout << sc_time_stamp() << " - " << m_name
161                                 << " - ring cmd = " << ring_cmd_fsm_state_str_ht[r_ring_cmd_fsm]
162                                 << " - ring rsp = " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm] 
163                                 << std::endl;
164#endif
165       
166//////////// VCI CMD FSM /////////////////////////
167
168        if (p_gate_target.rsp_rok.read()) {
169                rsp_fifo_data = (uint64_t) p_gate_target.rsp_data.read();
170                rsp_fifo_put =  m_rsp_fifo.wok();
171        }
172
173        bool cmd_fifo_get = p_gate_target.cmd_wok.read();
174   
175//////////// RING RSP FSM (distributed) /////////////////////////
176       
177        switch( r_ring_rsp_fsm ) 
178        {
179                case RSP_IDLE:   
180#ifdef HT_DEBUG
181if( trace(sc_time_stamp()))
182std::cout << sc_time_stamp() << " -- " << m_name << " -- ring_rsp_fsm : RSP_IDLE"
183          << " -- fifo rok : " <<  m_rsp_fifo.rok()
184          << " -- ring rok : " <<  p_ring_in.rsp_w
185          << " -- ringin rsp grant : " << p_ring_in.rsp_grant
186          << " -- fifo rsp data  : " << std::hex << m_rsp_fifo.read()
187          << std::endl;
188#endif   
189                        if ( p_ring_in.rsp_grant && m_rsp_fifo.rok() ) 
190
191                                r_ring_rsp_fsm = KEEP;           
192               
193                break;
194
195                case DEFAULT: 
196#ifdef HT_DEBUG
197if( trace(sc_time_stamp()))
198std::cout << sc_time_stamp() << " -- " << m_name << " --  ring_rsp_fsm : DEFAULT " 
199          << " -- fifo_rsp_data : " << std::hex << m_rsp_fifo.read()
200          << std::endl;
201#endif                 
202                        if ( m_rsp_fifo.rok()) // && p_ring_in.rsp_r )
203                        {
204
205                                rsp_fifo_get = p_ring_in.rsp_r; //true;
206                                r_ring_rsp_fsm = KEEP;
207                        }   
208                        else if ( !p_ring_in.rsp_grant )
209                                r_ring_rsp_fsm = RSP_IDLE; 
210                break;
211
212                case KEEP:   
213             
214                        if(m_rsp_fifo.rok() && p_ring_in.rsp_r) 
215                        {
216#ifdef HT_DEBUG
217if( trace(sc_time_stamp()))
218std::cout << sc_time_stamp() << " -- " << m_name << " -- ring_rsp_fsm : KEEP "
219          << " -- fifo_rok : " << m_rsp_fifo.rok()
220          << " -- ring_in_wok : " << p_ring_in.rsp_r
221          << " -- fifo_out_data : " << std::hex << m_rsp_fifo.read()
222          << std::endl;
223#endif
224                                rsp_fifo_get = true;             
225                                if ((int) ((m_rsp_fifo.read() >> 32 ) & 0x1) == 1) 
226                                {             
227                                        if ( p_ring_in.rsp_grant )
228                                                r_ring_rsp_fsm = DEFAULT; 
229                                        else   
230                                                r_ring_rsp_fsm = RSP_IDLE;               
231                                } 
232                        }           
233                break;
234
235        } // end switch ring cmd fsm
236
237/////////// RING CMD FSM ////////////////////////
238        switch( r_ring_cmd_fsm ) 
239        {
240
241                case CMD_IDLE: 
242                {
243                        vci_addr_t rtgtid = (vci_addr_t) ((p_ring_in.cmd_data >> 1) << 2);
244                        int cluster =  (int) (p_ring_in.cmd_data >> 24) & 0xF; // a voir FF
245                        bool brdcst = (IntTab(cluster) == m_ringid) && ((p_ring_in.cmd_data & 0x1) == 0X1) ;                       
246                        bool loc = !((p_ring_in.cmd_data & 0x1) == 0x1) && !m_lt[rtgtid] && !m_local;
247                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
248 
249#ifdef HT_DEBUG
250if( trace(sc_time_stamp())) {
251std::cout     << sc_time_stamp() << " -- " << m_name
252              << " -- ring_cmd_fsm -- CMD_IDLE "
253              << " - in rok : " << p_ring_in.cmd_w
254              << " - addr : " << std::hex << rtgtid
255              << " - brdcst : " << brdcst
256              << " - eop : " << eop
257              << " - isloc : " << loc
258              << " - in wok : " << p_ring_in.cmd_r
259              << " - fifo wok : " << m_cmd_fifo.wok()
260              << " - ringid  : " << m_ringid
261              << " - cluster : " << cluster
262              << " - intTab : " << IntTab(cluster)
263              << std::endl;
264}
265#endif
266                      if(p_ring_in.cmd_w && !eop && brdcst && !m_cmd_fifo.wok()) {
267                              r_ring_cmd_fsm = BROADCAST_0; 
268                      } 
269       
270                      if(p_ring_in.cmd_w && !eop && brdcst && m_cmd_fifo.wok()) {
271                              r_ring_cmd_fsm = BROADCAST_1;
272                              cmd_fifo_put  = true;
273                              cmd_fifo_data = p_ring_in.cmd_data;
274
275                      } 
276       
277                      if (p_ring_in.cmd_w && !eop && !brdcst && loc) {
278                              r_ring_cmd_fsm = LOCAL; 
279                              cmd_fifo_put   = m_cmd_fifo.wok();
280                              cmd_fifo_data  = p_ring_in.cmd_data; 
281
282                      } 
283       
284                      if (p_ring_in.cmd_w && !eop && !brdcst && !loc) {
285                              r_ring_cmd_fsm = RING;
286                      } 
287
288                      if (!p_ring_in.cmd_w || eop) {
289                              r_ring_cmd_fsm = CMD_IDLE;
290                      }
291
292                }
293
294                break;
295
296                case BROADCAST_0:
297
298#ifdef HT_DEBUG
299if( trace(sc_time_stamp()))
300         std::cout << sc_time_stamp() << " -- " << m_name 
301              << " -- ring_cmd_fsm -- BROADCAST_0 "
302              << " -- ringin cmd rok : " << p_ring_in.cmd_w
303              << " -- ringin cmd wok : " << p_ring_in.cmd_r
304              << " -- ringin data : " << std::hex << p_ring_in.cmd_data
305              << " -- fifo cmd wok : " << m_cmd_fifo.wok()
306              << std::endl;
307#endif
308                        if ( m_cmd_fifo.wok() )
309                        { 
310                                cmd_fifo_data = p_ring_in.cmd_data;
311                                r_ring_cmd_fsm = BROADCAST_1;
312
313                        } else {
314                                r_ring_cmd_fsm = BROADCAST_0;
315                        }
316
317                break;
318
319                case BROADCAST_1:
320                {
321#ifdef HT_DEBUG
322if( trace(sc_time_stamp()))
323         std::cout << sc_time_stamp() << " -- " << m_name
324              << " -- ring_cmd_fsm -- BROADCAST_1 "
325              << " -- ringin cmd rok : " << p_ring_in.cmd_w
326              << " -- ringin cmd wok : " << p_ring_in.cmd_r
327              << " -- ringin data : " << std::hex << p_ring_in.cmd_data
328              << " -- fifo cmd wok : " << m_cmd_fifo.wok()
329              << std::endl;
330#endif
331
332                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
333
334                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
335                        { 
336                                cmd_fifo_data = p_ring_in.cmd_data;
337                                cmd_fifo_put  = 1;
338                                r_ring_cmd_fsm = CMD_IDLE;
339
340                        }
341                        else {                   
342                                r_ring_cmd_fsm = BROADCAST_1;
343                        }
344                       
345                } 
346                break;
347
348                case LOCAL:   
349                {
350                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
351#ifdef HT_DEBUG
352if( trace(sc_time_stamp()))
353         std::cout << sc_time_stamp() << " -- " << m_name
354              << " -- ring_cmd_fsm -- LOCAL "
355              << " -- in cmd rok : " << p_ring_in.cmd_w
356              << " -- in cmd wok : " << p_ring_in.cmd_r
357              << " -- in data : " << std::hex << p_ring_in.cmd_data
358              << " -- fifo wok : " << m_cmd_fifo.wok() 
359              << " -- eop : " << eop
360              << std::endl;
361#endif
362
363                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
364                        { 
365
366                                cmd_fifo_put  = true;
367                                cmd_fifo_data = p_ring_in.cmd_data;
368                                r_ring_cmd_fsm = CMD_IDLE;
369                                       
370                        }
371                       
372                        if ( !p_ring_in.cmd_w || !m_cmd_fifo.wok() || !eop )
373                        { 
374
375                                cmd_fifo_put  = p_ring_in.cmd_w && m_cmd_fifo.wok();
376                                cmd_fifo_data = p_ring_in.cmd_data;
377                                r_ring_cmd_fsm = LOCAL;
378                                       
379                        }                       
380                } 
381                break;
382
383                case RING:   
384                { 
385 
386                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
387#ifdef HT_DEBUG
388if( trace(sc_time_stamp()))
389         std::cout << sc_time_stamp() << " -- " << m_name
390              << " -- ring_cmd_fsm -- RING "
391              << " -- in cmd rok : " << p_ring_in.cmd_w
392              << " -- in data : " << std::hex << p_ring_in.cmd_data
393              << " -- in wok : " << p_ring_in.cmd_r
394              << " -- eop : " << eop
395
396              << std::endl;
397#endif
398
399                        if ( p_ring_in.cmd_w && eop ) {       
400                                r_ring_cmd_fsm = CMD_IDLE;
401                        }
402                        else {
403                                r_ring_cmd_fsm = RING;
404                        }
405                }
406                break;
407        } // end switch cmd fsm
408
409    ////////////////////////
410    //  fifos update      //
411   ////////////////////////
412
413// local cmd fifo update
414        if ( cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
415        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
416        else if ( !cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.simple_get();
417// local rsp fifo update
418        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
419        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
420        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
421 
422}  // end Transition()
423 
424///////////////////////////////////////////////////////////////////
425void genMoore(gate_target_t &p_gate_target)
426///////////////////////////////////////////////////////////////////
427{
428        p_gate_target.cmd_w    = m_cmd_fifo.rok();
429        p_gate_target.cmd_data = (sc_uint<ring_cmd_data_size>) m_cmd_fifo.read();
430
431        p_gate_target.rsp_r= m_rsp_fifo.wok();
432
433} // end genMoore
434
435///////////////////////////////////////////////////////////////////
436void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out)
437///////////////////////////////////////////////////////////////////
438{
439
440        switch( r_ring_rsp_fsm ) 
441        {
442                case RSP_IDLE:
443                        p_ring_out.rsp_grant = p_ring_in.rsp_grant && !m_rsp_fifo.rok();
444
445                        p_ring_out.rsp_w    = p_ring_in.rsp_w;
446                        p_ring_out.rsp_data = p_ring_in.rsp_data;
447
448                        p_ring_out.rsp_r = p_ring_in.rsp_r;
449                break;
450
451                case DEFAULT:
452                        p_ring_out.rsp_grant = !( m_rsp_fifo.rok()); 
453
454                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
455                        p_ring_out.rsp_data =  m_rsp_fifo.read(); 
456
457                        p_ring_out.rsp_r = 1;
458                break;
459
460                case KEEP: 
461                        int rsp_fifo_eop = (int) ((m_rsp_fifo.read() >> 32) & 0x1);
462                        p_ring_out.rsp_grant = m_rsp_fifo.rok() && p_ring_in.rsp_r && (rsp_fifo_eop == 1);
463
464                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
465                        p_ring_out.rsp_data =  m_rsp_fifo.read();
466
467                        p_ring_out.rsp_r = 1;
468
469                break; 
470
471        } // end switch
472
473        p_ring_out.cmd_w    = p_ring_in.cmd_w;
474        p_ring_out.cmd_data = p_ring_in.cmd_data;
475
476        p_ring_out.cmd_grant = p_ring_in.cmd_grant;
477
478        switch( r_ring_cmd_fsm ) 
479        {
480                case CMD_IDLE:
481                {
482
483                        vci_addr_t rtgtid = (vci_addr_t) ((p_ring_in.cmd_data >> 1) << 2);
484                        int cluster = (int) (p_ring_in.cmd_data >> 24) & 0xF; // a voir FF
485                        bool brdcst = (IntTab(cluster) == m_ringid) && ((p_ring_in.cmd_data & 0x1) == 0X1) ;
486                        bool loc = !((p_ring_in.cmd_data & 0x1) == 0x1) && !m_lt[rtgtid] && !m_local;
487                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
488
489                        if(p_ring_in.cmd_w && !eop && brdcst && !m_cmd_fifo.wok()) {
490                                p_ring_out.cmd_r = m_cmd_fifo.wok() && p_ring_in.cmd_r;
491                        } 
492                        if(p_ring_in.cmd_w && !eop && brdcst && m_cmd_fifo.wok()) {
493                                p_ring_out.cmd_r = m_cmd_fifo.wok() && p_ring_in.cmd_r;
494
495                        } 
496                        if (p_ring_in.cmd_w && !eop && !brdcst && loc) {
497                                p_ring_out.cmd_r =  m_cmd_fifo.wok();
498
499                        } 
500                        if (p_ring_in.cmd_w && !eop && !brdcst && !loc) {
501                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
502                        } 
503
504                        if (!p_ring_in.cmd_w || eop) {
505                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
506                        }
507                }
508                break;
509               case BROADCAST_0:
510                        p_ring_out.cmd_r =  m_cmd_fifo.wok() && p_ring_in.cmd_r; 
511                break;
512
513                case BROADCAST_1:
514                        p_ring_out.cmd_r =  m_cmd_fifo.wok() && p_ring_in.cmd_r; 
515                break;
516
517                case LOCAL:
518
519                        p_ring_out.cmd_r =  m_cmd_fifo.wok();   
520                break;
521
522                case RING:
523
524                        p_ring_out.cmd_r = p_ring_in.cmd_r;
525                break;
526
527        } // end switch
528
529} // end update_ring_signals
530 
531};
532
533}} // end namespace
534
535
Note: See TracBrowser for help on using the repository browser.