source: branches/v5/modules/dspin_local_ring_fast_c/caba/source/include/dspin_half_gateway_target_fast_c.h @ 330

Last change on this file since 330 was 330, checked in by joannou, 11 years ago
  • Commented debug in dspin_local_ring_fast_c
  • Added test on plen value in case of LL command in mem cache (vci_mem_cache and vci_mem_cache_dspin_coherence)
  • Removed coherence handling in *CACHE_MISS_DATA_UPDT states, in vci_cc_vcache_wrapper_dspin_coherence component
File size: 18.7 KB
Line 
1/* -*- c++ -*-
2 * SOCLIB_LGPL_HEADER_BEGIN
3 *
4 * This file is part of SoCLib, GNU LGPLv2.1.
5 *
6 * SoCLib is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; version 2.1 of the License.
9 *
10 * SoCLib is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with SoCLib; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 * SOCLIB_LGPL_HEADER_END
21 *
22 * Author   : Abdelmalek SI MERABET
23 * Date     : Februrary 2013
24 * Copyright: UPMC - LIP6
25 */
26
27#ifndef DSPIN_HALF_GATEWAY_TARGET_FAST_H
28#define DSPIN_HALF_GATEWAY_TARGET_FAST_H
29
30#include "generic_fifo.h"
31#include "mapping_table.h"
32#include "ring_signals_fast.h"
33#include "dspin_interface.h"
34
35//#define HT_DEBUG
36
37namespace soclib { namespace caba {
38
39using soclib::common::IntTab;
40
41namespace {
42const char *ring_rsp_fsm_state_str_ht[] = {
43                "RSP_IDLE",
44                "OWNER",
45                "SENDING",
46                "PREEMPT",
47        };
48
49#ifdef HT_DEBUG
50
51const char *ring_cmd_fsm_state_str_ht[] = {
52        "CMD_IDLE",
53        "ALLOC",
54        "NALLOC",
55        };
56#endif
57
58} // end namespace
59
60template<typename vci_param, int ring_cmd_data_size, int ring_rsp_data_size>
61class DspinHalfGatewayTargetFastC
62{
63
64typedef typename vci_param::fast_addr_t vci_addr_t;
65typedef LocalRingSignals ring_signal_t; 
66typedef DspinOutput<ring_cmd_data_size >  cmd_out_t;
67typedef DspinInput<ring_rsp_data_size >   rsp_in_t;
68
69private:
70       
71        enum ring_cmd_fsm_state_e {
72                CMD_IDLE,        // waiting for first flit of a command packet
73                ALLOC,          // next flit of a local cmd packet
74                NALLOC,         // next flit of a ring cmd packet
75        };
76       
77        // cmd token allocation fsm
78        enum ring_rsp_fsm_state_e {
79                RSP_IDLE,           
80                OWNER,         
81                SENDING, 
82                PREEMPT,                   
83        };
84       
85        // structural parameters
86        std::string   m_name;
87        bool          m_alloc_target;
88 
89        // internal fifos
90        GenericFifo<uint64_t > m_cmd_fifo;     
91        GenericFifo<uint64_t > m_rsp_fifo;     
92       
93        // locality table
94        soclib::common::AddressDecodingTable<vci_addr_t, bool> m_lt;
95
96       int           m_tgtid;
97
98        // internal registers
99        sc_core::sc_signal<int>         r_ring_cmd_fsm;     // ring command packet FSM
100        sc_core::sc_signal<int>         r_ring_rsp_fsm;     // ring response packet FSM
101
102public :
103
104#define __renRegGateTgt(x) x((((std::string) name)+"_" #x).c_str())
105
106DspinHalfGatewayTargetFastC(
107        const char     *name,
108        bool            alloc_target,
109        const int       &wrapper_fifo_depth,
110        const soclib::common::MappingTable &mt,
111        const soclib::common::IntTab &ringid,
112        const int &tgtid) 
113    :   m_name(name), 
114        m_alloc_target(alloc_target),
115        m_cmd_fifo("m_cmd_fifo", wrapper_fifo_depth),
116        m_rsp_fifo("m_rsp_fifo", wrapper_fifo_depth),
117        m_lt(mt.getLocalityTable<typename vci_param::fast_addr_t>(ringid)),
118        m_tgtid(tgtid),
119        __renRegGateTgt(r_ring_cmd_fsm),
120        __renRegGateTgt(r_ring_rsp_fsm)
121{
122} //  end constructor
123
124void reset()
125{
126        if(m_alloc_target)
127                r_ring_rsp_fsm = OWNER;
128        else
129                r_ring_rsp_fsm = RSP_IDLE;
130       
131        r_ring_cmd_fsm = CMD_IDLE;
132        m_cmd_fifo.init();
133        m_rsp_fifo.init(); 
134
135}
136////////////////////////////////
137//      transition
138////////////////////////////////
139void transition(const cmd_out_t &p_gate_cmd_out, const rsp_in_t &p_gate_rsp_in, const ring_signal_t p_ring_in, bool &tgt_cmd_val, rsp_str &tgt_rsp, const bool iga)
140{
141
142//      bool      cmd_fifo_get = false;
143        bool      cmd_fifo_put = false;
144        uint64_t  cmd_fifo_data = 0;
145       
146        bool      rsp_fifo_get = false;
147        bool      rsp_fifo_put = false;
148        uint64_t  rsp_fifo_data = 0;
149
150       
151//////////// DSPIN CMD FSM /////////////////////////
152
153        if (p_gate_rsp_in.write) {
154                rsp_fifo_data = (uint64_t) p_gate_rsp_in.data.read();
155                rsp_fifo_put =  m_rsp_fifo.wok();
156        }
157
158        bool cmd_fifo_get = p_gate_cmd_out.read;
159   
160//////////// NET RSP FSM (distributed) /////////////////////////
161       
162        switch( r_ring_rsp_fsm ) 
163        {
164                case RSP_IDLE: 
165                { 
166                         bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
167#ifdef HT_DEBUG
168if(m_rsp_fifo.rok())
169   std::cout << std::dec << sc_time_stamp() << " - " << m_name
170          << " - ring_rsp_fsm : " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm]
171          << " - fifo rok : " <<  m_rsp_fifo.rok()
172          << " - fifo data : " <<  std::hex << m_rsp_fifo.read()
173          << " - in grant : " << p_ring_in.rsp_grant
174          << " - in iga : " << iga
175          << " - in wok : " << p_ring_in.rsp_r
176          << " - in data : " << p_ring_in.rsp_data
177          << std::endl;
178#endif
179
180                        if(m_rsp_fifo.rok() && iga)
181                        {
182                                rsp_fifo_get = p_ring_in.rsp_r;
183                                //if(p_ring_in.rsp_r && eop)
184
185                                if(eop)
186                                        r_ring_rsp_fsm = RSP_IDLE;
187                                else 
188                                        r_ring_rsp_fsm = PREEMPT;
189                                break;
190                        }
191                        if (m_rsp_fifo.rok() && p_ring_in.rsp_grant) 
192                                r_ring_rsp_fsm = SENDING;           
193                }
194                break;
195
196                case OWNER: 
197                {
198
199#ifdef HT_DEBUG
200if(m_rsp_fifo.rok())
201   std::cout << std::dec << sc_time_stamp() << " - " << m_name
202                         << " - ring_rsp_fsm  = " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm] 
203                         << " - fifo ROK : " << m_rsp_fifo.rok()
204                         << " - in grant : " << p_ring_in.rsp_grant
205                         << " - in wok : " << p_ring_in.rsp_r
206                         << " - fifo data : " << std::hex << m_rsp_fifo.read()
207                         << std::endl;
208#endif
209               
210                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
211
212                        if ( m_rsp_fifo.rok() && eop && p_ring_in.rsp_r ) 
213                        {
214                                rsp_fifo_get = true;
215                                if ( !p_ring_in.rsp_grant )
216                                        r_ring_rsp_fsm = RSP_IDLE;
217                                else
218                                        r_ring_rsp_fsm = OWNER;
219                        }   
220                        if ( m_rsp_fifo.rok() && (!eop || !p_ring_in.rsp_r)) 
221                        {
222                                rsp_fifo_get = p_ring_in.rsp_r;
223                                r_ring_rsp_fsm = SENDING;
224                        }
225
226                        if ( !m_rsp_fifo.rok() && !p_ring_in.rsp_grant )
227                                r_ring_rsp_fsm = RSP_IDLE; 
228
229                        if ( !m_rsp_fifo.rok() && p_ring_in.rsp_grant )
230                                r_ring_rsp_fsm = OWNER;
231                } 
232                break;
233
234                case SENDING:   
235#ifdef HT_DEBUG
236if(m_rsp_fifo.rok())
237   std::cout << std::dec << sc_time_stamp() << " - " << m_name
238                         << " - ring_rsp_fsm  = " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm] 
239                         << " - fifo ROK : " << m_rsp_fifo.rok()
240                         << " - in grant : " << p_ring_in.rsp_grant
241                         << " - in wok : " << p_ring_in.rsp_r
242                         << " - fifo data : " << std::hex << m_rsp_fifo.read()
243                         << std::endl;
244#endif           
245                        if(m_rsp_fifo.rok() && p_ring_in.rsp_r) 
246                        {
247
248                                bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
249
250                                rsp_fifo_get = true;             
251 
252                                if (eop) 
253                                {             
254                                        if ( p_ring_in.rsp_grant )
255                                                r_ring_rsp_fsm = OWNER; 
256                                        else   
257                                                r_ring_rsp_fsm = RSP_IDLE;               
258                                } 
259                        }           
260                break;
261
262                case PREEMPT:   
263#ifdef HT_DEBUG
264if(m_rsp_fifo.rok())
265   std::cout << std::dec << sc_time_stamp() << " - " << m_name
266                         << " - ring_rsp_fsm  = " << ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm] 
267                         << " - fifo ROK : " << m_rsp_fifo.rok()
268                         << " - in grant : " << p_ring_in.rsp_grant
269                         << " - in iga : " << iga
270                         << " - in wok : " << p_ring_in.rsp_r
271                         << " - fifo data : " << std::hex << m_rsp_fifo.read()
272                         << std::endl;
273#endif                 
274                        if(m_rsp_fifo.rok() && p_ring_in.rsp_r ) 
275                        {
276                                rsp_fifo_get = true; 
277                                bool eop = ((int) (m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1;
278                                if (eop) 
279                                { 
280                                        r_ring_rsp_fsm = RSP_IDLE; 
281                                }       
282                        }     
283                break;
284        } // end switch ring rsp fsm
285
286/////////// NET CMD FSM ////////////////////////
287        switch( r_ring_cmd_fsm ) 
288        {
289
290                case CMD_IDLE:
291                {
292                        vci_addr_t rtgtid = (vci_addr_t) (((p_ring_in.cmd_data >> (ring_cmd_data_size-vci_param::S-1)) << (vci_param::N-vci_param::S)));
293                        bool islocalm = !m_lt[rtgtid];                                           // multicast
294                        bool isbrdcst = (p_ring_in.cmd_data & 0x1) == 0x1;
295                        bool islocalb = ( (int) ((p_ring_in.cmd_data >> 1 ) & 0xF) == m_tgtid); // broadcast
296                        bool eop      = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
297 
298#ifdef HT_DEBUG
299if(p_ring_in.cmd_w)
300   std::cout << std::dec << sc_time_stamp() << " - " << m_name
301              << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_ht[r_ring_cmd_fsm]
302              << " - tgtid : " << m_tgtid
303              << " - in preempt : " << p_ring_in.cmd_preempt
304              << " - in rok : " << p_ring_in.cmd_w
305              << " - in data : " << std::hex << p_ring_in.cmd_data
306              << " - addr : " << rtgtid
307              << " - islocalm : " << islocalm
308              << " - isbrdcst : " << isbrdcst
309              << " - islocalb : " << islocalb
310              << " - in wok : " << p_ring_in.cmd_r
311              << " - fifo wok : " << m_cmd_fifo.wok()
312              << std::endl;
313#endif
314
315                        if(p_ring_in.cmd_w) 
316                        {
317                                if ( (isbrdcst && islocalb) || (!isbrdcst && islocalm) )
318                                {
319                                       
320                                        cmd_fifo_put   = m_cmd_fifo.wok();
321                                        cmd_fifo_data  = p_ring_in.cmd_data;
322
323                                        if (eop && m_cmd_fifo.wok())
324                                                r_ring_cmd_fsm = CMD_IDLE;
325                                        else
326                                                r_ring_cmd_fsm = ALLOC;
327       
328                                }
329
330                                else
331                                {
332                                        if (eop && p_ring_in.cmd_r)
333                                                r_ring_cmd_fsm = CMD_IDLE;
334                                        else
335                                                r_ring_cmd_fsm = NALLOC;
336                                }
337                        }
338                        else
339                                r_ring_cmd_fsm = CMD_IDLE;
340                }
341                break;
342
343                case ALLOC: 
344                // in this state, ring can be preempted by Init gate
345                {
346                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
347#ifdef HT_DEBUG
348if(p_ring_in.cmd_w)
349
350   std::cout << std::dec << sc_time_stamp() << " - " << m_name
351              << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_ht[r_ring_cmd_fsm] 
352              << " - in preempt : " << p_ring_in.cmd_preempt
353              << " - in rok : " << p_ring_in.cmd_w
354              << " - in wok : " << p_ring_in.cmd_r
355              << " - in data : " << std::hex << p_ring_in.cmd_data
356              << " - fifo wok : " << m_cmd_fifo.wok()   
357              << " - eop : " << eop
358              << std::endl;
359#endif
360
361                        if(p_ring_in.cmd_preempt) break;
362
363                        if ( p_ring_in.cmd_w && m_cmd_fifo.wok() && eop )
364                        { 
365
366                                cmd_fifo_put  = true;
367                                cmd_fifo_data = p_ring_in.cmd_data;
368                                if(p_ring_in.cmd_palloc)
369                                        r_ring_cmd_fsm = NALLOC;
370                                else
371                                        r_ring_cmd_fsm = CMD_IDLE;             
372                        }
373                       
374                        else // !p_ring_in.cmd_w || !m_cmd_fifo.wok() || !eop
375                        { 
376
377                                cmd_fifo_put  = p_ring_in.cmd_w && m_cmd_fifo.wok();
378                                cmd_fifo_data = p_ring_in.cmd_data;
379                                r_ring_cmd_fsm = ALLOC;
380                                       
381                        }                       
382                } 
383                break;
384
385                case NALLOC:   
386                { 
387 
388                        bool eop = ( (int) ((p_ring_in.cmd_data >> (ring_cmd_data_size - 1) ) & 0x1) == 1);
389#ifdef HT_DEBUG
390if(p_ring_in.cmd_w)
391
392   std::cout << std::dec << sc_time_stamp() << " - " << m_name
393              << " - ring_cmd_fsm = " << ring_cmd_fsm_state_str_ht[r_ring_cmd_fsm]
394              << " - in rok : " << p_ring_in.cmd_w
395              << " - in data : " << std::hex << p_ring_in.cmd_data
396              << " - in wok : " << p_ring_in.cmd_r
397              << " - eop : " << eop
398              << std::endl;
399#endif
400
401                        if (p_ring_in.cmd_w && eop && p_ring_in.cmd_r) {       
402                                r_ring_cmd_fsm = CMD_IDLE;
403                        }
404                        else {
405                                r_ring_cmd_fsm = NALLOC;
406                        }
407                }
408                break;
409        } // end switch cmd fsm
410
411
412    ////////////////////////
413    //  fifos update      //
414   ////////////////////////
415//-- keep trace on ring traffic
416        tgt_rsp.rspval  = rsp_fifo_get;
417        tgt_rsp.flit    = m_rsp_fifo.read();
418        tgt_rsp.state   = ring_rsp_fsm_state_str_ht[r_ring_rsp_fsm];
419
420        tgt_cmd_val = cmd_fifo_put;
421        //tgt_rsp_val = rsp_fifo_get;
422// local cmd fifo update
423        if ( cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.put_and_get(cmd_fifo_data);
424        else if (  cmd_fifo_put && !cmd_fifo_get ) m_cmd_fifo.simple_put(cmd_fifo_data);
425        else if ( !cmd_fifo_put && cmd_fifo_get ) m_cmd_fifo.simple_get();
426// local rsp fifo update
427        if (  rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.put_and_get(rsp_fifo_data);
428        else if (  rsp_fifo_put && !rsp_fifo_get ) m_rsp_fifo.simple_put(rsp_fifo_data);
429        else if ( !rsp_fifo_put &&  rsp_fifo_get ) m_rsp_fifo.simple_get();
430 
431}  // end Transition()
432 
433///////////////////////////////////////////////////////////////////
434void genMoore(cmd_out_t &p_gate_cmd_out, rsp_in_t &p_gate_rsp_in)
435///////////////////////////////////////////////////////////////////
436{
437        p_gate_cmd_out.write = m_cmd_fifo.rok();
438        p_gate_cmd_out.data  = (sc_dt::sc_uint<ring_cmd_data_size>) m_cmd_fifo.read();
439
440        p_gate_rsp_in.read = m_rsp_fifo.wok();
441
442} // end genMoore
443
444/////////////////////////////////////////////////////////////////////////////
445void update_ring_signals(ring_signal_t p_ring_in, ring_signal_t &p_ring_out, bool &tga, bool iga)
446////////////////////////////////////////////////////////////////////////////
447{
448
449        switch( r_ring_rsp_fsm ) 
450        {
451                case RSP_IDLE:
452               {
453
454                        p_ring_out.rsp_grant = !m_rsp_fifo.rok() && p_ring_in.rsp_grant;
455
456                        p_ring_out.rsp_preempt   = m_rsp_fifo.rok() && iga; 
457                        p_ring_out.rsp_palloc    = m_rsp_fifo.rok() && iga; 
458                        p_ring_out.rsp_header    = m_rsp_fifo.rok();
459 
460                        if (m_rsp_fifo.rok() && iga) 
461                        {
462                                p_ring_out.rsp_w     =  m_rsp_fifo.rok();
463                                p_ring_out.rsp_data  =  m_rsp_fifo.read();
464                        }
465                        else
466                        {
467                                p_ring_out.rsp_w     = p_ring_in.rsp_w;
468                                p_ring_out.rsp_data  = p_ring_in.rsp_data;
469                        }
470
471                }
472                break;
473
474                case OWNER:
475                { 
476                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
477                        p_ring_out.rsp_grant = (!m_rsp_fifo.rok() || (eop && p_ring_in.rsp_r)) ;
478 
479                        p_ring_out.rsp_preempt = 0;
480                        p_ring_out.rsp_header  = 0;
481                        p_ring_out.rsp_palloc  = 0;
482
483                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
484                        p_ring_out.rsp_data =  m_rsp_fifo.read(); 
485
486                }
487                break;
488
489                case SENDING: 
490                { 
491                        bool eop = ( (int) ((m_rsp_fifo.read() >> (ring_rsp_data_size - 1) ) & 0x1) == 1);
492                        p_ring_out.rsp_grant = m_rsp_fifo.rok() && p_ring_in.rsp_r && eop;
493
494                        p_ring_out.rsp_preempt = 0;
495                        p_ring_out.rsp_header  = 0;
496                        p_ring_out.rsp_palloc  = 0;
497
498                        p_ring_out.rsp_w    =  m_rsp_fifo.rok();
499                        p_ring_out.rsp_data =  m_rsp_fifo.read();
500
501                }
502
503                break; 
504
505                case PREEMPT: 
506                        p_ring_out.rsp_grant = p_ring_in.rsp_grant;
507                        p_ring_out.rsp_palloc    = 1+(iga ? 1:0);
508                        p_ring_out.rsp_preempt   = m_rsp_fifo.rok(); //&& iga;
509                        p_ring_out.rsp_header    = 0;
510
511                        if ( m_rsp_fifo.rok() )
512                        {
513                                p_ring_out.rsp_w     = 1; //m_rsp_fifo.rok();
514                                p_ring_out.rsp_data  = m_rsp_fifo.read();
515                        }
516                        else
517                        {
518                                // if tgt  local has finished, iga = 0
519                                // tgt  gate remains the only target, then w = 0
520                                p_ring_out.rsp_w     = p_ring_in.rsp_w && iga; 
521                                p_ring_out.rsp_data  = p_ring_in.rsp_data;
522                        }
523                break;
524        } // end switch
525        p_ring_out.rsp_r       = p_ring_in.rsp_r;
526
527        p_ring_out.cmd_w       = p_ring_in.cmd_w;
528        p_ring_out.cmd_data    = p_ring_in.cmd_data;
529
530        p_ring_out.cmd_grant   = p_ring_in.cmd_grant;
531
532        p_ring_out.cmd_palloc  = p_ring_in.cmd_palloc;
533        p_ring_out.cmd_preempt = p_ring_in.cmd_preempt;
534        p_ring_out.cmd_header  = p_ring_in.cmd_header;
535
536        switch( r_ring_cmd_fsm ) 
537        {
538                case CMD_IDLE:
539                {
540                        vci_addr_t rtgtid = (vci_addr_t) (((p_ring_in.cmd_data >> (ring_cmd_data_size-vci_param::S+1)) << (vci_param::N-vci_param::S)));
541                        bool islocalm = !m_lt[rtgtid];                                           // multicast
542                        bool isbrdcst = (p_ring_in.cmd_data & 0x1) == 0x1;
543                        bool islocalb = ( (int) ((p_ring_in.cmd_data >> 1 ) & 0xF) == m_tgtid); // broadcast
544
545                        tga = false;
546
547                        if (p_ring_in.cmd_w && ((isbrdcst && islocalb) || (!isbrdcst && islocalm))) 
548                        {
549                                p_ring_out.cmd_r =  m_cmd_fifo.wok();
550                        } 
551                        else
552                        {
553                                p_ring_out.cmd_r =  p_ring_in.cmd_r; 
554                        }
555                }
556                break;
557
558                case ALLOC:
559                        tga = true;
560                        if (!p_ring_in.cmd_preempt)
561                                p_ring_out.cmd_r =  m_cmd_fifo.wok();   
562                        else
563                                p_ring_out.cmd_r = p_ring_in.cmd_r;                       
564                break;
565
566                case NALLOC:
567                        tga = false;
568                        p_ring_out.cmd_r = p_ring_in.cmd_r;
569                break;
570
571        } // end switch
572
573} // end update_ring_signals
574 
575};
576
577}} // end namespace
578
579#endif // DSPIN_HALF_GATEWAY_TARGET_FAST_H
Note: See TracBrowser for help on using the repository browser.