source: trunk/modules/vci_mem_cache_v3/caba/source/src/vci_mem_cache_v3.cpp @ 69

Last change on this file since 69 was 57, checked in by guthmull, 14 years ago

Fix a bug with uncached reads, add more debug capabilities

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Rev URL Revision"
  • Property svn:mime-type set to text/plain
File size: 181.7 KB
Line 
1/* -*- c++ -*-
2 * File         : vci_mem_cache_v3.cpp
3 * Date         : 30/10/2008
4 * Copyright    : UPMC / LIP6
5 * Authors      : Alain Greiner / Eric Guthmuller
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 * Maintainers: alain eric.guthmuller@polytechnique.edu
28 */
29#include "../include/vci_mem_cache_v3.h"
30
31//#define TDEBUG // Transaction tab debug
32//#define IDEBUG // Update tab debug
33//#define DDEBUG // Directory debug
34//#define DEBUG_VCI_MEM_CACHE 1
35namespace soclib { namespace caba {
36
37#ifdef DEBUG_VCI_MEM_CACHE
38  const char *tgt_cmd_fsm_str[] = {
39    "TGT_CMD_IDLE",
40    "TGT_CMD_READ",
41    "TGT_CMD_READ_EOP",
42    "TGT_CMD_WRITE",
43    "TGT_CMD_ATOMIC",
44  };
45  const char *tgt_rsp_fsm_str[] = {
46    "TGT_RSP_READ_IDLE",
47    "TGT_RSP_WRITE_IDLE",
48    "TGT_RSP_LLSC_IDLE",
49    "TGT_RSP_XRAM_IDLE",
50    "TGT_RSP_INIT_IDLE",
51    "TGT_RSP_CLEANUP_IDLE",
52    "TGT_RSP_READ",
53    "TGT_RSP_WRITE",
54    "TGT_RSP_LLSC",
55    "TGT_RSP_XRAM",
56    "TGT_RSP_INIT",
57    "TGT_RSP_CLEANUP",
58  };
59  const char *init_cmd_fsm_str[] = {
60    "INIT_CMD_INVAL_IDLE",
61    "INIT_CMD_INVAL_NLINE",
62    "INIT_CMD_XRAM_BRDCAST",
63    "INIT_CMD_UPDT_IDLE",
64    "INIT_CMD_WRITE_BRDCAST",
65    "INIT_CMD_UPDT_NLINE",
66    "INIT_CMD_UPDT_INDEX",
67    "INIT_CMD_UPDT_DATA",
68    "INIT_CMD_SC_UPDT_IDLE",
69    "INIT_CMD_SC_BRDCAST",
70    "INIT_CMD_SC_UPDT_NLINE",
71    "INIT_CMD_SC_UPDT_INDEX",
72    "INIT_CMD_SC_UPDT_DATA",
73  };
74  const char *init_rsp_fsm_str[] = {
75    "INIT_RSP_IDLE",
76    "INIT_RSP_UPT_LOCK",
77    "INIT_RSP_UPT_CLEAR",
78    "INIT_RSP_END",
79  };
80  const char *read_fsm_str[] = {
81    "READ_IDLE",
82    "READ_DIR_LOCK",
83    "READ_DIR_HIT",
84    "READ_HEAP_LOCK",
85    "READ_HEAP_WRITE",
86    "READ_HEAP_ERASE",
87    "READ_HEAP_LAST",
88    "READ_RSP",
89    "READ_TRT_LOCK",
90    "READ_TRT_SET",
91    "READ_XRAM_REQ",
92  };
93  const char *write_fsm_str[] = {
94    "WRITE_IDLE",
95    "WRITE_NEXT",
96    "WRITE_DIR_LOCK",
97    "WRITE_DIR_HIT_READ",
98    "WRITE_DIR_HIT",
99    "WRITE_DIR_HIT_RSP",
100    "WRITE_UPT_LOCK",
101    "WRITE_HEAP_LOCK",
102    "WRITE_UPT_REQ",
103    "WRITE_UPDATE",
104    "WRITE_UPT_DEC",
105    "WRITE_RSP",
106    "WRITE_TRT_LOCK",
107    "WRITE_TRT_DATA",
108    "WRITE_TRT_SET",
109    "WRITE_WAIT",
110    "WRITE_XRAM_REQ",
111    "WRITE_TRT_WRITE_LOCK",
112    "WRITE_INVAL_LOCK",
113    "WRITE_DIR_INVAL",
114    "WRITE_INVAL",
115    "WRITE_XRAM_SEND",
116    "WRITE_HEAP_ERASE",
117    "WRITE_HEAP_LAST",
118  };
119  const char *ixr_rsp_fsm_str[] = {
120    "IXR_RSP_IDLE",
121    "IXR_RSP_ACK",
122    "IXR_RSP_TRT_ERASE",
123    "IXR_RSP_TRT_READ",
124  };
125  const char *xram_rsp_fsm_str[] = {
126    "XRAM_RSP_IDLE",
127    "XRAM_RSP_TRT_COPY",
128    "XRAM_RSP_TRT_DIRTY",
129    "XRAM_RSP_DIR_LOCK",
130    "XRAM_RSP_DIR_UPDT",
131    "XRAM_RSP_DIR_RSP",
132    "XRAM_RSP_INVAL_LOCK",
133    "XRAM_RSP_INVAL_WAIT",
134    "XRAM_RSP_INVAL",
135    "XRAM_RSP_WRITE_DIRTY",
136    "XRAM_RSP_HEAP_ERASE",
137    "XRAM_RSP_HEAP_LAST",
138  };
139  const char *ixr_cmd_fsm_str[] = {
140    "IXR_CMD_READ_IDLE",
141    "IXR_CMD_WRITE_IDLE",
142    "IXR_CMD_LLSC_IDLE",
143    "IXR_CMD_XRAM_IDLE",
144    "IXR_CMD_READ_NLINE",
145    "IXR_CMD_WRITE_NLINE",
146    "IXR_CMD_LLSC_NLINE",
147    "IXR_CMD_XRAM_DATA",
148  };
149  const char *llsc_fsm_str[] = {
150    "LLSC_IDLE",
151    "LL_DIR_LOCK",
152    "LL_DIR_HIT",
153    "LL_RSP",
154    "SC_DIR_LOCK",
155    "SC_DIR_HIT",
156    "SC_UPT_LOCK",
157    "SC_WAIT",
158    "SC_HEAP_LOCK",
159    "SC_UPT_REQ",
160    "SC_UPDATE",
161    "SC_TRT_LOCK",
162    "SC_INVAL_LOCK",
163    "SC_DIR_INVAL",
164    "SC_INVAL",
165    "SC_XRAM_SEND",
166    "SC_HEAP_ERASE",
167    "SC_HEAP_LAST",
168    "SC_RSP_FALSE",
169    "SC_RSP_TRUE",
170    "LLSC_TRT_LOCK",
171    "LLSC_TRT_SET",
172    "LLSC_XRAM_REQ",
173  };
174  const char *cleanup_fsm_str[] = {
175    "CLEANUP_IDLE",
176    "CLEANUP_DIR_LOCK",
177    "CLEANUP_DIR_WRITE",
178    "CLEANUP_HEAP_LOCK",
179    "CLEANUP_HEAP_SEARCH",
180    "CLEANUP_HEAP_CLEAN",
181    "CLEANUP_HEAP_FREE",
182    "CLEANUP_UPT_LOCK",
183    "CLEANUP_UPT_WRITE",
184    "CLEANUP_WRITE_RSP",
185    "CLEANUP_RSP",
186  };
187  const char *alloc_dir_fsm_str[] = {
188    "ALLOC_DIR_READ",
189    "ALLOC_DIR_WRITE",
190    "ALLOC_DIR_LLSC",
191    "ALLOC_DIR_CLEANUP",
192    "ALLOC_DIR_XRAM_RSP",
193  };
194  const char *alloc_trt_fsm_str[] = {
195    "ALLOC_TRT_READ",
196    "ALLOC_TRT_WRITE",
197    "ALLOC_TRT_LLSC",
198    "ALLOC_TRT_XRAM_RSP",
199    "ALLOC_TRT_IXR_RSP",
200  };
201  const char *alloc_upt_fsm_str[] = {
202    "ALLOC_UPT_WRITE",
203    "ALLOC_UPT_XRAM_RSP",
204    "ALLOC_UPT_INIT_RSP",
205    "ALLOC_UPT_CLEANUP",
206  };
207  const char *alloc_heap_fsm_str[] = {
208    "ALLOC_HEAP_READ",
209    "ALLOC_HEAP_WRITE",
210    "ALLOC_HEAP_LLSC",
211    "ALLOC_HEAP_CLEANUP",
212    "ALLOC_HEAP_XRAM_RSP",
213  };
214
215#endif
216
217#define tmpl(x) template<typename vci_param> x VciMemCacheV3<vci_param>
218
219  using soclib::common::uint32_log2;
220
221  ////////////////////////////////
222  //    Constructor
223  ////////////////////////////////
224
225  tmpl(/**/)::VciMemCacheV3(
226      sc_module_name name,
227      const soclib::common::MappingTable &mtp,
228      const soclib::common::MappingTable &mtc,
229      const soclib::common::MappingTable &mtx,
230      const soclib::common::IntTab &vci_ixr_index,
231      const soclib::common::IntTab &vci_ini_index,
232      const soclib::common::IntTab &vci_tgt_index,
233      const soclib::common::IntTab &vci_tgt_index_cleanup,
234      size_t nways,
235      size_t nsets,
236      size_t nwords,
237      size_t heap_size)
238
239    : soclib::caba::BaseModule(name),
240
241    p_clk("clk"),
242    p_resetn("resetn"),
243    p_vci_tgt("vci_tgt"),
244    p_vci_tgt_cleanup("vci_tgt_cleanup"),
245    p_vci_ini("vci_ini"),
246    p_vci_ixr("vci_ixr"),
247
248    m_initiators( 1 << vci_param::S ),
249    m_heap_size( heap_size ),
250    m_ways( nways ),
251    m_sets( nsets ),
252    m_words( nwords ),
253    m_srcid_ixr( mtx.indexForId(vci_ixr_index) ),
254    m_srcid_ini( mtc.indexForId(vci_ini_index) ),
255    m_seglist(mtp.getSegmentList(vci_tgt_index)),
256    m_cseglist(mtc.getSegmentList(vci_tgt_index_cleanup)),
257    m_coherence_table( mtc.getCoherenceTable<vci_addr_t>() ),
258    m_atomic_tab( m_initiators ),
259    m_transaction_tab( TRANSACTION_TAB_LINES, nwords ),
260    m_update_tab( UPDATE_TAB_LINES ),
261    m_cache_directory( nways, nsets, nwords, vci_param::N ),
262    m_heap_directory( m_heap_size ),
263#define L2 soclib::common::uint32_log2
264    m_x( L2(m_words), 2),
265    m_y( L2(m_sets), L2(m_words) + 2),
266    m_z( vci_param::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
267    m_nline( vci_param::N - L2(m_words) - 2, L2(m_words) + 2),
268#undef L2
269
270    //  FIFOs
271    m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
272    m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
273    m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
274    m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
275    m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
276
277    m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
278    m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
279    m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
280    m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
281    m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
282    m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
283    m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
284
285    m_cmd_llsc_addr_fifo("m_cmd_llsc_addr_fifo",4),
286    m_cmd_llsc_sc_fifo("m_cmd_llsc_sc_fifo",4),
287    m_cmd_llsc_srcid_fifo("m_cmd_llsc_srcid_fifo",4),
288    m_cmd_llsc_trdid_fifo("m_cmd_llsc_trdid_fifo",4),
289    m_cmd_llsc_pktid_fifo("m_cmd_llsc_pktid_fifo",4),
290    m_cmd_llsc_wdata_fifo("m_cmd_llsc_wdata_fifo",4),
291
292    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
293   
294    nseg(0),   
295    ncseg(0),   
296
297    r_read_fsm("r_read_fsm"),
298    r_write_fsm("r_write_fsm"),
299    m_write_to_init_cmd_inst_fifo("m_write_to_init_cmd_inst_fifo",8),
300    m_write_to_init_cmd_srcid_fifo("m_write_to_init_cmd_srcid_fifo",8),
301    r_init_rsp_fsm("r_init_rsp_fsm"),
302    r_cleanup_fsm("r_cleanup_fsm"),
303    r_llsc_fsm("r_llsc_fsm"),
304    m_llsc_to_init_cmd_inst_fifo("m_llsc_to_init_cmd_inst_fifo",8),
305    m_llsc_to_init_cmd_srcid_fifo("m_llsc_to_init_cmd_srcid_fifo",8),
306    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
307    r_xram_rsp_fsm("r_xram_rsp_fsm"),
308    m_xram_rsp_to_init_cmd_inst_fifo("m_xram_rsp_to_init_cmd_inst_fifo",8),
309    m_xram_rsp_to_init_cmd_srcid_fifo("m_xram_rsp_to_init_cmd_srcid_fifo",8),
310    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
311    r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
312    r_init_cmd_fsm("r_init_cmd_fsm"),
313    r_alloc_dir_fsm("r_alloc_dir_fsm"),
314    r_alloc_trt_fsm("r_alloc_trt_fsm"),
315    r_alloc_upt_fsm("r_alloc_upt_fsm")
316    {
317      assert(IS_POW_OF_2(nsets));
318      assert(IS_POW_OF_2(nwords));
319      assert(IS_POW_OF_2(nways));
320      assert(nsets);
321      assert(nwords);
322      assert(nways);
323      assert(nsets <= 1024);
324      assert(nwords <= 32);
325      assert(nways <= 32);
326
327
328      // Get the segments associated to the MemCache
329      std::list<soclib::common::Segment>::iterator seg;
330
331      for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++) {
332        nseg++;
333      }
334      for(seg = m_cseglist.begin(); seg != m_cseglist.end() ; seg++) {
335        ncseg++;
336      }
337
338      m_seg = new soclib::common::Segment*[nseg];
339      size_t i = 0;
340      for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) {
341        m_seg[i] = &(*seg);
342        i++;
343      }
344      m_cseg = new soclib::common::Segment*[ncseg];
345      i = 0;
346      for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) {
347          m_cseg[i] = &(*seg);
348          i++;
349      }
350
351      // Memory cache allocation & initialisation
352      m_cache_data = new data_t**[nways];
353      for ( size_t i=0 ; i<nways ; ++i ) {
354        m_cache_data[i] = new data_t*[nsets];
355      }
356      for ( size_t i=0; i<nways; ++i ) {
357        for ( size_t j=0; j<nsets; ++j ) {
358          m_cache_data[i][j] = new data_t[nwords];
359          for ( size_t k=0; k<nwords; k++){
360            m_cache_data[i][j][k]=0;
361          }     
362        }
363      }
364
365      // Allocation for IXR_RSP FSM
366      r_ixr_rsp_to_xram_rsp_rok     = new sc_signal<bool>[TRANSACTION_TAB_LINES];
367
368      // Allocation for XRAM_RSP FSM
369      r_xram_rsp_victim_data        = new sc_signal<data_t>[nwords];
370      r_xram_rsp_to_tgt_rsp_data    = new sc_signal<data_t>[nwords];
371      r_xram_rsp_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
372
373      // Allocation for READ FSM
374      r_read_data                               = new sc_signal<data_t>[nwords];
375      r_read_to_tgt_rsp_data            = new sc_signal<data_t>[nwords];
376
377      // Allocation for WRITE FSM
378      r_write_data                              = new sc_signal<data_t>[nwords];
379      r_write_be                                = new sc_signal<be_t>[nwords];
380      r_write_to_init_cmd_data          = new sc_signal<data_t>[nwords];
381      r_write_to_init_cmd_we            = new sc_signal<bool>[nwords];
382      r_write_to_ixr_cmd_data       = new sc_signal<data_t>[nwords];
383
384      // Allocation for LLSC FSM
385      r_llsc_to_ixr_cmd_data        = new sc_signal<data_t>[nwords];
386
387
388      // Simulation
389
390      SC_METHOD(transition);
391      dont_initialize();
392      sensitive << p_clk.pos();
393
394      SC_METHOD(genMoore);
395      dont_initialize();
396      sensitive << p_clk.neg();
397
398    } // end constructor
399
400  /////////////////////////////////////////
401  // This function prints the statistics
402  /////////////////////////////////////////
403
404  tmpl(void)::print_stats()
405  {
406    std::cout << "----------------------------------" << std::dec << std::endl;
407    std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl
408      << "- READ RATE            = " << (double)m_cpt_read/m_cpt_cycles << std::endl
409      << "- READ MISS RATE       = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
410      << "- WRITE RATE           = " << (double)m_cpt_write/m_cpt_cycles << std::endl
411      << "- WRITE MISS RATE      = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
412      << "- WRITE BURST LENGTH   = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
413      << "- UPDATE RATE          = " << (double)m_cpt_update/m_cpt_cycles << std::endl
414      << "- UPDATE ARITY         = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
415      << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
416      << "- INVAL MULTICAST ARITY= " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
417      << "- INVAL BROADCAST RATE = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
418      << "- SAVE DIRTY RATE      = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
419      << "- CLEANUP RATE         = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
420      << "- LL RATE              = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
421      << "- SC RATE              = " << (double)m_cpt_sc/m_cpt_cycles << std::endl;
422  }
423
424  /////////////////////////////////
425  tmpl(/**/)::~VciMemCacheV3()
426    /////////////////////////////////
427  {
428    for(size_t i=0; i<m_ways ; i++){
429      for(size_t j=0; j<m_sets ; j++){
430        delete [] m_cache_data[i][j];
431      }
432    }
433    for(size_t i=0; i<m_ways ; i++){
434      delete [] m_cache_data[i];
435    }
436    delete [] m_cache_data;
437    delete [] m_coherence_table;
438
439    delete [] r_ixr_rsp_to_xram_rsp_rok;
440
441    delete [] r_xram_rsp_victim_data;
442    delete [] r_xram_rsp_to_tgt_rsp_data;
443    delete [] r_xram_rsp_to_ixr_cmd_data;
444
445    delete [] r_read_data;
446    delete [] r_read_to_tgt_rsp_data;
447
448    delete [] r_write_data;
449    delete [] r_write_be;
450    delete [] r_write_to_init_cmd_data;
451  }
452
453  //////////////////////////////////
454  tmpl(void)::transition()
455    //////////////////////////////////
456  {
457    using soclib::common::uint32_log2;
458    //  RESET         
459    if ( ! p_resetn.read() ) {
460
461      //     Initializing FSMs
462      r_tgt_cmd_fsm     = TGT_CMD_IDLE;
463      r_tgt_rsp_fsm     = TGT_RSP_READ_IDLE;
464      r_init_cmd_fsm    = INIT_CMD_INVAL_IDLE;
465      r_init_rsp_fsm    = INIT_RSP_IDLE;
466      r_read_fsm        = READ_IDLE;
467      r_write_fsm       = WRITE_IDLE;
468      r_llsc_fsm        = LLSC_IDLE;
469      r_cleanup_fsm     = CLEANUP_IDLE;
470      r_alloc_dir_fsm   = ALLOC_DIR_READ;
471      r_alloc_trt_fsm   = ALLOC_TRT_READ;
472      r_alloc_upt_fsm   = ALLOC_UPT_WRITE;
473      r_ixr_rsp_fsm     = IXR_RSP_IDLE;
474      r_xram_rsp_fsm    = XRAM_RSP_IDLE;
475      r_ixr_cmd_fsm     = IXR_CMD_READ_IDLE;
476
477      //  Initializing Tables
478      m_cache_directory.init();
479      m_atomic_tab.init();     
480      m_transaction_tab.init();
481      m_heap_directory.init();
482
483      // initializing FIFOs and communication Buffers
484
485      m_cmd_read_addr_fifo.init();
486      m_cmd_read_length_fifo.init();
487      m_cmd_read_srcid_fifo.init();
488      m_cmd_read_trdid_fifo.init();
489      m_cmd_read_pktid_fifo.init();
490
491      m_cmd_write_addr_fifo.init();
492      m_cmd_write_eop_fifo.init();
493      m_cmd_write_srcid_fifo.init();
494      m_cmd_write_trdid_fifo.init();
495      m_cmd_write_pktid_fifo.init();
496      m_cmd_write_data_fifo.init();
497
498      m_cmd_llsc_addr_fifo.init();
499      m_cmd_llsc_srcid_fifo.init();
500      m_cmd_llsc_trdid_fifo.init();
501      m_cmd_llsc_pktid_fifo.init();
502      m_cmd_llsc_wdata_fifo.init();
503      m_cmd_llsc_sc_fifo.init();
504
505      r_read_to_tgt_rsp_req         = false;
506      r_read_to_ixr_cmd_req         = false;
507
508      r_write_to_tgt_rsp_req            = false;
509      r_write_to_ixr_cmd_req            = false;
510      r_write_to_init_cmd_multi_req         = false;
511      r_write_to_init_cmd_brdcast_req   = false;
512      r_write_to_init_rsp_req           = false;
513      m_write_to_init_cmd_inst_fifo.init();
514      m_write_to_init_cmd_srcid_fifo.init();
515
516      r_cleanup_to_tgt_rsp_req  = false;
517
518      r_init_rsp_to_tgt_rsp_req = false;
519
520      r_llsc_to_tgt_rsp_req                 = false;
521      r_llsc_to_ixr_cmd_req                 = false;
522      r_llsc_to_init_cmd_multi_req          = false;
523      r_llsc_to_init_cmd_brdcast_req    = false;
524      m_llsc_to_init_cmd_inst_fifo.init();
525      m_llsc_to_init_cmd_srcid_fifo.init();
526
527      for(size_t i=0; i<TRANSACTION_TAB_LINES ; i++){
528        r_ixr_rsp_to_xram_rsp_rok[i] = false;
529      }
530
531      r_xram_rsp_to_tgt_rsp_req             = false;
532      r_xram_rsp_to_init_cmd_multi_req      = false;
533      r_xram_rsp_to_init_cmd_brdcast_req    = false;
534      r_xram_rsp_to_ixr_cmd_req             = false;
535      r_xram_rsp_trt_index                      = 0;
536      m_xram_rsp_to_init_cmd_inst_fifo.init();
537      m_xram_rsp_to_init_cmd_srcid_fifo.init();
538
539      r_ixr_cmd_cpt         = 0;
540
541      r_copies_limit        = 3;
542
543      // Activity counters
544      m_cpt_cycles                  = 0;
545      m_cpt_read                    = 0;
546      m_cpt_read_miss       = 0;
547      m_cpt_write                   = 0;
548      m_cpt_write_miss      = 0;
549      m_cpt_write_cells     = 0;
550      m_cpt_write_dirty     = 0;
551      m_cpt_update                  = 0;
552      m_cpt_update_mult     = 0;
553      m_cpt_inval_brdcast       = 0;
554      m_cpt_inval                   = 0;
555      m_cpt_inval_mult          = 0;
556      m_cpt_cleanup                 = 0;
557      m_cpt_ll                      = 0;
558      m_cpt_sc                      = 0;
559
560      return;
561    }
562
563    bool    cmd_read_fifo_put = false;
564    bool    cmd_read_fifo_get = false;
565
566    bool    cmd_write_fifo_put = false;
567    bool    cmd_write_fifo_get = false;
568
569    bool    cmd_llsc_fifo_put = false;
570    bool    cmd_llsc_fifo_get = false;
571
572    bool    write_to_init_cmd_fifo_put   = false;
573    bool    write_to_init_cmd_fifo_get   = false;
574    bool    write_to_init_cmd_fifo_inst  = false;
575    size_t  write_to_init_cmd_fifo_srcid = 0;
576
577    bool    xram_rsp_to_init_cmd_fifo_put   = false;
578    bool    xram_rsp_to_init_cmd_fifo_get   = false;
579    bool    xram_rsp_to_init_cmd_fifo_inst  = false;
580    size_t  xram_rsp_to_init_cmd_fifo_srcid = 0;
581
582    bool    llsc_to_init_cmd_fifo_put   = false;
583    bool    llsc_to_init_cmd_fifo_get   = false;
584    bool    llsc_to_init_cmd_fifo_inst  = false;
585    size_t  llsc_to_init_cmd_fifo_srcid = 0;
586
587#if DEBUG_VCI_MEM_CACHE
588    std::cout << "---------------------------------------------" << std::dec << std::endl;
589    std::cout << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
590      << " - TGT_CMD FSM    = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
591      << " - TGT_RSP FSM    = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
592      << " - INIT_CMD FSM   = " << init_cmd_fsm_str[r_init_cmd_fsm] << std::endl
593      << " - INIT_RSP FSM   = " << init_rsp_fsm_str[r_init_rsp_fsm] << std::endl
594      << " - READ FSM       = " << read_fsm_str[r_read_fsm] << std::endl
595      << " - WRITE FSM      = " << write_fsm_str[r_write_fsm] << std::endl
596      << " - LLSC FSM       = " << llsc_fsm_str[r_llsc_fsm] << std::endl
597      << " - CLEANUP FSM    = " << cleanup_fsm_str[r_cleanup_fsm] << std::endl
598      << " - IXR_CMD FSM    = " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] << std::endl
599      << " - IXR_RSP FSM    = " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] << std::endl
600      << " - XRAM_RSP FSM   = " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl
601      << " - ALLOC_DIR FSM  = " << alloc_dir_fsm_str[r_alloc_dir_fsm] << std::endl
602      << " - ALLOC_TRT FSM  = " << alloc_trt_fsm_str[r_alloc_trt_fsm] << std::endl
603      << " - ALLOC_UPT FSM  = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl
604      << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm] << std::endl;
605#endif
606
607
608    ////////////////////////////////////////////////////////////////////////////////////
609    //          TGT_CMD FSM
610    ////////////////////////////////////////////////////////////////////////////////////
611    // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
612    //
613    // There is 4 types of packets for the m_mem_segment :
614    // - READ    : a READ request has a length of 1 VCI cell. It can be a single word
615    //             or an entire cache line, depending on the PLEN value.
616    // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
617    //             concern words in a same line.
618    // - LL      : The LL request has a length of 1 cell.
619    // - SC      : The SC request has a length of 1 cell.
620    //             The WDATA field contains the data to write.
621    //
622    ////////////////////////////////////////////////////////////////////////////////////
623
624    switch ( r_tgt_cmd_fsm.read() ) {
625
626      //////////////////
627      case TGT_CMD_IDLE:
628        {
629          if ( p_vci_tgt.cmdval ) {
630            assert( (p_vci_tgt.srcid.read() < m_initiators)
631                && "VCI_MEM_CACHE error in VCI_MEM_CACHE : The received SRCID is larger than the number of initiators");
632
633            bool reached = false;
634            for ( size_t index = 0 ; index < nseg && !reached ; index++)
635            {
636//              if ( m_seg[index]->contains((addr_t)(p_vci_tgt.address.read())) ) {
637              if ( m_seg[index]->contains(p_vci_tgt.address.read()) ) {
638                reached = true;
639                r_index = index;
640              }
641            }
642
643
644            if ( !reached )
645            {
646              std::cout << "VCI_MEM_CACHE Out of segment access in VCI_MEM_CACHE" << std::endl;
647              std::cout << "Faulty address = " << std::hex << (addr_t)(p_vci_tgt.address.read()) << std::endl;
648              std::cout << "Faulty initiator = " << std::dec << p_vci_tgt.srcid.read() << std::endl;
649              exit(0);
650            }
651            else if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ )
652            {
653              r_tgt_cmd_fsm = TGT_CMD_READ;
654            }
655            else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )
656            { 
657              r_tgt_cmd_fsm = TGT_CMD_WRITE;
658            }
659            else if ((p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) ||
660                (p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND) )
661            {
662              r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
663            }
664          }
665          break;
666        }
667        //////////////////
668      case TGT_CMD_READ:
669
670        {
671          assert(((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2))<=16)
672              && "VCI_MEM_CACHE All read request to the MemCache must stay within a cache line");
673
674          if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() ) {
675            cmd_read_fifo_put = true;
676            if ( p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
677            else                  r_tgt_cmd_fsm = TGT_CMD_READ_EOP;             
678          }
679          break;
680        }
681        //////////////////////
682      case TGT_CMD_READ_EOP:
683        {
684          if ( p_vci_tgt.cmdval && p_vci_tgt.eop ){
685            r_tgt_cmd_fsm = TGT_CMD_IDLE;
686          }
687          break;
688        }
689        ///////////////////
690      case TGT_CMD_WRITE:
691        {
692
693          if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() ) {
694            cmd_write_fifo_put = true;
695            if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
696
697          }
698          break;
699        }
700        ////////////////////
701      case TGT_CMD_ATOMIC:
702        {
703          assert(p_vci_tgt.eop && "Memory Cache Error: LL or SC command with length > 1 ");
704
705          if ( p_vci_tgt.cmdval && m_cmd_llsc_addr_fifo.wok() ) {
706            cmd_llsc_fifo_put = true;
707            r_tgt_cmd_fsm = TGT_CMD_IDLE;
708          }
709          break;
710        }
711    } // end switch tgt_cmd_fsm
712
713    /////////////////////////////////////////////////////////////////////////
714    //          INIT_RSP FSM
715    /////////////////////////////////////////////////////////////////////////
716    // This FSM controls the response to the update or invalidate requests
717    // sent by the memory cache to the L1 caches :
718    //
719    // - update request initiated by the WRITE FSM. 
720    //   The FSM decrements the proper entry in the Update/Inval Table.
721    //   It sends a request to the TGT_RSP FSM to complete the pending
722    //   write transaction (acknowledge response to the writer processor),
723    //   and clear the UPT entry when all responses have been received. 
724    // - invalidate request initiated by the XRAM_RSP FSM.
725    //   The FSM decrements the proper entry in the Update/Inval_Table,
726    //   and clear the entry when all responses have been received.
727    //
728    // All those response packets are one word, compact
729    // packets complying with the VCI advanced format.
730    // The index in the Table is defined in the RTRDID field, and
731    // the Transaction type is defined in the Update/Inval Table.
732    /////////////////////////////////////////////////////////////////////
733
734    switch ( r_init_rsp_fsm.read() ) {
735
736      ///////////////////
737      case INIT_RSP_IDLE:
738        {
739
740          if ( p_vci_ini.rspval ) {
741
742            assert ( ( p_vci_ini.rtrdid.read() < m_update_tab.size() )
743                && "VCI_MEM_CACHE UPT index too large in VCI response paquet received by memory cache" );
744            assert ( p_vci_ini.reop
745                && "VCI_MEM_CACHE All response packets to update/invalidate requests must be one cell" );
746            r_init_rsp_upt_index = p_vci_ini.rtrdid.read();
747            r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
748          } else if( r_write_to_init_rsp_req.read() ){
749            r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read();
750            r_write_to_init_rsp_req = false;
751            r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
752          }
753          break;
754        }
755        ///////////////////////
756      case INIT_RSP_UPT_LOCK:   // decrement the number of expected responses
757        {
758
759          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) {
760            size_t count = 0;
761            bool valid  = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
762#ifdef IDEBUG
763        std::cout << sc_time_stamp() << " " << name() << " INIT_RSP_UPT_LOCK update table : " << std::endl;
764        m_update_tab.print();
765#endif
766            assert ( valid
767                && "VCI_MEM_CACHE Invalid UPT entry in VCI response paquet received by memory cache" );
768
769            if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
770            else              r_init_rsp_fsm = INIT_RSP_IDLE;
771          }
772          break;
773        }
774        ////////////////////////
775      case INIT_RSP_UPT_CLEAR:  // clear the UPT entry
776        {
777          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) {
778            r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
779            r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
780            r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
781            r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
782            bool need_rsp = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
783            if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
784            else            r_init_rsp_fsm = INIT_RSP_IDLE;
785            m_update_tab.clear(r_init_rsp_upt_index.read());
786#ifdef IDEBUG
787        std::cout << sc_time_stamp() << " " << name() << " INIT_RSP_UPT_CLEAR update table : " << std::endl;
788        m_update_tab.print();
789#endif
790          }
791          break;
792        }
793        //////////////////
794      case INIT_RSP_END:
795        {
796
797          if ( !r_init_rsp_to_tgt_rsp_req ) {
798            r_init_rsp_to_tgt_rsp_req = true;
799            r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
800            r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
801            r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
802            r_init_rsp_fsm = INIT_RSP_IDLE;
803          }
804          break;
805        }
806    } // end switch r_init_rsp_fsm
807
808    ////////////////////////////////////////////////////////////////////////////////////
809    //          READ FSM
810    ////////////////////////////////////////////////////////////////////////////////////
811    // The READ FSM controls the read requests sent by processors.
812    // It takes the lock protecting the cache directory to check the cache line status:
813    // - In case of HIT, the fsm copies the data (one line, or one single word)
814    //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
815    //   The requesting initiator is registered in the cache directory.
816    // - In case of MISS, the READ fsm takes the lock protecting the transaction tab.
817    //   If a read transaction to the XRAM for this line already exists,
818    //   or if the transaction tab is full, the fsm is stalled.
819    //   If a transaction entry is free, the READ fsm sends a request to the XRAM.
820    ////////////////////////////////////////////////////////////////////////////////////
821
822    switch ( r_read_fsm.read() ) {
823
824      ///////////////
825      case READ_IDLE:
826        {
827          if (m_cmd_read_addr_fifo.rok()) {
828            m_cpt_read++;
829            r_read_fsm = READ_DIR_LOCK;
830          }
831          break;
832        }
833        ///////////////////
834      case READ_DIR_LOCK:       // check directory for hit / miss
835        {
836          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
837            size_t way = 0;
838            DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
839#ifdef DDEBUG
840           std::cout << "In READ_DIR_LOCK printing the entry of address is : " << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
841           entry.print();
842           std::cout << "done" << std::endl;
843#endif
844
845            r_read_is_cnt   = entry.is_cnt;
846            r_read_dirty    = entry.dirty;
847            r_read_lock     = entry.lock;
848            r_read_inst     = entry.inst;
849            r_read_tag      = entry.tag;
850            r_read_way      = way;
851            r_read_count    = entry.count;
852            r_read_copy     = entry.owner.srcid;
853            r_read_copy_inst= entry.owner.inst;
854            r_read_ptr      = entry.ptr;
855
856            bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
857            // In case of hit, the read acces must be registered in the copies bit-vector
858            if(  entry.valid ) {
859              if(entry.is_cnt || (entry.count == 0) || !cached_read)  { // No new entry in the heap
860                r_read_fsm = READ_DIR_HIT;
861              } else {
862                r_read_fsm = READ_HEAP_LOCK;
863              }
864            } else {
865              r_read_fsm = READ_TRT_LOCK;
866              m_cpt_read_miss++;
867            }
868          }
869          break;
870        }
871        //////////////////
872      case READ_DIR_HIT:        // read hit : update the memory cache
873        {
874          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
875            // signals generation
876            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
877            bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
878            bool is_cnt = r_read_is_cnt.read();
879
880            // read data in the cache
881            size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
882            size_t way = r_read_way.read();
883            for ( size_t i=0 ; i<m_words ; i++ ) {
884              r_read_data[i] = m_cache_data[way][set][i];
885            }
886
887            // update the cache directory (for the copies)
888            DirectoryEntry entry;
889            entry.valid   = true;
890            entry.is_cnt  = is_cnt;
891            entry.dirty   = r_read_dirty.read();
892            entry.tag     = r_read_tag.read();
893            entry.lock    = r_read_lock.read();
894            entry.ptr     = r_read_ptr.read();
895            if(cached_read){  // Cached read, we update the copy
896              if(!is_cnt){ // Not counter mode
897                entry.owner.srcid   = m_cmd_read_srcid_fifo.read();
898                entry.owner.inst    = inst_read;
899                entry.inst          = r_read_inst.read() || inst_read;
900                entry.count         = r_read_count.read() + 1;
901              } else { // Counter mode
902                entry.owner.srcid   = 0;
903                entry.owner.inst    = false;
904                entry.inst          = r_read_inst.read() || inst_read;
905                entry.count         = r_read_count.read() + 1;
906              }
907            } else { // Uncached read
908              entry.owner.srcid     = r_read_copy.read();
909              entry.owner.inst      = r_read_copy_inst.read();
910              entry.inst            = r_read_inst.read();
911              entry.count           = r_read_count.read();
912            }
913#ifdef DDEBUG
914           std::cout << "In READ_DIR_HIT printing the entry of address is : " << std::endl;
915           entry.print();
916           std::cout << "done" << std::endl;
917#endif
918
919            m_cache_directory.write(set, way, entry);
920            r_read_fsm    = READ_RSP;
921          }
922          break;
923        }
924        //////////////
925      case READ_HEAP_LOCK:
926        {
927          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) {
928            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
929            bool is_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap_directory.is_full();
930            // read data in the cache
931            size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
932            size_t way = r_read_way.read();
933            for ( size_t i=0 ; i<m_words ; i++ ) {
934              r_read_data[i] = m_cache_data[way][set][i];
935            }
936
937            // update the cache directory (for the copies)
938            DirectoryEntry entry;
939            entry.valid   = true;
940            entry.is_cnt  = is_cnt; // when we reach the limit of copies or the heap is full
941            entry.dirty   = r_read_dirty.read();
942            entry.tag     = r_read_tag.read();
943            entry.lock    = r_read_lock.read();
944            if(!is_cnt){ // Not counter mode
945                entry.owner.srcid   = r_read_copy.read();
946                entry.owner.inst    = r_read_copy_inst.read();
947                entry.inst          = r_read_inst.read() || inst_read;
948                entry.count         = r_read_count.read() + 1;
949                entry.ptr           = m_heap_directory.next_free_ptr();
950            } else { // Counter mode
951                entry.owner.srcid   = 0;
952                entry.owner.inst    = false;
953                entry.inst          = r_read_inst.read() || inst_read;
954                entry.count         = r_read_count.read() + 1;
955                entry.ptr           = 0;
956            }
957#ifdef DDEBUG
958           std::cout << "In READ_HEAP_LOCK printing the entry of address is : " << std::endl;
959           entry.print();
960           std::cout << "done" << std::endl;
961#endif
962
963            m_cache_directory.write(set, way, entry);
964
965            if(!is_cnt){
966              HeapEntry free_heap_entry = m_heap_directory.next_free_entry();
967              r_read_next_ptr = free_heap_entry.next;
968              if( free_heap_entry.next == m_heap_directory.next_free_ptr() ) { // Last free heap entry
969                r_read_last_free = true;
970              } else {
971                r_read_last_free = false;
972              }
973              r_read_fsm = READ_HEAP_WRITE; // we add an entry in the list of copies
974            } else {
975              if(r_read_count.read()>1) { // else there is no list of copies...
976                HeapEntry next_entry = m_heap_directory.read(r_read_ptr.read());
977                r_read_next_ptr = m_heap_directory.next_free_ptr();
978                m_heap_directory.write_free_ptr(r_read_ptr.read());
979                if( next_entry.next == r_read_ptr.read() ) { // The last list member
980                  r_read_fsm = READ_HEAP_LAST; // we erase the list of copies (counter mode)
981                } else { // Not the end of the list
982                  r_read_ptr = next_entry.next;
983                  r_read_fsm = READ_HEAP_ERASE; // we erase the list of copies (counter mode)
984                }
985              } else {
986                r_read_fsm = READ_RSP;
987              }
988            }
989          }
990          break;
991        }
992        //////////////
993      case READ_HEAP_WRITE:
994        {
995          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
996            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
997            HeapEntry new_heap_entry;
998            new_heap_entry.owner.srcid  = m_cmd_read_srcid_fifo.read();
999            new_heap_entry.owner.inst   = inst_read;
1000            if(r_read_count.read() == 1){ // creation of a new list
1001              new_heap_entry.next         = m_heap_directory.next_free_ptr();
1002            } else {                      // it is an insertion
1003              new_heap_entry.next         = r_read_ptr.read();
1004            }
1005            m_heap_directory.write_free_entry(new_heap_entry);
1006            m_heap_directory.write_free_ptr(r_read_next_ptr.read());
1007            if(r_read_last_free.read()) {
1008              m_heap_directory.set_full();
1009            }
1010
1011            r_read_fsm = READ_RSP;
1012          } else {
1013            assert(false && "MEMCACHE Error : Bad HEAP allocation");
1014          }
1015          break;
1016        }
1017        //////////////
1018      case READ_HEAP_ERASE:
1019        {
1020          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
1021            HeapEntry next_entry = m_heap_directory.read(r_read_ptr.read());
1022            if( next_entry.next == r_read_ptr.read() ){
1023              r_read_fsm = READ_HEAP_LAST;
1024            } else {
1025              r_read_ptr = next_entry.next;
1026              r_read_fsm = READ_HEAP_ERASE;
1027            }
1028          } else {
1029            assert(false && "MEMCACHE Error : Bad HEAP allocation");
1030          }
1031          break;
1032        }
1033        //////////////
1034      case READ_HEAP_LAST:
1035        {
1036          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
1037            HeapEntry last_entry;
1038            last_entry.owner.srcid = 0;
1039            last_entry.owner.inst  = false;
1040            if(m_heap_directory.is_full()){
1041              last_entry.next      = r_read_ptr.read();
1042              m_heap_directory.unset_full();
1043            } else {
1044              last_entry.next      = r_read_next_ptr.read();
1045            }
1046            m_heap_directory.write(r_read_ptr.read(),last_entry);
1047            r_read_fsm = READ_RSP;
1048          } else {
1049            assert(false && "MEMCACHE Error : Bad HEAP allocation");
1050          }
1051          break;
1052        }
1053        //////////////
1054      case READ_RSP:            //  request the TGT_RSP FSM to return data
1055        {
1056          if( !r_read_to_tgt_rsp_req ) {       
1057            for ( size_t i=0 ; i<m_words ; i++ ) {
1058              r_read_to_tgt_rsp_data[i] = r_read_data[i];
1059            }
1060            r_read_to_tgt_rsp_word   = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()];
1061            r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
1062            cmd_read_fifo_get            = true;
1063            r_read_to_tgt_rsp_req        = true;
1064            r_read_to_tgt_rsp_srcid      = m_cmd_read_srcid_fifo.read();
1065            r_read_to_tgt_rsp_trdid      = m_cmd_read_trdid_fifo.read();
1066            r_read_to_tgt_rsp_pktid      = m_cmd_read_pktid_fifo.read();
1067            r_read_fsm                       = READ_IDLE; 
1068          }
1069          break;
1070        }
1071        ///////////////////
1072      case READ_TRT_LOCK:       // read miss : check the Transaction Table
1073        {
1074          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
1075#ifdef TDEBUG
1076        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_LOCK " << std::endl;
1077#endif
1078            size_t index = 0;
1079            bool   hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())], index);
1080            bool   hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())]);
1081            bool   wok = !m_transaction_tab.full(index);
1082            if( hit_read || !wok || hit_write ) {  // missing line already requested or no space
1083              r_read_fsm = READ_IDLE;
1084            } else {                       // missing line is requested to the XRAM
1085              r_read_trt_index = index;
1086              r_read_fsm       = READ_TRT_SET;
1087            }
1088          }
1089          break;
1090        }
1091        //////////////////
1092      case READ_TRT_SET:
1093        {
1094          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
1095            m_transaction_tab.set(r_read_trt_index.read(),
1096                true,
1097                m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
1098                m_cmd_read_srcid_fifo.read(),
1099                m_cmd_read_trdid_fifo.read(),
1100                m_cmd_read_pktid_fifo.read(),
1101                true,
1102                m_cmd_read_length_fifo.read(),
1103                m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
1104                std::vector<be_t>(m_words,0),
1105                std::vector<data_t>(m_words,0));
1106#ifdef TDEBUG
1107        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_SET transaction table : " << std::endl;
1108        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1109          m_transaction_tab.print(i);
1110#endif
1111
1112            r_read_fsm   = READ_XRAM_REQ;
1113          }
1114          break;
1115        }
1116        /////////////////////
1117      case READ_XRAM_REQ:
1118        {
1119          if( !r_read_to_ixr_cmd_req ) {
1120            cmd_read_fifo_get           = true;
1121            r_read_to_ixr_cmd_req       = true;
1122            r_read_to_ixr_cmd_nline     = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
1123            r_read_to_ixr_cmd_trdid     = r_read_trt_index.read();
1124            r_read_fsm                            = READ_IDLE;
1125          }
1126          break;
1127        }
1128    } // end switch read_fsm
1129
1130    ///////////////////////////////////////////////////////////////////////////////////
1131    //          WRITE FSM
1132    ///////////////////////////////////////////////////////////////////////////////////
1133    // The WRITE FSM handles the write bursts sent by the processors.
1134    // All addresses in a burst must be in the same cache line.
1135    // A complete write burst is consumed in the FIFO & copied to a local buffer.
1136    // Then the FSM takes the lock protecting the cache directory, to check
1137    // if the line is in the cache.
1138    //
1139    // - In case of HIT, the cache is updated.
1140    //   If there is no other copy, an acknowledge response is immediately
1141    //   returned to the writing processor.
1142    //   if the data is cached by other processoris, the FSM takes the lock
1143    //   protecting the Update Table (UPT) to register this update transaction.
1144    //   If the UPT is full, it releases the lock  and waits. Then, it sends
1145    //   a multi-update request to all owners of the line (but the writer),
1146    //   through the INIT_CMD FSM. In case of multi-update transaction, the WRITE FSM
1147    //   does not respond to the writing processor, as this response will be sent by
1148    //   the INIT_RSP FSM when all update responses have been received.
1149    //
1150    // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
1151    //   table (TRT). If a read transaction to the XRAM for this line already exists,
1152    //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
1153    //   the WRITE FSM register a new transaction in TRT, and sends a read line request
1154    //   to the XRAM. If the TRT is full, it releases the lock, and waits.
1155    //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
1156    /////////////////////////////////////////////////////////////////////////////////////
1157
1158    switch ( r_write_fsm.read() ) {
1159
1160      ////////////////
1161      case WRITE_IDLE:  // copy first word of a write burst in local buffer     
1162        {
1163          if ( m_cmd_write_addr_fifo.rok()) {
1164            m_cpt_write++;
1165            m_cpt_write_cells++;
1166            // consume a word in the FIFO & write it in the local buffer
1167            cmd_write_fifo_get  = true;
1168            size_t index            = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
1169            r_write_address         = (addr_t)(m_cmd_write_addr_fifo.read());
1170            r_write_word_index  = index;
1171            r_write_word_count  = 1;
1172            r_write_data[index] = m_cmd_write_data_fifo.read();
1173            r_write_srcid           = m_cmd_write_srcid_fifo.read();
1174            r_write_trdid           = m_cmd_write_trdid_fifo.read();
1175            r_write_pktid           = m_cmd_write_pktid_fifo.read();
1176
1177            // the be field must be set for all words
1178            for ( size_t i=0 ; i<m_words ; i++ ) {
1179              if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
1180              else                      r_write_be[i] = 0x0;
1181            }
1182            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1183                    r_write_byte=true;
1184            else    r_write_byte=false;
1185
1186            if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1187            else                               r_write_fsm = WRITE_NEXT;
1188          }
1189          break;
1190        }
1191        ////////////////
1192      case WRITE_NEXT:  // copy next word of a write burst in local buffer
1193        {
1194          if ( m_cmd_write_addr_fifo.rok() ) {
1195            m_cpt_write_cells++;
1196
1197            // check that the next word is in the same cache line
1198            assert( (m_nline[(vci_addr_t)(r_write_address.read())] == m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())]) 
1199                && "VCI_MEM_CACHE write error in vci_mem_cache : write burst over a line" );
1200            // consume a word in the FIFO & write it in the local buffer
1201            cmd_write_fifo_get=true;
1202            size_t index                = r_write_word_index.read() + r_write_word_count.read();
1203            r_write_be[index]       = m_cmd_write_be_fifo.read();
1204            r_write_data[index]     = m_cmd_write_data_fifo.read();
1205            r_write_word_count      = r_write_word_count.read() + 1;
1206            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1207              r_write_byte=true;
1208            if ( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1209          }
1210          break;
1211        }
1212        ////////////////////
1213      case WRITE_DIR_LOCK:      // access directory to check hit/miss
1214        {
1215          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) {
1216            size_t  way = 0;
1217            DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
1218
1219            // copy directory entry in local buffers in case of hit
1220            if ( entry.valid )  {       
1221              r_write_is_cnt    = entry.is_cnt;
1222              r_write_lock          = entry.lock;
1223              r_write_inst      = entry.inst;
1224              r_write_tag       = entry.tag;
1225              r_write_copy      = entry.owner.srcid;
1226              r_write_copy_inst = entry.owner.inst;
1227              r_write_count     = entry.count;
1228              r_write_ptr       = entry.ptr;
1229              r_write_way           = way;
1230             
1231              bool owner = (entry.owner.srcid==r_write_srcid.read()) && !entry.owner.inst;
1232              bool no_update = (entry.count==0) || ( owner && (entry.count==1));
1233              if((entry.is_cnt && entry.count) ||
1234                  entry.inst){
1235                r_write_fsm      = WRITE_DIR_HIT_READ;
1236              } else {
1237                if(r_write_byte.read())
1238                  r_write_fsm      = WRITE_DIR_HIT_READ;
1239                else{
1240                    if( no_update) r_write_fsm  = WRITE_DIR_HIT_RSP;
1241                    else           r_write_fsm  = WRITE_DIR_HIT;
1242                }
1243              }
1244            } else {
1245              r_write_fsm = WRITE_TRT_LOCK;
1246              m_cpt_write_miss++;
1247            }
1248          }
1249          break;
1250        }
1251        ///////////////////
1252      case WRITE_DIR_HIT_READ:  // read the cache and complete the buffer (data, when be!=0xF)
1253        {
1254          // update local buffer
1255          size_t set    = m_y[(vci_addr_t)(r_write_address.read())];
1256          size_t way    = r_write_way.read();
1257          for(size_t i=0 ; i<m_words ; i++) {
1258            data_t mask      = 0;
1259            if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
1260            if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
1261            if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
1262            if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
1263            if(r_write_be[i].read()||r_write_is_cnt.read()||r_write_inst.read()) { // complete only if mask is not null (for energy consumption)
1264              r_write_data[i]  = (r_write_data[i].read() & mask) |
1265                (m_cache_data[way][set][i] & ~mask);
1266            }
1267          } // end for
1268
1269          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
1270          bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
1271          if((r_write_is_cnt.read() && r_write_count.read()) ||
1272              r_write_inst.read()){
1273            r_write_fsm            = WRITE_TRT_WRITE_LOCK;
1274          } else {
1275            if( no_update ) r_write_fsm = WRITE_DIR_HIT_RSP;
1276            else            r_write_fsm = WRITE_DIR_HIT;
1277          }
1278          break;
1279        }
1280        ///////////////////
1281      case WRITE_DIR_HIT:       // update the cache (data & dirty bit)
1282        {
1283          // update directory with Dirty bit
1284          DirectoryEntry entry;
1285          entry.valid       = true;
1286          entry.dirty       = true;
1287          entry.tag             = r_write_tag.read();
1288          entry.is_cnt      = r_write_is_cnt.read();
1289          entry.lock        = r_write_lock.read();
1290          entry.inst        = r_write_inst.read();
1291          entry.owner.srcid = r_write_copy.read();
1292          entry.owner.inst  = r_write_copy_inst.read();
1293          entry.count       = r_write_count.read();
1294          entry.ptr         = r_write_ptr.read();
1295          size_t set        = m_y[(vci_addr_t)(r_write_address.read())];
1296          size_t way        = r_write_way.read();
1297          m_cache_directory.write(set, way, entry);
1298
1299          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
1300
1301          size_t count_signal   = r_write_count.read();
1302          if(owner){
1303            count_signal        = count_signal - 1;
1304          }
1305          r_write_count         = count_signal;
1306          r_write_to_dec        = false;
1307
1308          if( !r_write_to_init_cmd_multi_req.read() &&
1309              !r_write_to_init_cmd_brdcast_req.read()  )
1310            r_write_fsm = WRITE_UPT_LOCK;
1311          else
1312            r_write_fsm = WRITE_WAIT;
1313          break;
1314        }
1315        ///////////////////
1316      case WRITE_DIR_HIT_RSP:   // update the cache (data & dirty bit) no update
1317        {
1318          // update directory with Dirty bit
1319          DirectoryEntry entry;
1320          entry.valid       = true;
1321          entry.dirty       = true;
1322          entry.tag             = r_write_tag.read();
1323          entry.is_cnt      = r_write_is_cnt.read();
1324          entry.lock        = r_write_lock.read();
1325          entry.inst        = r_write_inst.read();
1326          entry.owner.srcid = r_write_copy.read();
1327          entry.owner.inst  = r_write_copy_inst.read();
1328          entry.count       = r_write_count.read();
1329          entry.ptr         = r_write_ptr.read();
1330          size_t set        = m_y[(vci_addr_t)(r_write_address.read())];
1331          size_t way        = r_write_way.read();
1332          m_cache_directory.write(set, way, entry);
1333
1334          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
1335
1336          // write data in cache
1337          for(size_t i=0 ; i<m_words ; i++) {
1338              if  ( r_write_be[i].read() ) {
1339                  m_cache_data[way][set][i]  = r_write_data[i].read();
1340              }
1341          } // end for
1342
1343          if ( !r_write_to_tgt_rsp_req.read() ) {
1344            r_write_to_tgt_rsp_req          = true;
1345            r_write_to_tgt_rsp_srcid    = r_write_srcid.read();
1346            r_write_to_tgt_rsp_trdid    = r_write_trdid.read();
1347            r_write_to_tgt_rsp_pktid    = r_write_pktid.read();
1348            r_write_fsm                         = WRITE_IDLE;
1349          } else {
1350            r_write_fsm = WRITE_RSP;
1351          }
1352          break;
1353        }
1354        /////////////////////
1355      case WRITE_UPT_LOCK:      // Try to register the request in Update Table
1356        {
1357
1358          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1359            bool        wok        = false;
1360            size_t      index      = 0;
1361            size_t      srcid      = r_write_srcid.read();
1362            size_t      trdid      = r_write_trdid.read();
1363            size_t      pktid      = r_write_pktid.read();
1364            addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
1365            size_t      nb_copies  = r_write_count.read();
1366            size_t set      = m_y[(vci_addr_t)(r_write_address.read())];
1367            size_t way      = r_write_way.read();
1368
1369            wok =m_update_tab.set(true, // it's an update transaction
1370                false,                  // it's not a broadcast
1371                true,                   // it needs a response
1372                srcid,
1373                trdid,
1374                pktid,
1375                nline,
1376                nb_copies,
1377                index);
1378            if(wok){
1379              // write data in cache
1380              for(size_t i=0 ; i<m_words ; i++) {
1381                if  ( r_write_be[i].read() ) {
1382                  m_cache_data[way][set][i]  = r_write_data[i].read();
1383                }
1384              } // end for
1385            }
1386#ifdef IDEBUG
1387            if(wok){
1388        std::cout << sc_time_stamp() << " " << name() << " WRITE_UPT_LOCK update table : " << std::endl;
1389        m_update_tab.print();
1390            }
1391#endif
1392            r_write_upt_index = index;
1393            //  releases the lock protecting the Update Table and the Directory if no entry...
1394            if ( wok ) r_write_fsm = WRITE_HEAP_LOCK;
1395            else       r_write_fsm = WRITE_WAIT;
1396          }
1397          break;
1398        }
1399        //////////////////
1400      case WRITE_HEAP_LOCK:
1401        {
1402          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE ){
1403            r_write_fsm = WRITE_UPT_REQ;
1404          }
1405          break;
1406        }
1407        //////////////////
1408      case WRITE_UPT_REQ:
1409        {
1410          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
1411                    "MemCache ERROR : bad HEAP allocation");
1412          if( !r_write_to_init_cmd_multi_req.read() &&
1413              !r_write_to_init_cmd_brdcast_req.read()  ){
1414            r_write_to_init_cmd_brdcast_req  = false;
1415            r_write_to_init_cmd_trdid        = r_write_upt_index.read();
1416            r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
1417            r_write_to_init_cmd_index        = r_write_word_index.read();
1418            r_write_to_init_cmd_count        = r_write_word_count.read();
1419
1420            for(size_t i=0; i<m_words ; i++){
1421              if(r_write_be[i].read())  r_write_to_init_cmd_we[i]=true;
1422              else                      r_write_to_init_cmd_we[i]=false;
1423            }
1424
1425            size_t min = r_write_word_index.read();
1426            size_t max = r_write_word_index.read() + r_write_word_count.read();
1427            for (size_t i=min ; i<max ; i++) {
1428              r_write_to_init_cmd_data[i] = r_write_data[i];
1429            }
1430           
1431            if( r_write_copy.read() != r_write_srcid.read() ) {
1432              // We put the first copy in the fifo
1433              write_to_init_cmd_fifo_put     = true;
1434              write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
1435              write_to_init_cmd_fifo_srcid   = r_write_copy.read();
1436              if(r_write_count.read() == 1){
1437                r_write_fsm = WRITE_IDLE;
1438                r_write_to_init_cmd_multi_req = true;
1439              } else {
1440                r_write_fsm = WRITE_UPDATE;
1441              }
1442            } else {
1443              r_write_fsm = WRITE_UPDATE;
1444            }
1445          }
1446          break;
1447        }
1448        //////////////////
1449      case WRITE_UPDATE:        // send a multi-update request to INIT_CMD fsm
1450        {
1451          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
1452                    "MemCache ERROR : bad HEAP allocation");
1453          HeapEntry entry = m_heap_directory.read(r_write_ptr.read());
1454          write_to_init_cmd_fifo_inst  = entry.owner.inst;
1455          write_to_init_cmd_fifo_srcid = entry.owner.srcid;
1456          bool dec_upt_counter = r_write_to_dec.read();
1457          if( (entry.owner.srcid != r_write_srcid.read()) || entry.owner.inst ){
1458            write_to_init_cmd_fifo_put = true;
1459          } else {
1460            dec_upt_counter = true;
1461          }
1462          r_write_to_dec = dec_upt_counter;
1463
1464          if( m_write_to_init_cmd_inst_fifo.wok() ){
1465            r_write_ptr = entry.next;
1466            if( entry.next == r_write_ptr.read() ) { // last copy
1467              r_write_to_init_cmd_multi_req = true;
1468              if(dec_upt_counter){
1469                r_write_fsm = WRITE_UPT_DEC;
1470              } else {
1471                r_write_fsm = WRITE_IDLE;
1472              }
1473            } else {
1474              r_write_fsm = WRITE_UPDATE;
1475            }
1476          } else {
1477            r_write_fsm = WRITE_UPDATE;
1478          }
1479          break;
1480        }
1481        //////////////////
1482      case WRITE_UPT_DEC:
1483        {
1484          if(!r_write_to_init_rsp_req.read()){
1485            r_write_to_init_rsp_req = true;
1486            r_write_to_init_rsp_upt_index = r_write_upt_index.read();
1487            r_write_fsm = WRITE_IDLE;
1488          }
1489          break;
1490        }
1491        ///////////////
1492      case WRITE_RSP:           // send a request to TGT_RSP FSM to acknowledge the write
1493        {
1494          if ( !r_write_to_tgt_rsp_req.read() ) {
1495            r_write_to_tgt_rsp_req          = true;
1496            r_write_to_tgt_rsp_srcid    = r_write_srcid.read();
1497            r_write_to_tgt_rsp_trdid    = r_write_trdid.read();
1498            r_write_to_tgt_rsp_pktid    = r_write_pktid.read();
1499            r_write_fsm                         = WRITE_IDLE;
1500          }
1501          break;
1502        }
1503        ////////////////////
1504      case WRITE_TRT_LOCK:      // Miss : check Transaction Table
1505        {
1506          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1507#ifdef TDEBUG
1508        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_LOCK " << std::endl;
1509#endif
1510            size_t hit_index = 0;
1511            size_t wok_index = 0;
1512            bool hit_read  = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(r_write_address.read())],hit_index);
1513            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(r_write_address.read())]);
1514            bool wok = !m_transaction_tab.full(wok_index);
1515            if ( hit_read ) {   // register the modified data in TRT
1516              r_write_trt_index = hit_index;
1517              r_write_fsm       = WRITE_TRT_DATA;
1518            } else if ( wok && !hit_write ) {   // set a new entry in TRT
1519              r_write_trt_index = wok_index;
1520              r_write_fsm       = WRITE_TRT_SET;
1521            } else {            // wait an empty entry in TRT
1522              r_write_fsm       = WRITE_WAIT;
1523            }
1524          }
1525          break;
1526        }
1527        ////////////////////
1528      case WRITE_WAIT:  // release the lock protecting TRT
1529        {
1530          r_write_fsm = WRITE_DIR_LOCK;
1531          break;
1532        }
1533        ///////////////////
1534      case WRITE_TRT_SET:       // register a new transaction in TRT (Write Buffer)
1535        { 
1536          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
1537          {
1538            std::vector<be_t> be_vector;
1539            std::vector<data_t> data_vector;
1540            be_vector.clear();
1541            data_vector.clear();
1542            for ( size_t i=0; i<m_words; i++ )
1543            {
1544              be_vector.push_back(r_write_be[i]);
1545              data_vector.push_back(r_write_data[i]);
1546            }
1547            m_transaction_tab.set(r_write_trt_index.read(),
1548                true,                           // read request to XRAM
1549                m_nline[(vci_addr_t)(r_write_address.read())],
1550                r_write_srcid.read(),
1551                r_write_trdid.read(),
1552                r_write_pktid.read(),
1553                false,                          // not a processor read
1554                0,                              // not a single word
1555                0,                              // word index
1556                be_vector,
1557                data_vector);
1558#ifdef TDEBUG
1559        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_SET transaction table : " << std::endl;
1560        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1561          m_transaction_tab.print(i);
1562#endif
1563
1564            r_write_fsm = WRITE_XRAM_REQ;
1565          }
1566          break;
1567        } 
1568        ///////////////////
1569      case WRITE_TRT_DATA:      // update an entry in TRT (Write Buffer)
1570        {
1571          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1572            std::vector<be_t> be_vector;
1573            std::vector<data_t> data_vector;
1574            be_vector.clear();
1575            data_vector.clear();
1576            for ( size_t i=0; i<m_words; i++ ) {
1577              be_vector.push_back(r_write_be[i]);
1578              data_vector.push_back(r_write_data[i]);
1579            }
1580            m_transaction_tab.write_data_mask(r_write_trt_index.read(),
1581                be_vector,
1582                data_vector);
1583            r_write_fsm = WRITE_RSP;
1584#ifdef TDEBUG
1585        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_DATA transaction table : " << std::endl;
1586        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1587          m_transaction_tab.print(i);
1588#endif
1589
1590          }
1591          break;
1592        }
1593        ////////////////////
1594      case WRITE_XRAM_REQ:      // send a request to IXR_CMD FSM
1595        { 
1596
1597          if ( !r_write_to_ixr_cmd_req ) {
1598            r_write_to_ixr_cmd_req   = true;
1599            r_write_to_ixr_cmd_write = false;
1600            r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
1601            r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
1602            r_write_fsm              = WRITE_RSP;
1603          }
1604          break;
1605        }
1606        ////////////////////
1607      case WRITE_TRT_WRITE_LOCK:
1608        {
1609          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1610            size_t wok_index = 0;
1611            bool wok = !m_transaction_tab.full(wok_index);
1612            if ( wok ) {        // set a new entry in TRT
1613              r_write_trt_index = wok_index;
1614              r_write_fsm       = WRITE_INVAL_LOCK;
1615            } else {            // wait an empty entry in TRT
1616              r_write_fsm       = WRITE_WAIT;
1617            }
1618          }
1619
1620          break;
1621        }
1622        ////////////////////
1623      case WRITE_INVAL_LOCK:
1624        {
1625          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1626            bool        wok       = false;
1627            size_t      index     = 0;
1628            size_t      srcid     = r_write_srcid.read();
1629            size_t      trdid     = r_write_trdid.read();
1630            size_t      pktid     = r_write_pktid.read();
1631            addr_t          nline     = m_nline[(vci_addr_t)(r_write_address.read())];
1632            size_t      nb_copies = r_write_count.read();
1633
1634            wok =m_update_tab.set(false,        // it's an inval transaction
1635                true,                       // it's a broadcast
1636                true,                       // it needs a response
1637                srcid,
1638                trdid,
1639                pktid,
1640                nline,
1641                nb_copies,
1642                index);
1643#ifdef IDEBUG
1644            if(wok){
1645        std::cout << sc_time_stamp() << " " << name() << " WRITE_INVAL_LOCK update table : " << std::endl;
1646        m_update_tab.print();
1647            }
1648#endif
1649            r_write_upt_index = index;
1650            //  releases the lock protecting Update Table if no entry...
1651            if ( wok ) r_write_fsm = WRITE_DIR_INVAL;
1652            else       r_write_fsm = WRITE_WAIT;
1653          }
1654
1655          break;
1656        }
1657        ////////////////////
1658      case WRITE_DIR_INVAL:
1659        {
1660            assert(((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) &&
1661                    (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) &&
1662                    (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ))&&
1663                    "MemCache ERROR : bad TRT,DIR or UPT allocation error");
1664            m_transaction_tab.set(r_write_trt_index.read(),
1665                false,                          // write request to XRAM
1666                m_nline[(vci_addr_t)(r_write_address.read())],
1667                0,
1668                0,
1669                0,
1670                false,                          // not a processor read
1671                0,                              // not a single word
1672                0,                              // word index
1673                std::vector<be_t>(m_words,0),
1674                std::vector<data_t>(m_words,0));
1675#ifdef TDEBUG
1676        std::cout << sc_time_stamp() << " " << name() << " WRITE_DIR_INVAL transaction table : " << std::endl;
1677        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1678          m_transaction_tab.print(i);
1679#endif
1680
1681            // invalidate directory entry
1682            DirectoryEntry entry;
1683            entry.valid         = false;
1684            entry.dirty         = false;
1685            entry.tag           = 0;
1686            entry.is_cnt        = false;
1687            entry.lock          = false;
1688            entry.inst          = false;
1689            entry.owner.srcid   = 0;
1690            entry.owner.inst    = false;
1691            entry.ptr           = 0;
1692            entry.count         = 0;
1693            size_t set          = m_y[(vci_addr_t)(r_write_address.read())];
1694            size_t way          = r_write_way.read();
1695            m_cache_directory.write(set, way, entry);
1696
1697            r_write_fsm = WRITE_INVAL;
1698            break;
1699        }
1700        ////////////////////
1701      case WRITE_INVAL:
1702        {
1703          if (  !r_write_to_init_cmd_multi_req.read() &&
1704                !r_write_to_init_cmd_brdcast_req.read() ) {
1705            r_write_to_init_cmd_multi_req   = false;
1706            r_write_to_init_cmd_brdcast_req = true;
1707            r_write_to_init_cmd_trdid       = r_write_upt_index.read();
1708            r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
1709            r_write_to_init_cmd_index       = 0;
1710            r_write_to_init_cmd_count       = 0;
1711
1712            for(size_t i=0; i<m_words ; i++){
1713              r_write_to_init_cmd_we[i]=false;
1714              r_write_to_init_cmd_data[i] = 0;
1715            }
1716            r_write_fsm = WRITE_XRAM_SEND;
1717            // all inval responses
1718          }
1719
1720          break;
1721        }
1722        ////////////////////
1723      case WRITE_XRAM_SEND:
1724        {
1725          if ( !r_write_to_ixr_cmd_req ) {
1726            r_write_to_ixr_cmd_req     = true;
1727            r_write_to_ixr_cmd_write   = true;
1728            r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
1729            r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
1730            for(size_t i=0; i<m_words; i++){
1731              r_write_to_ixr_cmd_data[i] = r_write_data[i];
1732            }
1733            if(  r_write_is_cnt.read() ||
1734                ((!r_write_is_cnt.read()) && (r_write_count.read()==1)) ){
1735              r_write_fsm = WRITE_IDLE;
1736            } else {
1737              r_write_fsm = WRITE_HEAP_ERASE;
1738              r_write_next_ptr = r_write_ptr.read();
1739            }
1740          }
1741          break;
1742        }
1743        ////////////////////
1744      case WRITE_HEAP_ERASE:
1745        {
1746          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE){
1747            HeapEntry next_entry = m_heap_directory.read(r_write_next_ptr.read());
1748            if( next_entry.next == r_write_next_ptr.read()){
1749              r_write_fsm = WRITE_HEAP_LAST;
1750            } else {
1751              r_write_next_ptr = next_entry.next;
1752              r_write_fsm = WRITE_HEAP_ERASE;
1753            }
1754          }
1755          break;
1756        }
1757        ////////////////////
1758      case WRITE_HEAP_LAST:
1759        {
1760          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
1761                  "MemCache ERROR : bad HEAP allocation");
1762          size_t free_pointer = m_heap_directory.next_free_ptr();
1763
1764          HeapEntry last_entry;
1765          last_entry.owner.srcid = 0;
1766          last_entry.owner.inst  = false;
1767          if(m_heap_directory.is_full()){
1768            last_entry.next     = r_write_next_ptr.read();
1769            m_heap_directory.unset_full();
1770          } else {
1771            last_entry.next     = free_pointer;
1772          }
1773
1774          m_heap_directory.write_free_ptr(r_write_ptr.read());
1775          m_heap_directory.write(r_write_next_ptr.read(),last_entry);
1776
1777          r_write_fsm = WRITE_IDLE;
1778          break;
1779        }
1780    } // end switch r_write_fsm
1781
1782    ///////////////////////////////////////////////////////////////////////
1783    //          IXR_CMD FSM
1784    ///////////////////////////////////////////////////////////////////////
1785    // The IXR_CMD fsm controls the command packets to the XRAM :
1786    // - It sends a single cell VCI read to the XRAM in case of MISS request
1787    // posted by the READ, WRITE or LLSC FSMs : the TRDID field contains
1788    // the Transaction Tab index.
1789    // The VCI response is a multi-cell packet : the N cells contain
1790    // the N data words.
1791    // - It sends a multi-cell VCI write when the XRAM_RSP FSM request
1792    // to save a dirty line to the XRAM.
1793    // The VCI response is a single cell packet.
1794    // This FSM handles requests from the READ, WRITE, LLSC & XRAM_RSP FSMs
1795    // with a round-robin priority.
1796    ////////////////////////////////////////////////////////////////////////
1797
1798    switch ( r_ixr_cmd_fsm.read() ) {
1799      ////////////////////////
1800      case IXR_CMD_READ_IDLE:
1801        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1802        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1803        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1804        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1805        break;
1806        ////////////////////////
1807      case IXR_CMD_WRITE_IDLE:
1808        if      ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1809        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1810        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1811        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1812        break;
1813        ////////////////////////
1814      case IXR_CMD_LLSC_IDLE:
1815        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1816        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1817        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1818        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1819        break;
1820        ////////////////////////
1821      case IXR_CMD_XRAM_IDLE:
1822        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1823        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1824        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1825        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1826        break;
1827        /////////////////////////
1828      case IXR_CMD_READ_NLINE:
1829        if ( p_vci_ixr.cmdack ) {
1830          r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;           
1831          r_read_to_ixr_cmd_req = false;
1832        }
1833        break;
1834        //////////////////////////
1835      case IXR_CMD_WRITE_NLINE:
1836        if ( p_vci_ixr.cmdack ) {
1837          if( r_write_to_ixr_cmd_write.read()){
1838            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1839              r_ixr_cmd_cpt = 0;
1840              r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
1841              r_write_to_ixr_cmd_req = false;
1842            } else {
1843              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1844            }
1845          } else {
1846            r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;         
1847            r_write_to_ixr_cmd_req = false;
1848          }
1849        }
1850        break;
1851        /////////////////////////
1852      case IXR_CMD_LLSC_NLINE:
1853        if ( p_vci_ixr.cmdack ) {
1854          if( r_llsc_to_ixr_cmd_write.read()){
1855            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1856              r_ixr_cmd_cpt = 0;
1857              r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;
1858              r_llsc_to_ixr_cmd_req = false;
1859            } else {
1860              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1861            }
1862          } else {
1863            r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;         
1864            r_llsc_to_ixr_cmd_req = false;
1865          }
1866        }
1867        break;
1868        ////////////////////////
1869      case IXR_CMD_XRAM_DATA:
1870        if ( p_vci_ixr.cmdack ) {
1871          if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1872            r_ixr_cmd_cpt = 0;
1873            r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
1874            r_xram_rsp_to_ixr_cmd_req = false;
1875          } else {
1876            r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1877          }
1878        }
1879        break;
1880
1881    } // end switch r_ixr_cmd_fsm
1882
1883    ////////////////////////////////////////////////////////////////////////////
1884    //                IXR_RSP FSM
1885    ////////////////////////////////////////////////////////////////////////////
1886    // The IXR_RSP FSM receives the response packets from the XRAM,
1887    // for both write transaction, and read transaction.
1888    //
1889    // - A response to a write request is a single-cell VCI packet.
1890    // The Transaction Tab index is contained in the RTRDID field.
1891    // The FSM takes the lock protecting the TRT, and the corresponding
1892    // entry is erased.
1893    // 
1894    // - A response to a read request is a multi-cell VCI packet.
1895    // The Transaction Tab index is contained in the RTRDID field.
1896    // The N cells contain the N words of the cache line in the RDATA field.
1897    // The FSM takes the lock protecting the TRT to store the line in the TRT
1898    // (taking into account the write requests already stored in the TRT).
1899    // When the line is completely written, the corresponding rok signal is set.
1900    ///////////////////////////////////////////////////////////////////////////////
1901
1902    switch ( r_ixr_rsp_fsm.read() ) {
1903
1904      ///////////////////
1905      case IXR_RSP_IDLE:        // test if it's a read or a write transaction
1906        {
1907          if ( p_vci_ixr.rspval ) {
1908            r_ixr_rsp_cpt   = 0;
1909            r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
1910            if ( p_vci_ixr.reop )  r_ixr_rsp_fsm = IXR_RSP_ACK;
1911            else                   r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
1912          }
1913          break; 
1914        }
1915        ////////////////////////
1916      case IXR_RSP_ACK:        // Acknowledge the vci response
1917        r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
1918        break;
1919        ////////////////////////
1920      case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
1921        {
1922          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP ) {
1923            m_transaction_tab.erase(r_ixr_rsp_trt_index.read());
1924            r_ixr_rsp_fsm = IXR_RSP_IDLE;
1925#ifdef TDEBUG
1926        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_ERASE transaction table : " << std::endl;
1927        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1928          m_transaction_tab.print(i);
1929#endif
1930
1931          }
1932          break;
1933        }
1934        ///////////////////////
1935      case IXR_RSP_TRT_READ:            // write data in the TRT
1936        {
1937          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&  p_vci_ixr.rspval ) {
1938            bool   eop          = p_vci_ixr.reop.read();
1939            data_t data         = p_vci_ixr.rdata.read();
1940            size_t index        = r_ixr_rsp_trt_index.read();
1941            assert( eop == (r_ixr_rsp_cpt.read() == (m_words-1))
1942                && "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
1943            m_transaction_tab.write_rsp(index, r_ixr_rsp_cpt.read(), data);
1944            r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1;
1945            if ( eop ) {
1946#ifdef TDEBUG
1947        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_READ transaction table : " << std::endl;
1948        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1949          m_transaction_tab.print(i);
1950#endif
1951
1952              r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
1953              r_ixr_rsp_fsm = IXR_RSP_IDLE;
1954            }
1955          }
1956          break;
1957        }
1958    } // end swich r_ixr_rsp_fsm
1959
1960
1961    ////////////////////////////////////////////////////////////////////////////
1962    //                XRAM_RSP FSM
1963    ////////////////////////////////////////////////////////////////////////////
1964    // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
1965    // The cache line has been written in the TRT buffer by the IXR_FSM.
1966    //
1967    // When a response is available, the corresponding TRT entry
1968    // is copied in a local buffer to be written in the cache.
1969    // Then, the FSM releases the lock protecting the TRT, and takes the lock
1970    // protecting the cache directory.
1971    // It selects a cache slot and writes the line in the cache.
1972    // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
1973    // FSM to return the cache line to the registered processor.
1974    // If there is no empty slot, a victim line is evicted, and
1975    // invalidate requests are sent to the L1 caches containing copies.
1976    // If this line is dirty, the XRAM_RSP FSM send a request to the IXR_CMD
1977    // FSM to save the victim line to the XRAM, and register the write transaction
1978    // in the TRT (using the entry previously used by the read transaction).
1979    ///////////////////////////////////////////////////////////////////////////////
1980
1981    switch ( r_xram_rsp_fsm.read() ) {
1982
1983      ///////////////////
1984      case XRAM_RSP_IDLE:       // test if there is a response with a round robin priority
1985        {
1986          size_t ptr   = r_xram_rsp_trt_index.read();
1987          size_t lines = TRANSACTION_TAB_LINES;
1988          for(size_t i=0; i<lines; i++){
1989            size_t index=(i+ptr+1)%lines;
1990            if(r_ixr_rsp_to_xram_rsp_rok[index]){
1991              r_xram_rsp_trt_index=index;
1992              r_ixr_rsp_to_xram_rsp_rok[index]=false;
1993              r_xram_rsp_fsm           = XRAM_RSP_DIR_LOCK;
1994              break;
1995#ifdef TDEBUG
1996        std::cout << "XRAM_RSP FSM in XRAM_RSP_IDLE state" << std::endl;
1997#endif
1998            }
1999          }
2000          break; 
2001        }
2002        ///////////////////////
2003      case XRAM_RSP_DIR_LOCK:   // Take the lock on the directory
2004        {
2005          if( r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP ) {
2006            r_xram_rsp_fsm           = XRAM_RSP_TRT_COPY;
2007#ifdef TDEBUG
2008        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_LOCK state" << std::endl;
2009#endif
2010          }
2011          break;
2012        }
2013        ///////////////////////
2014      case XRAM_RSP_TRT_COPY:           // Copy the TRT entry in the local buffer and eviction of a cache line
2015        {
2016          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) ) {
2017            size_t index = r_xram_rsp_trt_index.read();
2018            TransactionTabEntry    trt_entry(m_transaction_tab.read(index));   
2019
2020            r_xram_rsp_trt_buf.copy(trt_entry);  // TRT entry local buffer
2021
2022            // selects & extracts a victim line from cache
2023            size_t way = 0;
2024            size_t set = m_y[(vci_addr_t)(trt_entry.nline * m_words * 4)];
2025            DirectoryEntry victim(m_cache_directory.select(set, way));
2026
2027            for (size_t i=0 ; i<m_words ; i++) r_xram_rsp_victim_data[i] = m_cache_data[way][set][i];
2028
2029            bool inval = (victim.count && victim.valid) ;
2030
2031            r_xram_rsp_victim_copy      = victim.owner.srcid;
2032            r_xram_rsp_victim_copy_inst = victim.owner.inst;
2033            r_xram_rsp_victim_count     = victim.count;
2034            r_xram_rsp_victim_ptr       = victim.ptr;
2035            r_xram_rsp_victim_way       = way;
2036            r_xram_rsp_victim_set       = set;
2037            r_xram_rsp_victim_nline     = victim.tag*m_sets + set;
2038            r_xram_rsp_victim_is_cnt    = victim.is_cnt;
2039            r_xram_rsp_victim_inval     = inval ;
2040            r_xram_rsp_victim_dirty     = victim.dirty;
2041
2042            r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
2043#ifdef TDEBUG
2044        std::cout << "XRAM_RSP FSM in XRAM_RSP_TRT_COPY state" << std::endl;
2045        std::cout << "Victim way : " << std::hex << way << " set " << std::hex << set << std::endl;
2046        victim.print();
2047#endif
2048          }
2049          break;
2050        }
2051        ///////////////////////
2052      case XRAM_RSP_INVAL_LOCK:
2053        {
2054          if ( r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP ) {
2055#ifdef IDEBUG
2056        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state" << std::endl;
2057#endif
2058            size_t index;
2059            if(m_update_tab.search_inval(r_xram_rsp_trt_buf.nline, index)){
2060              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
2061#ifdef IDEBUG
2062        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
2063    std::cout << "A invalidation is already registered at this address" << std::endl;
2064        m_update_tab.print();
2065#endif
2066
2067            }
2068            else if(m_update_tab.is_full() && r_xram_rsp_victim_inval.read()){
2069              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
2070#ifdef IDEBUG
2071        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
2072    std::cout << "The inval tab is full" << std::endl;
2073        m_update_tab.print();
2074#endif
2075            }
2076            else {
2077              r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
2078#ifdef IDEBUG
2079        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_DIR_UPDT state" << std::endl;
2080        m_update_tab.print();
2081#endif
2082            }
2083          }
2084          break;
2085        }
2086        ///////////////////////
2087      case XRAM_RSP_INVAL_WAIT:
2088        {
2089          r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
2090          break;
2091#ifdef IDEBUG
2092        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_WAIT state" << std::endl;
2093#endif
2094        }
2095        ///////////////////////
2096      case XRAM_RSP_DIR_UPDT:           // updates the cache (both data & directory)
2097        {
2098          // signals generation
2099          bool inst_read = (r_xram_rsp_trt_buf.trdid & 0x2) && r_xram_rsp_trt_buf.proc_read; // It is an instruction read
2100          bool cached_read = (r_xram_rsp_trt_buf.trdid & 0x1) && r_xram_rsp_trt_buf.proc_read ;
2101          // update data
2102          size_t set   = r_xram_rsp_victim_set.read();
2103          size_t way   = r_xram_rsp_victim_way.read();
2104          for(size_t i=0; i<m_words ; i++){
2105            m_cache_data[way][set][i] = r_xram_rsp_trt_buf.wdata[i];
2106          }
2107          // compute dirty
2108          bool dirty = false;
2109          for(size_t i=0; i<m_words;i++){
2110            dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0);
2111          }
2112
2113          // update directory
2114          DirectoryEntry entry;
2115          entry.valid     = true;
2116          entry.is_cnt    = false;
2117          entry.lock      = false;
2118          entry.dirty     = dirty;
2119          entry.tag           = r_xram_rsp_trt_buf.nline / m_sets;
2120          entry.ptr       = 0;
2121          if(cached_read) {
2122            if(inst_read) {
2123              entry.inst        = true;
2124              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
2125              entry.owner.inst  = true;
2126              entry.count       = 1;
2127            } else {
2128              entry.inst        = false;
2129              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
2130              entry.owner.inst  = false;
2131              entry.count       = 1;
2132            }
2133          } else {
2134            entry.owner.srcid = 0;
2135            entry.owner.inst  = 0;
2136            entry.inst        = false;
2137            entry.count       = 0;
2138          }
2139          m_cache_directory.write(set, way, entry);
2140#ifdef DDEBUG
2141           std::cout << "printing the entry : " << std::endl;
2142           entry.print();
2143           std::cout << "done" << std::endl;
2144#endif
2145
2146#ifdef TDEBUG
2147        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_DIR_UPDT transaction table : " << std::endl;
2148        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2149          m_transaction_tab.print(i);
2150#endif
2151
2152          if(r_xram_rsp_victim_inval.read()){
2153            bool    brdcast = r_xram_rsp_victim_is_cnt.read();
2154            size_t index;
2155            size_t count_copies = r_xram_rsp_victim_count.read();
2156
2157            bool         wok = m_update_tab.set(false,  // it's an inval transaction
2158                brdcast,                          // set brdcast bit
2159                false,  // it does not need a response
2160                0,
2161                0,
2162                0,
2163                r_xram_rsp_victim_nline.read(),
2164                count_copies,
2165                index);
2166
2167#ifdef IDEBUG
2168            std::cout << "xram_rsp : record invalidation, time = " << std::dec << m_cpt_cycles << std::endl;
2169            m_update_tab.print();
2170#endif
2171            r_xram_rsp_upt_index = index;
2172            if(!wok) {
2173              assert(false && "mem_cache error : xram_rsp_dir_upt, an update_tab entry was free but write unsuccessful");
2174            }
2175          }
2176          // If the victim is not dirty, we erase the entry in the TRT
2177          if      (!r_xram_rsp_victim_dirty.read()){
2178          m_transaction_tab.erase(r_xram_rsp_trt_index.read());
2179
2180          }
2181          // Next state
2182          if      ( r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
2183          else if ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2184          else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2185          else                                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2186          break;
2187        }
2188        ////////////////////////
2189      case XRAM_RSP_TRT_DIRTY:          // set the TRT entry (write line to XRAM) if the victim is dirty
2190        {
2191          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP ) {
2192            m_transaction_tab.set(r_xram_rsp_trt_index.read(),
2193                false,                          // write to XRAM
2194                r_xram_rsp_victim_nline.read(), // line index
2195                0,
2196                0,
2197                0,
2198                false,
2199                0,
2200                0,
2201                std::vector<be_t>(m_words,0),
2202                std::vector<data_t>(m_words,0) );
2203#ifdef TDEBUG
2204        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_TRT_DIRTY transaction table : " << std::endl;
2205        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2206          m_transaction_tab.print(i);
2207#endif
2208
2209            if      ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2210            else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2211            else                                            r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2212          }
2213          break;
2214        }
2215        //////////////////////
2216      case XRAM_RSP_DIR_RSP:     // send a request to TGT_RSP FSM in case of read
2217        {
2218          if ( !r_xram_rsp_to_tgt_rsp_req.read() ) {
2219            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
2220            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
2221            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
2222            for (size_t i=0; i < m_words; i++) {
2223              r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
2224            }
2225            r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
2226            r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
2227            r_xram_rsp_to_tgt_rsp_req    = true;
2228
2229            if      ( r_xram_rsp_victim_inval ) r_xram_rsp_fsm = XRAM_RSP_INVAL;
2230            else if ( r_xram_rsp_victim_dirty ) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2231            else                                r_xram_rsp_fsm = XRAM_RSP_IDLE;
2232
2233#ifdef DDEBUG
2234        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_RSP state" << std::endl;
2235#endif
2236          }
2237          break;
2238        }
2239        ////////////////////
2240      case XRAM_RSP_INVAL:      // send invalidate request to INIT_CMD FSM
2241        {
2242          if(   !r_xram_rsp_to_init_cmd_multi_req.read() &&
2243                !r_xram_rsp_to_init_cmd_brdcast_req.read() ) {       
2244           
2245            bool multi_req = !r_xram_rsp_victim_is_cnt.read();
2246            bool last_multi_req  = multi_req && (r_xram_rsp_victim_count.read() == 1);
2247            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
2248
2249            r_xram_rsp_to_init_cmd_multi_req    = last_multi_req;
2250            r_xram_rsp_to_init_cmd_brdcast_req  = r_xram_rsp_victim_is_cnt.read();
2251            r_xram_rsp_to_init_cmd_nline        = r_xram_rsp_victim_nline.read();
2252            r_xram_rsp_to_init_cmd_trdid        = r_xram_rsp_upt_index;
2253            xram_rsp_to_init_cmd_fifo_srcid     = r_xram_rsp_victim_copy.read();
2254            xram_rsp_to_init_cmd_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
2255            xram_rsp_to_init_cmd_fifo_put       = multi_req;
2256           
2257            r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
2258
2259            if ( r_xram_rsp_victim_dirty )  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2260            else if (not_last_multi_req)    r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2261            else                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2262#ifdef IDEBUG
2263        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL state" << std::endl;
2264#endif
2265          }
2266          break;
2267        }
2268        //////////////////////////
2269      case XRAM_RSP_WRITE_DIRTY:        // send a write request to IXR_CMD FSM
2270        {
2271          if ( !r_xram_rsp_to_ixr_cmd_req.read() ) {
2272            r_xram_rsp_to_ixr_cmd_req = true;
2273            r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
2274            r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
2275            for(size_t i=0; i<m_words ; i++) {
2276              r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
2277            }
2278            m_cpt_write_dirty++;
2279            bool multi_req = !r_xram_rsp_victim_is_cnt.read() && r_xram_rsp_victim_inval.read();
2280            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
2281            if ( not_last_multi_req )   r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2282            else                        r_xram_rsp_fsm = XRAM_RSP_IDLE;
2283#ifdef TDEBUG
2284        std::cout << "XRAM_RSP FSM in XRAM_RSP_WRITE_DIRTY state" << std::endl;
2285#endif
2286          }
2287          break;
2288        }
2289        //////////////////////////
2290      case XRAM_RSP_HEAP_ERASE: // erase the list of copies and sent invalidations
2291        {
2292          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP ) {
2293            HeapEntry entry = m_heap_directory.read(r_xram_rsp_next_ptr.read());
2294            xram_rsp_to_init_cmd_fifo_srcid = entry.owner.srcid;
2295            xram_rsp_to_init_cmd_fifo_inst  = entry.owner.inst;
2296            xram_rsp_to_init_cmd_fifo_put   = true;
2297            if( m_xram_rsp_to_init_cmd_inst_fifo.wok() ){
2298              r_xram_rsp_next_ptr = entry.next;
2299              if( entry.next == r_xram_rsp_next_ptr.read() ){ // last copy
2300                r_xram_rsp_to_init_cmd_multi_req = true;
2301                r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST;
2302              } else {
2303                r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2304              }
2305            } else {
2306              r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2307            }
2308          }
2309          break;
2310        }
2311        //////////////////////////
2312      case XRAM_RSP_HEAP_LAST:  // last member of the list
2313        {
2314          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) &&
2315                  "MemCache ERROR : bad HEAP allocation");
2316          size_t free_pointer = m_heap_directory.next_free_ptr();
2317
2318          HeapEntry last_entry;
2319          last_entry.owner.srcid = 0;
2320          last_entry.owner.inst  = false;
2321          if(m_heap_directory.is_full()){
2322            last_entry.next     = r_xram_rsp_next_ptr.read();
2323            m_heap_directory.unset_full();
2324          } else {
2325            last_entry.next     = free_pointer;
2326          }
2327
2328          m_heap_directory.write_free_ptr(r_xram_rsp_victim_ptr.read());
2329          m_heap_directory.write(r_xram_rsp_next_ptr.read(),last_entry);
2330
2331          r_xram_rsp_fsm = XRAM_RSP_IDLE;
2332
2333          break;
2334        }
2335    } // end swich r_xram_rsp_fsm
2336
2337    ////////////////////////////////////////////////////////////////////////////////////
2338    //          CLEANUP FSM
2339    ////////////////////////////////////////////////////////////////////////////////////
2340    // The CLEANUP FSM handles the cleanup request from L1 caches.
2341    // It accesses the cache directory to update the list of copies.
2342    //
2343    ////////////////////////////////////////////////////////////////////////////////////
2344    switch ( r_cleanup_fsm.read() ) {
2345
2346      ///////////////////
2347      case CLEANUP_IDLE:
2348        {
2349
2350          if ( p_vci_tgt_cleanup.cmdval.read() ) {
2351            assert( (p_vci_tgt_cleanup.srcid.read() < m_initiators) &&
2352                "VCI_MEM_CACHE error in VCI_MEM_CACHE in the CLEANUP network : The received SRCID is larger than the number of initiators");
2353            bool reached = false;
2354            for ( size_t index = 0 ; index < ncseg && !reached ; index++ ){
2355              if ( m_cseg[index]->contains((addr_t)(p_vci_tgt_cleanup.address.read())) ){
2356                reached = true;
2357              }
2358            }
2359            if ( (p_vci_tgt_cleanup.cmd.read() == vci_param::CMD_WRITE) &&
2360                (((addr_t)(p_vci_tgt_cleanup.address.read())) != BROADCAST_ADDR) &&
2361                reached) {
2362
2363              m_cpt_cleanup++;
2364
2365              r_cleanup_nline      = (addr_t)(m_nline[(vci_addr_t)(p_vci_tgt_cleanup.address.read())]) ;
2366              r_cleanup_srcid      = p_vci_tgt_cleanup.srcid.read();
2367              r_cleanup_trdid      = p_vci_tgt_cleanup.trdid.read();
2368              r_cleanup_pktid      = p_vci_tgt_cleanup.pktid.read();
2369
2370              r_cleanup_fsm        = CLEANUP_DIR_LOCK;
2371            }
2372          }
2373          break;
2374        }
2375        //////////////////////
2376      case CLEANUP_DIR_LOCK:
2377        {
2378          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) {
2379
2380            // Read the directory
2381            size_t way = 0;
2382           addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
2383           DirectoryEntry entry = m_cache_directory.read(cleanup_address , way);
2384#ifdef DDEBUG
2385           std::cout << "In CLEANUP_DIR_LOCK printing the entry of address is : " << std::hex << cleanup_address << std::endl;
2386           entry.print();
2387           std::cout << "done" << std::endl;
2388#endif
2389            r_cleanup_is_cnt    = entry.is_cnt;
2390            r_cleanup_dirty         = entry.dirty;
2391            r_cleanup_tag           = entry.tag;
2392            r_cleanup_lock          = entry.lock;
2393            r_cleanup_inst      = entry.inst;
2394            r_cleanup_way           = way;
2395            r_cleanup_copy      = entry.owner.srcid;
2396            r_cleanup_copy_inst = entry.owner.inst;
2397            r_cleanup_count     = entry.count;
2398            r_cleanup_ptr       = entry.ptr;
2399
2400
2401            // In case of hit, the copy must be cleaned in the copies bit-vector
2402            if( entry.valid){
2403              if ( (entry.count==1) || (entry.is_cnt) )  { // no access to the heap
2404                r_cleanup_fsm = CLEANUP_DIR_WRITE;
2405              } else {
2406                r_cleanup_fsm = CLEANUP_HEAP_LOCK;
2407              }
2408            } else {
2409              r_cleanup_fsm = CLEANUP_UPT_LOCK;
2410            }
2411          }
2412          break;
2413        }
2414        ///////////////////////
2415      case CLEANUP_DIR_WRITE:
2416        {
2417          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) &&
2418                "MemCache ERROR : Bad DIR allocation");
2419          size_t way      = r_cleanup_way.read();
2420#define L2 soclib::common::uint32_log2
2421          size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
2422#undef L2
2423          bool cleanup_inst  = r_cleanup_trdid.read() & 0x1;
2424          bool match_srcid   = (r_cleanup_copy.read() == r_cleanup_srcid.read());
2425          bool match_inst    = (r_cleanup_copy_inst.read()  == cleanup_inst);
2426          bool match         = match_srcid && match_inst;
2427
2428          // update the cache directory (for the copies)
2429          DirectoryEntry entry;
2430          entry.valid   = true;
2431          entry.is_cnt  = r_cleanup_is_cnt.read();
2432          entry.dirty   = r_cleanup_dirty.read();
2433          entry.tag         = r_cleanup_tag.read();
2434          entry.lock    = r_cleanup_lock.read();
2435          entry.ptr     = r_cleanup_ptr.read();
2436          if(r_cleanup_is_cnt.read()) { // Directory is a counter
2437            entry.count  = r_cleanup_count.read() -1;
2438            if((r_cleanup_count.read()-1) == 0){
2439              entry.inst    = false;
2440            } else {
2441              entry.inst    = r_cleanup_inst.read();
2442            }
2443            entry.owner.srcid = 0;
2444            entry.owner.inst  = 0;
2445            // response to the cache
2446            r_cleanup_fsm = CLEANUP_RSP;
2447          }
2448          else{                         // Directory is a list
2449            if(match) { // hit
2450              entry.count       = 0; // no more copy
2451              entry.owner.srcid = 0;
2452              entry.owner.inst  = 0;
2453              entry.inst        = false;
2454              r_cleanup_fsm     = CLEANUP_RSP;
2455            } else { // miss
2456              entry.count       = r_cleanup_count.read();
2457              entry.owner.srcid = r_cleanup_copy.read();
2458              entry.owner.inst  = r_cleanup_copy_inst.read();
2459              entry.inst        = r_cleanup_inst.read();
2460              r_cleanup_fsm     = CLEANUP_UPT_LOCK;
2461            }
2462          }
2463          m_cache_directory.write(set, way, entry); 
2464
2465          break;
2466        }
2467        /////////////////
2468      case CLEANUP_HEAP_LOCK:
2469        {
2470          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP){
2471            size_t way      = r_cleanup_way.read();
2472#define L2 soclib::common::uint32_log2
2473            size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
2474#undef L2
2475            HeapEntry heap_entry = m_heap_directory.read(r_cleanup_ptr.read());
2476            bool last = (heap_entry.next == r_cleanup_ptr.read());
2477            bool cleanup_inst       = r_cleanup_trdid.read() & 0x1;
2478            bool match_dir_srcid    = (r_cleanup_copy.read() == r_cleanup_srcid.read());
2479            bool match_dir_inst     = (r_cleanup_copy_inst.read()  == cleanup_inst);
2480            bool match_dir          = match_dir_srcid && match_dir_inst;
2481            bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
2482            bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
2483            bool match_heap         = match_heap_srcid && match_heap_inst;
2484
2485            r_cleanup_prev_ptr = r_cleanup_ptr.read();
2486            r_cleanup_prev_srcid = heap_entry.owner.srcid;
2487            r_cleanup_prev_inst  = heap_entry.owner.inst;
2488
2489            if(match_dir){
2490              DirectoryEntry dir_entry;
2491              dir_entry.valid       = true;
2492              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
2493              dir_entry.dirty       = r_cleanup_dirty.read();
2494              dir_entry.tag             = r_cleanup_tag.read();
2495              dir_entry.lock        = r_cleanup_lock.read();
2496              dir_entry.ptr         = heap_entry.next;
2497              dir_entry.count       = r_cleanup_count.read()-1;
2498              dir_entry.owner.srcid = heap_entry.owner.srcid;
2499              dir_entry.owner.inst  = heap_entry.owner.inst;
2500              dir_entry.inst        = r_cleanup_inst.read();
2501              m_cache_directory.write(set,way,dir_entry);
2502              r_cleanup_next_ptr    = r_cleanup_ptr.read();
2503              r_cleanup_fsm         = CLEANUP_HEAP_FREE;
2504            }
2505            else if(match_heap){
2506              DirectoryEntry dir_entry;
2507              dir_entry.valid       = true;
2508              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
2509              dir_entry.dirty       = r_cleanup_dirty.read();
2510              dir_entry.tag             = r_cleanup_tag.read();
2511              dir_entry.lock        = r_cleanup_lock.read();
2512              dir_entry.ptr         = heap_entry.next;
2513              dir_entry.count       = r_cleanup_count.read()-1;
2514              dir_entry.owner.srcid = r_cleanup_copy.read();
2515              dir_entry.owner.inst  = r_cleanup_copy_inst.read();
2516              dir_entry.inst        = r_cleanup_inst.read();
2517              m_cache_directory.write(set,way,dir_entry);
2518              r_cleanup_next_ptr    = r_cleanup_ptr.read();
2519              r_cleanup_fsm         = CLEANUP_HEAP_FREE;
2520            }
2521            else{
2522              if(!last){
2523                DirectoryEntry dir_entry;
2524                dir_entry.valid         = true;
2525                dir_entry.is_cnt        = r_cleanup_is_cnt.read();
2526                dir_entry.dirty         = r_cleanup_dirty.read();
2527                dir_entry.tag           = r_cleanup_tag.read();
2528                dir_entry.lock          = r_cleanup_lock.read();
2529                dir_entry.ptr           = r_cleanup_ptr.read();
2530                dir_entry.count         = r_cleanup_count.read()-1;
2531                dir_entry.owner.srcid   = r_cleanup_copy.read();
2532                dir_entry.owner.inst    = r_cleanup_copy_inst.read();
2533                dir_entry.inst          = r_cleanup_inst.read();
2534                m_cache_directory.write(set,way,dir_entry);
2535
2536                r_cleanup_next_ptr = heap_entry.next;
2537                r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
2538
2539              } else{
2540                assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
2541              }
2542            }
2543          }
2544          break;
2545        }
2546        /////////////////
2547      case CLEANUP_HEAP_SEARCH:
2548        {
2549          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2550                    "MemCache ERROR : bad HEAP allocation");
2551          HeapEntry heap_entry = m_heap_directory.read(r_cleanup_next_ptr.read());
2552          bool last = (heap_entry.next == r_cleanup_next_ptr.read());
2553          bool cleanup_inst       = r_cleanup_trdid.read() & 0x1;
2554          bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
2555          bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
2556          bool match_heap         = match_heap_srcid && match_heap_inst;
2557
2558          if(match_heap){
2559            r_cleanup_ptr           = heap_entry.next; // reuse ressources
2560            r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
2561          }
2562          else{
2563            if(last) {
2564              assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
2565            } else {
2566              r_cleanup_prev_ptr = r_cleanup_next_ptr.read();
2567              r_cleanup_prev_srcid = heap_entry.owner.srcid;
2568              r_cleanup_prev_inst  = heap_entry.owner.inst;
2569              r_cleanup_next_ptr = heap_entry.next;
2570              r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
2571            }
2572          }
2573
2574          break;
2575        }
2576        /////////////////
2577      case CLEANUP_HEAP_CLEAN:
2578        {
2579          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2580                    "MemCache ERROR : bad HEAP allocation");
2581          bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
2582          HeapEntry heap_entry;
2583          heap_entry.owner.srcid = r_cleanup_prev_srcid.read();
2584          heap_entry.owner.inst  = r_cleanup_prev_inst.read();
2585          if(last){ // this is the last entry of the list of copies
2586            heap_entry.next     = r_cleanup_prev_ptr.read();
2587          } else { // this is not the last entry
2588            heap_entry.next     = r_cleanup_ptr.read();
2589          }
2590          m_heap_directory.write(r_cleanup_prev_ptr.read(),heap_entry);
2591          r_cleanup_fsm = CLEANUP_HEAP_FREE;
2592          break;
2593        }
2594        /////////////////
2595      case CLEANUP_HEAP_FREE:
2596        {
2597          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2598                    "MemCache ERROR : bad HEAP allocation");
2599          HeapEntry heap_entry;
2600          heap_entry.owner.srcid = 0;
2601          heap_entry.owner.inst  = false;
2602          if(m_heap_directory.is_full()){
2603            heap_entry.next     = r_cleanup_next_ptr.read();
2604          } else {
2605            heap_entry.next     = m_heap_directory.next_free_ptr();
2606          }
2607          m_heap_directory.write(r_cleanup_next_ptr.read(),heap_entry);
2608          m_heap_directory.write_free_ptr(r_cleanup_next_ptr.read());
2609          m_heap_directory.unset_full();
2610          r_cleanup_fsm = CLEANUP_RSP;
2611          break;
2612        }
2613        /////////////////
2614      case CLEANUP_UPT_LOCK:
2615        {
2616          if( r_alloc_upt_fsm.read() == ALLOC_UPT_CLEANUP )
2617          {
2618            size_t index;
2619            bool hit_inval;
2620            hit_inval = m_update_tab.search_inval(r_cleanup_nline.read(),index);
2621            if(!hit_inval) {
2622#ifdef DEBUG_VCI_MEM_CACHE
2623              std::cout << "MEM_CACHE WARNING: cleanup with no corresponding entry at address : " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::dec << std::endl;
2624#endif
2625              r_cleanup_fsm = CLEANUP_RSP;
2626            } else {
2627              r_cleanup_write_srcid = m_update_tab.srcid(index);
2628              r_cleanup_write_trdid = m_update_tab.trdid(index);
2629              r_cleanup_write_pktid = m_update_tab.pktid(index);
2630              r_cleanup_need_rsp    = m_update_tab.need_rsp(index);
2631              r_cleanup_fsm = CLEANUP_UPT_WRITE;
2632            }
2633            r_cleanup_index.write(index) ;
2634          }
2635          break;
2636        }
2637        /////////////////
2638      case CLEANUP_UPT_WRITE:
2639        {
2640          size_t count = 0;
2641          m_update_tab.decrement(r_cleanup_index.read(), count); // &count
2642          if(count == 0){
2643            m_update_tab.clear(r_cleanup_index.read());
2644#ifdef IDEBUG
2645        std::cout << sc_time_stamp() << " " << name() << " CLEANUP_UPT_WRITE update table : " << std::endl;
2646        m_update_tab.print();
2647#endif
2648
2649            if(r_cleanup_need_rsp.read()){
2650              r_cleanup_fsm = CLEANUP_WRITE_RSP ;
2651            } else {
2652              r_cleanup_fsm = CLEANUP_RSP;
2653            }
2654          } else {
2655            r_cleanup_fsm = CLEANUP_RSP ;
2656          }
2657          break;
2658        }
2659        /////////////////
2660      case CLEANUP_WRITE_RSP:
2661        {
2662          if( !r_cleanup_to_tgt_rsp_req.read()) {
2663            r_cleanup_to_tgt_rsp_req     = true;
2664            r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
2665            r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
2666            r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
2667            r_cleanup_fsm = CLEANUP_RSP;
2668          }
2669          break;
2670        }
2671        /////////////////
2672      case CLEANUP_RSP:
2673        {
2674          if(p_vci_tgt_cleanup.rspack)
2675            r_cleanup_fsm = CLEANUP_IDLE;
2676          break;
2677        }
2678    } // end switch cleanup fsm
2679
2680
2681    ////////////////////////////////////////////////////////////////////////////////////
2682    //          LLSC FSM
2683    ////////////////////////////////////////////////////////////////////////////////////
2684    // The LLSC FSM handles the LL & SC atomic access.
2685    //
2686    // For a LL :
2687    // It access the directory to check hit / miss.
2688    // - In case of hit, the LL request is registered in the Atomic Table and the
2689    // response is sent to the requesting processor.
2690    // - In case of miss, the LLSC FSM accesses the transaction table.
2691    // If a read transaction to the XRAM for this line already exists,
2692    // or if the transaction table is full, it returns to IDLE state.
2693    // Otherwise, a new transaction to the XRAM is initiated.
2694    // In both cases, the LL request is not consumed in the FIFO.
2695    //
2696    // For a SC :
2697    // It access the directory to check hit / miss.
2698    // - In case of hit, the Atomic Table is checked and the proper response
2699    // (true or false is sent to the requesting processor.
2700    // - In case of miss, the LLSC FSM accesses the transaction table.
2701    // If a read transaction to the XRAM for this line already exists,
2702    // or if the transaction table is full, it returns to IDLE state.
2703    // Otherwise, a new transaction to the XRAM is initiated.
2704    // In both cases, the SC request is not consumed in the FIFO.
2705    /////////////////////////////////////////////////////////////////////
2706
2707    switch ( r_llsc_fsm.read() ) {
2708
2709      ///////////////
2710      case LLSC_IDLE:           // test LL / SC
2711        {
2712          if( m_cmd_llsc_addr_fifo.rok() ) {
2713            if(m_cmd_llsc_sc_fifo.read()){
2714              m_cpt_sc++;
2715              r_llsc_fsm = SC_DIR_LOCK;
2716            }
2717            else{
2718              m_cpt_ll++;
2719              r_llsc_fsm = LL_DIR_LOCK;
2720            }
2721          }     
2722          break;
2723        }
2724        /////////////////
2725      case LL_DIR_LOCK:         // check directory for hit / miss
2726        {
2727          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
2728            size_t way = 0;
2729            DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
2730            r_llsc_is_cnt     = entry.is_cnt;
2731            r_llsc_dirty      = entry.dirty;
2732            r_llsc_inst       = entry.inst;
2733            r_llsc_tag        = entry.tag;
2734            r_llsc_way        = way;
2735            r_llsc_copy       = entry.owner.srcid;
2736            r_llsc_copy_inst  = entry.owner.inst;
2737            r_llsc_count      = entry.count;
2738            r_llsc_ptr        = entry.ptr;
2739
2740            // set Atomic Table
2741            m_atomic_tab.set(m_cmd_llsc_srcid_fifo.read(), m_cmd_llsc_addr_fifo.read());
2742
2743            if ( entry.valid )  r_llsc_fsm = LL_DIR_HIT;
2744            else                r_llsc_fsm = LLSC_TRT_LOCK;
2745          }
2746          break;
2747        }
2748        ////////////////
2749      case LL_DIR_HIT:          // read hit : update the memory cache
2750        {
2751          size_t way    = r_llsc_way.read();
2752          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2753          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2754
2755          // update directory (lock bit & copies)
2756          DirectoryEntry entry;
2757          entry.valid       = true;
2758          entry.is_cnt      = r_llsc_is_cnt.read();
2759          entry.dirty       = r_llsc_dirty.read();
2760          entry.lock        = true;
2761          entry.inst        = r_llsc_inst.read();
2762          entry.tag             = r_llsc_tag.read();
2763          entry.owner.srcid = r_llsc_copy.read();
2764          entry.owner.inst  = r_llsc_copy_inst.read();
2765          entry.count       = r_llsc_count.read();
2766          entry.ptr         = r_llsc_ptr.read();
2767          m_cache_directory.write(set, way, entry);
2768
2769          // read data in cache
2770          r_llsc_data   = m_cache_data[way][set][word];
2771
2772          r_llsc_fsm    = LL_RSP;
2773          break;
2774        }
2775        ////////////
2776      case LL_RSP:              // request the TGT_RSP FSM to return data
2777        {
2778          if ( !r_llsc_to_tgt_rsp_req ) {
2779            cmd_llsc_fifo_get           = true;
2780            r_llsc_to_tgt_rsp_data      = r_llsc_data.read();
2781            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
2782            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
2783            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
2784            r_llsc_to_tgt_rsp_req       = true;
2785            r_llsc_fsm = LLSC_IDLE;
2786          }
2787          break;
2788        }
2789        /////////////////
2790      case SC_DIR_LOCK:
2791        {
2792          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
2793            size_t way = 0;
2794            DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
2795            bool ok = m_atomic_tab.isatomic(m_cmd_llsc_srcid_fifo.read(),m_cmd_llsc_addr_fifo.read());
2796            if( ok ) {
2797              r_llsc_is_cnt   = entry.is_cnt;
2798              r_llsc_dirty    = entry.dirty;
2799              r_llsc_tag      = entry.tag;
2800              r_llsc_way      = way;
2801              r_llsc_copy     = entry.owner.srcid;
2802              r_llsc_copy_inst= entry.owner.inst;
2803              r_llsc_inst     = entry.inst;
2804              r_llsc_ptr      = entry.ptr;
2805              r_llsc_count    = entry.count;
2806              if ( entry.valid ){
2807                if((entry.is_cnt && entry.count) || entry.inst) {
2808                  r_llsc_fsm = SC_TRT_LOCK;
2809                } else {
2810                  r_llsc_fsm = SC_DIR_HIT;
2811                }
2812              }
2813              else r_llsc_fsm = LLSC_TRT_LOCK;
2814            } else {
2815              r_llsc_fsm = SC_RSP_FALSE;
2816            }
2817          }
2818          break;
2819        }
2820        ////////////////
2821      case SC_DIR_HIT:
2822        {
2823          size_t way    = r_llsc_way.read();
2824          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2825          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2826
2827          // update directory (lock & dirty bits
2828          DirectoryEntry entry;
2829          entry.valid       = true;
2830          entry.is_cnt      = r_llsc_is_cnt.read();
2831          entry.dirty       = true;
2832          entry.lock        = true;
2833          entry.inst        = r_llsc_inst.read();
2834          entry.tag             = r_llsc_tag.read();
2835          entry.owner.srcid = r_llsc_copy.read();
2836          entry.owner.inst  = r_llsc_copy_inst.read();
2837          entry.count       = r_llsc_count.read();
2838          entry.ptr         = r_llsc_ptr.read();
2839          m_cache_directory.write(set, way, entry);
2840
2841          if(!r_llsc_count.read()){ // no update
2842            // write data in cache
2843            m_cache_data[way][set][word] = m_cmd_llsc_wdata_fifo.read();
2844            // reset Atomic Table
2845            m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
2846          }
2847         
2848          if(r_llsc_count.read()) {  // Shared line
2849              if( !r_llsc_to_init_cmd_multi_req.read() &&
2850                  !r_llsc_to_init_cmd_brdcast_req.read()  )
2851                  r_llsc_fsm = SC_UPT_LOCK;
2852              else
2853                  r_llsc_fsm = SC_WAIT;
2854          } else {
2855            r_llsc_fsm = SC_RSP_TRUE;
2856          }
2857          break;
2858        }
2859        /////////////////////
2860      case SC_UPT_LOCK:         // Try to register the request in Update Table
2861        {
2862
2863          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
2864            size_t way  = r_llsc_way.read();
2865            size_t set  = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2866            size_t word = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2867            bool        wok        = false;
2868            size_t      index      = 0;
2869            size_t      srcid      = m_cmd_llsc_srcid_fifo.read();
2870            size_t      trdid      = m_cmd_llsc_trdid_fifo.read();
2871            size_t      pktid      = m_cmd_llsc_pktid_fifo.read();
2872            addr_t          nline      = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2873            size_t      nb_copies  = r_llsc_count.read();
2874
2875            wok =m_update_tab.set(true, // it's an update transaction
2876                false,                  // it's not a broadcast
2877                true,                   // it needs a response
2878                srcid,
2879                trdid,
2880                pktid,
2881                nline,
2882                nb_copies,
2883                index);
2884            if(wok){
2885              // write data in cache
2886              m_cache_data[way][set][word] = m_cmd_llsc_wdata_fifo.read();
2887              // reset Atomic Table
2888              m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
2889            }
2890#ifdef IDEBUG
2891            if(wok){
2892        std::cout << sc_time_stamp() << " " << name() << " SC_UPT_LOCK update table : " << std::endl;
2893        m_update_tab.print();
2894            }
2895#endif
2896            r_llsc_upt_index = index;
2897            //  releases the lock protecting the Update Table and the Directory if no entry...
2898            if ( wok ) r_llsc_fsm = SC_HEAP_LOCK;
2899            else       r_llsc_fsm = SC_WAIT;
2900          }
2901          break;
2902        }
2903        ////////////////////
2904      case SC_WAIT:     // release all locks
2905        {
2906          r_llsc_fsm = SC_DIR_LOCK;
2907          break;
2908        }
2909        ////////////////////
2910      case SC_HEAP_LOCK:        // lock the heap
2911        {
2912          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC ){
2913            r_llsc_fsm = SC_UPT_REQ;
2914          }
2915          break;
2916        }
2917        ////////////////////
2918      case SC_UPT_REQ:  // Request the update
2919        {
2920          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
2921                    "MemCache ERROR : bad HEAP allocation");
2922          if( !r_llsc_to_init_cmd_multi_req.read() &&
2923              !r_llsc_to_init_cmd_brdcast_req.read()  ){
2924            r_llsc_to_init_cmd_brdcast_req  = false;
2925            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
2926            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2927            r_llsc_to_init_cmd_index        = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2928            r_llsc_to_init_cmd_wdata        = m_cmd_llsc_wdata_fifo.read();
2929
2930            // We put the first copy in the fifo
2931            llsc_to_init_cmd_fifo_put     = true;
2932            llsc_to_init_cmd_fifo_inst    = r_llsc_copy_inst.read();
2933            llsc_to_init_cmd_fifo_srcid   = r_llsc_copy.read();
2934            if(r_llsc_count.read() == 1){
2935              r_llsc_fsm = LLSC_IDLE;
2936              cmd_llsc_fifo_get            = true;
2937              r_llsc_to_init_cmd_multi_req = true;
2938            } else {
2939              r_llsc_fsm = SC_UPDATE;
2940            }
2941          }
2942          break;
2943        }
2944        //////////////////
2945      case SC_UPDATE:           // send a multi-update request to INIT_CMD fsm
2946        {
2947          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
2948                    "MemCache ERROR : bad HEAP allocation");
2949          HeapEntry entry = m_heap_directory.read(r_llsc_ptr.read());
2950          llsc_to_init_cmd_fifo_inst  = entry.owner.inst;
2951          llsc_to_init_cmd_fifo_srcid = entry.owner.srcid;
2952          llsc_to_init_cmd_fifo_put = true;
2953
2954          if( m_llsc_to_init_cmd_inst_fifo.wok() ){
2955            r_llsc_ptr = entry.next;
2956            if( entry.next == r_llsc_ptr.read() ) { // last copy
2957              r_llsc_to_init_cmd_multi_req = true;
2958              r_llsc_fsm = LLSC_IDLE; // Response will be sent after receiving
2959                                      // all update responses
2960              cmd_llsc_fifo_get         = true;
2961            } else {
2962              r_llsc_fsm = SC_UPDATE;
2963            }
2964          } else {
2965            r_llsc_fsm = SC_UPDATE;
2966          }
2967         
2968          break;
2969        }
2970        //////////////////
2971      case SC_TRT_LOCK:
2972        {
2973          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
2974            if( !r_llsc_to_ixr_cmd_req ) { // we can transfer the data to the buffer
2975              size_t way        = r_llsc_way.read();
2976              size_t set        = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2977              for(size_t i = 0; i<m_words; i++){
2978                if(i==m_x[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]) {
2979                  r_llsc_to_ixr_cmd_data[i] = m_cmd_llsc_wdata_fifo.read();
2980                } else {
2981                  r_llsc_to_ixr_cmd_data[i] = m_cache_data[way][set][i];
2982                }
2983              }
2984              size_t wok_index = 0;
2985              bool wok = !m_transaction_tab.full(wok_index);
2986              if ( wok ) { // set a new entry in TRT
2987                r_llsc_trt_index = wok_index;
2988                r_llsc_fsm       = SC_INVAL_LOCK;
2989              } else {
2990                r_llsc_fsm       = SC_WAIT;
2991              }
2992            } else {
2993              r_llsc_fsm = SC_WAIT;
2994            }
2995          }
2996          break;
2997        }
2998        //////////////////
2999      case SC_INVAL_LOCK:
3000        {
3001          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
3002            bool        wok       = false;
3003            size_t      index     = 0;
3004            size_t      srcid     = m_cmd_llsc_srcid_fifo.read();
3005            size_t      trdid     = m_cmd_llsc_trdid_fifo.read();
3006            size_t      pktid     = m_cmd_llsc_pktid_fifo.read();
3007            addr_t          nline     = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
3008            size_t      nb_copies = r_llsc_count.read();
3009
3010            wok =m_update_tab.set(false,        // it's an inval transaction
3011                true,                       // it's a broadcast
3012                true,                       // it needs a response
3013                srcid,
3014                trdid,
3015                pktid,
3016                nline,
3017                nb_copies,
3018                index);
3019#ifdef IDEBUG
3020            if(wok){
3021        std::cout << sc_time_stamp() << " " << name() << " LLSC_INVAL_LOCK update table : " << std::endl;
3022        m_update_tab.print();
3023            }
3024#endif
3025            r_llsc_upt_index = index;
3026            //  releases the lock protecting Update Table if no entry...
3027            if ( wok ) r_llsc_fsm = SC_DIR_INVAL;
3028            else       r_llsc_fsm = SC_WAIT;
3029          }
3030          break;
3031        }
3032        //////////////////
3033      case SC_DIR_INVAL:
3034        {
3035          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) &&
3036              (r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC )  &&
3037              (r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ))
3038          {
3039            m_transaction_tab.set(r_llsc_trt_index.read(),
3040                false,                          // write request to XRAM
3041                m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())],
3042                0,
3043                0,
3044                0,
3045                false,                          // not a processor read
3046                0,                              // not a single word
3047                0,                              // word index
3048                std::vector<be_t>(m_words,0),
3049                std::vector<data_t>(m_words,0));
3050#ifdef TDEBUG
3051        std::cout << sc_time_stamp() << " " << name() << " SC_DIR_INVAL transaction table : " << std::endl;
3052        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
3053          m_transaction_tab.print(i);
3054#endif
3055            // reset Atomic Table
3056            m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
3057
3058            // invalidate directory entry
3059            DirectoryEntry entry;
3060            entry.valid    = false;
3061            entry.dirty    = false;
3062            entry.tag      = 0;
3063            entry.is_cnt   = false;
3064            entry.lock     = false;
3065//            entry.d_copies = 0;
3066//            entry.i_copies = 0;
3067            entry.count    = 0;
3068            size_t set     = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
3069            size_t way     = r_llsc_way.read();
3070            m_cache_directory.write(set, way, entry);
3071
3072            r_llsc_fsm = SC_INVAL;
3073          } else {
3074            assert(false && "LOCK ERROR in LLSC_FSM, STATE = LLSC_DIR_INVAL");
3075          }
3076
3077          break;
3078
3079        }
3080        //////////////////
3081      case SC_INVAL:
3082        {
3083          if ( !r_llsc_to_init_cmd_multi_req.read() &&
3084               !r_llsc_to_init_cmd_brdcast_req.read()) {
3085            r_llsc_to_init_cmd_multi_req    = false;
3086            r_llsc_to_init_cmd_brdcast_req  = true;
3087            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
3088            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
3089            r_llsc_to_init_cmd_index        = 0;
3090            r_llsc_to_init_cmd_wdata        = 0;
3091
3092            r_llsc_fsm = SC_XRAM_SEND;
3093            // all update responses
3094          }
3095
3096          break;
3097        }
3098        //////////////////
3099      case SC_XRAM_SEND:
3100        {
3101          if ( !r_llsc_to_ixr_cmd_req ) {
3102            r_llsc_to_ixr_cmd_req     = true;
3103            r_llsc_to_ixr_cmd_write   = true;
3104            r_llsc_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
3105            r_llsc_to_ixr_cmd_trdid   = r_llsc_trt_index.read();
3106            if(  r_llsc_is_cnt.read() ||
3107                ((!r_llsc_is_cnt.read()) && (r_llsc_count.read()==1)) ){
3108              r_llsc_fsm        = LLSC_IDLE;
3109              cmd_llsc_fifo_get = true;
3110            } else {
3111              r_llsc_fsm        = SC_HEAP_ERASE;
3112              r_llsc_next_ptr   = r_llsc_ptr.read();
3113            }
3114          } else {
3115            assert( false && "MEM_CACHE, LLSC FSM : SC_XRAM_SEND state : the request should not have been previously set");
3116          }
3117          break;
3118        }
3119        //////////////////
3120      case SC_HEAP_ERASE:
3121        {
3122          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC){
3123            HeapEntry next_entry = m_heap_directory.read(r_llsc_next_ptr.read());
3124            if( next_entry.next == r_llsc_next_ptr.read()){
3125              r_write_fsm = SC_HEAP_LAST;
3126            } else {
3127              r_llsc_next_ptr = next_entry.next;
3128              r_llsc_fsm = SC_HEAP_ERASE;
3129            }
3130          }
3131          break;
3132        }
3133        //////////////////
3134      case SC_HEAP_LAST:
3135        {
3136          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
3137                  "MemCache ERROR : bad HEAP allocation");
3138          size_t free_pointer = m_heap_directory.next_free_ptr();
3139
3140          HeapEntry last_entry;
3141          last_entry.owner.srcid = 0;
3142          last_entry.owner.inst  = false;
3143          if(m_heap_directory.is_full()){
3144            last_entry.next     = r_llsc_next_ptr.read();
3145            m_heap_directory.unset_full();
3146          } else {
3147            last_entry.next     = free_pointer;
3148          }
3149
3150          m_heap_directory.write_free_ptr(r_llsc_ptr.read());
3151          m_heap_directory.write(r_llsc_next_ptr.read(),last_entry);
3152
3153          cmd_llsc_fifo_get             = true;
3154          r_llsc_fsm = LLSC_IDLE;
3155          break;
3156        }
3157        //////////////////
3158      case SC_RSP_FALSE:
3159        {
3160          if( !r_llsc_to_tgt_rsp_req ) {
3161            cmd_llsc_fifo_get           = true;
3162            r_llsc_to_tgt_rsp_req       = true;
3163            r_llsc_to_tgt_rsp_data      = 1;
3164            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
3165            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
3166            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
3167            r_llsc_fsm                      = LLSC_IDLE;
3168          }
3169          break;
3170        }
3171        /////////////////
3172      case SC_RSP_TRUE:
3173        {
3174          if( !r_llsc_to_tgt_rsp_req ) {
3175            cmd_llsc_fifo_get       = true;
3176            r_llsc_to_tgt_rsp_req       = true;
3177            r_llsc_to_tgt_rsp_data      = 0;
3178            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
3179            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
3180            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
3181            r_llsc_fsm                      = LLSC_IDLE;
3182          }
3183          break;
3184        }
3185        ///////////////////
3186      case LLSC_TRT_LOCK:         // read or write miss : check the Transaction Table
3187        {
3188          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
3189            size_t   index = 0;
3190            bool hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],index);
3191            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]);
3192            bool wok = !m_transaction_tab.full(index);
3193
3194            if ( hit_read || !wok || hit_write ) {  // missing line already requested or no space in TRT
3195              r_llsc_fsm = LLSC_IDLE;
3196            } else {
3197              r_llsc_trt_index = index;
3198              r_llsc_fsm       = LLSC_TRT_SET;
3199            }
3200          }
3201          break;
3202        }
3203        //////////////////
3204      case LLSC_TRT_SET:        // register the XRAM transaction in Transaction Table
3205        {
3206          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
3207            size_t word = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
3208            bool proc_read = !m_cmd_llsc_sc_fifo.read();
3209            if(proc_read){
3210              m_transaction_tab.set(r_llsc_trt_index.read(),
3211                  true,
3212                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
3213                  m_cmd_llsc_srcid_fifo.read(),
3214                  m_cmd_llsc_trdid_fifo.read(),
3215                  m_cmd_llsc_pktid_fifo.read(),
3216                  true,
3217                  1,
3218                  word,
3219                  std::vector<be_t>(m_words,0),
3220                  std::vector<data_t>(m_words,0));
3221            }else{
3222              std::vector<be_t> be_vector;
3223              std::vector<data_t> data_vector;
3224              be_vector.clear();
3225              data_vector.clear();
3226              // reset Atomic Table
3227              m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
3228              for ( size_t i=0; i<m_words; i++ )
3229              {   
3230                if(i == word){
3231                  be_vector.push_back(0xF);
3232                  data_vector.push_back(m_cmd_llsc_wdata_fifo.read());
3233                } else {
3234                  be_vector.push_back(0);
3235                  data_vector.push_back(0);
3236                }
3237              }
3238 
3239              m_transaction_tab.set(r_llsc_trt_index.read(),
3240                  true,
3241                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
3242                  m_cmd_llsc_srcid_fifo.read(),
3243                  m_cmd_llsc_trdid_fifo.read(),
3244                  m_cmd_llsc_pktid_fifo.read(),
3245                  false,
3246                  0,
3247                  0,
3248                  be_vector,
3249                  data_vector);
3250            }
3251#ifdef TDEBUG
3252        std::cout << sc_time_stamp() << " " << name() << " LLSC_TRT_SET transaction table : " << std::endl;
3253        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
3254          m_transaction_tab.print(i);
3255#endif
3256
3257            r_llsc_fsm = LLSC_XRAM_REQ;
3258          }
3259          break;
3260        }
3261        ///////////////////
3262      case LLSC_XRAM_REQ:       // request the IXR_CMD FSM to fetch the missing line
3263        {
3264          if ( !r_llsc_to_ixr_cmd_req ) {
3265            r_llsc_to_ixr_cmd_req        = true;
3266            r_llsc_to_ixr_cmd_write      = false;
3267            r_llsc_to_ixr_cmd_trdid      = r_llsc_trt_index.read();
3268            r_llsc_to_ixr_cmd_nline      = m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()];
3269            if( m_cmd_llsc_sc_fifo.read() ) {
3270              r_llsc_fsm                 = SC_RSP_TRUE;
3271            } else {
3272              cmd_llsc_fifo_get          = true;
3273              r_llsc_fsm                 = LLSC_IDLE;
3274            }
3275          }
3276          break;
3277        }
3278    } // end switch r_llsc_fsm
3279
3280
3281    //////////////////////////////////////////////////////////////////////////////
3282    //          INIT_CMD FSM
3283    //////////////////////////////////////////////////////////////////////////////
3284    // The INIT_CMD fsm controls the VCI CMD initiator port, used to update
3285    // or invalidate cache lines in L1 caches.
3286    // It implements a round-robin priority between the two following requests:
3287    // - r_write_to_init_cmd_req : update request from WRITE FSM
3288    // - r_xram_rsp_to_init_cmd_req : invalidate request from XRAM_RSP FSM
3289    // The inval request is a single cell VCI write command containing the
3290    // index of the line to be invalidated.
3291    // The update request is a multi-cells VCI write command : The first cell
3292    // contains the index of the cache line to be updated. The second cell contains
3293    // the index of the first modified word in the line. The following cells
3294    // contain the data.
3295    ///////////////////////////////////////////////////////////////////////////////
3296
3297    switch ( r_init_cmd_fsm.read() ) {
3298
3299      ////////////////////////
3300      case INIT_CMD_UPDT_IDLE:  // Invalidate requests have highest priority
3301        {
3302
3303          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3304               r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3305            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3306            m_cpt_inval++;
3307          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3308            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3309            m_cpt_inval++;
3310          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
3311                      r_write_to_init_cmd_multi_req.read() ) {
3312            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3313            m_cpt_update++;
3314          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3315            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3316            m_cpt_inval++;
3317          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3318                      r_llsc_to_init_cmd_multi_req.read()  ) {
3319            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3320            m_cpt_update++;
3321          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3322            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3323            m_cpt_inval++;
3324          }
3325          break;
3326        }
3327        /////////////////////////
3328      case INIT_CMD_INVAL_IDLE: // Update requests have highest priority
3329        {
3330          if ( m_write_to_init_cmd_inst_fifo.rok() ||
3331               r_write_to_init_cmd_multi_req.read() ) {
3332            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3333            m_cpt_update++;
3334          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3335            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3336            m_cpt_inval++;
3337          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3338                      r_llsc_to_init_cmd_multi_req.read()  ) {
3339            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3340            m_cpt_update++;
3341          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3342            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3343            m_cpt_inval++;
3344          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3345                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3346            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3347            m_cpt_inval++;
3348          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3349            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3350            m_cpt_inval++;
3351          }
3352          break;
3353        }
3354        /////////////////////////
3355      case INIT_CMD_SC_UPDT_IDLE:       // Update requests for SCs have highest priority
3356        {
3357          if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3358               r_llsc_to_init_cmd_multi_req.read()  ) {
3359            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3360            m_cpt_update++;
3361          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3362            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3363            m_cpt_inval++;
3364          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3365                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3366            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3367            m_cpt_inval++;
3368          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3369            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3370            m_cpt_inval++;
3371          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
3372                      r_write_to_init_cmd_multi_req.read() ) {
3373            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3374            m_cpt_update++;
3375          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3376            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3377            m_cpt_inval++;
3378          }
3379          break;
3380        }
3381        ////////////////////////
3382      case INIT_CMD_INVAL_NLINE:        // send the cache line index
3383        {
3384          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ){
3385            if ( p_vci_ini.cmdack ) {
3386              m_cpt_inval_mult++;
3387              r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3388              xram_rsp_to_init_cmd_fifo_get = true;
3389            }
3390          } else {
3391            if( r_xram_rsp_to_init_cmd_multi_req.read() ){
3392              r_xram_rsp_to_init_cmd_multi_req = false;
3393            }
3394            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
3395          }
3396          break;
3397        }
3398        ////////////////////////
3399      case INIT_CMD_XRAM_BRDCAST:       // send the cache line index
3400        {
3401          if ( p_vci_ini.cmdack ) {
3402            m_cpt_inval_brdcast++;
3403            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
3404            r_xram_rsp_to_init_cmd_brdcast_req = false;
3405          }
3406          break;
3407        }
3408        /////////////////////////
3409      case INIT_CMD_WRITE_BRDCAST:
3410        {
3411          if( p_vci_ini.cmdack ) {
3412            m_cpt_inval_brdcast++;
3413            r_write_to_init_cmd_brdcast_req = false;
3414            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
3415          }
3416          break;
3417        }
3418        /////////////////////////
3419      case INIT_CMD_UPDT_NLINE: // send the cache line index
3420        {
3421          if ( m_write_to_init_cmd_inst_fifo.rok() ) {
3422            if ( p_vci_ini.cmdack ){
3423              m_cpt_update_mult++;
3424              r_init_cmd_fsm = INIT_CMD_UPDT_INDEX;
3425            }
3426          } else {
3427            if ( r_write_to_init_cmd_multi_req.read() ){
3428              r_write_to_init_cmd_multi_req = false;
3429            }
3430            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
3431          }
3432          break;
3433        }
3434        /////////////////////////
3435      case INIT_CMD_UPDT_INDEX: // send the first word index
3436        {
3437          r_init_cmd_cpt    = 0;
3438          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_UPDT_DATA;
3439          break;
3440        }
3441        ////////////////////////
3442      case INIT_CMD_UPDT_DATA:  // send the data
3443        {
3444          if ( p_vci_ini.cmdack ) {
3445            if ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) ) {
3446              r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3447              write_to_init_cmd_fifo_get = true;
3448            } else {
3449              r_init_cmd_cpt = r_init_cmd_cpt.read() + 1;
3450            }
3451          }
3452          break;
3453        }
3454        /////////////////////////
3455      case INIT_CMD_SC_BRDCAST:
3456        {
3457          if( p_vci_ini.cmdack ) {
3458            m_cpt_inval_brdcast++;
3459            r_llsc_to_init_cmd_brdcast_req = false;
3460            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
3461          }
3462          break;
3463        }
3464        /////////////////////////
3465      case INIT_CMD_SC_UPDT_NLINE:      // send the cache line index
3466        {
3467          if ( m_llsc_to_init_cmd_inst_fifo.rok() ){
3468            if ( p_vci_ini.cmdack ){
3469              m_cpt_update_mult++;
3470              r_init_cmd_fsm = INIT_CMD_SC_UPDT_INDEX;
3471            }
3472          } else {
3473            if( r_llsc_to_init_cmd_multi_req.read() ){
3474              r_llsc_to_init_cmd_multi_req = false;
3475            }
3476            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
3477          }
3478          break;
3479        }
3480        /////////////////////////
3481      case INIT_CMD_SC_UPDT_INDEX:      // send the first word index
3482        {
3483          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA;
3484          break;
3485        }
3486        ////////////////////////
3487      case INIT_CMD_SC_UPDT_DATA:       // send the data
3488        {
3489          if ( p_vci_ini.cmdack ) {
3490            llsc_to_init_cmd_fifo_get = true;
3491            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3492          }
3493          break;
3494        }
3495
3496    } // end switch r_init_cmd_fsm
3497
3498    /////////////////////////////////////////////////////////////////////
3499    //          TGT_RSP FSM
3500    /////////////////////////////////////////////////////////////////////
3501    // The TGT_RSP fsm sends the responses on the VCI target port
3502    // with a round robin priority between six requests :
3503    // - r_read_to_tgt_rsp_req
3504    // - r_write_to_tgt_rsp_req
3505    // - r_llsc_to_tgt_rsp_req
3506    // - r_cleanup_to_tgt_rsp_req
3507    // - r_init_rsp_to_tgt_rsp_req
3508    // - r_xram_rsp_to_tgt_rsp_req
3509    // The  ordering is :  read > write > llsc > cleanup > xram > init
3510    /////////////////////////////////////////////////////////////////////
3511
3512    switch ( r_tgt_rsp_fsm.read() ) {
3513
3514      ///////////////////////
3515      case TGT_RSP_READ_IDLE:           // write requests have the highest priority
3516        {
3517          if      ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3518          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3519          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3520            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3521            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3522          }
3523          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3524          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3525          else if ( r_read_to_tgt_rsp_req     ) {
3526            r_tgt_rsp_fsm = TGT_RSP_READ;
3527            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3528          }
3529          break;
3530        }
3531        ////////////////////////
3532      case TGT_RSP_WRITE_IDLE:          // llsc requests have the highest priority
3533        {
3534          if      ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3535          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3536            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3537            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3538          }
3539          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3540          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3541          else if ( r_read_to_tgt_rsp_req     ) {
3542            r_tgt_rsp_fsm = TGT_RSP_READ;
3543            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3544          }
3545
3546          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3547          break;
3548        }
3549        ///////////////////////
3550      case TGT_RSP_LLSC_IDLE:           // cleanup requests have the highest priority
3551        {
3552          if ( r_xram_rsp_to_tgt_rsp_req )  {
3553            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3554            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3555          }
3556          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3557          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3558          else if ( r_read_to_tgt_rsp_req     ) {
3559            r_tgt_rsp_fsm = TGT_RSP_READ;
3560            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3561          }
3562          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3563          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3564          break;
3565        }
3566      case TGT_RSP_XRAM_IDLE:           // init requests have the highest priority
3567        {
3568
3569          if      ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3570          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3571          else if ( r_read_to_tgt_rsp_req     ) {
3572            r_tgt_rsp_fsm = TGT_RSP_READ;
3573            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3574          }
3575          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3576          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3577          else if ( r_xram_rsp_to_tgt_rsp_req )  {
3578            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3579            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3580          }
3581          break;
3582        }
3583        ///////////////////////
3584      case TGT_RSP_INIT_IDLE:           // cleanup requests have the highest priority
3585        {
3586          if      ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3587          else if ( r_read_to_tgt_rsp_req     ) {
3588            r_tgt_rsp_fsm = TGT_RSP_READ;
3589            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3590          }
3591          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3592          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3593          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3594            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3595            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3596          }
3597          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3598          break;
3599        }
3600        ///////////////////////
3601      case TGT_RSP_CLEANUP_IDLE:                // read requests have the highest priority
3602        {
3603          if      ( r_read_to_tgt_rsp_req     ) {
3604            r_tgt_rsp_fsm = TGT_RSP_READ;
3605            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3606          }
3607          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3608          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3609          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3610            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3611            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3612          }
3613          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3614          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3615          break;
3616        }
3617        ///////////////////////
3618      case TGT_RSP_READ:                // send the response
3619        {
3620          if ( p_vci_tgt.rspack ) {
3621            if ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) ) {
3622              r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
3623              r_read_to_tgt_rsp_req = false;
3624            } else {
3625              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
3626            }
3627          }
3628          break;
3629        }
3630        ///////////////////
3631      case TGT_RSP_WRITE:               // send the write acknowledge
3632        {
3633          if ( p_vci_tgt.rspack ) {
3634            r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE;
3635            r_write_to_tgt_rsp_req = false;
3636          }
3637          break;
3638        }
3639        ///////////////////
3640      case TGT_RSP_CLEANUP:             // send the write acknowledge
3641        {
3642          if ( p_vci_tgt.rspack ) {
3643            r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE;
3644            r_cleanup_to_tgt_rsp_req = false;
3645          }
3646          break;
3647        }
3648        //////////////////
3649      case TGT_RSP_LLSC:                // send one atomic word response
3650        {
3651          if ( p_vci_tgt.rspack ) {
3652            r_tgt_rsp_fsm = TGT_RSP_LLSC_IDLE;
3653            r_llsc_to_tgt_rsp_req = false;
3654          }
3655          break;
3656        }
3657
3658        ///////////////////////
3659      case TGT_RSP_XRAM:                // send the response
3660        {
3661          if ( p_vci_tgt.rspack ) {
3662            if ( r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1)) {
3663              r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
3664              r_xram_rsp_to_tgt_rsp_req = false;
3665            } else {
3666              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
3667            }
3668          }
3669          break;
3670        }
3671        ///////////////////
3672      case TGT_RSP_INIT:                // send the pending write acknowledge
3673        {
3674          if ( p_vci_tgt.rspack ) {
3675            r_tgt_rsp_fsm = TGT_RSP_INIT_IDLE;
3676            r_init_rsp_to_tgt_rsp_req = false;
3677          }
3678          break;
3679        }
3680    } // end switch tgt_rsp_fsm
3681    ////////////////////////////////////////////////////////////////////////////////////
3682    //          NEW ALLOC_UPT FSM
3683    ////////////////////////////////////////////////////////////////////////////////////
3684    // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT).
3685    // with a round robin priority between three FSMs : INIT_RSP > WRITE > XRAM_RSP > CLEANUP
3686    // - The WRITE FSM initiates update transactions and sets  new entry in UPT.
3687    // - The XRAM_RSP FSM initiates inval transactions and sets  new entry in UPT.
3688    // - The INIT_RSP FSM complete those trasactions and erase the UPT entry.
3689    // - The CLEANUP  FSM decrement an entry in UPT.
3690    // The resource is always allocated.
3691    /////////////////////////////////////////////////////////////////////////////////////
3692
3693    switch ( r_alloc_upt_fsm.read() ) {
3694
3695      ////////////////////////
3696      case ALLOC_UPT_INIT_RSP:
3697        if ( (r_init_rsp_fsm.read() != INIT_RSP_UPT_LOCK) &&
3698             (r_init_rsp_fsm.read() != INIT_RSP_UPT_CLEAR) )
3699        {
3700          if      ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3701                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3702          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3703          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3704          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3705                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3706        }
3707        break;
3708
3709        /////////////////////
3710      case ALLOC_UPT_WRITE:
3711        if ( (r_write_fsm.read() != WRITE_UPT_LOCK) &&
3712             (r_write_fsm.read() != WRITE_INVAL_LOCK))
3713        {
3714          if      (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3715          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3716          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3717                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3718          else if (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3719        }
3720        break;
3721
3722        ////////////////////////
3723      case ALLOC_UPT_XRAM_RSP:
3724        if (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
3725        {
3726          if       (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)       r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3727          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3728                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3729          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3730          else if ((r_write_fsm.read() == WRITE_UPT_LOCK)   ||
3731                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3732        }
3733        break;
3734
3735        //////////////////////////
3736      case ALLOC_UPT_CLEANUP:
3737        if(r_cleanup_fsm.read() != CLEANUP_UPT_LOCK )
3738        {
3739          if      ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3740                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3741          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3742          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3743                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3744          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3745        }
3746        break;
3747       
3748        //////////////////////////
3749      case ALLOC_UPT_LLSC:
3750        if( (r_llsc_fsm.read() != SC_UPT_LOCK) &&
3751            (r_llsc_fsm.read() != SC_INVAL_LOCK))
3752        {
3753          if      (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3754          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3755                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3756          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3757          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3758        }
3759        break;
3760
3761    } // end switch r_alloc_upt_fsm
3762
3763    ////////////////////////////////////////////////////////////////////////////////////
3764    //          ALLOC_DIR FSM
3765    ////////////////////////////////////////////////////////////////////////////////////
3766    // The ALLOC_DIR FSM allocates the access to the directory and
3767    // the data cache with a round robin priority between 5 user FSMs :
3768    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
3769    // The ressource is always allocated.
3770    /////////////////////////////////////////////////////////////////////////////////////
3771
3772    switch ( r_alloc_dir_fsm.read() ) {
3773
3774      ////////////////////
3775      case ALLOC_DIR_READ:
3776        if ( ( (r_read_fsm.read() != READ_DIR_LOCK) &&
3777              (r_read_fsm.read() != READ_TRT_LOCK)  &&
3778              (r_read_fsm.read() != READ_HEAP_LOCK))
3779            ||
3780            ( (r_read_fsm.read()        == READ_HEAP_LOCK) &&
3781              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_READ) )
3782            ||
3783            ( (r_read_fsm.read()      == READ_TRT_LOCK)  &&
3784              (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)    )  )
3785        {
3786          if        (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3787          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
3788                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3789          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3790          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3791        }
3792        break;
3793
3794        /////////////////////
3795      case ALLOC_DIR_WRITE:
3796        if ( ( (r_write_fsm.read() != WRITE_DIR_LOCK)     &&
3797              (r_write_fsm.read() != WRITE_TRT_LOCK)     &&
3798              (r_write_fsm.read() != WRITE_DIR_HIT_READ) &&
3799              (r_write_fsm.read() != WRITE_DIR_HIT) &&
3800              (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3801              (r_write_fsm.read() != WRITE_INVAL_LOCK) &&
3802              (r_write_fsm.read() != WRITE_UPT_LOCK) &&
3803              (r_write_fsm.read() != WRITE_HEAP_LOCK))
3804            ||
3805            ( (r_write_fsm.read()       == WRITE_HEAP_LOCK) &&
3806              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_WRITE) )
3807            ||
3808            ( (r_write_fsm.read()     == WRITE_TRT_LOCK) &&
3809              (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)   )   )
3810        {
3811          if        ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
3812                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3813          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3814          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3815          else if   (r_read_fsm.read() == READ_DIR_LOCK)                r_alloc_dir_fsm = ALLOC_DIR_READ;
3816        }
3817        break;
3818
3819        ////////////////////
3820      case ALLOC_DIR_LLSC:
3821        if ( ( (r_llsc_fsm.read() != LL_DIR_LOCK)    &&
3822              (r_llsc_fsm.read() != LL_DIR_HIT )    &&
3823              (r_llsc_fsm.read() != SC_DIR_LOCK)    &&
3824              (r_llsc_fsm.read() != SC_DIR_HIT )    &&
3825              (r_llsc_fsm.read() != LLSC_TRT_LOCK ) &&
3826              (r_llsc_fsm.read() != SC_TRT_LOCK)    &&
3827              (r_llsc_fsm.read() != SC_INVAL_LOCK)  &&
3828              (r_llsc_fsm.read() != SC_UPT_LOCK)    &&
3829              (r_llsc_fsm.read() != SC_HEAP_LOCK))
3830            ||
3831            ( (r_llsc_fsm.read()       == SC_HEAP_LOCK) &&
3832              (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) )
3833            ||
3834            ( (r_llsc_fsm.read()      == LLSC_TRT_LOCK ) &&
3835              (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC)    ) )
3836        {
3837          if      (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3838          else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)  r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3839          else if (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3840          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3841        }
3842        break;
3843
3844        ///////////////////////
3845      case ALLOC_DIR_CLEANUP:
3846        if ( (r_cleanup_fsm.read() != CLEANUP_DIR_LOCK) &&
3847            (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) )
3848        {
3849          if        (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3850          else if   (r_read_fsm.read() == READ_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_READ;
3851          else if   (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3852          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
3853                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3854        }
3855        break;
3856        ////////////////////////
3857      case ALLOC_DIR_XRAM_RSP:
3858        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_LOCK)  &&
3859            (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)   &&
3860            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK))
3861        {
3862          if      (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3863          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3864          else if ( (r_llsc_fsm.read() == LL_DIR_LOCK) ||
3865                    (r_llsc_fsm.read() == SC_DIR_LOCK))         r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3866          else if (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3867        }
3868        break;
3869
3870    } // end switch alloc_dir_fsm
3871
3872    ////////////////////////////////////////////////////////////////////////////////////
3873    //          ALLOC_TRT FSM
3874    ////////////////////////////////////////////////////////////////////////////////////
3875    // The ALLOC_TRT fsm allocates the access to the Transaction Table (write buffer)
3876    // with a round robin priority between 4 user FSMs :
3877    // The cyclic priority is READ > WRITE > LLSC > XRAM_RSP
3878    // The ressource is always allocated.
3879    ///////////////////////////////////////////////////////////////////////////////////
3880
3881    switch (r_alloc_trt_fsm) {
3882
3883      ////////////////////
3884      case ALLOC_TRT_READ:
3885        if ( r_read_fsm.read() != READ_TRT_LOCK )
3886        {
3887          if      ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3888                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3889          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3890                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3891          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3892          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3893                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) )    r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3894        }
3895        break;
3896        /////////////////////
3897      case ALLOC_TRT_WRITE:
3898        if ( (r_write_fsm.read() != WRITE_TRT_LOCK) &&
3899             (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3900             (r_write_fsm.read() != WRITE_INVAL_LOCK))
3901        {
3902          if      ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3903                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3904          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3905          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3906                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3907          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3908        }
3909        break;
3910        ////////////////////
3911      case ALLOC_TRT_LLSC:
3912        if ( (r_llsc_fsm.read() != LLSC_TRT_LOCK) &&
3913             (r_llsc_fsm.read() != SC_TRT_LOCK) &&
3914             (r_llsc_fsm.read() != SC_INVAL_LOCK))
3915        {
3916          if      (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3917          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3918                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3919          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3920          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)     ||
3921                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3922        }
3923        break;
3924        ////////////////////////
3925      case ALLOC_TRT_XRAM_RSP:
3926        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)  &&
3927            (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_UPDT)   &&
3928            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)) {
3929          if      ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3930                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3931          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3932          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)    ||
3933                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3934          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3935                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3936        }
3937        break;
3938        ////////////////////////
3939      case ALLOC_TRT_IXR_RSP:
3940        if ( (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_ERASE) &&
3941            (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ) ) {
3942          if      (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3943          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3944                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3945          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3946                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3947          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3948        }
3949        break;
3950
3951    } // end switch alloc_trt_fsm
3952
3953    ////////////////////////////////////////////////////////////////////////////////////
3954    //          ALLOC_HEAP FSM
3955    ////////////////////////////////////////////////////////////////////////////////////
3956    // The ALLOC_HEAP FSM allocates the access to the heap
3957    // with a round robin priority between 5 user FSMs :
3958    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
3959    // The ressource is always allocated.
3960    /////////////////////////////////////////////////////////////////////////////////////
3961
3962    switch ( r_alloc_heap_fsm.read() ) {
3963
3964      ////////////////////
3965      case ALLOC_HEAP_READ:
3966        if (  (r_read_fsm.read() != READ_HEAP_LOCK) &&
3967              (r_read_fsm.read() != READ_HEAP_ERASE)     )
3968        {
3969          if        ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||         
3970                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
3971          else if  ((r_llsc_fsm.read() == SC_HEAP_LOCK) ||
3972                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3973          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3974          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3975        }
3976        break;
3977
3978        /////////////////////
3979      case ALLOC_HEAP_WRITE:
3980        if (  (r_write_fsm.read() != WRITE_HEAP_LOCK)   &&
3981              (r_write_fsm.read() != WRITE_UPT_REQ)     &&
3982              (r_write_fsm.read() != WRITE_UPDATE)      &&
3983              (r_write_fsm.read() != WRITE_HEAP_ERASE))
3984        {
3985          if       ((r_llsc_fsm.read() == SC_HEAP_LOCK) ||
3986                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3987          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3988          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3989          else if   (r_read_fsm.read() == READ_HEAP_LOCK)               r_alloc_heap_fsm = ALLOC_HEAP_READ;
3990        }
3991        break;
3992
3993        ////////////////////
3994      case ALLOC_HEAP_LLSC:
3995        if (  (r_llsc_fsm.read() != SC_HEAP_LOCK)  &&
3996              (r_llsc_fsm.read() != SC_UPT_REQ )    &&
3997              (r_llsc_fsm.read() != SC_UPDATE)      &&
3998              (r_llsc_fsm.read() != SC_HEAP_ERASE ) )
3999        {
4000          if      (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
4001          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
4002          else if (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
4003          else if ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||       
4004                   (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
4005        }
4006        break;
4007
4008        ///////////////////////
4009      case ALLOC_HEAP_CLEANUP:
4010        if ( (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) &&
4011            (r_cleanup_fsm.read() != CLEANUP_HEAP_SEARCH)&&
4012            (r_cleanup_fsm.read() != CLEANUP_HEAP_CLEAN)    )
4013        {
4014          if        (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
4015          else if   (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
4016          else if   ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||       
4017                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
4018          else if   ((r_llsc_fsm.read() == SC_HEAP_LOCK) ||
4019                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
4020        }
4021        break;
4022        ////////////////////////
4023      case ALLOC_HEAP_XRAM_RSP:
4024        if ( r_xram_rsp_fsm.read() != XRAM_RSP_HEAP_ERASE )
4025        {
4026          if        (r_read_fsm.read() == READ_HEAP_LOCK)               r_alloc_heap_fsm = ALLOC_HEAP_READ;
4027          else if   ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||       
4028                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
4029          else if   ( (r_llsc_fsm.read() == SC_HEAP_LOCK) ||
4030                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
4031          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
4032        }
4033        break;
4034
4035    } // end switch alloc_heap_fsm
4036
4037
4038    ////////////////////////////////////////////////////////////////////////////////////
4039    //          TGT_CMD to READ FIFO
4040    ////////////////////////////////////////////////////////////////////////////////////
4041
4042    if ( cmd_read_fifo_put ) {
4043      if ( cmd_read_fifo_get ) {
4044        m_cmd_read_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
4045        m_cmd_read_length_fifo.put_and_get(p_vci_tgt.plen.read()>>2);
4046        m_cmd_read_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
4047        m_cmd_read_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
4048        m_cmd_read_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
4049      } else {
4050        m_cmd_read_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
4051        m_cmd_read_length_fifo.simple_put(p_vci_tgt.plen.read()>>2);
4052        m_cmd_read_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
4053        m_cmd_read_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
4054        m_cmd_read_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
4055      }
4056    } else {
4057      if ( cmd_read_fifo_get ) {
4058        m_cmd_read_addr_fifo.simple_get();
4059        m_cmd_read_length_fifo.simple_get();
4060        m_cmd_read_srcid_fifo.simple_get();
4061        m_cmd_read_trdid_fifo.simple_get();
4062        m_cmd_read_pktid_fifo.simple_get();
4063      }
4064    }
4065    /////////////////////////////////////////////////////////////////////
4066    //          TGT_CMD to WRITE FIFO
4067    /////////////////////////////////////////////////////////////////////
4068
4069    if ( cmd_write_fifo_put ) {
4070      if ( cmd_write_fifo_get ) {
4071        m_cmd_write_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
4072        m_cmd_write_eop_fifo.put_and_get(p_vci_tgt.eop.read());
4073        m_cmd_write_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
4074        m_cmd_write_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
4075        m_cmd_write_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
4076        m_cmd_write_data_fifo.put_and_get(p_vci_tgt.wdata.read());
4077        m_cmd_write_be_fifo.put_and_get(p_vci_tgt.be.read());
4078      } else {
4079        m_cmd_write_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
4080        m_cmd_write_eop_fifo.simple_put(p_vci_tgt.eop.read());
4081        m_cmd_write_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
4082        m_cmd_write_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
4083        m_cmd_write_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
4084        m_cmd_write_data_fifo.simple_put(p_vci_tgt.wdata.read());
4085        m_cmd_write_be_fifo.simple_put(p_vci_tgt.be.read());
4086      }
4087    } else {
4088      if ( cmd_write_fifo_get ) {
4089        m_cmd_write_addr_fifo.simple_get();
4090        m_cmd_write_eop_fifo.simple_get();
4091        m_cmd_write_srcid_fifo.simple_get();
4092        m_cmd_write_trdid_fifo.simple_get();
4093        m_cmd_write_pktid_fifo.simple_get();
4094        m_cmd_write_data_fifo.simple_get();
4095        m_cmd_write_be_fifo.simple_get();
4096      }
4097    }
4098    ////////////////////////////////////////////////////////////////////////////////////
4099    //          TGT_CMD to LLSC FIFO
4100    ////////////////////////////////////////////////////////////////////////////////////
4101
4102    if ( cmd_llsc_fifo_put ) {
4103      if ( cmd_llsc_fifo_get ) {
4104        m_cmd_llsc_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
4105        m_cmd_llsc_sc_fifo.put_and_get(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND);
4106        m_cmd_llsc_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
4107        m_cmd_llsc_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
4108        m_cmd_llsc_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
4109        m_cmd_llsc_wdata_fifo.put_and_get(p_vci_tgt.wdata.read());
4110      } else {
4111        m_cmd_llsc_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
4112        m_cmd_llsc_sc_fifo.simple_put(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND);
4113        m_cmd_llsc_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
4114        m_cmd_llsc_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
4115        m_cmd_llsc_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
4116        m_cmd_llsc_wdata_fifo.simple_put(p_vci_tgt.wdata.read());
4117      }
4118    } else {
4119      if ( cmd_llsc_fifo_get ) {
4120        m_cmd_llsc_addr_fifo.simple_get();
4121        m_cmd_llsc_sc_fifo.simple_get();
4122        m_cmd_llsc_srcid_fifo.simple_get();
4123        m_cmd_llsc_trdid_fifo.simple_get();
4124        m_cmd_llsc_pktid_fifo.simple_get();
4125        m_cmd_llsc_wdata_fifo.simple_get();
4126      }
4127    }
4128    ////////////////////////////////////////////////////////////////////////////////////
4129    //          WRITE to INIT_CMD FIFO
4130    ////////////////////////////////////////////////////////////////////////////////////
4131
4132    if ( write_to_init_cmd_fifo_put ) {
4133      if ( write_to_init_cmd_fifo_get ) {
4134        m_write_to_init_cmd_inst_fifo.put_and_get(write_to_init_cmd_fifo_inst);
4135        m_write_to_init_cmd_srcid_fifo.put_and_get(write_to_init_cmd_fifo_srcid);
4136      } else {
4137        m_write_to_init_cmd_inst_fifo.simple_put(write_to_init_cmd_fifo_inst);
4138        m_write_to_init_cmd_srcid_fifo.simple_put(write_to_init_cmd_fifo_srcid);
4139      }
4140    } else {
4141      if ( write_to_init_cmd_fifo_get ) {
4142        m_write_to_init_cmd_inst_fifo.simple_get();
4143        m_write_to_init_cmd_srcid_fifo.simple_get();
4144      }
4145    }
4146    ////////////////////////////////////////////////////////////////////////////////////
4147    //          XRAM_RSP to INIT_CMD FIFO
4148    ////////////////////////////////////////////////////////////////////////////////////
4149
4150    if ( xram_rsp_to_init_cmd_fifo_put ) {
4151      if ( xram_rsp_to_init_cmd_fifo_get ) {
4152        m_xram_rsp_to_init_cmd_inst_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_inst);
4153        m_xram_rsp_to_init_cmd_srcid_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_srcid);
4154      } else {
4155        m_xram_rsp_to_init_cmd_inst_fifo.simple_put(xram_rsp_to_init_cmd_fifo_inst);
4156        m_xram_rsp_to_init_cmd_srcid_fifo.simple_put(xram_rsp_to_init_cmd_fifo_srcid);
4157      }
4158    } else {
4159      if ( xram_rsp_to_init_cmd_fifo_get ) {
4160        m_xram_rsp_to_init_cmd_inst_fifo.simple_get();
4161        m_xram_rsp_to_init_cmd_srcid_fifo.simple_get();
4162      }
4163    }
4164    ////////////////////////////////////////////////////////////////////////////////////
4165    //          LLSC to INIT_CMD FIFO
4166    ////////////////////////////////////////////////////////////////////////////////////
4167
4168    if ( llsc_to_init_cmd_fifo_put ) {
4169      if ( llsc_to_init_cmd_fifo_get ) {
4170        m_llsc_to_init_cmd_inst_fifo.put_and_get(llsc_to_init_cmd_fifo_inst);
4171        m_llsc_to_init_cmd_srcid_fifo.put_and_get(llsc_to_init_cmd_fifo_srcid);
4172      } else {
4173        m_llsc_to_init_cmd_inst_fifo.simple_put(llsc_to_init_cmd_fifo_inst);
4174        m_llsc_to_init_cmd_srcid_fifo.simple_put(llsc_to_init_cmd_fifo_srcid);
4175      }
4176    } else {
4177      if ( llsc_to_init_cmd_fifo_get ) {
4178        m_llsc_to_init_cmd_inst_fifo.simple_get();
4179        m_llsc_to_init_cmd_srcid_fifo.simple_get();
4180      }
4181    }
4182
4183
4184  //////////////////////////////////////////////////////////////
4185    m_cpt_cycles++;
4186
4187  } // end transition()
4188
4189  /////////////////////////////
4190  tmpl(void)::genMoore()
4191    /////////////////////////////
4192  {
4193    ////////////////////////////////////////////////////////////
4194    // Command signals on the p_vci_ixr port
4195    ////////////////////////////////////////////////////////////
4196
4197
4198    p_vci_ixr.be      = 0xF;
4199    p_vci_ixr.pktid   = 0;
4200    p_vci_ixr.srcid   = m_srcid_ixr;
4201    p_vci_ixr.cons    = false;
4202    p_vci_ixr.wrap    = false;
4203    p_vci_ixr.contig  = true;
4204    p_vci_ixr.clen    = 0;
4205    p_vci_ixr.cfixed  = false;
4206
4207    if ( r_ixr_cmd_fsm.read() == IXR_CMD_READ_NLINE ) {
4208      p_vci_ixr.cmd     = vci_param::CMD_READ;
4209      p_vci_ixr.cmdval  = true;
4210      p_vci_ixr.address = (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4);
4211      p_vci_ixr.plen    = m_words*4;
4212      p_vci_ixr.wdata   = 0x00000000;
4213      p_vci_ixr.trdid   = r_read_to_ixr_cmd_trdid.read();
4214      p_vci_ixr.eop     = true;
4215    }
4216    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_LLSC_NLINE ) {
4217      if(r_llsc_to_ixr_cmd_write.read()){
4218        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4219        p_vci_ixr.cmdval  = true;
4220        p_vci_ixr.address = (addr_t)((r_llsc_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4221        p_vci_ixr.plen    = m_words*4;
4222        p_vci_ixr.wdata   = r_llsc_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4223        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
4224        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4225      } else {
4226        p_vci_ixr.cmd     = vci_param::CMD_READ;
4227        p_vci_ixr.cmdval  = true;
4228        p_vci_ixr.address = (addr_t)(r_llsc_to_ixr_cmd_nline.read()*m_words*4);
4229        p_vci_ixr.plen    = m_words*4;
4230        p_vci_ixr.wdata   = 0x00000000;
4231        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
4232        p_vci_ixr.eop     = true;
4233      }
4234    }
4235    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_WRITE_NLINE ) {
4236      if(r_write_to_ixr_cmd_write.read()){
4237        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4238        p_vci_ixr.cmdval  = true;
4239        p_vci_ixr.address = (addr_t)((r_write_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4240        p_vci_ixr.plen    = m_words*4;
4241        p_vci_ixr.wdata   = r_write_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4242        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
4243        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4244      } else {
4245        p_vci_ixr.cmd     = vci_param::CMD_READ;
4246        p_vci_ixr.cmdval  = true;
4247        p_vci_ixr.address = (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4);
4248        p_vci_ixr.plen    = m_words*4;
4249        p_vci_ixr.wdata   = 0x00000000;
4250        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
4251        p_vci_ixr.eop     = true;
4252      }
4253    }
4254    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_XRAM_DATA ) {
4255      p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4256      p_vci_ixr.cmdval  = true;
4257      p_vci_ixr.address = (addr_t)((r_xram_rsp_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4258      p_vci_ixr.plen    = m_words*4;
4259      p_vci_ixr.wdata   = r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4260      p_vci_ixr.trdid   = r_xram_rsp_to_ixr_cmd_trdid.read();
4261      p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4262    } else {
4263      p_vci_ixr.cmdval  = false;
4264      p_vci_ixr.address = 0;
4265      p_vci_ixr.plen    = 0;
4266      p_vci_ixr.wdata   = 0;
4267      p_vci_ixr.trdid   = 0;
4268      p_vci_ixr.eop     = false;
4269    }
4270
4271    ////////////////////////////////////////////////////
4272    // Response signals on the p_vci_ixr port
4273    ////////////////////////////////////////////////////
4274
4275    if ( ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&
4276          (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ)) ||
4277        (r_ixr_rsp_fsm.read() == IXR_RSP_ACK) ) p_vci_ixr.rspack = true;
4278    else                                        p_vci_ixr.rspack = false;
4279
4280    ////////////////////////////////////////////////////
4281    // Command signals on the p_vci_tgt port
4282    ////////////////////////////////////////////////////
4283
4284    switch ((tgt_cmd_fsm_state_e)r_tgt_cmd_fsm.read()) {
4285      case TGT_CMD_IDLE:
4286        p_vci_tgt.cmdack  = false;
4287        break;
4288      case TGT_CMD_READ:
4289        p_vci_tgt.cmdack  = m_cmd_read_addr_fifo.wok();
4290        break;
4291      case TGT_CMD_READ_EOP:
4292        p_vci_tgt.cmdack  = true;
4293        break;
4294      case TGT_CMD_WRITE:
4295        p_vci_tgt.cmdack  = m_cmd_write_addr_fifo.wok();
4296        break;
4297      case TGT_CMD_ATOMIC:
4298        p_vci_tgt.cmdack  = m_cmd_llsc_addr_fifo.wok();
4299        break;
4300      default:
4301        p_vci_tgt.cmdack = false;
4302        break;
4303    }
4304
4305    ////////////////////////////////////////////////////
4306    // Response signals on the p_vci_tgt port
4307    ////////////////////////////////////////////////////
4308    switch ( r_tgt_rsp_fsm.read() ) {
4309
4310      case TGT_RSP_READ_IDLE:
4311      case TGT_RSP_WRITE_IDLE:
4312      case TGT_RSP_LLSC_IDLE:
4313      case TGT_RSP_XRAM_IDLE:
4314      case TGT_RSP_INIT_IDLE:
4315      case TGT_RSP_CLEANUP_IDLE:
4316        p_vci_tgt.rspval  = false;
4317        p_vci_tgt.rsrcid  = 0;
4318        p_vci_tgt.rdata   = 0;
4319        p_vci_tgt.rpktid  = 0;
4320        p_vci_tgt.rtrdid  = 0;
4321        p_vci_tgt.rerror  = 0;
4322        p_vci_tgt.reop    = false;     
4323        break;
4324      case TGT_RSP_READ:
4325        p_vci_tgt.rspval   = true;
4326        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
4327        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
4328        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
4329        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
4330        p_vci_tgt.rerror   = 0;
4331        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) );
4332        break;
4333      case TGT_RSP_WRITE:
4334        p_vci_tgt.rspval   = true;
4335        p_vci_tgt.rdata    = 0;
4336        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
4337        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
4338        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
4339        p_vci_tgt.rerror   = 0;
4340        p_vci_tgt.reop     = true;
4341        break;
4342      case TGT_RSP_CLEANUP:
4343        p_vci_tgt.rspval   = true;
4344        p_vci_tgt.rdata    = 0;
4345        p_vci_tgt.rsrcid   = r_cleanup_to_tgt_rsp_srcid.read();
4346        p_vci_tgt.rtrdid   = r_cleanup_to_tgt_rsp_trdid.read();
4347        p_vci_tgt.rpktid   = r_cleanup_to_tgt_rsp_pktid.read();
4348        p_vci_tgt.rerror   = 0;
4349        p_vci_tgt.reop     = true;
4350        break;
4351      case TGT_RSP_LLSC:
4352        p_vci_tgt.rspval   = true;
4353        p_vci_tgt.rdata    = r_llsc_to_tgt_rsp_data.read();
4354        p_vci_tgt.rsrcid   = r_llsc_to_tgt_rsp_srcid.read();
4355        p_vci_tgt.rtrdid   = r_llsc_to_tgt_rsp_trdid.read();
4356        p_vci_tgt.rpktid   = r_llsc_to_tgt_rsp_pktid.read();
4357        p_vci_tgt.rerror   = 0;
4358        p_vci_tgt.reop     = true;
4359        break;
4360      case TGT_RSP_XRAM:
4361        p_vci_tgt.rspval   = true;
4362        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
4363        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
4364        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
4365        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
4366        p_vci_tgt.rerror   = 0;
4367        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1));
4368        break;
4369      case TGT_RSP_INIT:
4370        p_vci_tgt.rspval   = true;
4371        p_vci_tgt.rdata    = 0;
4372        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
4373        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
4374        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
4375        p_vci_tgt.rerror   = 0;
4376        p_vci_tgt.reop     = true;     
4377        break;
4378    } // end switch r_tgt_rsp_fsm
4379
4380    ///////////////////////////////////////////////////
4381    // Command signals on the p_vci_ini port
4382    ///////////////////////////////////////////////////
4383
4384    p_vci_ini.cmd     = vci_param::CMD_WRITE;
4385    p_vci_ini.srcid   = m_srcid_ini;
4386    p_vci_ini.pktid   = 0;
4387    p_vci_ini.cons    = true;
4388    p_vci_ini.wrap    = false;
4389    p_vci_ini.contig  = false;
4390    p_vci_ini.clen    = 0;
4391    p_vci_ini.cfixed  = false;
4392
4393    switch ( r_init_cmd_fsm.read() ) {
4394
4395      case INIT_CMD_UPDT_IDLE:
4396      case INIT_CMD_INVAL_IDLE:
4397      case INIT_CMD_SC_UPDT_IDLE:
4398        p_vci_ini.cmdval  = false;
4399        p_vci_ini.address = 0;
4400        p_vci_ini.wdata   = 0;
4401        p_vci_ini.be      = 0;
4402        p_vci_ini.plen    = 0;
4403        p_vci_ini.trdid   = 0;
4404        p_vci_ini.eop     = false;
4405        break;
4406      case INIT_CMD_INVAL_NLINE:
4407        p_vci_ini.cmdval  = m_xram_rsp_to_init_cmd_inst_fifo.rok();
4408        if(m_xram_rsp_to_init_cmd_inst_fifo.rok()){
4409          if(m_xram_rsp_to_init_cmd_inst_fifo.read()) {
4410            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]+8);
4411          } else {
4412            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]);
4413          }
4414        } else p_vci_ini.address = 0; // prevent segmentation faults by reading an empty fifo
4415        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
4416        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
4417        p_vci_ini.plen    = 4;
4418        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
4419        p_vci_ini.eop     = true;
4420        break;
4421      case INIT_CMD_XRAM_BRDCAST:
4422        p_vci_ini.cmdval  = true;
4423        p_vci_ini.address = BROADCAST_ADDR;
4424        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
4425        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
4426        p_vci_ini.plen    = 4;
4427        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
4428        p_vci_ini.eop     = true;
4429        break;
4430
4431      case INIT_CMD_WRITE_BRDCAST:
4432        p_vci_ini.cmdval  = true;
4433        p_vci_ini.address = BROADCAST_ADDR;
4434        p_vci_ini.wdata   = (addr_t)r_write_to_init_cmd_nline.read();
4435        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32) & 0x3);
4436        p_vci_ini.plen    = 4 ;
4437        p_vci_ini.eop     = true;
4438        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4439        break;
4440      case INIT_CMD_UPDT_NLINE:
4441        p_vci_ini.cmdval  = m_write_to_init_cmd_inst_fifo.rok();
4442        if(m_write_to_init_cmd_inst_fifo.rok()){
4443          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
4444        } else {
4445          p_vci_ini.address = 0;
4446        }
4447        p_vci_ini.wdata   = (uint32_t)r_write_to_init_cmd_nline.read();
4448        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32 ) & 0x3);
4449        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4450        p_vci_ini.eop     = false;
4451        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4452        break;
4453      case INIT_CMD_UPDT_INDEX:
4454        p_vci_ini.cmdval  = true;
4455        p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
4456        p_vci_ini.wdata   = r_write_to_init_cmd_index.read();
4457        p_vci_ini.be      = 0xF;
4458        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4459        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4460        p_vci_ini.eop     = false;
4461        break;
4462      case INIT_CMD_UPDT_DATA:
4463        p_vci_ini.cmdval  = true;
4464        p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
4465        p_vci_ini.wdata   = r_write_to_init_cmd_data[r_init_cmd_cpt.read() +
4466          r_write_to_init_cmd_index.read()].read();
4467        if(r_write_to_init_cmd_we[r_init_cmd_cpt.read() +
4468            r_write_to_init_cmd_index.read()].read()) 
4469          p_vci_ini.be      = 0xF;
4470        else                    p_vci_ini.be      = 0x0;
4471        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4472        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4473        p_vci_ini.eop     = ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) );
4474        break;
4475
4476      case INIT_CMD_SC_BRDCAST:
4477        p_vci_ini.cmdval  = true;
4478        p_vci_ini.address = BROADCAST_ADDR;
4479        p_vci_ini.wdata   = (addr_t)r_llsc_to_init_cmd_nline.read();
4480        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32) & 0x3);
4481        p_vci_ini.plen    = 4 ;
4482        p_vci_ini.eop     = true;
4483        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4484        break;
4485      case INIT_CMD_SC_UPDT_NLINE:
4486        p_vci_ini.cmdval  = m_llsc_to_init_cmd_inst_fifo.rok();
4487        if(m_llsc_to_init_cmd_inst_fifo.rok()){
4488          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
4489        } else {
4490          p_vci_ini.address = 0;
4491        }
4492        p_vci_ini.wdata   = (uint32_t)r_llsc_to_init_cmd_nline.read();
4493        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32 ) & 0x3);
4494        p_vci_ini.plen    = 4 * 3;
4495        p_vci_ini.eop     = false;
4496        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4497        break;
4498      case INIT_CMD_SC_UPDT_INDEX:
4499        p_vci_ini.cmdval  = true;
4500        p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
4501        p_vci_ini.wdata   = r_llsc_to_init_cmd_index.read();
4502        p_vci_ini.be      = 0xF;
4503        p_vci_ini.plen    = 4 * 3;
4504        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4505        p_vci_ini.eop     = false;
4506        break;
4507      case INIT_CMD_SC_UPDT_DATA:
4508        p_vci_ini.cmdval  = true;
4509        p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
4510        p_vci_ini.wdata   = r_llsc_to_init_cmd_wdata.read();
4511        p_vci_ini.be      = 0xF;
4512        p_vci_ini.plen    = 4 * 3;
4513        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4514        p_vci_ini.eop     = true;
4515        break;
4516
4517    } // end switch r_init_cmd_fsm
4518
4519    //////////////////////////////////////////////////////
4520    // Response signals on the p_vci_ini port
4521    //////////////////////////////////////////////////////
4522
4523    if ( r_init_rsp_fsm.read() == INIT_RSP_IDLE ) p_vci_ini.rspack  = true;
4524    else                                          p_vci_ini.rspack  = false;
4525
4526    //////////////////////////////////////////////////////
4527    // Response signals on the p_vci_tgt_cleanup port
4528    //////////////////////////////////////////////////////
4529    p_vci_tgt_cleanup.rspval = false;
4530    p_vci_tgt_cleanup.rsrcid = 0;
4531    p_vci_tgt_cleanup.rdata  = 0;
4532    p_vci_tgt_cleanup.rpktid = 0;
4533    p_vci_tgt_cleanup.rtrdid = 0;
4534    p_vci_tgt_cleanup.rerror = 0;
4535    p_vci_tgt_cleanup.reop   = false;
4536    p_vci_tgt_cleanup.cmdack = false ;
4537
4538    switch(r_cleanup_fsm.read()){
4539      case CLEANUP_IDLE:
4540        {
4541          p_vci_tgt_cleanup.cmdack = true ;
4542          break;
4543        }
4544      case CLEANUP_RSP:
4545        {
4546          p_vci_tgt_cleanup.rspval = true;
4547          p_vci_tgt_cleanup.rdata  = 0;
4548          p_vci_tgt_cleanup.rsrcid = r_cleanup_srcid.read();
4549          p_vci_tgt_cleanup.rpktid = r_cleanup_pktid.read();
4550          p_vci_tgt_cleanup.rtrdid = r_cleanup_trdid.read();
4551          p_vci_tgt_cleanup.rerror = 0;
4552          p_vci_tgt_cleanup.reop   = 1;
4553          break;
4554        }
4555
4556    }
4557
4558  } // end genMoore()
4559
4560}} // end name space
4561
4562// Local Variables:
4563// tab-width: 4
4564// c-basic-offset: 4
4565// c-file-offsets:((innamespace . 0)(inline-open . 0))
4566// indent-tabs-mode: nil
4567// End:
4568
4569// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
4570
Note: See TracBrowser for help on using the repository browser.