source: trunk/modules/half_gateway_initiator_2/caba/source/include/half_gateway_initiator_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: 12.0 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
148    std::cout << "--------------------------------------------" << std::endl;
149    std::cout << " ring cmd fsm = " << ring_cmd_fsm_state_str_hi[r_ring_cmd_fsm] << std::endl;
150    std::cout << " ring rsp fsm = " << ring_rsp_fsm_state_str_hi[r_ring_rsp_fsm] << std::endl;
151#endif
152//////////// VCI CMD FSM /////////////////////////
153
154        if (p_gate_initiator.cmd_rok.read()) {
155                cmd_fifo_data = (uint64_t) p_gate_initiator.cmd_data.read();
156                cmd_fifo_put =  m_cmd_fifo.wok();
157        }
158
159        bool rsp_fifo_get = p_gate_initiator.rsp_wok.read();
160
161//////////// RING CMD FSM /////////////////////////
162        switch( r_ring_cmd_fsm ) 
163        {
164                case CMD_IDLE:   
165#ifdef HI_DEBUG
166if( trace(sc_time_stamp()))
167std::cout << sc_time_stamp() << " -- " << m_name << " -- r_ring_cmd_fsm : CMD_IDLE "
168          << " -- fifo ROK : " << m_cmd_fifo.rok()
169          << " -- in grant : " << p_ring_in.cmd_grant
170          << " -- fifo _data : " << std::hex << m_cmd_fifo.read()
171          << std::endl;
172#endif
173   
174                        if ( p_ring_in.cmd_grant && m_cmd_fifo.rok() ) 
175                        {
176// debug above is here
177                                r_ring_cmd_fsm = KEEP; 
178                        }
179                break;
180
181                case DEFAULT: 
182#ifdef HI_DEBUG
183if( trace(sc_time_stamp()))
184std::cout << sc_time_stamp() << " -- " << m_name << " -- r_ring_cmd_fsm : DEFAULT "
185          << " -- fifo ROK : " << m_cmd_fifo.rok()
186          << " -- in grant : " << p_ring_in.cmd_grant
187          << " -- fifo _data : " << std::hex << m_cmd_fifo.read()
188          << std::endl;
189#endif
190       
191                        if ( m_cmd_fifo.rok() ) 
192                        {
193// debug above is here
194                                cmd_fifo_get = p_ring_in.cmd_r; 
195                                r_ring_cmd_fsm = KEEP;             
196                        }   
197                        else if ( !p_ring_in.cmd_grant )
198                                r_ring_cmd_fsm = CMD_IDLE; 
199                break;
200
201                case KEEP:   
202 #ifdef HI_DEBUG
203if( trace(sc_time_stamp()))
204std::cout << sc_time_stamp() << " -- " << m_name << " -- r_ring_cmd_fsm : KEEP "
205          << " -- fifo_rok : " << m_cmd_fifo.rok()
206          << " -- in grant : " << p_ring_in.cmd_grant
207          << " -- ring_in_wok : " << p_ring_in.cmd_r
208          << " -- fifo_out_data : " << std::hex << m_cmd_fifo.read()
209          << std::endl;
210#endif
211                         
212                        if(m_cmd_fifo.rok() && p_ring_in.cmd_r ) 
213                        {
214// debug above is here
215                                cmd_fifo_get = true; 
216                                if (((int) (m_cmd_fifo.read() >> (ring_cmd_data_size - 1) ) & 0x1) == 1)  // 39
217                                { 
218                                        if ( p_ring_in.cmd_grant )
219                                                r_ring_cmd_fsm = DEFAULT; 
220                                        else   
221                                                r_ring_cmd_fsm = CMD_IDLE; 
222                                }       
223                        }     
224                break;
225
226        } // end switch ring cmd fsm
227 
228/////////// RING RSP FSM ////////////////////////
229   
230        switch( r_ring_rsp_fsm ) 
231        {
232                case RSP_IDLE: 
233                {
234                        int rsrcid   = (int)  ((p_ring_in.rsp_data >> 12 ) & 0x3FFF);
235                        bool islocal = (m_lt[rsrcid] && m_local) || (!m_lt[rsrcid] && !m_local);
236                        bool reop     = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
237
238#ifdef HI_DEBUG
239if( trace(sc_time_stamp()))
240        std::cout << sc_time_stamp() << " -- " << m_name 
241              << " -- ring_rsp_fsm -- RSP_IDLE "
242              << " -- islocal : " << islocal
243              << " -- eop : " << reop
244              << " -- rsrcid : " << std::hex << rsrcid
245              << " -- in rok : " << p_ring_in.rsp_w
246              << " -- in wok : " << p_ring_in.rsp_r
247              << " -- fifo wok : " <<  m_rsp_fifo.wok()         
248              << std::endl;
249#endif
250                        if (p_ring_in.rsp_w  &&  !reop && islocal) 
251                        {   
252                                r_ring_rsp_fsm = LOCAL;
253                                rsp_fifo_put  = m_rsp_fifo.wok();
254                                rsp_fifo_data = p_ring_in.rsp_data;
255                        }
256                        if (p_ring_in.rsp_w  &&  !reop && !islocal) 
257                        {
258                                r_ring_rsp_fsm = RING; 
259                        }
260                        if (!p_ring_in.rsp_w  || reop ) 
261                        {                       
262                                r_ring_rsp_fsm = RSP_IDLE;
263                        } 
264                }
265                break;
266
267                case LOCAL:
268                {
269
270                        bool reop     = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
271#ifdef HI_DEBUG
272if( trace(sc_time_stamp()))
273         std::cout << sc_time_stamp() << " -- " << m_name 
274              << " -- ring_rsp_fsm -- LOCAL "
275              << " -- in rok : " << p_ring_in.rsp_w
276              << " -- fifo wok : " <<  m_rsp_fifo.wok()   
277              << " -- in data : " << std::hex << p_ring_in.rsp_data
278              << " -- eop : " << reop
279              << std::endl;
280#endif
281
282
283                        if (p_ring_in.rsp_w && m_rsp_fifo.wok() && reop)         
284                        {
285
286                                rsp_fifo_put  = true;
287                                rsp_fifo_data = p_ring_in.rsp_data;
288                                r_ring_rsp_fsm = RSP_IDLE;             
289                        }
290                        if (!p_ring_in.rsp_w || !m_rsp_fifo.wok() || !reop)         
291                        {
292
293                                rsp_fifo_put  = p_ring_in.rsp_w && m_rsp_fifo.wok();
294                                rsp_fifo_data = p_ring_in.rsp_data;
295                                r_ring_rsp_fsm = LOCAL;             
296                        }
297                } 
298                break;
299
300                case RING:     
301                {
302                        bool reop     = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
303
304#ifdef I_DEBUG
305if( trace(sc_time_stamp()))
306         std::cout << sc_time_stamp() << " -- " << m_name 
307              << " -- ring_rsp_fsm -- RING "
308              << " -- in rok : " << p_ring_in.rsp_w
309              << " -- in wok : " <<  p_ring_in.rsp_r   
310              << " -- in data : " << std::hex << p_ring_in.rsp_data
311              << " -- eop : " << reop   
312              << std::endl;
313#endif
314
315
316                        if (p_ring_in.rsp_w && reop)
317                        {
318                                r_ring_rsp_fsm = RSP_IDLE; 
319                        }
320                        else
321                        {
322                                r_ring_rsp_fsm = RING;
323                        }
324                }
325                break;
326
327        } // end switch rsp fsm
328     
329    ////////////////////////
330    //  fifos update      //
331   ////////////////////////
332
333// local cmd fifo update
334        if (  cmd_fifo_put &&  cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
335        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
336        else if ( !cmd_fifo_put &&  cmd_fifo_get ) m_cmd_fifo.simple_get();
337       
338// local rsp fifo update
339        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
340        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
341        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
342     
343}  // end Transition()
344
345///////////////////////////////////////////////////////////////////
346void genMoore(gate_initiator_t &p_gate_initiator)
347///////////////////////////////////////////////////////////////////
348{
349        p_gate_initiator.rsp_w    = m_rsp_fifo.rok();
350        p_gate_initiator.rsp_data = m_rsp_fifo.read();
351
352        p_gate_initiator.cmd_r= m_cmd_fifo.wok();
353
354} // end genMoore
355
356///////////////////////////////////////////////////////////////////
357void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out)
358///////////////////////////////////////////////////////////////////
359{   
360        switch( r_ring_cmd_fsm ) 
361        {
362                case CMD_IDLE:
363                        p_ring_out.cmd_grant = p_ring_in.cmd_grant && !m_cmd_fifo.rok();
364
365                        p_ring_out.cmd_r     = p_ring_in.cmd_r;
366
367                        p_ring_out.cmd_w     = p_ring_in.cmd_w;
368                        p_ring_out.cmd_data  = p_ring_in.cmd_data;
369                break;
370       
371                case DEFAULT:       
372                        p_ring_out.cmd_grant = !( m_cmd_fifo.rok()); 
373
374                        p_ring_out.cmd_r    = 1;
375
376                        p_ring_out.cmd_w    =  m_cmd_fifo.rok();
377                        p_ring_out.cmd_data =  m_cmd_fifo.read();
378                break;
379       
380                case KEEP: 
381                        int cmd_fifo_eop = (int) ((m_cmd_fifo.read() >> (ring_cmd_data_size - 1)) & 0x1) ; //39
382                        p_ring_out.cmd_grant = m_cmd_fifo.rok() && p_ring_in.cmd_r && (cmd_fifo_eop == 1);
383
384                        p_ring_out.cmd_r    = 1;       
385
386                        p_ring_out.cmd_w    =  m_cmd_fifo.rok();
387                        p_ring_out.cmd_data =  m_cmd_fifo.read();
388                break;
389       
390        } // end switch
391
392        p_ring_out.rsp_grant = p_ring_in.rsp_grant;
393
394        p_ring_out.rsp_w    = p_ring_in.rsp_w;
395        p_ring_out.rsp_data = p_ring_in.rsp_data;
396
397        switch( r_ring_rsp_fsm ) 
398        {
399                case RSP_IDLE: 
400                {
401                        int rsrcid   = (int)  ((p_ring_in.rsp_data >> 12 ) & 0x3FFF);
402                        bool islocal = (m_lt[rsrcid] && m_local) || (!m_lt[rsrcid] && !m_local);
403                        bool reop     = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
404
405                        if(p_ring_in.rsp_w && !reop && islocal) {
406                                p_ring_out.rsp_r = m_rsp_fifo.wok();
407                        }
408                        if(p_ring_in.rsp_w && !reop && !islocal) {
409                                p_ring_out.rsp_r = p_ring_in.rsp_r;
410                        }
411                        if(!p_ring_in.rsp_w || reop)  {
412                                p_ring_out.rsp_r = p_ring_in.rsp_r;
413                        }
414 
415                }
416                break;
417       
418                case LOCAL:
419                        p_ring_out.rsp_r = m_rsp_fifo.wok();
420                break;
421       
422                case RING:
423                        p_ring_out.rsp_r = p_ring_in.rsp_r;
424                break;   
425        } // end switch
426
427
428} // end update_ring_signals
429
430};
431
432}} // end namespace
433
434
Note: See TracBrowser for help on using the repository browser.