source: branches/v5/modules/dspin_simple_ring_fast_c/caba/source/include/dspin_simple_ring_target_fast_c.h @ 326

Last change on this file since 326 was 326, checked in by simerabe, 11 years ago

introducing 2 new components : simple and local ring interconnect using dspin interface

  • Property svn:executable set to *
File size: 15.8 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#ifndef SOCLIB_CABA_DSPIN_SIMPLE_RING_TARGET_FAST_C_H
28#define SOCLIB_CABA_DSPIN_SIMPLE_RING_TARGET_FAST_C_H
29
30#include "generic_fifo.h"
31#include "mapping_table.h"
32#include "ring_signals_fast.h"
33#include "dspin_interface.h"
34
35#define T_DEBUG
36
37namespace soclib { namespace caba {
38
39namespace {
40
41const char *ring_rsp_fsm_state_str_st[] = {
42                "RSP_IDLE",
43                "DEFAULT",
44                "KEEP",
45        };
46
47#ifdef T_DEBUG
48
49const char *ring_cmd_fsm_state_str_st[] = {
50        "CMD_IDLE",
51        "LOCAL",
52        "RING",
53};
54#endif
55} // end namespace
56
57template<typename vci_param, int ring_cmd_data_size, int ring_rsp_data_size>
58class DspinSimpleRingTargetFastC
59{
60
61typedef typename vci_param::fast_addr_t vci_addr_t;
62typedef SimpleRingSignals ring_signal_t; 
63typedef DspinOutput<ring_cmd_data_size >  cmd_out_t;
64typedef DspinInput<ring_rsp_data_size >   rsp_in_t;
65
66private:
67        enum ring_cmd_fsm_state_e {
68                CMD_IDLE,        // waiting for first flit of a command packet
69                LOCAL,           // next flit of a local cmd packet
70                RING,            // next flit of a ring cmd packet
71        };
72       
73        enum ring_rsp_fsm_state_e {
74                RSP_IDLE,           
75                DEFAULT,       
76                KEEP,               
77        };
78       
79        // structural parameters
80        std::string   m_name;
81        bool          m_alloc_target;
82
83        // internal fifos
84        GenericFifo<uint64_t > m_cmd_fifo;     // fifo for the local command paquet
85        GenericFifo<uint64_t > m_rsp_fifo;     // fifo for the local response paquet
86
87        // routing table
88        soclib::common::AddressDecodingTable<vci_addr_t, int> m_rt;
89        // locality table
90        soclib::common::AddressDecodingTable<vci_addr_t, bool> m_lt;
91
92        int           m_tgtid;
93 
94        // internal registers
95        sc_core::sc_signal<uint32_t> r_ring_cmd_fsm;        // ring command packet FSM
96        sc_core::sc_signal<uint32_t> r_ring_rsp_fsm;        // ring response packet FSM
97       
98public :
99
100#define __renRegTgtS(x) x((((std::string) name)+"_" #x).c_str())
101
102DspinSimpleRingTargetFastC(
103        const char *name,
104        bool       alloc_target,
105        const int  &wrapper_fifo_depth,
106        const soclib::common::MappingTable &mt,
107        const soclib::common::IntTab &ringid,
108        const int  &tgtid)
109     :  m_name(name),
110        m_alloc_target(alloc_target),
111        m_cmd_fifo(((std::string) name)+"m_cmd_fifo", wrapper_fifo_depth),
112        m_rsp_fifo(((std::string) name)+"m_rsp_fifo", wrapper_fifo_depth),
113        m_rt(mt.getRoutingTable<typename vci_param::fast_addr_t>(ringid)),
114        m_lt(mt.getLocalityTable<typename vci_param::fast_addr_t>(ringid)),
115        m_tgtid(tgtid),
116        __renRegTgtS(r_ring_cmd_fsm),
117        __renRegTgtS(r_ring_rsp_fsm)
118
119{} //  end constructor
120
121void reset()
122{
123        if(m_alloc_target)
124                r_ring_rsp_fsm = DEFAULT;
125        else
126                r_ring_rsp_fsm = RSP_IDLE;
127       
128        r_ring_cmd_fsm = CMD_IDLE;
129        m_cmd_fifo.init();
130        m_rsp_fifo.init();   
131}
132void transition(const cmd_out_t &p_cmd_out, const rsp_in_t &p_rsp_in, const ring_signal_t p_ring_in, bool &tgt_cmd_val, rsp_str &tgt_rsp)
133{
134
135        bool      cmd_fifo_put = false;
136        uint64_t  cmd_fifo_data = 0;
137       
138        bool      rsp_fifo_get = false;
139        bool      rsp_fifo_put = false;
140        uint64_t  rsp_fifo_data = 0;
141
142
143//////////// DSPIN FIFOS ACCESS /////////////////////////
144
145        if (p_rsp_in.write) {
146#ifdef T_DEBUG
147std::cout << sc_time_stamp() << " -- " << m_name << " -- DSPIN FIFO" 
148          << " -- rsp in rok : " << p_rsp_in.write
149          << " --  in data  : " << std::hex << p_rsp_in.data.read()
150          << " --  fifo wok : "  << m_rsp_fifo.wok()         
151          << std::endl;
152#endif
153
154                rsp_fifo_data = (uint64_t) p_rsp_in.data.read();
155                rsp_fifo_put =  m_rsp_fifo.wok();
156        }
157
158        bool cmd_fifo_get = p_cmd_out.read;   
159//////////// RING RSP FSM  /////////////////////////
160       
161        switch( r_ring_rsp_fsm ) 
162        {
163                case RSP_IDLE:   
164#ifdef T_DEBUG
165if(m_rsp_fifo.rok())
166    std::cout << std::dec << sc_time_stamp() << " - " << m_name
167                          << " - r_ring_rsp_fsm = " << ring_rsp_fsm_state_str_st[r_ring_rsp_fsm]
168                          << " -- in rsp grant : " << p_ring_in.rsp_grant
169                          << " -- in wok : " <<  p_ring_in.rsp_r
170                          << " -- fifo rok : " <<  m_rsp_fifo.rok()
171                          << " -- fifo data  : " <<  std::hex << m_rsp_fifo.read()
172                          << std::endl; 
173#endif   
174                        if ( p_ring_in.rsp_grant && m_rsp_fifo.rok() ) 
175
176                                r_ring_rsp_fsm = KEEP;           
177               
178                break;
179
180                case DEFAULT: 
181                { 
182#ifdef T_DEBUG
183if(m_rsp_fifo.rok())
184    std::cout << std::dec << sc_time_stamp() << " - " << m_name
185                          << " - r_ring_rsp_fsm = " << ring_rsp_fsm_state_str_st[r_ring_rsp_fsm]
186                          << " -- in rsp grant : " << p_ring_in.rsp_grant
187                          << " -- in wok : " <<  p_ring_in.rsp_r
188                          << " -- fifo rok : " <<  m_rsp_fifo.rok()
189                          << " -- fifo data  : " <<  std::hex << m_rsp_fifo.read()
190                          << std::endl; 
191#endif
192                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
193
194                        if ( m_rsp_fifo.rok() && eop && p_ring_in.rsp_r ) 
195                        {
196                                rsp_fifo_get = true;
197                                if ( p_ring_in.rsp_grant )
198                                        r_ring_rsp_fsm = DEFAULT;
199                                else
200                                        r_ring_rsp_fsm = RSP_IDLE;
201                        } 
202 
203                        if ( m_rsp_fifo.rok() && (!eop || !p_ring_in.rsp_r)) 
204                        {
205                                rsp_fifo_get = p_ring_in.rsp_r;
206                                r_ring_rsp_fsm = KEEP;
207                        }
208
209                        if ( !m_rsp_fifo.rok() && !p_ring_in.rsp_grant )
210                                r_ring_rsp_fsm = RSP_IDLE; 
211
212                        if ( !m_rsp_fifo.rok() && p_ring_in.rsp_grant )
213                                r_ring_rsp_fsm = DEFAULT;
214                }
215                break;
216
217                case KEEP:   
218#ifdef T_DEBUG
219if(m_rsp_fifo.rok())
220    std::cout << std::dec << sc_time_stamp() << " - " << m_name
221                          << " - r_ring_rsp_fsm = " << ring_rsp_fsm_state_str_st[r_ring_rsp_fsm]
222                          << " -- in rsp grant : " << p_ring_in.rsp_grant
223                          << " -- in wok : " <<  p_ring_in.rsp_r
224                          << " -- fifo rok : " <<  m_rsp_fifo.rok()
225                          << " -- fifo data  : " <<  std::hex << m_rsp_fifo.read()
226                          << std::endl; 
227#endif             
228                        if(m_rsp_fifo.rok() && p_ring_in.rsp_r) 
229                        {
230                                bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
231
232                                rsp_fifo_get = true;             
233
234                                if (eop) 
235                                {             
236                                        if ( p_ring_in.rsp_grant )
237                                                r_ring_rsp_fsm = DEFAULT; 
238                                        else   
239                                                r_ring_rsp_fsm = RSP_IDLE;               
240                                } 
241                        }           
242                break;
243
244        } // end switch ring cmd fsm
245
246/////////// RING CMD FSM ////////////////////////
247        switch( r_ring_cmd_fsm ) 
248        {
249
250                case CMD_IDLE: 
251                { // for variable scope
252#ifdef T_DEBUG
253if(p_ring_in.cmd_w)
254    std::cout << std::dec << sc_time_stamp() << " - " << m_name
255                          << " - r_ring_cmd_fsm = " << ring_cmd_fsm_state_str_st[r_ring_cmd_fsm]
256                          << " - in gnt : " << p_ring_in.cmd_grant
257                          << " - in rok : " << p_ring_in.cmd_w
258                          << " - in data : " << std::hex << p_ring_in.cmd_data
259                          << " - in wok : " << p_ring_in.cmd_r
260                          << " - fifo wok : " << m_cmd_fifo.wok()
261                          << std::endl;
262#endif
263                       
264                        vci_addr_t rtgtid = (vci_addr_t) (((p_ring_in.cmd_data >> (ring_cmd_data_size-vci_param::S-1)) << (vci_param::N-vci_param::S)));
265                        bool islocalm = m_lt[rtgtid]  && (m_rt[rtgtid] == m_tgtid);              // multicast
266                        bool isbrdcst = (p_ring_in.cmd_data & 0x1) == 0x1;
267                        bool islocalb = ( (int) ((p_ring_in.cmd_data >> 1 ) & 0xF) == m_tgtid); // broadcast
268                        bool eop      = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1); 
269
270                        if(p_ring_in.cmd_w)
271                        {
272#ifdef T_DEBUG
273    std::cout << std::dec << sc_time_stamp() << " - " << m_name
274                          << " - islocalm : " << islocalm
275                          << " - isbrdcst : " << isbrdcst
276                          << " - islocalb : " << islocalb
277                          << " - eop : " << eop
278                          << std::endl;
279#endif
280                                if ( (isbrdcst && islocalb) || (!isbrdcst && islocalm) )
281                                {
282                                       
283                                        cmd_fifo_put   = m_cmd_fifo.wok();
284                                        cmd_fifo_data  = p_ring_in.cmd_data;
285
286                                        if (eop && m_cmd_fifo.wok())
287                                                r_ring_cmd_fsm = CMD_IDLE;
288                                        else
289                                                r_ring_cmd_fsm = LOCAL;
290       
291                                }
292
293                                else
294                                {
295                                        if (eop && p_ring_in.cmd_r)
296                                                r_ring_cmd_fsm = CMD_IDLE;
297                                        else
298                                                r_ring_cmd_fsm = RING;
299                                }
300                        }
301                        else
302                                r_ring_cmd_fsm = CMD_IDLE;
303                }
304
305                break;
306
307                case LOCAL:   
308                {
309#ifdef T_DEBUG
310if(p_ring_in.cmd_w)
311    std::cout << std::dec << sc_time_stamp() << " - " << m_name
312                          << " - r_ring_cmd_fsm = " << ring_cmd_fsm_state_str_st[r_ring_cmd_fsm]
313                          << " - in rok : " << p_ring_in.cmd_w
314                          << " - in gnt : " << p_ring_in.cmd_grant
315                          << " - in data : " << std::hex << p_ring_in.cmd_data
316                          << " - in wok : " << p_ring_in.cmd_r
317                          << " - fifo wok : " << m_cmd_fifo.wok()
318                          << std::endl;
319#endif
320                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
321
322
323                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
324                        { 
325
326                                cmd_fifo_put  = true;
327                                cmd_fifo_data = p_ring_in.cmd_data;
328                                r_ring_cmd_fsm = CMD_IDLE;
329                                       
330                        }
331                       
332                        else // !p_ring_in.cmd_w || !m_cmd_fifo.wok() || !eop
333                        { 
334
335                                cmd_fifo_put  = p_ring_in.cmd_w && m_cmd_fifo.wok();
336                                cmd_fifo_data = p_ring_in.cmd_data;
337                                r_ring_cmd_fsm = LOCAL;
338                                       
339                        }                       
340                } 
341                break;
342
343                case RING:   
344                { 
345 #ifdef T_DEBUG
346if(p_ring_in.cmd_w)
347    std::cout << std::dec << sc_time_stamp() << " - " << m_name
348                          << " - r_ring_cmd_fsm = " << ring_cmd_fsm_state_str_st[r_ring_cmd_fsm]
349                          << " - in rok : " << p_ring_in.cmd_w
350                          << " - in gnt : " << p_ring_in.cmd_grant
351                          << " - in data : " << std::hex << p_ring_in.cmd_data
352                          << " - in wok : " << p_ring_in.cmd_r
353                          << " - fifo wok : " << m_cmd_fifo.wok()
354                          << std::endl;
355#endif
356                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
357
358                        if ( p_ring_in.cmd_w && eop  && p_ring_in.cmd_r) {       
359                                r_ring_cmd_fsm = CMD_IDLE;
360                        }
361                        else {
362                                r_ring_cmd_fsm = RING;
363                        }
364                }
365                break;
366
367        } // end switch cmd fsm
368
369    ////////////////////////
370    //  fifos update      //
371   ////////////////////////
372//-- to keep trace on ring traffic : a valid command is received by the target
373        tgt_rsp.rspval  = rsp_fifo_get;
374        tgt_rsp.flit    = m_rsp_fifo.read();
375        tgt_rsp.state   = ring_rsp_fsm_state_str_st[r_ring_rsp_fsm];
376
377        tgt_cmd_val = cmd_fifo_put;
378        //tgt_rsp_val = rsp_fifo_get;
379// local cmd fifo update
380        if ( cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
381        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
382        else if ( !cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.simple_get();
383// local rsp fifo update
384        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
385        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
386        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
387 
388}  // end Transition()
389 
390///////////////////////////////////////////////////////////////////
391void genMoore(cmd_out_t &p_cmd_out, rsp_in_t &p_rsp_in)
392///////////////////////////////////////////////////////////////////
393{
394        p_cmd_out.write = m_cmd_fifo.rok();
395        p_cmd_out.data  = (sc_dt::sc_uint<ring_cmd_data_size>) m_cmd_fifo.read();
396
397        p_rsp_in.read = m_rsp_fifo.wok();
398
399} // end genMoore
400
401///////////////////////////////////////////////////////////////////
402void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out)
403///////////////////////////////////////////////////////////////////
404{
405
406        switch( r_ring_rsp_fsm ) 
407        {
408                case RSP_IDLE:
409                        p_ring_out.rsp_grant = p_ring_in.rsp_grant && !m_rsp_fifo.rok();
410
411                        p_ring_out.rsp_w    = p_ring_in.rsp_w;
412                        p_ring_out.rsp_data = p_ring_in.rsp_data;
413
414                break;
415
416                case DEFAULT:
417                {
418                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
419                        p_ring_out.rsp_grant = (!m_rsp_fifo.rok() || (eop && p_ring_in.rsp_r)) ; 
420
421                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
422                        p_ring_out.rsp_data =  m_rsp_fifo.read(); 
423
424                }
425                break;
426
427                case KEEP: 
428                { 
429                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
430                        p_ring_out.rsp_grant = m_rsp_fifo.rok() && p_ring_in.rsp_r && eop;
431
432                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
433                        p_ring_out.rsp_data =  m_rsp_fifo.read();
434
435                }
436                break; 
437
438        } // end switch
439        p_ring_out.rsp_r     = p_ring_in.rsp_r;
440
441        p_ring_out.cmd_w     = p_ring_in.cmd_w;
442        p_ring_out.cmd_data  = p_ring_in.cmd_data;
443        p_ring_out.cmd_grant = p_ring_in.cmd_grant;
444
445        switch( r_ring_cmd_fsm ) 
446        {
447                case CMD_IDLE:
448                {
449                        vci_addr_t rtgtid = (vci_addr_t) (((p_ring_in.cmd_data >> (ring_cmd_data_size-vci_param::S-1)) << (vci_param::N-vci_param::S)));
450                        bool islocalm = m_lt[rtgtid]  && (m_rt[rtgtid] == m_tgtid); // multicast
451                        bool isbrdcst = (p_ring_in.cmd_data & 0x1) == 0x1;
452                        bool islocalb = ( (int) ((p_ring_in.cmd_data >> 1 ) & 0xF) == m_tgtid); // broadcast
453                        //bool eop      = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
454
455                        if (p_ring_in.cmd_w && ((isbrdcst && islocalb) || (!isbrdcst && islocalm))) 
456                        {
457                                p_ring_out.cmd_r =  m_cmd_fifo.wok();
458                        } 
459                        else
460                        {
461                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
462                        }
463                }
464                break;
465
466                case LOCAL:
467
468                        p_ring_out.cmd_r =  m_cmd_fifo.wok();   
469                break;
470
471                case RING:
472
473                        p_ring_out.cmd_r = p_ring_in.cmd_r;
474                break; 
475        } // end switch
476
477} // end update_ring_signals
478 
479};
480
481}} // end namespace
482#endif // SOCLIB_CABA_DSPIN_SIMPLE_RING_TARGET_FAST_C_H
483
Note: See TracBrowser for help on using the repository browser.