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

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

updating lib components

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