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

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

new ring components for systemcass

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