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

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

Fix same deadlock issue as in V4

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