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

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

Fix the masking of RERROR field

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