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

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

Fix a deadlock issue on the coherency network

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