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

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

Fix uninitialized variable

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