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

Last change on this file since 141 was 141, checked in by guthmull, 13 years ago

Improve activity counters. Table sizes are now instance parameters.

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