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

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

reconf: replace internal BH variable by an input port in the dspin_router

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