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

Last change on this file since 873 was 873, checked in by cfuguet, 8 years ago

reconf: introducing recovery_route function in the dspin_router

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