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

Last change on this file since 175 was 175, checked in by kane, 13 years ago

vci_cc_xcache_wrapper_v4 : suppress one state (CC_UPDATE)

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