source: trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp @ 57

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

Fix a bug with uncached reads, add more debug capabilities

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