source: branches/v5/modules/dspin_local_ring_fast_c/caba/source/include/dspin_local_ring_initiator_fast_c.h @ 359

Last change on this file since 359 was 359, checked in by joannou, 11 years ago

bugfix : correctly updating the r_preempt register

  • Property svn:executable set to *
File size: 33.1 KB
Line 
1 /* SOCLIB_LGPL_HEADER_BEGIN
2 *
3 * This file is part of SoCLib, GNU LGPLv2.1.
4 *
5 * SoCLib is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; version 2.1 of the License.
8 *
9 * SoCLib is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with SoCLib; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
18 *
19 * SOCLIB_LGPL_HEADER_END
20 *
21 * Author   : Abdelmalek SI MERABET
22 * Date     : February 2013
23 * Copyright: UPMC - LIP6
24 */
25/////////////////////////////////////////////////////////////////////////////
26//   Ring : Broadcast-inval : 2 flits l2(1)->l1(n)                         //
27//---------------------------------------------------------------------------
28//  1st flit    | eop |xmin  |xmax  |ymin  |ymax  |  memcid       | lid*  |1|
29//     (40)       (1)   (5)    (5)    (5)    (5)     (14)            (4)  (1)
30//---------------------------------------------------------------------------
31//  next flit   | eop |res| trdid |     nline                                |
32//     (40)       (1)  (1)   (4)        (34)                                         
33//---------------------------------------------------------------------------
34// *lid : local id (port number on ring) for sequential broadcast
35//////////////////////////////////////////////////////////////////////////////
36//   Ring : Multicast-inval  2 flits (l2->l1)                               //
37//----------------------------------------------------------------------------
38//  1st flit    | eop | procid          |res| memcid        | trdid | type |0|
39//     (40)       (1)   (14)             (3)  (14)            (4)      (3) (1)
40//----------------------------------------------------------------------------
41//  next flit   | eop |res   |                nline                          |
42//    (40)        (1)  (5)                     (34)                                 
43//////////////////////////////////////////////////////////////////////////////
44//   Ring : Multicast-update  2+N flits l2(1)->l1(n)                        //
45//----------------------------------------------------------------------------
46//  1st flit    | eop | procid          |res| memcid        | trdid | type |0|
47//     (40)       (1)   (14)             (3)  (14)            (4)      (3) (1)
48//----------------------------------------------------------------------------
49//  next flit   | eop |res| wdidx |           nline                          |
50//    (40)        (1)  (1)  (4)                (34)
51//----------------------------------------------------------------------------
52//  next flits  | eop |   res    | be |     wdata                            |
53//    (40)        (1)     (3)      (4)      (32)
54//////////////////////////////////////////////////////////////////////////////
55//   Ring : Cleanup Ack 1 flit  l2(1)-l1(n)                                 //
56//----------------------------------------------------------------------------
57//  1st flit    | eop | procid          |res|    set        | way   | type |0|
58//     (40)       (1)   (14)             (1)     (16)         (4)      (3) (1)
59//----------------------------------------------------------------------------
60// Type         | cleanup ACK | Update/Inval | Data/instr |
61//  (3)               (1)          (1)           (1)
62////////////////////////////////////////////////////////////////////
63//   Ring : cleanup 2 flits l1(n)->l2(1)                          //
64//------------------------------------------------------------------
65//  1st flit    | eop | clustid*| procid | nline  | way    | type  |
66//     (33)       (1)    (10)     (14)     (2)      (4)     (2)   
67//  next flit   | eop |                       nline                |
68//    (33)        (1)                          (32)                           
69/////////////////////////////////////////////////////////////////////
70//   Ring : multicast ack 1 flit l1(n)->l2(1)                      //
71//------------------------------------------------------------------
72//  1st flit    | eop | clustid*|    res          | trdid  | type  |
73//     (33)       (1)    (10)        (16)           (4)     (2)   
74//------------------------------------------------------------------
75// Type         | cleanup/MulticastACK | Data/instr |
76//  (2)               (1)               (1)
77// *clusterid : identifiy cluster id of the dest memory cache.
78// all memory caches have the same Identifier in their clusters.
79//------------------------------------------------------------------
80
81#ifndef DSPIN_LOCAL_RING_INITIATOR_FAST_H
82#define DSPIN_LOCAL_RING_INITIATOR_FAST_H
83
84#include "generic_fifo.h"
85#include "mapping_table.h"
86#include "ring_signals_fast.h"
87#include "dspin_interface.h"
88
89#define  BRDCST_TGT_MASK  0xFFFFFFFFE1ULL
90#define I_DEBUG
91
92namespace soclib { namespace caba {
93
94namespace {
95
96const char *ring_cmd_fsm_state_str_i[] = {
97                "CMD_IDLE",
98                "OWNER",
99                "BDC_FIRST",
100                "BDC_SECOND",
101                "SENDING",
102                "WAIT_PALLOC_END",
103};
104
105#ifdef I_DEBUG
106
107const char *ring_rsp_fsm_state_str_i[] = {
108        "RSP_IDLE",
109        "ALLOC",
110        "NALLOC",
111        "PALLOC2",
112        "PALLOC1",
113};
114#endif
115} // end namespace
116
117template<typename vci_param, int ring_cmd_data_size, int ring_rsp_data_size>
118class DspinLocalRingInitiatorFastC
119{
120
121typedef LocalRingSignals ring_signal_t;
122typedef DspinInput<ring_cmd_data_size>   cmd_in_t;
123typedef DspinOutput<ring_rsp_data_size>  rsp_out_t;
124
125private:
126       
127        enum ring_rsp_fsm_state_e {
128                RSP_IDLE,    // waiting for first flit of a response packet
129                ALLOC,      // next flit of a local rsp packet
130                NALLOC,     // next flit of a ring rsp packet
131                PALLOC2,
132                PALLOC1,
133            };
134       
135        enum ring_cmd_fsm_state_e {
136                CMD_IDLE,           
137                OWNER, 
138                BDC_FIRST,
139                BDC_SECOND,     
140                SENDING, 
141                WAIT_PALLOC_END,                   
142            };
143       
144        // structural parameters
145        std::string         m_name;
146        bool                m_alloc_init;
147
148        // internal fifos
149        GenericFifo<uint64_t > m_cmd_fifo;     // fifo for the local command packet
150        GenericFifo<uint64_t > m_rsp_fifo;     // fifo for the local response packet
151       
152        // routing table
153        soclib::common::AddressMaskingTable<uint32_t> m_rt;
154        soclib::common::AddressDecodingTable<uint32_t, bool> m_lt;
155
156        uint64_t r_brdcst_save; 
157        uint32_t m_srcid;
158        uint32_t m_nb_target;
159        uint32_t m_x_width;
160        uint32_t m_y_width;
161
162        sc_core::sc_signal<uint32_t> r_cpt_tgt;         // target id for sequential broadcast
163        sc_core::sc_signal<uint32_t> r_ring_cmd_fsm;    // ring command packet FSM (distributed)
164        sc_core::sc_signal<uint32_t> r_ring_rsp_fsm;    // ring response packet FSM
165
166public :
167
168#define __renRegInit(x) x((((std::string) name)+"_" #x).c_str())
169
170DspinLocalRingInitiatorFastC(
171        const char     *name,
172        bool            alloc_init,
173        const int       &wrapper_fifo_depth,
174        const soclib::common::MappingTable &mt,
175        const soclib::common::IntTab &ringid,
176        const uint32_t &srcid,
177        const uint32_t &nb_target,
178        const uint32_t &x_width,
179        const uint32_t &y_width)
180      : m_name(name),
181        m_alloc_init(alloc_init),
182        m_cmd_fifo(((std::string) name)+"m_cmd_fifo", wrapper_fifo_depth),
183        m_rsp_fifo(((std::string) name)+"m_rsp_fifo", wrapper_fifo_depth),
184        m_rt(mt.getIdMaskingTable(ringid.level())),
185        m_lt(mt.getIdLocalityTable(ringid)),
186        m_srcid(srcid),
187        m_nb_target(nb_target),
188        m_x_width(x_width),
189        m_y_width(y_width),
190        __renRegInit(r_cpt_tgt),
191        __renRegInit(r_ring_cmd_fsm),
192        __renRegInit(r_ring_rsp_fsm)
193 
194 {} //  end constructor
195
196 void reset()
197{
198        if(m_alloc_init)
199                r_ring_cmd_fsm = OWNER;
200        else
201                r_ring_cmd_fsm = CMD_IDLE;
202
203        r_ring_rsp_fsm = RSP_IDLE;
204        m_cmd_fifo.init();
205        m_rsp_fifo.init();
206
207 }
208
209void transition(const cmd_in_t &p_cmd_in, const rsp_out_t &p_rsp_out, const ring_signal_t p_ring_in, cmd_str &init_cmd, bool &init_rsp_val)
210{
211
212        bool      cmd_fifo_get = false;
213        bool      cmd_fifo_put = false;
214        uint64_t  cmd_fifo_data = 0;
215
216        bool      rsp_fifo_put = false;
217        uint64_t  rsp_fifo_data = 0;
218
219//////////// ACCESS DSPIN FIFOS  ///////////////////
220        if (p_cmd_in.write.read()) {
221#ifdef I_DEBUG
222std::cout << sc_time_stamp() << " -- " << m_name << " -- DSPIN FIFO" 
223          << " -- cmd in rok : " << p_cmd_in.write
224          << " --  in data  : " << std::hex << p_cmd_in.data.read()
225          << " --  fifo wok : "  << m_cmd_fifo.wok()         
226          << std::endl;
227#endif
228                cmd_fifo_data = (uint64_t) p_cmd_in.data.read();
229                cmd_fifo_put =  m_cmd_fifo.wok();
230        }
231
232        bool rsp_fifo_get = p_rsp_out.read.read();
233       
234//////////// RING CMD FSM /////////////////////////
235        switch( r_ring_cmd_fsm ) 
236        {
237                case CMD_IDLE: 
238                // stay here while : !fifo_rok + !gnt   
239#ifdef I_DEBUG
240if(m_cmd_fifo.rok())
241        std::cout << std::dec << sc_time_stamp() << " - " << m_name
242                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm]
243                  << " - fifo ROK : " << m_cmd_fifo.rok()
244                  << " - in grant : " << p_ring_in.cmd_grant 
245                  << " - in palloc : " << p_ring_in.cmd_palloc
246                  << " - in wok : " << p_ring_in.cmd_r
247                  << " - fifo data : " << std::hex << m_cmd_fifo.read()
248                  << std::endl;
249#endif 
250 
251                        if ( p_ring_in.cmd_grant && m_cmd_fifo.rok() ) 
252                        {
253
254
255                                if (m_cmd_fifo.read() & 0x1 == 0x1) // broadcast
256                                {
257                                        r_cpt_tgt      = m_nb_target;                   
258                                        r_brdcst_save  = m_cmd_fifo.read() & BRDCST_TGT_MASK; // save first flit of brdcst
259                                        r_ring_cmd_fsm = BDC_FIRST;                                 
260
261                                } else {
262                                        r_ring_cmd_fsm = SENDING; 
263                                }
264                        }
265                break;
266
267                case OWNER:
268                        if ( m_cmd_fifo.rok()) // && p_ring_in.cmd_wok.read() )
269                        {
270#ifdef I_DEBUG
271        std::cout << std::dec << sc_time_stamp() << " - " << m_name
272                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm] 
273                  << " - fifo ROK : " << m_cmd_fifo.rok()
274                  << " - in grant : " << p_ring_in.cmd_grant 
275                  << " - in preempt : " << p_ring_in.cmd_preempt
276                  << " - in palloc : " << p_ring_in.cmd_palloc
277                  << " - in wok : " << p_ring_in.cmd_r
278                  << " - fifo data : " << std::hex << m_cmd_fifo.read()
279                  << std::endl;
280
281#endif
282                                bool eop = ( (int) ((m_cmd_fifo.read() >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
283
284                                if (m_cmd_fifo.read() & 0x1 == 0x1) // broadcast
285                                {
286                                        r_cpt_tgt      = m_nb_target;                   
287                                        r_brdcst_save  = m_cmd_fifo.read() & BRDCST_TGT_MASK; // save first flit of brdcst
288                                        r_ring_cmd_fsm = BDC_FIRST;                                       
289                                } 
290//
291                                else
292                                {
293                                        if ( eop && p_ring_in.cmd_r ) 
294                                         {
295                                                cmd_fifo_get = true;
296                                                if ( p_ring_in.cmd_grant )
297                                                        r_ring_cmd_fsm = OWNER;
298                                                else
299                                                        r_ring_cmd_fsm = CMD_IDLE;
300                                         } 
301                                       
302                                         if (!eop || !p_ring_in.cmd_r) 
303                                         {
304                                                cmd_fifo_get = p_ring_in.cmd_r;
305                                                r_ring_cmd_fsm = SENDING;
306                                         }
307
308                                }
309             
310                        }   
311                        else if ( !p_ring_in.cmd_grant)
312                                r_ring_cmd_fsm = CMD_IDLE; 
313                break;
314
315                case BDC_FIRST:
316                       
317#ifdef I_DEBUG
318        std::cout << std::dec << sc_time_stamp() << " - " << m_name
319                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm] 
320                  << " - fifo ROK : " << m_cmd_fifo.rok()
321                  << " - in grant : " << p_ring_in.cmd_grant 
322                  << " - in preempt : " << p_ring_in.cmd_preempt
323                  << " - in palloc : " << p_ring_in.cmd_palloc
324                  << " - in wok : " << p_ring_in.cmd_r
325                  << " - cpt_tgt : " << r_cpt_tgt.read()
326                  << " - fifo data : " << std::hex << m_cmd_fifo.read()
327                  << std::endl;
328
329#endif
330                        if (p_ring_in.cmd_preempt) break;
331
332                        if (p_ring_in.cmd_r)                                 
333                        {
334                                if (r_cpt_tgt.read() == m_nb_target)
335                                {
336                                        cmd_fifo_get = true;
337                                }
338                                r_ring_cmd_fsm = BDC_SECOND;
339                        }
340                break;
341
342                case BDC_SECOND:
343#ifdef I_DEBUG
344        std::cout << std::dec << sc_time_stamp() << " - " << m_name
345                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm] 
346                  << " - fifo ROK : " << m_cmd_fifo.rok()
347                  << " - in grant : " << p_ring_in.cmd_grant 
348                  << " - in preempt : " << p_ring_in.cmd_preempt
349                  << " - in palloc : " << p_ring_in.cmd_palloc
350                  << " - in wok : " << p_ring_in.cmd_r
351                  << " - fifo data : " << std::hex << m_cmd_fifo.read()
352                  << std::endl;
353
354#endif
355                        if (p_ring_in.cmd_preempt) break;
356
357                        if(m_cmd_fifo.rok() && p_ring_in.cmd_r)
358                        { 
359                                if(r_cpt_tgt.read() == 0)
360                                {
361                                        cmd_fifo_get = true; 
362
363                                        if ( !p_ring_in.cmd_palloc && p_ring_in.cmd_grant )
364                                        {
365                                                r_ring_cmd_fsm = OWNER; 
366                                        }
367                                        else    if ( !p_ring_in.cmd_palloc && !p_ring_in.cmd_grant ) 
368                                                {
369                                                        r_ring_cmd_fsm = CMD_IDLE;
370                                                }
371                                                else
372                                                {
373                                                        r_ring_cmd_fsm = WAIT_PALLOC_END;
374                                                }
375                                }
376                                else
377                                {
378                                        r_cpt_tgt      = r_cpt_tgt - 1;
379                                        r_ring_cmd_fsm = BDC_FIRST;
380                                }
381
382                        }
383                break;
384
385                case SENDING:
386                // stay here while !release + cmd_preempt
387                // release = fifo_rok.ring_in.wok.fifo_data.eop
388                // palloc : a local target is stil allocated by the gateway_initiator
389#ifdef I_DEBUG
390if(m_cmd_fifo.rok())
391        std::cout << std::dec << sc_time_stamp() << " - " << m_name
392                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm] 
393                  << " - fifo ROK : " << m_cmd_fifo.rok()
394                  << " - in grant : " << p_ring_in.cmd_grant 
395                  << " - in preempt : " << p_ring_in.cmd_preempt
396                  << " - in palloc : " << p_ring_in.cmd_palloc
397                  << " - in wok : " << p_ring_in.cmd_r
398                  << " - fifo data : " << std::hex << m_cmd_fifo.read()
399                  << std::endl;
400#endif                       
401
402                        if(p_ring_in.cmd_preempt) break;
403
404                        if(m_cmd_fifo.rok() && p_ring_in.cmd_r) 
405                        {
406                                cmd_fifo_get = true; 
407                                bool eop = ((int) (m_cmd_fifo.read() >> (ring_cmd_data_size - 1) ) & 0x1) == 1;
408                               
409                                if (eop && !p_ring_in.cmd_palloc && p_ring_in.cmd_grant)
410                                { 
411                                                r_ring_cmd_fsm = OWNER; 
412                                }
413                                else if  (eop && !p_ring_in.cmd_palloc && !p_ring_in.cmd_grant)         
414                                        {   
415                                                r_ring_cmd_fsm = CMD_IDLE; 
416                                        }
417                                        else if (eop && p_ring_in.cmd_palloc) 
418                                                {
419                                                        r_ring_cmd_fsm = WAIT_PALLOC_END;
420                                                }
421                        }   
422   
423                break;
424
425                case WAIT_PALLOC_END:
426                // stay here and keep token till last flit from Init Gate, ring is preempted
427                bool eop = ((int) (p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1;
428#ifdef I_DEBUG
429if(p_ring_in.cmd_w)
430        std::cout << std::dec << sc_time_stamp() << " - " << m_name
431                  << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_i[r_ring_cmd_fsm] 
432                  << " - palloc : " << p_ring_in.cmd_palloc
433                  << " - in grant : " << p_ring_in.cmd_grant 
434                  << " - in preempt : " << p_ring_in.cmd_preempt
435                  << " - in rok : " << p_ring_in.cmd_w
436                  << " - in wok : " << p_ring_in.cmd_r
437                  << " - in data : " << std::hex << p_ring_in.cmd_data
438                  << " - eop : " << eop
439                  << std::endl;
440#endif                 
441
442                        if(p_ring_in.cmd_w && p_ring_in.cmd_r && eop) // last flit from init gate
443                        {
444                                if (p_ring_in.cmd_grant)
445                                        r_ring_cmd_fsm = OWNER; 
446                                else           
447                                        r_ring_cmd_fsm = CMD_IDLE; 
448                                       
449                        }   
450   
451                break;
452        } // end switch ring cmd fsm
453 
454/////////// RING RSP FSM ////////////////////////
455   
456        switch( r_ring_rsp_fsm ) 
457        {
458                case RSP_IDLE: 
459                {
460                        uint32_t  rsrcid  = (uint32_t)  ((sc_dt::sc_uint<vci_param::S>) ((p_ring_in.rsp_data >> (ring_rsp_data_size-m_x_width-m_y_width - 1)) << (vci_param::S-m_x_width-m_y_width)));
461                        bool islocal      = m_lt[rsrcid] && (m_rt[rsrcid] == m_srcid);
462                        bool reop         = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
463#ifdef I_DEBUG
464if(p_ring_in.rsp_w)
465        std::cout << std::dec << sc_time_stamp() << " - " << m_name
466                  << " - ring_rsp_fsm = " << ring_rsp_fsm_state_str_i[r_ring_rsp_fsm]
467                  << " - in rok : " << p_ring_in.rsp_w
468                  << " - in data : " << std::hex << p_ring_in.rsp_data
469                  << " - rsrcid : " << rsrcid
470                  << " - isloc : " << islocal
471                  << " - in wok : " << p_ring_in.rsp_r
472                  << " - fifo wok : " <<  m_rsp_fifo.wok()
473                  << " - reop : " << reop
474                  << std::endl;
475#endif
476 
477
478                        if (p_ring_in.rsp_w  &&  islocal)
479                        {
480                                rsp_fifo_put  = m_rsp_fifo.wok();
481                                rsp_fifo_data = p_ring_in.rsp_data;
482                               
483                                if (reop && m_rsp_fifo.wok())
484                                        r_ring_rsp_fsm = RSP_IDLE;
485                                else
486                                        r_ring_rsp_fsm = ALLOC;
487                        }
488                        else    if (p_ring_in.rsp_w  &&  !islocal) 
489                                {
490
491                                        if (reop && p_ring_in.rsp_r)
492                                                r_ring_rsp_fsm = RSP_IDLE;
493                                        else
494                                                r_ring_rsp_fsm = NALLOC;
495                                }
496
497                                else // !p_ring_in.rsp_w
498                                {                       
499                                        r_ring_rsp_fsm = RSP_IDLE;
500                                }
501                }
502                break;
503
504                case ALLOC:
505                {
506                        bool reop     = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;
507#ifdef I_DEBUG
508if(p_ring_in.rsp_w)
509        std::cout << std::dec << sc_time_stamp() << " - " << m_name
510                  << " - ring_rsp_fsm = " << ring_rsp_fsm_state_str_i[r_ring_rsp_fsm]
511                  << " - in rok : " << p_ring_in.rsp_w
512                  << " - in wok : " << p_ring_in.rsp_r
513                  << " - fifo wok : " <<  m_rsp_fifo.wok() 
514                  << " - in data : " << std::hex << p_ring_in.rsp_data
515                  << " - reop : " << reop
516                  << std::endl;
517#endif
518
519
520                        if (p_ring_in.rsp_w && m_rsp_fifo.wok() && reop)         
521                        {
522
523                                rsp_fifo_put  = true;
524                                rsp_fifo_data = p_ring_in.rsp_data;
525                                r_ring_rsp_fsm = RSP_IDLE;             
526                        }
527                        else // !p_ring_in.rsp_w || !m_rsp_fifo.wok() || !reop
528                        {
529
530                                rsp_fifo_put  = p_ring_in.rsp_w && m_rsp_fifo.wok();
531                                rsp_fifo_data = p_ring_in.rsp_data;
532                                r_ring_rsp_fsm = ALLOC;             
533                        }
534                } 
535                break;
536
537                case NALLOC:   
538                {
539#ifdef I_DEBUG
540if(p_ring_in.rsp_w)
541    std::cout << std::dec << sc_time_stamp() << " - " << m_name
542                          << " - ring_rsp_fsm = " << ring_rsp_fsm_state_str_i[r_ring_rsp_fsm]
543                          << " - preempt : " << p_ring_in.rsp_preempt
544                          << " - palloc : " << p_ring_in.rsp_palloc
545                          << " - header : " << p_ring_in.rsp_header
546                          << " - in rok : " << p_ring_in.rsp_w
547                          << " - in data : " << std::hex << p_ring_in.rsp_data
548                          << " - in wok : " << p_ring_in.rsp_r
549                          << " - fifo wok : " << m_rsp_fifo.wok()
550                          << std::endl;
551#endif
552
553                        bool reop = ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1)) & 0x1) == 1;     
554
555                        if(p_ring_in.rsp_preempt) 
556                        {
557                                uint32_t  rsrcid  = (uint32_t)  ((sc_dt::sc_uint<vci_param::S>) ((p_ring_in.rsp_data >> ring_rsp_data_size-m_x_width-m_y_width) << (vci_param::S-m_x_width-m_y_width)));
558                                bool islocal      = m_lt[rsrcid] && (m_rt[rsrcid] == m_srcid);
559
560                                if(p_ring_in.rsp_header) 
561                                {
562                                        if (islocal)
563                                        {
564                                                rsp_fifo_put   = m_rsp_fifo.wok();
565                                                rsp_fifo_data  = p_ring_in.rsp_data;
566                                                if (!reop) 
567                                                        r_ring_rsp_fsm = PALLOC2;
568                                        }
569                                }
570                                else // !header
571                                {
572                                        // palloc=1, means IG is not allocated, thus, if last flit, all inits must be in IDLE state
573                                        if (reop && p_ring_in.rsp_r && (p_ring_in.rsp_palloc == 1))
574                                                r_ring_rsp_fsm = RSP_IDLE;
575                                        else
576                                                r_ring_rsp_fsm = NALLOC;
577                               }
578
579                        }
580
581                        else // !preempt
582                        {
583                                if(p_ring_in.rsp_w && reop && p_ring_in.rsp_r && !p_ring_in.rsp_palloc)
584                                        r_ring_rsp_fsm = RSP_IDLE;
585                                else 
586                                        r_ring_rsp_fsm = NALLOC;
587
588                        }
589
590                }       
591                break;
592
593                case PALLOC2:
594#ifdef I_DEBUG
595if(p_ring_in.rsp_w)
596    std::cout << std::dec << sc_time_stamp() << " - " << m_name
597                          << " - ring_rsp_fsm = " << ring_rsp_fsm_state_str_i[r_ring_rsp_fsm]
598                          << " - in preempt : " << p_ring_in.rsp_preempt
599                          << " - in rok : " << p_ring_in.rsp_w
600                          << " - in data : " << std::hex << p_ring_in.rsp_data
601                          << " - in wok : " << p_ring_in.rsp_r
602                          << " - fifo wok : " << m_rsp_fifo.wok()
603                          << std::endl;
604#endif
605                {
606                        bool eop = ( (int) ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
607
608                        if(p_ring_in.rsp_preempt)     
609                        {
610                                rsp_fifo_put  = m_rsp_fifo.wok();
611                                rsp_fifo_data = p_ring_in.rsp_data;
612                               
613                                if(eop && m_rsp_fifo.wok())
614                                        r_ring_rsp_fsm = NALLOC;
615                                else
616                                        r_ring_rsp_fsm = PALLOC2;
617                                break;
618                        }
619
620                        if(p_ring_in.rsp_w && p_ring_in.rsp_r && eop)
621                        {
622                                r_ring_rsp_fsm = PALLOC1;
623                        }
624
625                                               
626                } 
627                break;                       
628
629                case PALLOC1:
630#ifdef I_DEBUG
631    std::cout << std::dec << sc_time_stamp() << " - " << m_name
632                          << " - ring_rsp_fsm = " << ring_rsp_fsm_state_str_i[r_ring_rsp_fsm]
633                          << " - in preempt : " << p_ring_in.rsp_preempt
634                          << " - in rok : " << p_ring_in.rsp_w
635                          << " - in data : " << std::hex << p_ring_in.rsp_data
636                          << " - in wok : " << p_ring_in.rsp_r
637                          << " - fifo wok : " << m_rsp_fifo.wok()
638                          << std::endl;
639#endif
640                {
641                         bool eop = ( (int) ((p_ring_in.rsp_data >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
642
643
644                        if ( p_ring_in.rsp_preempt && m_rsp_fifo.wok() && eop )
645                        { 
646
647                                rsp_fifo_put   = true;
648                                rsp_fifo_data  = p_ring_in.rsp_data;
649                                r_ring_rsp_fsm = RSP_IDLE;
650                                       
651                        }
652                       
653                        else // !p_ring_in.rsp_w || !m_rsp_fifo.wok() || !eop
654                        { 
655
656                                rsp_fifo_put  = p_ring_in.rsp_preempt && m_rsp_fifo.wok();
657                                rsp_fifo_data = p_ring_in.rsp_data;
658                                r_ring_rsp_fsm = PALLOC1;
659                                       
660                        }                       
661                } 
662                break;
663        } // end switch rsp fsm
664
665
666////////////////////////
667//  fifos update      //
668////////////////////////
669//-- to keep trace on ring traffic : a valid initiator command is being sent
670        init_cmd.cmdval  = cmd_fifo_get;
671        init_cmd.flit    = m_cmd_fifo.read();
672        init_cmd.state   = ring_cmd_fsm_state_str_i[r_ring_cmd_fsm]; 
673 
674        //init_cmd_val = cmd_fifo_get;
675        init_rsp_val = rsp_fifo_put;
676// local cmd fifo update
677        if (  cmd_fifo_put &&  cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
678        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
679        else if ( !cmd_fifo_put &&  cmd_fifo_get ) m_cmd_fifo.simple_get();
680       
681// local rsp fifo update
682        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
683        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
684        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
685     
686}  // end Transition()
687
688///////////////////////////////////////////////////////////////////
689void genMoore(cmd_in_t &p_cmd_in, rsp_out_t &p_rsp_out)
690///////////////////////////////////////////////////////////////////
691{
692        p_rsp_out.write = m_rsp_fifo.rok();
693        p_rsp_out.data  = (sc_dt::sc_uint<ring_rsp_data_size>) m_rsp_fifo.read();
694
695        p_cmd_in.read= m_cmd_fifo.wok();
696
697} // end genMoore
698
699/////////////////////////////////////////////////////////////////////////////
700void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out)
701////////////////////////////////////////////////////////////////////////////
702{   
703        switch( r_ring_cmd_fsm ) 
704        {
705                case CMD_IDLE:
706
707                        p_ring_out.cmd_grant = !m_cmd_fifo.rok() && p_ring_in.cmd_grant; 
708
709                        p_ring_out.cmd_palloc  = p_ring_in.cmd_palloc;
710                        p_ring_out.cmd_preempt = p_ring_in.cmd_preempt;
711                        p_ring_out.cmd_w       = p_ring_in.cmd_w;
712                        p_ring_out.cmd_data    = p_ring_in.cmd_data;
713                break;
714       
715                case OWNER: 
716                {
717                        bool eop = ((int) ((m_cmd_fifo.read() >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
718                        bool brdcst = (m_cmd_fifo.read() & 0x1 == 0x1);     
719 
720                        p_ring_out.cmd_grant = (!m_cmd_fifo.rok() || (eop && p_ring_in.cmd_r)) ; 
721
722                        p_ring_out.cmd_palloc  = 0; //p_ring_in.cmd_palloc;
723                        p_ring_out.cmd_preempt = 0; //p_ring_in.cmd_preempt;
724                        p_ring_out.cmd_w       = m_cmd_fifo.rok() && !brdcst;
725                        p_ring_out.cmd_data    = m_cmd_fifo.read();
726                }
727                break;
728
729                case BDC_FIRST:
730
731                        p_ring_out.cmd_palloc    = p_ring_in.cmd_palloc;
732                        p_ring_out.cmd_preempt   = p_ring_in.cmd_preempt;
733
734                        p_ring_out.cmd_grant = false;
735                        // if cmd_preempt : Init Gate is sending to Local Target, ring preempted
736                        if (p_ring_in.cmd_preempt) 
737                        {
738                                p_ring_out.cmd_w     = p_ring_in.cmd_w;
739                                p_ring_out.cmd_data  = p_ring_in.cmd_data;
740                        }
741                        else
742                        {
743                                p_ring_out.cmd_w     = true;
744                                p_ring_out.cmd_data  = r_brdcst_save | ((((uint64_t) r_cpt_tgt.read()) & 0xF) << 0x1);   
745                        } 
746                break;
747               
748                case BDC_SECOND:
749                        p_ring_out.cmd_palloc    = p_ring_in.cmd_palloc;
750                        p_ring_out.cmd_preempt   = p_ring_in.cmd_preempt;
751
752                        // if cmd_preempt : Init Gate is sending to Local Target, ring preempted
753                        if (p_ring_in.cmd_preempt) 
754                        {
755
756                                p_ring_out.cmd_w     = p_ring_in.cmd_w;
757                                p_ring_out.cmd_data  = p_ring_in.cmd_data;
758                                p_ring_out.cmd_grant = 0;
759                        }
760                        else
761                        {                       
762                                p_ring_out.cmd_grant = m_cmd_fifo.rok() && p_ring_in.cmd_r && (r_cpt_tgt.read() == 0);
763                                p_ring_out.cmd_w    =  m_cmd_fifo.rok();
764                                p_ring_out.cmd_data =  m_cmd_fifo.read();
765                        }
766                break;
767       
768                case SENDING:
769                { 
770                        bool eop = ((int) (m_cmd_fifo.read() >> (ring_cmd_data_size - 1) ) & 0x1) == 1;
771
772                        p_ring_out.cmd_palloc    = p_ring_in.cmd_palloc;
773                        p_ring_out.cmd_preempt   = p_ring_in.cmd_preempt;
774
775                        // if cmd_preempt : Init Gate is sending to Local Target, ring preempted
776                        if (p_ring_in.cmd_preempt) 
777                        {
778
779                                p_ring_out.cmd_w     = p_ring_in.cmd_w;
780                                p_ring_out.cmd_data  = p_ring_in.cmd_data;
781                                p_ring_out.cmd_grant = 0;
782                        }
783                        else
784                        {
785                                p_ring_out.cmd_w     = m_cmd_fifo.rok();
786                                p_ring_out.cmd_data  = m_cmd_fifo.read();
787                                p_ring_out.cmd_grant = m_cmd_fifo.rok() && p_ring_in.cmd_r && eop && !p_ring_in.cmd_palloc; 
788                        }
789                }
790                break;
791
792                case WAIT_PALLOC_END: 
793                {
794                        bool eop = ((int) (p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1;
795                        // No need to test preempt here
796                        // In this state, we're sure that only IG can transmit, all other IL but this, are in IDLE state
797                        p_ring_out.cmd_grant   = p_ring_in.cmd_w && p_ring_in.cmd_r && eop; 
798
799                        p_ring_out.cmd_palloc  = p_ring_in.cmd_palloc;
800                        p_ring_out.cmd_preempt = p_ring_in.cmd_preempt; 
801                        p_ring_out.cmd_w       = p_ring_in.cmd_w; //p_ring_in.cmd_preempt;
802                        p_ring_out.cmd_data    = p_ring_in.cmd_data;
803                }       
804                break;
805
806       
807        } // end switch
808        p_ring_out.cmd_header  = p_ring_in.cmd_header;
809        p_ring_out.cmd_r       = p_ring_in.cmd_r;
810
811        p_ring_out.rsp_w       = p_ring_in.rsp_w;
812        p_ring_out.rsp_data    = p_ring_in.rsp_data;
813
814        p_ring_out.rsp_grant   = p_ring_in.rsp_grant;
815
816        p_ring_out.rsp_preempt = p_ring_in.rsp_preempt;
817        p_ring_out.rsp_header  = p_ring_in.rsp_header;
818        p_ring_out.rsp_palloc  = p_ring_in.rsp_palloc;
819
820
821        switch( r_ring_rsp_fsm ) 
822        {
823                case RSP_IDLE: 
824                {
825                        uint32_t  rsrcid  = (uint32_t)  ((sc_dt::sc_uint<vci_param::S>) ((p_ring_in.rsp_data >> (ring_rsp_data_size-m_x_width-m_y_width - 1)) << (vci_param::S-m_x_width-m_y_width)));
826                        bool islocal      = m_lt[rsrcid] && (m_rt[rsrcid] == m_srcid);
827
828                        if(p_ring_in.rsp_w && islocal) 
829                                p_ring_out.rsp_r = m_rsp_fifo.wok();
830                        else
831                                p_ring_out.rsp_r = p_ring_in.rsp_r;
832                }
833                break;
834       
835                case ALLOC:
836                        p_ring_out.rsp_r = m_rsp_fifo.wok();
837                break;
838       
839                case NALLOC:
840                {
841                        uint32_t  rsrcid  = (uint32_t)  ((sc_dt::sc_uint<vci_param::S>) ((p_ring_in.rsp_data >> ring_rsp_data_size-m_x_width-m_y_width) << (vci_param::S-m_x_width-m_y_width)));
842                        bool islocal      = m_lt[rsrcid] && (m_rt[rsrcid] == m_srcid);
843
844                        if (p_ring_in.rsp_preempt && p_ring_in.rsp_header && islocal) 
845                                p_ring_out.rsp_r  =  m_rsp_fifo.wok();
846                        else 
847                                p_ring_out.rsp_r  =  p_ring_in.rsp_r; 
848
849
850                }
851                break; 
852
853                case PALLOC2:
854                        if(p_ring_in.rsp_preempt) 
855                                p_ring_out.rsp_r  = m_rsp_fifo.wok();   
856                        else 
857                                p_ring_out.rsp_r  = p_ring_in.rsp_r;
858                break;
859
860                case PALLOC1:
861                        p_ring_out.rsp_r  = m_rsp_fifo.wok(); 
862                break;
863        } // end switch
864
865
866} // end update_ring_signals
867
868#ifdef I_STATS
869void print_stats() {
870
871std::cout << m_name << " , " << m_cpt << " , " << flits_sent << " , " << tok_wait << " , " << fifo_full << " , " << preempt << " , " << palloc_wait << std::endl;
872 
873}
874#endif
875};
876
877}} // end namespace
878#endif // DSPIN_LOCAL_RING_INITIATOR_FAST_H
879
880
Note: See TracBrowser for help on using the repository browser.