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

Last change on this file since 2 was 2, checked in by nipo, 14 years ago

Import TSAR modules in TSAR's own svn

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