source: trunk/modules/half_gateway_initiator_2/caba/source/include/half_gateway_initiator_2.h @ 40

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

fixing bug : multi-inclusion control

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