source: branches/reconfiguration/modules/dspin_router/caba/source/src/dspin_router.cpp @ 886

Last change on this file since 886 was 886, checked in by cfuguet, 9 years ago

reconf: introduce a dspin_router_config.h interface file

  • This file contains the possible configuration values for the p_blackhole_pos port. It is meant to b used by software to configure, through the reconf:vci_xicu, the NoC routers.
File size: 27.0 KB
Line 
1/* -*- c++ -*-
2  *
3  * File : dspin_router.cpp
4  * Copyright (c) UPMC, Lip6
5  * Authors : Alain Greiner, Abbas Sheibanyrad, Ivan Miro, Zhen Zhang
6  *
7  * SOCLIB_LGPL_HEADER_BEGIN
8  *
9  * This file is part of SoCLib, GNU LGPLv2.1.
10  *
11  * SoCLib is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License as published
13  * by the Free Software Foundation; version 2.1 of the License.
14  *
15  * SoCLib is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with SoCLib; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  *
25  * SOCLIB_LGPL_HEADER_END
26  *
27  */
28
29    ///////////////////////////////////////////////////////////////////////////
30    // Implementation Note :
31    // The xfirst_route(), broadcast_route() and is_broadcast() functions
32    // defined below are used to decode the DSPIN first flit format:
33    // - In case of a non-broadcast packet :
34    //  |   X     |   Y     |---------------------------------------|BC |
35    //  | x_width | y_width |  flit_width - (x_width + y_width + 2) | 0 |
36    //
37    //  - In case of a broacast
38    //  |  XMIN   |  XMAX   |  YMIN   |  YMAX   |-------------------|BC |
39    //  |   5     |   5     |   5     |   5     | flit_width - 22   | 1 |
40    ///////////////////////////////////////////////////////////////////////////
41
42#include "../include/dspin_router.h"
43#include "dspin_router_config.h"
44
45namespace soclib { namespace caba {
46
47using namespace soclib::common;
48using namespace soclib::caba;
49
50#define tmpl(x) template<int flit_width> x DspinRouter<flit_width>
51
52    ////////////////////////////////////////////////
53    //              constructor
54    ////////////////////////////////////////////////
55    tmpl(/**/)::DspinRouter( sc_module_name name,
56                             const size_t   x,
57                             const size_t   y,
58                             const size_t   x_width,
59                             const size_t   y_width,
60                             const size_t   in_fifo_depth,
61                             const size_t   out_fifo_depth,
62                             const bool     broadcast_supported,
63                             const bool     reconfigurable )
64    : soclib::caba::BaseModule(name),
65
66      p_clk( "p_clk" ),
67      p_resetn( "p_resetn" ),
68      p_in( alloc_elems<DspinInput<flit_width> >("p_in", 5) ),
69      p_out( alloc_elems<DspinOutput<flit_width> >("p_out", 5) ),
70
71      r_alloc_out( alloc_elems<sc_signal<bool> >("r_alloc_out", 5)),
72      r_index_out( soclib::common::alloc_elems<sc_signal<size_t> >("r_index_out", 5)),
73      r_fsm_in( alloc_elems<sc_signal<int> >("r_fsm_in", 5)),
74      r_index_in( alloc_elems<sc_signal<size_t> >("r_index_in", 5)),
75
76      m_local_x( x ),
77      m_local_y( y ),
78      m_x_width( x_width ),
79      m_x_shift( flit_width - x_width ),
80      m_x_mask( (0x1 << x_width) - 1 ),
81      m_y_width( y_width ),
82      m_y_shift( flit_width - x_width - y_width ),
83      m_y_mask( (0x1 << y_width) - 1 ),
84      m_broadcast_supported( broadcast_supported ),
85      m_disable_mask( 0 )
86    {
87        std::cout << "  - Building DspinRouter : " << name << std::endl;
88
89        SC_METHOD (transition);
90        dont_initialize();
91        sensitive << p_clk.pos();
92
93        SC_METHOD (genMoore);
94        dont_initialize();
95        sensitive  << p_clk.neg();
96
97        r_fifo_in  = (GenericFifo<internal_flit_t>*)
98                     malloc(sizeof(GenericFifo<internal_flit_t>) * 5);
99
100        r_fifo_out = (GenericFifo<internal_flit_t>*)
101                     malloc(sizeof(GenericFifo<internal_flit_t>) * 5);
102
103        r_buf_in   = (internal_flit_t*)
104                     malloc(sizeof(internal_flit_t) * 5);
105
106        for( size_t i = 0 ; i < 5 ; i++ )
107        {
108            std::ostringstream stri;
109            stri << "r_in_fifo_" << i;
110            new(&r_fifo_in[i])
111                GenericFifo<internal_flit_t >(stri.str(), in_fifo_depth);
112
113            std::ostringstream stro;
114            stro << "r_out_fifo_" << i;
115            new(&r_fifo_out[i])
116                GenericFifo<internal_flit_t >(stro.str(), out_fifo_depth);
117        }
118
119        if ( reconfigurable ) p_blackhole_pos = new sc_core::sc_in<uint32_t>;
120        else                  p_blackhole_pos = NULL;
121    } //  end constructor
122
123    ///////////////////////////////////////////////////
124    tmpl(/**/)::~DspinRouter()
125    {
126        if ( p_blackhole_pos != NULL ) delete p_blackhole_pos;
127    }
128
129    ///////////////////////////////////////////////////
130    tmpl(int)::xfirst_route( size_t xdest, size_t ydest )
131    {
132        return (xdest < m_local_x ? REQ_WEST :
133               (xdest > m_local_x ? REQ_EAST :
134               (ydest < m_local_y ? REQ_SOUTH :
135               (ydest > m_local_y ? REQ_NORTH : REQ_LOCAL))));
136    }
137
138    ///////////////////////////////////////////////////
139    tmpl(int)::recovery_route( size_t xdest, size_t ydest )
140    {
141        int bhpos = p_blackhole_pos->read();
142        if ( xdest > m_local_x ) {
143            if ( (bhpos == BH_NE) || (bhpos == BH_E) || (bhpos == BH_SE) ||
144                 (bhpos == BH_S) ) {
145                return REQ_EAST;
146            }
147            else if ( bhpos == BH_N ) {
148                if ( (m_local_y == 1) || (m_local_x == 0) || (ydest >= m_local_y) ||
149                     (xdest > (m_local_x + 1)) ) {
150                    return REQ_EAST;
151                }
152                else {
153                    return REQ_WEST;
154                }
155            }
156            else if ( bhpos == BH_NW ) {
157                if ( (m_local_y == 1) || (ydest >= m_local_y) ||
158                     (xdest > (m_local_x + 2)) ) {
159                    return REQ_EAST;
160                }
161                else {
162                    return REQ_SOUTH;
163                }
164            }
165            else if ( bhpos == BH_W ) {
166                if ( (m_local_y == 0) || (ydest > m_local_y)) {
167                    return REQ_NORTH;
168                }
169                else {
170                    return REQ_SOUTH;
171                }
172            }
173            else if ( bhpos == BH_SW ) {
174                if ( (ydest <= m_local_y) || (xdest > (m_local_x + 1)) ) {
175                    return REQ_EAST;
176                }
177                else {
178                    return REQ_NORTH;
179                }
180            }
181            std::cout << "error: unexpected condition in function "
182                      << __FILE__ << ":" << __func__ << " +" << __LINE__
183                      << std::endl;
184            exit(1);
185        }                    // end if (xdest > m_local_x)
186        else if ( xdest < m_local_x ) {
187            if ( (bhpos == BH_N) || (bhpos == BH_NW) || (bhpos == BH_W) ||
188                 (bhpos == BH_SW) || (bhpos == BH_S) ) {
189                return REQ_WEST;
190            }
191            else if ( bhpos == BH_NE ) {
192                if ( (xdest < (m_local_x - 1)) || (ydest >= m_local_y) ) {
193                    return REQ_WEST;
194                }
195                else {
196                    return REQ_SOUTH;
197                }
198            }
199            else if ( bhpos == BH_SE ) {
200                if ( (m_local_x == 1) && (ydest > (m_local_y + 1)) ) {
201                    return REQ_NORTH;
202                }
203                else {
204                    return REQ_WEST;
205                }
206            }
207            else if ( bhpos == BH_E ) {
208                if ( (m_local_y == 0) ||
209                    ((m_local_x == 1) && (ydest > m_local_y)) ) {
210                    return REQ_NORTH;
211                }
212                else {
213                    return REQ_SOUTH;
214                }
215            }
216            std::cout << "error: unexpected condition in function "
217                      << __FILE__ << ":" << __func__ << " +" << __LINE__
218                      << std::endl;
219            exit(1);
220        }                    // end if (xdest < m_local_x)
221        else if ( ydest > m_local_y ) {
222            if ( bhpos != BH_S ) {
223                return REQ_NORTH;
224            }
225            else if ( m_local_x != 0 ) {
226                return REQ_WEST;
227            }
228            else {
229                return REQ_EAST;
230            }
231        }                    // end if (ydest > m_local_y)
232        else if ( ydest < m_local_y ) {
233            if ( bhpos != BH_N ) {
234                return REQ_SOUTH;
235            }
236            else if ( m_local_x != 0) {
237                return REQ_WEST;
238            }
239            else {
240                return REQ_EAST;
241            }
242        }                    // end if (ydest < m_local_y)
243        return REQ_LOCAL;
244    }
245
246    ///////////////////////////////////////////////////
247    tmpl(int)::route( sc_uint<flit_width> data )
248    {
249        size_t xdest = (size_t)(data >> m_x_shift) & m_x_mask;
250        size_t ydest = (size_t)(data >> m_y_shift) & m_y_mask;
251        if ( p_blackhole_pos != NULL )
252        {
253            if ( p_blackhole_pos->read() != BH_NONE )
254            {
255                return recovery_route(xdest, ydest);
256            }
257        }
258        return xfirst_route(xdest, ydest);
259    }
260
261    //////////////////////////////////////////////////////////////////////////
262    tmpl(int)::broadcast_route(int step, int source, sc_uint<flit_width> data)
263    {
264        int    sel  = REQ_NOP;
265        size_t xmin = (data >> (flit_width - 5 )) & 0x1F;
266        size_t xmax = (data >> (flit_width - 10)) & 0x1F;
267        size_t ymin = (data >> (flit_width - 15)) & 0x1F;
268        size_t ymax = (data >> (flit_width - 20)) & 0x1F;
269
270        switch(source) {
271        case REQ_LOCAL :
272            if      ( step == 1 )   sel = REQ_NORTH;
273            else if ( step == 2 )   sel = REQ_SOUTH;
274            else if ( step == 3 )   sel = REQ_EAST;
275            else if ( step == 4 )   sel = REQ_WEST;
276        break;
277        case REQ_NORTH :
278            if      ( step == 1 )   sel = REQ_SOUTH;
279            else if ( step == 2 )   sel = REQ_LOCAL;
280            else if ( step == 3 )   sel = REQ_NOP;
281            else if ( step == 4 )   sel = REQ_NOP;
282        break;
283        case REQ_SOUTH :
284            if      ( step == 1 )   sel = REQ_NORTH;
285            else if ( step == 2 )   sel = REQ_LOCAL;
286            else if ( step == 3 )   sel = REQ_NOP;
287            else if ( step == 4 )   sel = REQ_NOP;
288        break;
289        case REQ_EAST :
290            if      ( step == 1 )   sel = REQ_WEST;
291            else if ( step == 2 )   sel = REQ_NORTH;
292            else if ( step == 3 )   sel = REQ_SOUTH;
293            else if ( step == 4 )   sel = REQ_LOCAL;
294        break;
295        case REQ_WEST :
296            if      ( step == 1 )   sel = REQ_EAST;
297            else if ( step == 2 )   sel = REQ_NORTH;
298            else if ( step == 3 )   sel = REQ_SOUTH;
299            else if ( step == 4 )   sel = REQ_LOCAL;
300        break;
301        }
302        if      ( (sel == REQ_NORTH) && !(m_local_y < ymax) )   sel = REQ_NOP;
303        else if ( (sel == REQ_SOUTH) && !(m_local_y > ymin) )   sel = REQ_NOP;
304        else if ( (sel == REQ_EAST ) && !(m_local_x < xmax) )   sel = REQ_NOP;
305        else if ( (sel == REQ_WEST ) && !(m_local_x > xmin) )   sel = REQ_NOP;
306
307        return sel;
308    }
309
310    /////////////////////////////////////////////////////////
311    tmpl(inline bool)::is_broadcast(sc_uint<flit_width> data)
312    {
313        return ( (data & 0x1) != 0);
314    }
315
316    /////////////////////////
317    tmpl(void)::print_trace()
318    {
319        const char* port_name[] =
320        {
321            "N",
322            "S",
323            "E",
324            "W",
325            "L"
326        };
327
328        const char* infsm_str[] =
329        {
330            "IDLE",
331            "REQ",
332            "ALLOC",
333            "REQ_FIRST",
334            "ALLOC_FIRST",
335            "REQ_SECOND",
336            "ALLOC_SECOND",
337            "REQ_THIRD",
338            "ALLOC_THIRD",
339            "REQ_FOURTH",
340            "ALLOC_FOURTH"
341        };
342
343        std::cout << "DSPIN_ROUTER " << name();
344
345        for( size_t i = 0 ; i < 5 ; i++)  // loop on input ports
346        {
347            std::cout << " / infsm[" << port_name[i] << "] "
348                      << infsm_str[r_fsm_in[i].read()];
349        }
350
351        for ( size_t out=0 ; out<5 ; out++)  // loop on output ports
352        {
353            if ( r_alloc_out[out].read() )
354            {
355                int in = r_index_out[out];
356                std::cout << " / " << port_name[in] << " -> " << port_name[out] ;
357            }
358        }
359        std::cout << std::endl;
360    }
361
362    ////////////////////////
363    tmpl(void)::transition()
364    {
365        // Long wires connecting input and output ports
366        size_t              req_in[5];         // input ports  -> output ports
367        size_t              get_out[5];        // output ports -> input ports
368        bool                put_in[5];         // input ports  -> output ports
369        internal_flit_t     data_in[5];        // input ports  -> output ports
370
371        // control signals for the input fifos
372        bool                fifo_in_write[5];
373        bool                fifo_in_read[5];
374        internal_flit_t     fifo_in_wdata[5];
375
376        // control signals for the output fifos
377        bool                fifo_out_write[5];
378        bool                fifo_out_read[5];
379        internal_flit_t     fifo_out_wdata[5];
380
381        // Reset
382        if ( p_resetn == false )
383        {
384            for(size_t i = 0 ; i < 5 ; i++)
385            {
386                r_alloc_out[i] = false;
387                r_index_out[i] = 0;
388                r_index_in[i]  = 0;
389                r_fsm_in[i]    = INFSM_IDLE;
390                r_fifo_in[i].init();
391                r_fifo_out[i].init();
392            }
393            return;
394        }
395
396        // fifos signals default values
397        for(size_t i = 0 ; i < 5 ; i++)
398        {
399            fifo_in_read[i]        = false;
400
401            // do not write into the FIFO of disabled interfaces
402            fifo_in_write[i]       = p_in[i].write.read() &&
403                                     ((m_disable_mask & (1 << i)) == 0);
404
405            fifo_in_wdata[i].data  = p_in[i].data.read();
406            fifo_in_wdata[i].eop   = p_in[i].eop.read();
407
408            fifo_out_read[i]       = p_out[i].read.read();
409            fifo_out_write[i]      = false;
410        }
411
412        // loop on the output ports:
413        // compute get_out[j] depending on the output port state
414        // and combining fifo_out[j].wok and r_alloc_out[j]
415        for ( size_t j = 0 ; j < 5 ; j++ )
416        {
417            if( r_alloc_out[j].read() and (r_fifo_out[j].wok()) )
418            {
419                get_out[j] = r_index_out[j].read();
420            }
421            else
422            {
423                get_out[j] = 0xFFFFFFFF;
424            }
425        }
426
427        // loop on the input ports :
428        // The port state is defined by r_fsm_in[i], r_index_in[i] & r_buf_in[i]
429        // The req_in[i] computation implements the X-FIRST algorithm.
430        // data_in[i], put_in[i] and req_in[i] depend on the input port state.
431        // The fifo_in_read[i] is computed further...
432
433        for ( size_t i = 0 ; i < 5 ; i++ )
434        {
435            switch ( r_fsm_in[i].read() )
436            {
437                case INFSM_IDLE:    // no output port allocated
438                {
439                    put_in[i] = false;
440
441                    if ( r_fifo_in[i].rok() ) // packet available in input fifo
442                    {
443                        if ( is_broadcast( r_fifo_in[i].read().data ) and
444                             m_broadcast_supported )          // broadcast
445                        {
446                            fifo_in_read[i] = true;
447                            req_in[i]       = broadcast_route(1, i, r_fifo_in[i].read().data);
448                            r_buf_in[i]     = r_fifo_in[i].read();
449                            r_index_in[i]   = req_in[i];
450                            if( req_in[i] == REQ_NOP ) r_fsm_in[i] = INFSM_REQ_SECOND;
451                            else                       r_fsm_in[i] = INFSM_REQ_FIRST;
452                        }
453                        else                                  // unicast
454                        {
455                            req_in[i]       = route(r_fifo_in[i].read().data);
456                            r_index_in[i]   = req_in[i];
457                            r_fsm_in[i]     = INFSM_REQ;
458                        }
459                    }
460                    else
461                    {
462                        req_in[i] = REQ_NOP;
463                    }
464                    break;
465                }
466                case INFSM_REQ:   // not a broadcast / waiting output port allocation
467                {
468                    data_in[i]      = r_fifo_in[i].read();
469                    put_in[i]       = r_fifo_in[i].rok();
470                    req_in[i]       = r_index_in[i];
471                    fifo_in_read[i] = (get_out[r_index_in[i].read()] == i);
472                    if ( get_out[r_index_in[i].read()] == i ) // first flit transfered
473                    {
474                        if ( r_fifo_in[i].read().eop ) r_fsm_in[i] = INFSM_IDLE;
475                        else                           r_fsm_in[i] = INFSM_ALLOC;
476                    }
477                    break;
478                }
479                case INFSM_ALLOC:   // not a broadcast / output port allocated
480                {
481                    data_in[i]      = r_fifo_in[i].read();
482                    put_in[i]       = r_fifo_in[i].rok();
483                    req_in[i]       = REQ_NOP;                 // no request
484                    fifo_in_read[i] = (get_out[r_index_in[i].read()] == i);
485                    if ( r_fifo_in[i].read().eop and
486                         r_fifo_in[i].rok() and
487                         (get_out[r_index_in[i].read()] == i) ) // last flit transfered
488                    {
489                        r_fsm_in[i] = INFSM_IDLE;
490                    }
491                    break;
492                }
493                case INFSM_REQ_FIRST: // broacast / waiting first output port allocation
494                {
495                    data_in[i]    = r_buf_in[i];
496                    put_in[i]     = true;
497                    req_in[i]     = broadcast_route(1, i, r_buf_in[i].data);
498                    r_index_in[i] = req_in[i];
499                    if ( req_in[i] == REQ_NOP )   // no transfer for this step
500                    {
501                        r_fsm_in[i] = INFSM_REQ_SECOND;
502                    }
503                    else
504                    {
505                        if( get_out[req_in[i]] == i )  // header flit transfered
506                        {
507                            r_fsm_in[i] = INFSM_ALLOC_FIRST;
508                        }
509                    }
510                    break;
511                }
512                case INFSM_ALLOC_FIRST:  // broadcast / first output port allocated
513                {
514                    data_in[i] = r_fifo_in[i].read();
515                    put_in[i]  = r_fifo_in[i].rok();
516                    req_in[i]  = REQ_NOP;
517                    if( (get_out[r_index_in[i].read()] == i)
518                         and r_fifo_in[i].rok() )                 // data flit transfered
519                    {
520                        if ( not r_fifo_in[i].read().eop )
521                        {
522                            std::cout << "ERROR in DSPIN_ROUTER " << name()
523                                      << " : broadcast packet must be 2 flits" << std::endl;
524                        }
525                        r_fsm_in[i] = INFSM_REQ_SECOND;
526                    }
527                    break;
528                }
529                case INFSM_REQ_SECOND: // broacast / waiting second output port allocation
530                {
531                    data_in[i]    = r_buf_in[i];
532                    put_in[i]     = true;
533                    req_in[i]     = broadcast_route(2, i, r_buf_in[i].data);
534                    r_index_in[i] = req_in[i];
535                    if ( req_in[i] == REQ_NOP )  // no transfer for this step
536                    {
537                        r_fsm_in[i] = INFSM_REQ_THIRD;
538                    }
539                    else
540                    {
541                        if( get_out[req_in[i]] == i ) // header flit transfered
542                        {
543                            r_fsm_in[i] = INFSM_ALLOC_SECOND;
544                        }
545                    }
546                    break;
547                }
548                case INFSM_ALLOC_SECOND:  // broadcast / second output port allocated
549                {
550                    data_in[i] = r_fifo_in[i].read();
551                    put_in[i]  = r_fifo_in[i].rok();
552                    req_in[i]  = REQ_NOP;
553                    if( (get_out[r_index_in[i].read()] == i )
554                         and r_fifo_in[i].rok() )               // data flit transfered
555                    {
556                        if ( not r_fifo_in[i].read().eop )
557                        {
558                            std::cout << "ERROR in DSPIN_ROUTER " << name()
559                                      << " : broadcast packet must be 2 flits" << std::endl;
560                        }
561                        r_fsm_in[i] = INFSM_REQ_THIRD;
562                    }
563                    break;
564                }
565                case INFSM_REQ_THIRD: // broacast / waiting third output port allocation
566                {
567                    data_in[i]    = r_buf_in[i];
568                    put_in[i]     = true;
569                    req_in[i]     = broadcast_route(3, i, r_buf_in[i].data);
570                    r_index_in[i] = req_in[i];
571                    if ( req_in[i] == REQ_NOP )  // no transfer for this step
572                    {
573                        r_fsm_in[i] = INFSM_REQ_FOURTH;
574                    }
575                    else
576                    {
577                        if( get_out[req_in[i]] == i ) // header flit transfered
578                        {
579                            r_fsm_in[i] = INFSM_ALLOC_THIRD;
580                        }
581                    }
582                    break;
583                }
584                case INFSM_ALLOC_THIRD:  // broadcast / third output port allocated
585                {
586                    data_in[i] = r_fifo_in[i].read();
587                    put_in[i]  = r_fifo_in[i].rok();
588                    req_in[i]  = REQ_NOP;
589                    if( (get_out[r_index_in[i].read()] == i )
590                         and r_fifo_in[i].rok() )               // data flit transfered
591                    {
592                        if ( not r_fifo_in[i].read().eop )
593                        {
594                            std::cout << "ERROR in DSPIN_ROUTER " << name()
595                                      << " : broadcast packet must be 2 flits" << std::endl;
596                        }
597                        r_fsm_in[i] = INFSM_REQ_FOURTH;
598                    }
599                    break;
600                }
601                case INFSM_REQ_FOURTH: // broacast / waiting fourth output port allocation
602                {
603                    data_in[i]    = r_buf_in[i];
604                    put_in[i]     = true;
605                    req_in[i]     = broadcast_route(4, i, r_buf_in[i].data);
606                    r_index_in[i] = req_in[i];
607                    if ( req_in[i] == REQ_NOP )  // no transfer for this step
608                    {
609                        fifo_in_read[i] = true;
610                        r_fsm_in[i]     = INFSM_IDLE;
611                    }
612                    else
613                    {
614                        if( get_out[req_in[i]] == i )  // header flit transfered
615                        {
616                            r_fsm_in[i] = INFSM_ALLOC_FOURTH;
617                        }
618                    }
619                    break;
620                }
621                case INFSM_ALLOC_FOURTH:  // broadcast / fourth output port allocated
622                {
623                    data_in[i] = r_fifo_in[i].read();
624                    put_in[i]  = r_fifo_in[i].rok();
625                    req_in[i]  = REQ_NOP;
626                    if( (get_out[r_index_in[i].read()] == i )
627                         and r_fifo_in[i].rok() )                 // data flit transfered
628                    {
629                        if ( not r_fifo_in[i].read().eop )
630                        {
631                            std::cout << "ERROR in DSPIN_ROUTER " << name()
632                                      << " : broadcast packet must be 2 flits" << std::endl;
633                        }
634                        fifo_in_read[i] = true;
635                        r_fsm_in[i]     = INFSM_IDLE;
636                    }
637                    break;
638                }
639            } // end switch
640        } // end for input ports
641
642        // loop on the output ports :
643        // The r_alloc_out[j] and r_index_out[j] computation
644        // implements the round-robin allocation policy.
645        // These two registers implement a 10 states FSM.
646        for( size_t j = 0 ; j < 5 ; j++ )
647        {
648            if( not r_alloc_out[j].read() )  // not allocated: possible new allocation
649            {
650                for( size_t k = r_index_out[j].read() + 1 ;
651                     k < (r_index_out[j] + 6) ; k++)
652                {
653                    size_t i = k % 5;
654
655                    if( req_in[i] == j )
656                    {
657                        r_alloc_out[j] = true;
658                        r_index_out[j] = i;
659                        break;
660                    }
661                } // end loop on input ports
662            }
663            else                            // allocated: possible desallocation
664            {
665                if ( data_in[r_index_out[j]].eop and
666                     r_fifo_out[j].wok() and
667                     put_in[r_index_out[j]] )
668                {
669                    r_alloc_out[j] = false;
670                }
671            }
672        } // end loop on output ports
673
674        // loop on the output ports :
675        // The fifo_out_write[j] and fifo_out_wdata[j] computation
676        // implements the output port mux.
677        for( size_t j = 0 ; j < 5 ; j++ )
678        {
679            if( r_alloc_out[j] )  // output port allocated
680            {
681                fifo_out_write[j] = put_in[r_index_out[j]] &&
682                                    ((m_disable_mask & (1 << j)) == 0);
683                fifo_out_wdata[j] = data_in[r_index_out[j]];
684            }
685        }  // end loop on the output ports
686
687        //  FIFOS update
688        for(size_t i = 0 ; i < 5 ; i++)
689        {
690            r_fifo_in[i].update(fifo_in_read[i],
691                                fifo_in_write[i],
692                                fifo_in_wdata[i]);
693            r_fifo_out[i].update(fifo_out_read[i],
694                                 fifo_out_write[i],
695                                 fifo_out_wdata[i]);
696        }
697    } // end transition
698
699    ////////////////////////////////
700    //      genMoore
701    ////////////////////////////////
702    tmpl(void)::genMoore()
703    {
704        for(size_t i = 0 ; i < 5 ; i++)
705        {
706            // input ports : READ signals
707            p_in[i].read = r_fifo_in[i].wok();
708
709            // output ports : DATA & WRITE signals
710            p_out[i].data  = r_fifo_out[i].read().data;
711            p_out[i].eop   = r_fifo_out[i].read().eop;
712            p_out[i].write = r_fifo_out[i].rok();
713        }
714    } // end genMoore
715
716}} // end namespace
717
718// Local Variables:
719// tab-width: 4
720// c-basic-offset: 4
721// c-file-offsets:((innamespace . 0)(inline-open . 0))
722// indent-tabs-mode: nil
723// End:
724
725// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.