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

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

Fix the deadlock also for SC requests

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