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

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

Add broadcast limitation compatibility, indicate the type of response when possible

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