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

Last change on this file since 2 was 2, checked in by nipo, 14 years ago

Import TSAR modules in TSAR's own svn

  • 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: 176.8 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                  r_write_fsm = WRITE_UPT_LOCK;
1294          break;
1295        }
1296        /////////////////////
1297      case WRITE_UPT_LOCK:      // Try to register the request in Update Table
1298        {
1299
1300          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1301            bool        wok        = false;
1302            size_t      index      = 0;
1303            size_t      srcid      = r_write_srcid.read();
1304            size_t      trdid      = r_write_trdid.read();
1305            size_t      pktid      = r_write_pktid.read();
1306            addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
1307            size_t      nb_copies  = r_write_count.read();
1308            size_t set      = m_y[(vci_addr_t)(r_write_address.read())];
1309            size_t way      = r_write_way.read();
1310
1311            wok =m_update_tab.set(true, // it's an update transaction
1312                false,                  // it's not a broadcast
1313                true,                   // it needs a response
1314                srcid,
1315                trdid,
1316                pktid,
1317                nline,
1318                nb_copies,
1319                index);
1320            if(wok){
1321              // write data in cache
1322              for(size_t i=0 ; i<m_words ; i++) {
1323                if  ( r_write_be[i].read() ) {
1324                  m_cache_data[way][set][i]  = r_write_data[i].read();
1325                }
1326              } // end for
1327            }
1328#ifdef IDEBUG
1329            if(wok){
1330        std::cout << sc_time_stamp() << " " << name() << " WRITE_UPT_LOCK update table : " << std::endl;
1331        m_update_tab.print();
1332            }
1333#endif
1334            r_write_upt_index = index;
1335            //  releases the lock protecting the Update Table and the Directory if no entry...
1336            if ( wok ) r_write_fsm = WRITE_HEAP_LOCK;
1337            else       r_write_fsm = WRITE_WAIT;
1338          }
1339          break;
1340        }
1341        //////////////////
1342      case WRITE_HEAP_LOCK:
1343        {
1344          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE ){
1345            r_write_fsm = WRITE_UPT_REQ;
1346          }
1347          break;
1348        }
1349        //////////////////
1350      case WRITE_UPT_REQ:
1351        {
1352          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
1353                    "MemCache ERROR : bad HEAP allocation");
1354          if( !r_write_to_init_cmd_multi_req.read() &&
1355              !r_write_to_init_cmd_brdcast_req.read()  ){
1356            r_write_to_init_cmd_brdcast_req  = false;
1357            r_write_to_init_cmd_trdid        = r_write_upt_index.read();
1358            r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
1359            r_write_to_init_cmd_index        = r_write_word_index.read();
1360            r_write_to_init_cmd_count        = r_write_word_count.read();
1361
1362            for(size_t i=0; i<m_words ; i++){
1363              r_write_to_init_cmd_be[i]=r_write_be[i].read();
1364            }
1365
1366            size_t min = r_write_word_index.read();
1367            size_t max = r_write_word_index.read() + r_write_word_count.read();
1368            for (size_t i=min ; i<max ; i++) {
1369              r_write_to_init_cmd_data[i] = r_write_data[i];
1370            }
1371           
1372            if( (r_write_copy.read() != r_write_srcid.read()) || r_write_copy_inst.read() ) {
1373              // We put the first copy in the fifo
1374              write_to_init_cmd_fifo_put     = true;
1375              write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
1376              write_to_init_cmd_fifo_srcid   = r_write_copy.read();
1377              if(r_write_count.read() == 1){
1378                r_write_fsm = WRITE_IDLE;
1379                r_write_to_init_cmd_multi_req = true;
1380              } else {
1381                r_write_fsm = WRITE_UPDATE;
1382              }
1383            } else {
1384              r_write_fsm = WRITE_UPDATE;
1385            }
1386          }
1387          break;
1388        }
1389        //////////////////
1390      case WRITE_UPDATE:        // send a multi-update request to INIT_CMD fsm
1391        {
1392          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
1393                    "MemCache ERROR : bad HEAP allocation");
1394          HeapEntry entry = m_heap_directory.read(r_write_ptr.read());
1395          write_to_init_cmd_fifo_inst  = entry.owner.inst;
1396          write_to_init_cmd_fifo_srcid = entry.owner.srcid;
1397          bool dec_upt_counter = r_write_to_dec.read();
1398          if( (entry.owner.srcid != r_write_srcid.read()) || entry.owner.inst ){
1399            write_to_init_cmd_fifo_put = true;
1400          } else {
1401            dec_upt_counter = true;
1402          }
1403          r_write_to_dec = dec_upt_counter;
1404
1405          if( m_write_to_init_cmd_inst_fifo.wok() ){
1406            r_write_ptr = entry.next;
1407            if( entry.next == r_write_ptr.read() ) { // last copy
1408              r_write_to_init_cmd_multi_req = true;
1409              if(dec_upt_counter){
1410                r_write_fsm = WRITE_UPT_DEC;
1411              } else {
1412                r_write_fsm = WRITE_IDLE;
1413              }
1414            } else {
1415              r_write_fsm = WRITE_UPDATE;
1416            }
1417          } else {
1418            r_write_fsm = WRITE_UPDATE;
1419          }
1420          break;
1421        }
1422        //////////////////
1423      case WRITE_UPT_DEC:
1424        {
1425          if(!r_write_to_init_rsp_req.read()){
1426            r_write_to_init_rsp_req = true;
1427            r_write_to_init_rsp_upt_index = r_write_upt_index.read();
1428            r_write_fsm = WRITE_IDLE;
1429          }
1430          break;
1431        }
1432        ///////////////
1433      case WRITE_RSP:           // send a request to TGT_RSP FSM to acknowledge the write
1434        {
1435          if ( !r_write_to_tgt_rsp_req.read() ) {
1436            r_write_to_tgt_rsp_req          = true;
1437            r_write_to_tgt_rsp_srcid    = r_write_srcid.read();
1438            r_write_to_tgt_rsp_trdid    = r_write_trdid.read();
1439            r_write_to_tgt_rsp_pktid    = r_write_pktid.read();
1440            r_write_fsm                         = WRITE_IDLE;
1441          }
1442          break;
1443        }
1444        ////////////////////
1445      case WRITE_TRT_LOCK:      // Miss : check Transaction Table
1446        {
1447          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1448#ifdef TDEBUG
1449        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_LOCK " << std::endl;
1450#endif
1451            size_t hit_index = 0;
1452            size_t wok_index = 0;
1453            bool hit_read  = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(r_write_address.read())],hit_index);
1454            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(r_write_address.read())]);
1455            bool wok = !m_transaction_tab.full(wok_index);
1456            if ( hit_read ) {   // register the modified data in TRT
1457              r_write_trt_index = hit_index;
1458              r_write_fsm       = WRITE_TRT_DATA;
1459            } else if ( wok && !hit_write ) {   // set a new entry in TRT
1460              r_write_trt_index = wok_index;
1461              r_write_fsm       = WRITE_TRT_SET;
1462            } else {            // wait an empty entry in TRT
1463              r_write_fsm       = WRITE_WAIT;
1464            }
1465          }
1466          break;
1467        }
1468        ////////////////////
1469      case WRITE_WAIT:  // release the lock protecting TRT
1470        {
1471          r_write_fsm = WRITE_DIR_LOCK;
1472          break;
1473        }
1474        ///////////////////
1475      case WRITE_TRT_SET:       // register a new transaction in TRT (Write Buffer)
1476        { 
1477          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
1478          {
1479            std::vector<be_t> be_vector;
1480            std::vector<data_t> data_vector;
1481            be_vector.clear();
1482            data_vector.clear();
1483            for ( size_t i=0; i<m_words; i++ )
1484            {
1485              be_vector.push_back(r_write_be[i]);
1486              data_vector.push_back(r_write_data[i]);
1487            }
1488            m_transaction_tab.set(r_write_trt_index.read(),
1489                true,                           // read request to XRAM
1490                m_nline[(vci_addr_t)(r_write_address.read())],
1491                r_write_srcid.read(),
1492                r_write_trdid.read(),
1493                r_write_pktid.read(),
1494                false,                          // not a processor read
1495                0,                              // not a single word
1496                0,                              // word index
1497                be_vector,
1498                data_vector);
1499#ifdef TDEBUG
1500        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_SET transaction table : " << std::endl;
1501        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1502          m_transaction_tab.print(i);
1503#endif
1504
1505            r_write_fsm = WRITE_XRAM_REQ;
1506          }
1507          break;
1508        } 
1509        ///////////////////
1510      case WRITE_TRT_DATA:      // update an entry in TRT (Write Buffer)
1511        {
1512          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1513            std::vector<be_t> be_vector;
1514            std::vector<data_t> data_vector;
1515            be_vector.clear();
1516            data_vector.clear();
1517            for ( size_t i=0; i<m_words; i++ ) {
1518              be_vector.push_back(r_write_be[i]);
1519              data_vector.push_back(r_write_data[i]);
1520            }
1521            m_transaction_tab.write_data_mask(r_write_trt_index.read(),
1522                be_vector,
1523                data_vector);
1524            r_write_fsm = WRITE_RSP;
1525#ifdef TDEBUG
1526        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_DATA transaction table : " << std::endl;
1527        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1528          m_transaction_tab.print(i);
1529#endif
1530
1531          }
1532          break;
1533        }
1534        ////////////////////
1535      case WRITE_XRAM_REQ:      // send a request to IXR_CMD FSM
1536        { 
1537
1538          if ( !r_write_to_ixr_cmd_req ) {
1539            r_write_to_ixr_cmd_req   = true;
1540            r_write_to_ixr_cmd_write = false;
1541            r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
1542            r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
1543            r_write_fsm              = WRITE_RSP;
1544          }
1545          break;
1546        }
1547        ////////////////////
1548      case WRITE_TRT_WRITE_LOCK:
1549        {
1550          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1551            size_t wok_index = 0;
1552            bool wok = !m_transaction_tab.full(wok_index);
1553            if ( wok ) {        // set a new entry in TRT
1554              r_write_trt_index = wok_index;
1555              r_write_fsm       = WRITE_INVAL_LOCK;
1556            } else {            // wait an empty entry in TRT
1557              r_write_fsm       = WRITE_WAIT;
1558            }
1559          }
1560
1561          break;
1562        }
1563        ////////////////////
1564      case WRITE_INVAL_LOCK:
1565        {
1566          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1567            bool        wok       = false;
1568            size_t      index     = 0;
1569            size_t      srcid     = r_write_srcid.read();
1570            size_t      trdid     = r_write_trdid.read();
1571            size_t      pktid     = r_write_pktid.read();
1572            addr_t          nline     = m_nline[(vci_addr_t)(r_write_address.read())];
1573            size_t      nb_copies = r_write_count.read();
1574
1575            wok =m_update_tab.set(false,        // it's an inval transaction
1576                true,                       // it's a broadcast
1577                true,                       // it needs a response
1578                srcid,
1579                trdid,
1580                pktid,
1581                nline,
1582                nb_copies,
1583                index);
1584#ifdef IDEBUG
1585            if(wok){
1586        std::cout << sc_time_stamp() << " " << name() << " WRITE_INVAL_LOCK update table : " << std::endl;
1587        m_update_tab.print();
1588            }
1589#endif
1590            r_write_upt_index = index;
1591            //  releases the lock protecting Update Table if no entry...
1592            if ( wok ) r_write_fsm = WRITE_DIR_INVAL;
1593            else       r_write_fsm = WRITE_WAIT;
1594          }
1595
1596          break;
1597        }
1598        ////////////////////
1599      case WRITE_DIR_INVAL:
1600        {
1601            assert(((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) &&
1602                    (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) &&
1603                    (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ))&&
1604                    "MemCache ERROR : bad TRT,DIR or UPT allocation error");
1605            m_transaction_tab.set(r_write_trt_index.read(),
1606                false,                          // write request to XRAM
1607                m_nline[(vci_addr_t)(r_write_address.read())],
1608                0,
1609                0,
1610                0,
1611                false,                          // not a processor read
1612                0,                              // not a single word
1613                0,                              // word index
1614                std::vector<be_t>(m_words,0),
1615                std::vector<data_t>(m_words,0));
1616#ifdef TDEBUG
1617        std::cout << sc_time_stamp() << " " << name() << " WRITE_DIR_INVAL transaction table : " << std::endl;
1618        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1619          m_transaction_tab.print(i);
1620#endif
1621
1622            // invalidate directory entry
1623            DirectoryEntry entry;
1624            entry.valid         = false;
1625            entry.dirty         = false;
1626            entry.tag           = 0;
1627            entry.is_cnt        = false;
1628            entry.lock          = false;
1629            entry.owner.srcid   = 0;
1630            entry.owner.inst    = false;
1631            entry.ptr           = 0;
1632            entry.count         = 0;
1633            size_t set          = m_y[(vci_addr_t)(r_write_address.read())];
1634            size_t way          = r_write_way.read();
1635            m_cache_directory.write(set, way, entry);
1636
1637            r_write_fsm = WRITE_INVAL;
1638            break;
1639        }
1640        ////////////////////
1641      case WRITE_INVAL:
1642        {
1643          if (  !r_write_to_init_cmd_multi_req.read() &&
1644                !r_write_to_init_cmd_brdcast_req.read() ) {
1645            r_write_to_init_cmd_multi_req   = false;
1646            r_write_to_init_cmd_brdcast_req = true;
1647            r_write_to_init_cmd_trdid       = r_write_upt_index.read();
1648            r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
1649            r_write_to_init_cmd_index       = 0;
1650            r_write_to_init_cmd_count       = 0;
1651
1652            for(size_t i=0; i<m_words ; i++){
1653              r_write_to_init_cmd_be[i]=0;
1654              r_write_to_init_cmd_data[i] = 0;
1655            }
1656            r_write_fsm = WRITE_XRAM_SEND;
1657            // all inval responses
1658          }
1659
1660          break;
1661        }
1662        ////////////////////
1663      case WRITE_XRAM_SEND:
1664        {
1665          if ( !r_write_to_ixr_cmd_req ) {
1666            r_write_to_ixr_cmd_req     = true;
1667            r_write_to_ixr_cmd_write   = true;
1668            r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
1669            r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
1670            for(size_t i=0; i<m_words; i++){
1671              r_write_to_ixr_cmd_data[i] = r_write_data[i];
1672            }
1673            r_write_fsm = WRITE_IDLE;
1674          }
1675          break;
1676        }
1677    } // end switch r_write_fsm
1678
1679    ///////////////////////////////////////////////////////////////////////
1680    //          IXR_CMD FSM
1681    ///////////////////////////////////////////////////////////////////////
1682    // The IXR_CMD fsm controls the command packets to the XRAM :
1683    // - It sends a single cell VCI read to the XRAM in case of MISS request
1684    // posted by the READ, WRITE or LLSC FSMs : the TRDID field contains
1685    // the Transaction Tab index.
1686    // The VCI response is a multi-cell packet : the N cells contain
1687    // the N data words.
1688    // - It sends a multi-cell VCI write when the XRAM_RSP FSM request
1689    // to save a dirty line to the XRAM.
1690    // The VCI response is a single cell packet.
1691    // This FSM handles requests from the READ, WRITE, LLSC & XRAM_RSP FSMs
1692    // with a round-robin priority.
1693    ////////////////////////////////////////////////////////////////////////
1694
1695    switch ( r_ixr_cmd_fsm.read() ) {
1696      ////////////////////////
1697      case IXR_CMD_READ_IDLE:
1698        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1699        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1700        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1701        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1702        break;
1703        ////////////////////////
1704      case IXR_CMD_WRITE_IDLE:
1705        if      ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1706        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1707        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1708        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1709        break;
1710        ////////////////////////
1711      case IXR_CMD_LLSC_IDLE:
1712        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1713        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1714        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1715        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1716        break;
1717        ////////////////////////
1718      case IXR_CMD_XRAM_IDLE:
1719        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1720        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1721        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1722        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1723        break;
1724        /////////////////////////
1725      case IXR_CMD_READ_NLINE:
1726        if ( p_vci_ixr.cmdack ) {
1727          r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;           
1728          r_read_to_ixr_cmd_req = false;
1729        }
1730        break;
1731        //////////////////////////
1732      case IXR_CMD_WRITE_NLINE:
1733        if ( p_vci_ixr.cmdack ) {
1734          if( r_write_to_ixr_cmd_write.read()){
1735            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1736              r_ixr_cmd_cpt = 0;
1737              r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
1738              r_write_to_ixr_cmd_req = false;
1739            } else {
1740              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1741            }
1742          } else {
1743            r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;         
1744            r_write_to_ixr_cmd_req = false;
1745          }
1746        }
1747        break;
1748        /////////////////////////
1749      case IXR_CMD_LLSC_NLINE:
1750        if ( p_vci_ixr.cmdack ) {
1751          if( r_llsc_to_ixr_cmd_write.read()){
1752            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1753              r_ixr_cmd_cpt = 0;
1754              r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;
1755              r_llsc_to_ixr_cmd_req = false;
1756            } else {
1757              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1758            }
1759          } else {
1760            r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;         
1761            r_llsc_to_ixr_cmd_req = false;
1762          }
1763        }
1764        break;
1765        ////////////////////////
1766      case IXR_CMD_XRAM_DATA:
1767        if ( p_vci_ixr.cmdack ) {
1768          if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1769            r_ixr_cmd_cpt = 0;
1770            r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
1771            r_xram_rsp_to_ixr_cmd_req = false;
1772          } else {
1773            r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1774          }
1775        }
1776        break;
1777
1778    } // end switch r_ixr_cmd_fsm
1779
1780    ////////////////////////////////////////////////////////////////////////////
1781    //                IXR_RSP FSM
1782    ////////////////////////////////////////////////////////////////////////////
1783    // The IXR_RSP FSM receives the response packets from the XRAM,
1784    // for both write transaction, and read transaction.
1785    //
1786    // - A response to a write request is a single-cell VCI packet.
1787    // The Transaction Tab index is contained in the RTRDID field.
1788    // The FSM takes the lock protecting the TRT, and the corresponding
1789    // entry is erased.
1790    // 
1791    // - A response to a read request is a multi-cell VCI packet.
1792    // The Transaction Tab index is contained in the RTRDID field.
1793    // The N cells contain the N words of the cache line in the RDATA field.
1794    // The FSM takes the lock protecting the TRT to store the line in the TRT
1795    // (taking into account the write requests already stored in the TRT).
1796    // When the line is completely written, the corresponding rok signal is set.
1797    ///////////////////////////////////////////////////////////////////////////////
1798
1799    switch ( r_ixr_rsp_fsm.read() ) {
1800
1801      ///////////////////
1802      case IXR_RSP_IDLE:        // test if it's a read or a write transaction
1803        {
1804          if ( p_vci_ixr.rspval ) {
1805            r_ixr_rsp_cpt   = 0;
1806            r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
1807            if ( p_vci_ixr.reop )  r_ixr_rsp_fsm = IXR_RSP_ACK;
1808            else                   r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
1809          }
1810          break; 
1811        }
1812        ////////////////////////
1813      case IXR_RSP_ACK:        // Acknowledge the vci response
1814        r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
1815        break;
1816        ////////////////////////
1817      case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
1818        {
1819          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP ) {
1820            m_transaction_tab.erase(r_ixr_rsp_trt_index.read());
1821            r_ixr_rsp_fsm = IXR_RSP_IDLE;
1822#ifdef TDEBUG
1823        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_ERASE transaction table : " << std::endl;
1824        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1825          m_transaction_tab.print(i);
1826#endif
1827
1828          }
1829          break;
1830        }
1831        ///////////////////////
1832      case IXR_RSP_TRT_READ:            // write data in the TRT
1833        {
1834          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&  p_vci_ixr.rspval ) {
1835            bool   eop          = p_vci_ixr.reop.read();
1836            data_t data         = p_vci_ixr.rdata.read();
1837            size_t index        = r_ixr_rsp_trt_index.read();
1838            assert( eop == (r_ixr_rsp_cpt.read() == (m_words-1))
1839                && "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
1840            m_transaction_tab.write_rsp(index, r_ixr_rsp_cpt.read(), data);
1841            r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1;
1842            if ( eop ) {
1843#ifdef TDEBUG
1844        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_READ transaction table : " << std::endl;
1845        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1846          m_transaction_tab.print(i);
1847#endif
1848
1849              r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
1850              r_ixr_rsp_fsm = IXR_RSP_IDLE;
1851            }
1852          }
1853          break;
1854        }
1855    } // end swich r_ixr_rsp_fsm
1856
1857
1858    ////////////////////////////////////////////////////////////////////////////
1859    //                XRAM_RSP FSM
1860    ////////////////////////////////////////////////////////////////////////////
1861    // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
1862    // The cache line has been written in the TRT buffer by the IXR_FSM.
1863    //
1864    // When a response is available, the corresponding TRT entry
1865    // is copied in a local buffer to be written in the cache.
1866    // Then, the FSM releases the lock protecting the TRT, and takes the lock
1867    // protecting the cache directory.
1868    // It selects a cache slot and writes the line in the cache.
1869    // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
1870    // FSM to return the cache line to the registered processor.
1871    // If there is no empty slot, a victim line is evicted, and
1872    // invalidate requests are sent to the L1 caches containing copies.
1873    // If this line is dirty, the XRAM_RSP FSM send a request to the IXR_CMD
1874    // FSM to save the victim line to the XRAM, and register the write transaction
1875    // in the TRT (using the entry previously used by the read transaction).
1876    ///////////////////////////////////////////////////////////////////////////////
1877
1878    switch ( r_xram_rsp_fsm.read() ) {
1879
1880      ///////////////////
1881      case XRAM_RSP_IDLE:       // test if there is a response with a round robin priority
1882        {
1883          size_t ptr   = r_xram_rsp_trt_index.read();
1884          size_t lines = TRANSACTION_TAB_LINES;
1885          for(size_t i=0; i<lines; i++){
1886            size_t index=(i+ptr+1)%lines;
1887            if(r_ixr_rsp_to_xram_rsp_rok[index]){
1888              r_xram_rsp_trt_index=index;
1889              r_ixr_rsp_to_xram_rsp_rok[index]=false;
1890              r_xram_rsp_fsm           = XRAM_RSP_DIR_LOCK;
1891              break;
1892#ifdef TDEBUG
1893        std::cout << "XRAM_RSP FSM in XRAM_RSP_IDLE state" << std::endl;
1894#endif
1895            }
1896          }
1897          break; 
1898        }
1899        ///////////////////////
1900      case XRAM_RSP_DIR_LOCK:   // Take the lock on the directory
1901        {
1902          if( r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP ) {
1903            r_xram_rsp_fsm           = XRAM_RSP_TRT_COPY;
1904#ifdef TDEBUG
1905        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_LOCK state" << std::endl;
1906#endif
1907          }
1908          break;
1909        }
1910        ///////////////////////
1911      case XRAM_RSP_TRT_COPY:           // Copy the TRT entry in the local buffer and eviction of a cache line
1912        {
1913          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) ) {
1914            size_t index = r_xram_rsp_trt_index.read();
1915            TransactionTabEntry    trt_entry(m_transaction_tab.read(index));   
1916
1917            r_xram_rsp_trt_buf.copy(trt_entry);  // TRT entry local buffer
1918
1919            // selects & extracts a victim line from cache
1920            size_t way = 0;
1921            size_t set = m_y[(vci_addr_t)(trt_entry.nline * m_words * 4)];
1922            DirectoryEntry victim(m_cache_directory.select(set, way));
1923
1924            for (size_t i=0 ; i<m_words ; i++) r_xram_rsp_victim_data[i] = m_cache_data[way][set][i];
1925
1926            bool inval = (victim.count && victim.valid) ;
1927
1928            r_xram_rsp_victim_copy      = victim.owner.srcid;
1929            r_xram_rsp_victim_copy_inst = victim.owner.inst;
1930            r_xram_rsp_victim_count     = victim.count;
1931            r_xram_rsp_victim_ptr       = victim.ptr;
1932            r_xram_rsp_victim_way       = way;
1933            r_xram_rsp_victim_set       = set;
1934            r_xram_rsp_victim_nline     = victim.tag*m_sets + set;
1935            r_xram_rsp_victim_is_cnt    = victim.is_cnt;
1936            r_xram_rsp_victim_inval     = inval ;
1937            r_xram_rsp_victim_dirty     = victim.dirty;
1938
1939            r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
1940#ifdef TDEBUG
1941        std::cout << "XRAM_RSP FSM in XRAM_RSP_TRT_COPY state" << std::endl;
1942        std::cout << "Victim way : " << std::hex << way << " set " << std::hex << set << std::endl;
1943        victim.print();
1944#endif
1945          }
1946          break;
1947        }
1948        ///////////////////////
1949      case XRAM_RSP_INVAL_LOCK:
1950        {
1951          if ( r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP ) {
1952#ifdef IDEBUG
1953        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state" << std::endl;
1954#endif
1955            size_t index;
1956            if(m_update_tab.search_inval(r_xram_rsp_trt_buf.nline, index)){
1957              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
1958#ifdef IDEBUG
1959        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
1960    std::cout << "A invalidation is already registered at this address" << std::endl;
1961        m_update_tab.print();
1962#endif
1963
1964            }
1965            else if(m_update_tab.is_full() && r_xram_rsp_victim_inval.read()){
1966              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
1967#ifdef IDEBUG
1968        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
1969    std::cout << "The inval tab is full" << std::endl;
1970        m_update_tab.print();
1971#endif
1972            }
1973            else {
1974              r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
1975#ifdef IDEBUG
1976        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_DIR_UPDT state" << std::endl;
1977        m_update_tab.print();
1978#endif
1979            }
1980          }
1981          break;
1982        }
1983        ///////////////////////
1984      case XRAM_RSP_INVAL_WAIT:
1985        {
1986          r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
1987          break;
1988#ifdef IDEBUG
1989        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_WAIT state" << std::endl;
1990#endif
1991        }
1992        ///////////////////////
1993      case XRAM_RSP_DIR_UPDT:           // updates the cache (both data & directory)
1994        {
1995          // signals generation
1996          bool inst_read = (r_xram_rsp_trt_buf.trdid & 0x2) && r_xram_rsp_trt_buf.proc_read; // It is an instruction read
1997          bool cached_read = (r_xram_rsp_trt_buf.trdid & 0x1) && r_xram_rsp_trt_buf.proc_read ;
1998          // update data
1999          size_t set   = r_xram_rsp_victim_set.read();
2000          size_t way   = r_xram_rsp_victim_way.read();
2001          for(size_t i=0; i<m_words ; i++){
2002            m_cache_data[way][set][i] = r_xram_rsp_trt_buf.wdata[i];
2003          }
2004          // compute dirty
2005          bool dirty = false;
2006          for(size_t i=0; i<m_words;i++){
2007            dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0);
2008          }
2009
2010          // update directory
2011          DirectoryEntry entry;
2012          entry.valid     = true;
2013          entry.is_cnt    = false;
2014          entry.lock      = false;
2015          entry.dirty     = dirty;
2016          entry.tag           = r_xram_rsp_trt_buf.nline / m_sets;
2017          entry.ptr       = 0;
2018          if(cached_read) {
2019            if(inst_read) {
2020              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
2021              entry.owner.inst  = true;
2022              entry.count       = 1;
2023            } else {
2024              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
2025              entry.owner.inst  = false;
2026              entry.count       = 1;
2027            }
2028          } else {
2029            entry.owner.srcid = 0;
2030            entry.owner.inst  = 0;
2031            entry.count       = 0;
2032          }
2033          m_cache_directory.write(set, way, entry);
2034#ifdef DDEBUG
2035           std::cout << "printing the entry : " << std::endl;
2036           entry.print();
2037           std::cout << "done" << std::endl;
2038#endif
2039
2040#ifdef TDEBUG
2041        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_DIR_UPDT transaction table : " << std::endl;
2042        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2043          m_transaction_tab.print(i);
2044#endif
2045
2046          if(r_xram_rsp_victim_inval.read()){
2047            bool    brdcast = r_xram_rsp_victim_is_cnt.read();
2048            size_t index;
2049            size_t count_copies = r_xram_rsp_victim_count.read();
2050
2051            bool         wok = m_update_tab.set(false,  // it's an inval transaction
2052                brdcast,                          // set brdcast bit
2053                false,  // it does not need a response
2054                0,
2055                0,
2056                0,
2057                r_xram_rsp_victim_nline.read(),
2058                count_copies,
2059                index);
2060
2061#ifdef IDEBUG
2062            std::cout << "xram_rsp : record invalidation, time = " << std::dec << m_cpt_cycles << std::endl;
2063            m_update_tab.print();
2064#endif
2065            r_xram_rsp_upt_index = index;
2066            if(!wok) {
2067              assert(false && "mem_cache error : xram_rsp_dir_upt, an update_tab entry was free but write unsuccessful");
2068            }
2069          }
2070          // If the victim is not dirty, we erase the entry in the TRT
2071          if      (!r_xram_rsp_victim_dirty.read()){
2072          m_transaction_tab.erase(r_xram_rsp_trt_index.read());
2073
2074          }
2075          // Next state
2076          if      ( r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
2077          else if ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2078          else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2079          else                                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2080          break;
2081        }
2082        ////////////////////////
2083      case XRAM_RSP_TRT_DIRTY:          // set the TRT entry (write line to XRAM) if the victim is dirty
2084        {
2085          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP ) {
2086            m_transaction_tab.set(r_xram_rsp_trt_index.read(),
2087                false,                          // write to XRAM
2088                r_xram_rsp_victim_nline.read(), // line index
2089                0,
2090                0,
2091                0,
2092                false,
2093                0,
2094                0,
2095                std::vector<be_t>(m_words,0),
2096                std::vector<data_t>(m_words,0) );
2097#ifdef TDEBUG
2098        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_TRT_DIRTY transaction table : " << std::endl;
2099        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2100          m_transaction_tab.print(i);
2101#endif
2102
2103            if      ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
2104            else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
2105            else                                            r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2106          }
2107          break;
2108        }
2109        //////////////////////
2110      case XRAM_RSP_DIR_RSP:     // send a request to TGT_RSP FSM in case of read
2111        {
2112          if ( !r_xram_rsp_to_tgt_rsp_req.read() ) {
2113            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
2114            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
2115            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
2116            for (size_t i=0; i < m_words; i++) {
2117              r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
2118            }
2119            r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
2120            r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
2121            r_xram_rsp_to_tgt_rsp_req    = true;
2122
2123            if      ( r_xram_rsp_victim_inval ) r_xram_rsp_fsm = XRAM_RSP_INVAL;
2124            else if ( r_xram_rsp_victim_dirty ) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2125            else                                r_xram_rsp_fsm = XRAM_RSP_IDLE;
2126
2127#ifdef DDEBUG
2128        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_RSP state" << std::endl;
2129#endif
2130          }
2131          break;
2132        }
2133        ////////////////////
2134      case XRAM_RSP_INVAL:      // send invalidate request to INIT_CMD FSM
2135        {
2136          if(   !r_xram_rsp_to_init_cmd_multi_req.read() &&
2137                !r_xram_rsp_to_init_cmd_brdcast_req.read() ) {       
2138           
2139            bool multi_req = !r_xram_rsp_victim_is_cnt.read();
2140            bool last_multi_req  = multi_req && (r_xram_rsp_victim_count.read() == 1);
2141            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
2142
2143            r_xram_rsp_to_init_cmd_multi_req    = last_multi_req;
2144            r_xram_rsp_to_init_cmd_brdcast_req  = r_xram_rsp_victim_is_cnt.read();
2145            r_xram_rsp_to_init_cmd_nline        = r_xram_rsp_victim_nline.read();
2146            r_xram_rsp_to_init_cmd_trdid        = r_xram_rsp_upt_index;
2147            xram_rsp_to_init_cmd_fifo_srcid     = r_xram_rsp_victim_copy.read();
2148            xram_rsp_to_init_cmd_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
2149            xram_rsp_to_init_cmd_fifo_put       = multi_req;
2150           
2151            r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
2152
2153            if ( r_xram_rsp_victim_dirty )  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2154            else if (not_last_multi_req)    r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2155            else                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2156#ifdef IDEBUG
2157        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL state" << std::endl;
2158#endif
2159          }
2160          break;
2161        }
2162        //////////////////////////
2163      case XRAM_RSP_WRITE_DIRTY:        // send a write request to IXR_CMD FSM
2164        {
2165          if ( !r_xram_rsp_to_ixr_cmd_req.read() ) {
2166            r_xram_rsp_to_ixr_cmd_req = true;
2167            r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
2168            r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
2169            for(size_t i=0; i<m_words ; i++) {
2170              r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
2171            }
2172            m_cpt_write_dirty++;
2173            bool multi_req = !r_xram_rsp_victim_is_cnt.read() && r_xram_rsp_victim_inval.read();
2174            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
2175            if ( not_last_multi_req )   r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2176            else                        r_xram_rsp_fsm = XRAM_RSP_IDLE;
2177#ifdef TDEBUG
2178        std::cout << "XRAM_RSP FSM in XRAM_RSP_WRITE_DIRTY state" << std::endl;
2179#endif
2180          }
2181          break;
2182        }
2183        //////////////////////////
2184      case XRAM_RSP_HEAP_ERASE: // erase the list of copies and sent invalidations
2185        {
2186          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP ) {
2187            HeapEntry entry = m_heap_directory.read(r_xram_rsp_next_ptr.read());
2188            xram_rsp_to_init_cmd_fifo_srcid = entry.owner.srcid;
2189            xram_rsp_to_init_cmd_fifo_inst  = entry.owner.inst;
2190            xram_rsp_to_init_cmd_fifo_put   = true;
2191            if( m_xram_rsp_to_init_cmd_inst_fifo.wok() ){
2192              r_xram_rsp_next_ptr = entry.next;
2193              if( entry.next == r_xram_rsp_next_ptr.read() ){ // last copy
2194                r_xram_rsp_to_init_cmd_multi_req = true;
2195                r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST;
2196              } else {
2197                r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2198              }
2199            } else {
2200              r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
2201            }
2202          }
2203          break;
2204        }
2205        //////////////////////////
2206      case XRAM_RSP_HEAP_LAST:  // last member of the list
2207        {
2208          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) &&
2209                  "MemCache ERROR : bad HEAP allocation");
2210          size_t free_pointer = m_heap_directory.next_free_ptr();
2211
2212          HeapEntry last_entry;
2213          last_entry.owner.srcid = 0;
2214          last_entry.owner.inst  = false;
2215          if(m_heap_directory.is_full()){
2216            last_entry.next     = r_xram_rsp_next_ptr.read();
2217            m_heap_directory.unset_full();
2218          } else {
2219            last_entry.next     = free_pointer;
2220          }
2221
2222          m_heap_directory.write_free_ptr(r_xram_rsp_victim_ptr.read());
2223          m_heap_directory.write(r_xram_rsp_next_ptr.read(),last_entry);
2224
2225          r_xram_rsp_fsm = XRAM_RSP_IDLE;
2226
2227          break;
2228        }
2229    } // end swich r_xram_rsp_fsm
2230
2231    ////////////////////////////////////////////////////////////////////////////////////
2232    //          CLEANUP FSM
2233    ////////////////////////////////////////////////////////////////////////////////////
2234    // The CLEANUP FSM handles the cleanup request from L1 caches.
2235    // It accesses the cache directory to update the list of copies.
2236    //
2237    ////////////////////////////////////////////////////////////////////////////////////
2238    switch ( r_cleanup_fsm.read() ) {
2239
2240      ///////////////////
2241      case CLEANUP_IDLE:
2242        {
2243
2244          if ( p_vci_tgt_cleanup.cmdval.read() ) {
2245            assert( (p_vci_tgt_cleanup.srcid.read() < m_initiators) &&
2246                "VCI_MEM_CACHE error in VCI_MEM_CACHE in the CLEANUP network : The received SRCID is larger than the number of initiators");
2247            bool reached = false;
2248            for ( size_t index = 0 ; index < ncseg && !reached ; index++ ){
2249              if ( m_cseg[index]->contains((addr_t)(p_vci_tgt_cleanup.address.read())) ){
2250                reached = true;
2251              }
2252            }
2253            if ( (p_vci_tgt_cleanup.cmd.read() == vci_param::CMD_WRITE) &&
2254                (((addr_t)(p_vci_tgt_cleanup.address.read())) != BROADCAST_ADDR) &&
2255                reached) {
2256
2257              m_cpt_cleanup++;
2258
2259              r_cleanup_nline      = (addr_t)(m_nline[(vci_addr_t)(p_vci_tgt_cleanup.address.read())]) ;
2260              r_cleanup_srcid      = p_vci_tgt_cleanup.srcid.read();
2261              r_cleanup_trdid      = p_vci_tgt_cleanup.trdid.read();
2262              r_cleanup_pktid      = p_vci_tgt_cleanup.pktid.read();
2263
2264              r_cleanup_fsm        = CLEANUP_DIR_LOCK;
2265            }
2266          }
2267          break;
2268        }
2269        //////////////////////
2270      case CLEANUP_DIR_LOCK:
2271        {
2272          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) {
2273
2274            // Read the directory
2275            size_t way = 0;
2276           addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
2277           DirectoryEntry entry = m_cache_directory.read(cleanup_address , way);
2278#ifdef DDEBUG
2279           std::cout << "In CLEANUP_DIR_LOCK printing the entry of address is : " << std::hex << cleanup_address << std::endl;
2280           entry.print();
2281           std::cout << "done" << std::endl;
2282#endif
2283            r_cleanup_is_cnt    = entry.is_cnt;
2284            r_cleanup_dirty         = entry.dirty;
2285            r_cleanup_tag           = entry.tag;
2286            r_cleanup_lock          = entry.lock;
2287            r_cleanup_way           = way;
2288            r_cleanup_copy      = entry.owner.srcid;
2289            r_cleanup_copy_inst = entry.owner.inst;
2290            r_cleanup_count     = entry.count;
2291            r_cleanup_ptr       = entry.ptr;
2292
2293
2294            // In case of hit, the copy must be cleaned in the copies bit-vector
2295            if( entry.valid){
2296              if ( (entry.count==1) || (entry.is_cnt) )  { // no access to the heap
2297                r_cleanup_fsm = CLEANUP_DIR_WRITE;
2298              } else {
2299                r_cleanup_fsm = CLEANUP_HEAP_LOCK;
2300              }
2301            } else {
2302              r_cleanup_fsm = CLEANUP_UPT_LOCK;
2303            }
2304          }
2305          break;
2306        }
2307        ///////////////////////
2308      case CLEANUP_DIR_WRITE:
2309        {
2310          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) &&
2311                "MemCache ERROR : Bad DIR allocation");
2312          size_t way      = r_cleanup_way.read();
2313#define L2 soclib::common::uint32_log2
2314          size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
2315#undef L2
2316          bool cleanup_inst  = r_cleanup_trdid.read() & 0x1;
2317          bool match_srcid   = (r_cleanup_copy.read() == r_cleanup_srcid.read());
2318          bool match_inst    = (r_cleanup_copy_inst.read()  == cleanup_inst);
2319          bool match         = match_srcid && match_inst;
2320
2321          // update the cache directory (for the copies)
2322          DirectoryEntry entry;
2323          entry.valid   = true;
2324          entry.is_cnt  = r_cleanup_is_cnt.read();
2325          entry.dirty   = r_cleanup_dirty.read();
2326          entry.tag         = r_cleanup_tag.read();
2327          entry.lock    = r_cleanup_lock.read();
2328          entry.ptr     = r_cleanup_ptr.read();
2329          if(r_cleanup_is_cnt.read()) { // Directory is a counter
2330            entry.count  = r_cleanup_count.read() -1;
2331            entry.owner.srcid = 0;
2332            entry.owner.inst  = 0;
2333            // response to the cache
2334            r_cleanup_fsm = CLEANUP_RSP;
2335          }
2336          else{                         // Directory is a list
2337            if(match) { // hit
2338              entry.count       = 0; // no more copy
2339              entry.owner.srcid = 0;
2340              entry.owner.inst  = 0;
2341              r_cleanup_fsm     = CLEANUP_RSP;
2342            } else { // miss
2343              entry.count       = r_cleanup_count.read();
2344              entry.owner.srcid = r_cleanup_copy.read();
2345              entry.owner.inst  = r_cleanup_copy_inst.read();
2346              r_cleanup_fsm     = CLEANUP_UPT_LOCK;
2347            }
2348          }
2349          m_cache_directory.write(set, way, entry); 
2350
2351          break;
2352        }
2353        /////////////////
2354      case CLEANUP_HEAP_LOCK:
2355        {
2356          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP){
2357            size_t way      = r_cleanup_way.read();
2358#define L2 soclib::common::uint32_log2
2359            size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
2360#undef L2
2361            HeapEntry heap_entry = m_heap_directory.read(r_cleanup_ptr.read());
2362            bool last = (heap_entry.next == r_cleanup_ptr.read());
2363            bool cleanup_inst       = r_cleanup_trdid.read() & 0x1;
2364            bool match_dir_srcid    = (r_cleanup_copy.read() == r_cleanup_srcid.read());
2365            bool match_dir_inst     = (r_cleanup_copy_inst.read()  == cleanup_inst);
2366            bool match_dir          = match_dir_srcid && match_dir_inst;
2367            bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
2368            bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
2369            bool match_heap         = match_heap_srcid && match_heap_inst;
2370
2371            r_cleanup_prev_ptr = r_cleanup_ptr.read();
2372            r_cleanup_prev_srcid = heap_entry.owner.srcid;
2373            r_cleanup_prev_inst  = heap_entry.owner.inst;
2374
2375            if(match_dir){
2376              DirectoryEntry dir_entry;
2377              dir_entry.valid       = true;
2378              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
2379              dir_entry.dirty       = r_cleanup_dirty.read();
2380              dir_entry.tag             = r_cleanup_tag.read();
2381              dir_entry.lock        = r_cleanup_lock.read();
2382              dir_entry.ptr         = heap_entry.next;
2383              dir_entry.count       = r_cleanup_count.read()-1;
2384              dir_entry.owner.srcid = heap_entry.owner.srcid;
2385              dir_entry.owner.inst  = heap_entry.owner.inst;
2386              m_cache_directory.write(set,way,dir_entry);
2387              r_cleanup_next_ptr    = r_cleanup_ptr.read();
2388              r_cleanup_fsm         = CLEANUP_HEAP_FREE;
2389            }
2390            else if(match_heap){
2391              DirectoryEntry dir_entry;
2392              dir_entry.valid       = true;
2393              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
2394              dir_entry.dirty       = r_cleanup_dirty.read();
2395              dir_entry.tag             = r_cleanup_tag.read();
2396              dir_entry.lock        = r_cleanup_lock.read();
2397              dir_entry.ptr         = heap_entry.next;
2398              dir_entry.count       = r_cleanup_count.read()-1;
2399              dir_entry.owner.srcid = r_cleanup_copy.read();
2400              dir_entry.owner.inst  = r_cleanup_copy_inst.read();
2401              m_cache_directory.write(set,way,dir_entry);
2402              r_cleanup_next_ptr    = r_cleanup_ptr.read();
2403              r_cleanup_fsm         = CLEANUP_HEAP_FREE;
2404            }
2405            else{
2406              if(!last){
2407                DirectoryEntry dir_entry;
2408                dir_entry.valid         = true;
2409                dir_entry.is_cnt        = r_cleanup_is_cnt.read();
2410                dir_entry.dirty         = r_cleanup_dirty.read();
2411                dir_entry.tag           = r_cleanup_tag.read();
2412                dir_entry.lock          = r_cleanup_lock.read();
2413                dir_entry.ptr           = r_cleanup_ptr.read();
2414                dir_entry.count         = r_cleanup_count.read()-1;
2415                dir_entry.owner.srcid   = r_cleanup_copy.read();
2416                dir_entry.owner.inst    = r_cleanup_copy_inst.read();
2417                m_cache_directory.write(set,way,dir_entry);
2418
2419                r_cleanup_next_ptr = heap_entry.next;
2420                r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
2421
2422              } else{
2423                assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
2424              }
2425            }
2426          }
2427          break;
2428        }
2429        /////////////////
2430      case CLEANUP_HEAP_SEARCH:
2431        {
2432          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2433                    "MemCache ERROR : bad HEAP allocation");
2434          HeapEntry heap_entry = m_heap_directory.read(r_cleanup_next_ptr.read());
2435          bool last = (heap_entry.next == r_cleanup_next_ptr.read());
2436          bool cleanup_inst       = r_cleanup_trdid.read() & 0x1;
2437          bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
2438          bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
2439          bool match_heap         = match_heap_srcid && match_heap_inst;
2440
2441          if(match_heap){
2442            r_cleanup_ptr           = heap_entry.next; // reuse ressources
2443            r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
2444          }
2445          else{
2446            if(last) {
2447              assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
2448            } else {
2449              r_cleanup_prev_ptr = r_cleanup_next_ptr.read();
2450              r_cleanup_prev_srcid = heap_entry.owner.srcid;
2451              r_cleanup_prev_inst  = heap_entry.owner.inst;
2452              r_cleanup_next_ptr = heap_entry.next;
2453              r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
2454            }
2455          }
2456
2457          break;
2458        }
2459        /////////////////
2460      case CLEANUP_HEAP_CLEAN:
2461        {
2462          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2463                    "MemCache ERROR : bad HEAP allocation");
2464          bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
2465          HeapEntry heap_entry;
2466          heap_entry.owner.srcid = r_cleanup_prev_srcid.read();
2467          heap_entry.owner.inst  = r_cleanup_prev_inst.read();
2468          if(last){ // this is the last entry of the list of copies
2469            heap_entry.next     = r_cleanup_prev_ptr.read();
2470          } else { // this is not the last entry
2471            heap_entry.next     = r_cleanup_ptr.read();
2472          }
2473          m_heap_directory.write(r_cleanup_prev_ptr.read(),heap_entry);
2474          r_cleanup_fsm = CLEANUP_HEAP_FREE;
2475          break;
2476        }
2477        /////////////////
2478      case CLEANUP_HEAP_FREE:
2479        {
2480          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
2481                    "MemCache ERROR : bad HEAP allocation");
2482          HeapEntry heap_entry;
2483          heap_entry.owner.srcid = 0;
2484          heap_entry.owner.inst  = false;
2485          if(m_heap_directory.is_full()){
2486            heap_entry.next     = r_cleanup_next_ptr.read();
2487          } else {
2488            heap_entry.next     = m_heap_directory.next_free_ptr();
2489          }
2490          m_heap_directory.write(r_cleanup_next_ptr.read(),heap_entry);
2491          m_heap_directory.write_free_ptr(r_cleanup_next_ptr.read());
2492          m_heap_directory.unset_full();
2493          r_cleanup_fsm = CLEANUP_RSP;
2494          break;
2495        }
2496        /////////////////
2497      case CLEANUP_UPT_LOCK:
2498        {
2499          if( r_alloc_upt_fsm.read() == ALLOC_UPT_CLEANUP )
2500          {
2501            size_t index;
2502            bool hit_inval;
2503            hit_inval = m_update_tab.search_inval(r_cleanup_nline.read(),index);
2504            if(!hit_inval) {
2505#ifdef DEBUG_VCI_MEM_CACHE
2506              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;
2507#endif
2508              r_cleanup_fsm = CLEANUP_RSP;
2509            } else {
2510              r_cleanup_write_srcid = m_update_tab.srcid(index);
2511              r_cleanup_write_trdid = m_update_tab.trdid(index);
2512              r_cleanup_write_pktid = m_update_tab.pktid(index);
2513              r_cleanup_need_rsp    = m_update_tab.need_rsp(index);
2514              r_cleanup_fsm = CLEANUP_UPT_WRITE;
2515            }
2516            r_cleanup_index.write(index) ;
2517          }
2518          break;
2519        }
2520        /////////////////
2521      case CLEANUP_UPT_WRITE:
2522        {
2523          size_t count = 0;
2524          m_update_tab.decrement(r_cleanup_index.read(), count); // &count
2525          if(count == 0){
2526            m_update_tab.clear(r_cleanup_index.read());
2527#ifdef IDEBUG
2528        std::cout << sc_time_stamp() << " " << name() << " CLEANUP_UPT_WRITE update table : " << std::endl;
2529        m_update_tab.print();
2530#endif
2531
2532            if(r_cleanup_need_rsp.read()){
2533              r_cleanup_fsm = CLEANUP_WRITE_RSP ;
2534            } else {
2535              r_cleanup_fsm = CLEANUP_RSP;
2536            }
2537          } else {
2538            r_cleanup_fsm = CLEANUP_RSP ;
2539          }
2540          break;
2541        }
2542        /////////////////
2543      case CLEANUP_WRITE_RSP:
2544        {
2545          if( !r_cleanup_to_tgt_rsp_req.read()) {
2546            r_cleanup_to_tgt_rsp_req     = true;
2547            r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
2548            r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
2549            r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
2550            r_cleanup_fsm = CLEANUP_RSP;
2551          }
2552          break;
2553        }
2554        /////////////////
2555      case CLEANUP_RSP:
2556        {
2557          if(p_vci_tgt_cleanup.rspack)
2558            r_cleanup_fsm = CLEANUP_IDLE;
2559          break;
2560        }
2561    } // end switch cleanup fsm
2562
2563
2564    ////////////////////////////////////////////////////////////////////////////////////
2565    //          LLSC FSM
2566    ////////////////////////////////////////////////////////////////////////////////////
2567    // The LLSC FSM handles the LL & SC atomic access.
2568    //
2569    // For a LL :
2570    // It access the directory to check hit / miss.
2571    // - In case of hit, the LL request is registered in the Atomic Table and the
2572    // response is sent to the requesting processor.
2573    // - In case of miss, the LLSC FSM accesses the transaction table.
2574    // If a read transaction to the XRAM for this line already exists,
2575    // or if the transaction table is full, it returns to IDLE state.
2576    // Otherwise, a new transaction to the XRAM is initiated.
2577    // In both cases, the LL request is not consumed in the FIFO.
2578    //
2579    // For a SC :
2580    // It access the directory to check hit / miss.
2581    // - In case of hit, the Atomic Table is checked and the proper response
2582    // (true or false is sent to the requesting processor.
2583    // - In case of miss, the LLSC FSM accesses the transaction table.
2584    // If a read transaction to the XRAM for this line already exists,
2585    // or if the transaction table is full, it returns to IDLE state.
2586    // Otherwise, a new transaction to the XRAM is initiated.
2587    // In both cases, the SC request is not consumed in the FIFO.
2588    /////////////////////////////////////////////////////////////////////
2589
2590    switch ( r_llsc_fsm.read() ) {
2591
2592      ///////////////
2593      case LLSC_IDLE:    // fill the buffers
2594        {
2595          if( m_cmd_llsc_addr_fifo.rok() ) {
2596#ifdef LOCK_DEBUG
2597            std::cout << "SC data : " << m_cmd_llsc_wdata_fifo.read() << std::endl;
2598            std::cout << "SC addr : " << std::hex << m_cmd_llsc_addr_fifo.read() << std::dec << std::endl;
2599            std::cout << "SC cpt  : " << r_llsc_cpt.read() << std::endl;
2600#endif
2601            if(m_cmd_llsc_eop_fifo.read()){
2602              m_cpt_sc++;
2603              r_llsc_fsm = SC_DIR_LOCK;
2604#ifdef LOCK_DEBUG
2605              std::cout << "SC eop" << std::endl;
2606#endif
2607            } else { // we keep the last word
2608                cmd_llsc_fifo_get = true;
2609            }
2610            // We fill the two buffers
2611            if(r_llsc_cpt.read() < 2){
2612                r_llsc_rdata[r_llsc_cpt.read()] = m_cmd_llsc_wdata_fifo.read();
2613            }
2614            if((r_llsc_cpt.read() == 1) && m_cmd_llsc_eop_fifo.read())
2615                r_llsc_wdata = m_cmd_llsc_wdata_fifo.read();
2616            if(r_llsc_cpt.read()>3)
2617                assert(false && "MEMCACHE error : SC too long");
2618            if(r_llsc_cpt.read()==2){
2619                r_llsc_wdata = m_cmd_llsc_wdata_fifo.read();
2620            }
2621            r_llsc_cpt = r_llsc_cpt.read()+1;
2622          }     
2623          break;
2624        }
2625        /////////////////
2626      case SC_DIR_LOCK:
2627        {
2628          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
2629            size_t way = 0;
2630            DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
2631            r_llsc_is_cnt   = entry.is_cnt;
2632            r_llsc_dirty    = entry.dirty;
2633            r_llsc_tag      = entry.tag;
2634            r_llsc_way      = way;
2635            r_llsc_copy     = entry.owner.srcid;
2636            r_llsc_copy_inst= entry.owner.inst;
2637            r_llsc_ptr      = entry.ptr;
2638            r_llsc_count    = entry.count;
2639            if ( entry.valid ){
2640                r_llsc_fsm = SC_DIR_HIT_READ;
2641            }
2642            else r_llsc_fsm = LLSC_TRT_LOCK;
2643          }
2644          break;
2645        }
2646        ////////////////
2647      case SC_DIR_HIT_READ:
2648        {
2649          size_t way    = r_llsc_way.read();
2650          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2651          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2652
2653          // update directory (lock & dirty bits
2654          DirectoryEntry entry;
2655          entry.valid       = true;
2656          entry.is_cnt      = r_llsc_is_cnt.read();
2657          entry.dirty       = true;
2658          entry.lock        = true;
2659          entry.tag             = r_llsc_tag.read();
2660          entry.owner.srcid = r_llsc_copy.read();
2661          entry.owner.inst  = r_llsc_copy_inst.read();
2662          entry.count       = r_llsc_count.read();
2663          entry.ptr         = r_llsc_ptr.read();
2664          m_cache_directory.write(set, way, entry);
2665
2666          // read data in cache
2667          bool ok;
2668          ok = (r_llsc_rdata[0].read() == m_cache_data[way][set][word]);
2669          if(r_llsc_cpt.read()==4) // 64 bits SC
2670            ok &= (r_llsc_rdata[1] == m_cache_data[way][set][word+1]);
2671
2672#ifdef LOCK_DEBUG
2673          std::cout << "SC_DIR_HIT_READ ok ? " << ok << std::endl;
2674          if(!ok){
2675              std::cout << "SC_DIR_HIT_READ cache data 0 : " << m_cache_data[way][set][word] << std::endl;
2676              if(r_llsc_cpt.read()==4)
2677                  std::cout << "SC_DIR_HIT_READ rdata 1      : " << m_cache_data[way][set][word+1] << std::endl;
2678              std::cout << "SC_DIR_HIT_READ rdata 0      : " << r_llsc_rdata[0].read() << std::endl;
2679              if(r_llsc_cpt.read()==4)
2680                  std::cout << "SC_DIR_HIT_READ rdata 1      : " << r_llsc_rdata[1].read() << std::endl;
2681              std::cout << "SC_DIR_HIT_READ wdata 0      : " << r_llsc_wdata.read() << std::endl;
2682              if(r_llsc_cpt.read()==4)
2683                  std::cout << "SC_DIR_HIT_READ wdata 1      : " << m_cmd_llsc_wdata_fifo.read() << std::endl;
2684          }
2685#endif
2686          if(ok){
2687            /* to avoid livelock, force the atomic access to fail (pseudo-)randomly */
2688            bool fail = (r_llsc_lfsr % (64) == 0);
2689            r_llsc_lfsr = (r_llsc_lfsr >> 1) ^ ((-(r_llsc_lfsr & 1)) & 0xd0000001);
2690#ifdef RANDOMIZE_SC
2691            if(fail){
2692#else
2693            if(0){
2694#endif
2695                r_llsc_fsm = SC_RSP_FALSE;
2696            } else {
2697                if(r_llsc_count.read()) {  // Shared line
2698                    if(entry.is_cnt) {
2699                        r_llsc_fsm = SC_TRT_LOCK;
2700                    } else {
2701                        r_llsc_fsm = SC_UPT_LOCK;
2702                    }
2703                } else {
2704                    r_llsc_fsm = SC_DIR_HIT_WRITE;
2705                }
2706            }
2707          } else {
2708            r_llsc_fsm = SC_RSP_FALSE;
2709          }
2710          break;
2711        }
2712        ////////////////
2713      case SC_DIR_HIT_WRITE:
2714        {
2715          size_t way    = r_llsc_way.read();
2716          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2717          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2718
2719          if(!r_llsc_count.read()){ // no update
2720            // write data in cache
2721            m_cache_data[way][set][word] = r_llsc_wdata.read();
2722            if(r_llsc_cpt.read()==4)
2723                m_cache_data[way][set][word+1] = m_cmd_llsc_wdata_fifo.read();
2724          }
2725         
2726          if(r_llsc_count.read()) {  // Shared line
2727#ifdef LOCK_DEBUG
2728            std::cout << "SC, shared line" << std::endl;
2729#endif
2730            r_llsc_fsm = SC_UPT_LOCK;
2731          } else {
2732            r_llsc_fsm = SC_RSP_TRUE;
2733          }
2734          break;
2735        }
2736        /////////////////////
2737      case SC_UPT_LOCK:         // Try to register the request in Update Table
2738        {
2739
2740          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
2741            size_t way  = r_llsc_way.read();
2742            size_t set  = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2743            size_t word = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2744            bool        wok        = false;
2745            size_t      index      = 0;
2746            size_t      srcid      = m_cmd_llsc_srcid_fifo.read();
2747            size_t      trdid      = m_cmd_llsc_trdid_fifo.read();
2748            size_t      pktid      = m_cmd_llsc_pktid_fifo.read();
2749            addr_t          nline      = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2750            size_t      nb_copies  = r_llsc_count.read();
2751
2752            wok =m_update_tab.set(true, // it's an update transaction
2753                false,                  // it's not a broadcast
2754                true,                   // it needs a response
2755                srcid,
2756                trdid,
2757                pktid,
2758                nline,
2759                nb_copies,
2760                index);
2761            if(wok){
2762              // write data in cache
2763              m_cache_data[way][set][word] = r_llsc_wdata.read();
2764              if(r_llsc_cpt.read()==4)
2765                  m_cache_data[way][set][word+1] = m_cmd_llsc_wdata_fifo.read();
2766            }
2767#ifdef IDEBUG
2768            if(wok){
2769        std::cout << sc_time_stamp() << " " << name() << " SC_UPT_LOCK update table : " << std::endl;
2770        m_update_tab.print();
2771            }
2772#endif
2773            r_llsc_upt_index = index;
2774            //  releases the lock protecting the Update Table and the Directory if no entry...
2775            if ( wok ) r_llsc_fsm = SC_HEAP_LOCK;
2776            else       r_llsc_fsm = SC_WAIT;
2777          }
2778          break;
2779        }
2780        ////////////////////
2781      case SC_WAIT:     // release all locks
2782        {
2783          r_llsc_fsm = SC_DIR_LOCK;
2784          break;
2785        }
2786        ////////////////////
2787      case SC_HEAP_LOCK:        // lock the heap
2788        {
2789          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC ){
2790            r_llsc_fsm = SC_UPT_REQ;
2791          }
2792          break;
2793        }
2794        ////////////////////
2795      case SC_UPT_REQ:  // Request the update
2796        {
2797          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
2798                    "MemCache ERROR : bad HEAP allocation");
2799          if( !r_llsc_to_init_cmd_multi_req.read() &&
2800              !r_llsc_to_init_cmd_brdcast_req.read()  ){
2801            r_llsc_to_init_cmd_brdcast_req  = false;
2802            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
2803            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2804            r_llsc_to_init_cmd_index        = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2805            r_llsc_to_init_cmd_wdata        = r_llsc_wdata.read();
2806            if(r_llsc_cpt.read() == 4){
2807                r_llsc_to_init_cmd_is_long    = true;
2808                r_llsc_to_init_cmd_wdata_high = m_cmd_llsc_wdata_fifo.read();
2809            } else {
2810                r_llsc_to_init_cmd_is_long    = false;
2811                r_llsc_to_init_cmd_wdata_high = 0;
2812            }
2813
2814            // We put the first copy in the fifo
2815            llsc_to_init_cmd_fifo_put     = true;
2816            llsc_to_init_cmd_fifo_inst    = r_llsc_copy_inst.read();
2817            llsc_to_init_cmd_fifo_srcid   = r_llsc_copy.read();
2818            if(r_llsc_count.read() == 1){
2819#ifdef LOCK_DEBUG
2820              std::cout << "SC_UPT_REQ, only one owner : " << r_llsc_copy.read() << std::endl;
2821#endif
2822              r_llsc_fsm = LLSC_IDLE;
2823              cmd_llsc_fifo_get            = true;
2824              r_llsc_to_init_cmd_multi_req = true;
2825              r_llsc_cpt = 0;
2826            } else {
2827              r_llsc_fsm = SC_UPDATE;
2828            }
2829          }
2830          break;
2831        }
2832        //////////////////
2833      case SC_UPDATE:           // send a multi-update request to INIT_CMD fsm
2834        {
2835          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
2836                    "MemCache ERROR : bad HEAP allocation");
2837          HeapEntry entry = m_heap_directory.read(r_llsc_ptr.read());
2838          llsc_to_init_cmd_fifo_inst  = entry.owner.inst;
2839          llsc_to_init_cmd_fifo_srcid = entry.owner.srcid;
2840          llsc_to_init_cmd_fifo_put = true;
2841
2842          if( m_llsc_to_init_cmd_inst_fifo.wok() ){
2843            r_llsc_ptr = entry.next;
2844            if( entry.next == r_llsc_ptr.read() ) { // last copy
2845              r_llsc_to_init_cmd_multi_req = true;
2846              r_llsc_fsm = LLSC_IDLE; // Response will be sent after receiving
2847                                      // all update responses
2848              cmd_llsc_fifo_get         = true;
2849              r_llsc_cpt = 0;
2850            } else {
2851              r_llsc_fsm = SC_UPDATE;
2852            }
2853          } else {
2854            r_llsc_fsm = SC_UPDATE;
2855          }
2856         
2857          break;
2858        }
2859        //////////////////
2860      case SC_TRT_LOCK:
2861        {
2862          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
2863            if( !r_llsc_to_ixr_cmd_req ) { // we can transfer the data to the buffer
2864              size_t way        = r_llsc_way.read();
2865              size_t set        = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2866              for(size_t i = 0; i<m_words; i++){
2867                if(i==m_x[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]) {
2868                  r_llsc_to_ixr_cmd_data[i] = r_llsc_wdata.read();
2869                } else {
2870                    if((i==(m_x[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]+1)) && // 64 bit SC
2871                        (r_llsc_cpt.read()==4)) {
2872                        r_llsc_to_ixr_cmd_data[i] = m_cmd_llsc_wdata_fifo.read();
2873                    } else {
2874                        r_llsc_to_ixr_cmd_data[i] = m_cache_data[way][set][i];
2875                    }
2876                }
2877              }
2878              size_t wok_index = 0;
2879              bool wok = !m_transaction_tab.full(wok_index);
2880              if ( wok ) { // set a new entry in TRT
2881                r_llsc_trt_index = wok_index;
2882                r_llsc_fsm       = SC_INVAL_LOCK;
2883              } else {
2884                r_llsc_fsm       = SC_WAIT;
2885              }
2886            } else {
2887              r_llsc_fsm = SC_WAIT;
2888            }
2889          }
2890          break;
2891        }
2892        //////////////////
2893      case SC_INVAL_LOCK:
2894        {
2895          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
2896            bool        wok       = false;
2897            size_t      index     = 0;
2898            size_t      srcid     = m_cmd_llsc_srcid_fifo.read();
2899            size_t      trdid     = m_cmd_llsc_trdid_fifo.read();
2900            size_t      pktid     = m_cmd_llsc_pktid_fifo.read();
2901            addr_t          nline     = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2902            size_t      nb_copies = r_llsc_count.read();
2903
2904            wok =m_update_tab.set(false,        // it's an inval transaction
2905                true,                       // it's a broadcast
2906                true,                       // it needs a response
2907                srcid,
2908                trdid,
2909                pktid,
2910                nline,
2911                nb_copies,
2912                index);
2913#ifdef IDEBUG
2914            if(wok){
2915        std::cout << sc_time_stamp() << " " << name() << " LLSC_INVAL_LOCK update table : " << std::endl;
2916        m_update_tab.print();
2917            }
2918#endif
2919            r_llsc_upt_index = index;
2920            //  releases the lock protecting Update Table if no entry...
2921            if ( wok ) r_llsc_fsm = SC_DIR_INVAL;
2922            else       r_llsc_fsm = SC_WAIT;
2923          }
2924          break;
2925        }
2926        //////////////////
2927      case SC_DIR_INVAL:
2928        {
2929          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) &&
2930              (r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC )  &&
2931              (r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ))
2932          {
2933            m_transaction_tab.set(r_llsc_trt_index.read(),
2934                false,                          // write request to XRAM
2935                m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())],
2936                0,
2937                0,
2938                0,
2939                false,                          // not a processor read
2940                0,                              // not a single word
2941                0,                              // word index
2942                std::vector<be_t>(m_words,0),
2943                std::vector<data_t>(m_words,0));
2944#ifdef TDEBUG
2945        std::cout << sc_time_stamp() << " " << name() << " SC_DIR_INVAL transaction table : " << std::endl;
2946        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2947          m_transaction_tab.print(i);
2948#endif
2949
2950            // invalidate directory entry
2951            DirectoryEntry entry;
2952            entry.valid         = false;
2953            entry.dirty         = false;
2954            entry.tag           = 0;
2955            entry.is_cnt        = false;
2956            entry.lock          = false;
2957            entry.count         = 0;
2958            entry.owner.srcid   = 0;
2959            entry.owner.inst    = false;
2960            entry.ptr           = 0;
2961            size_t set     = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2962            size_t way     = r_llsc_way.read();
2963            m_cache_directory.write(set, way, entry);
2964
2965            r_llsc_fsm = SC_INVAL;
2966          } else {
2967            assert(false && "LOCK ERROR in LLSC_FSM, STATE = LLSC_DIR_INVAL");
2968          }
2969
2970          break;
2971
2972        }
2973        //////////////////
2974      case SC_INVAL:
2975        {
2976          if ( !r_llsc_to_init_cmd_multi_req.read() &&
2977               !r_llsc_to_init_cmd_brdcast_req.read()) {
2978            r_llsc_to_init_cmd_multi_req    = false;
2979            r_llsc_to_init_cmd_brdcast_req  = true;
2980            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
2981            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2982            r_llsc_to_init_cmd_index        = 0;
2983            r_llsc_to_init_cmd_wdata        = 0;
2984
2985            r_llsc_fsm = SC_XRAM_SEND;
2986            // all update responses
2987          }
2988
2989          break;
2990        }
2991        //////////////////
2992      case SC_XRAM_SEND:
2993        {
2994          if ( !r_llsc_to_ixr_cmd_req ) {
2995            r_llsc_to_ixr_cmd_req     = true;
2996            r_llsc_to_ixr_cmd_write   = true;
2997            r_llsc_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2998            r_llsc_to_ixr_cmd_trdid   = r_llsc_trt_index.read();
2999            r_llsc_fsm        = LLSC_IDLE;
3000            cmd_llsc_fifo_get = true;
3001            r_llsc_cpt = 0;
3002          } else {
3003            assert( false && "MEM_CACHE, LLSC FSM : SC_XRAM_SEND state : the request should not have been previously set");
3004          }
3005          break;
3006        }
3007        //////////////////
3008      case SC_RSP_FALSE:
3009        {
3010          if( !r_llsc_to_tgt_rsp_req ) {
3011            cmd_llsc_fifo_get           = true;
3012            r_llsc_cpt = 0;
3013            r_llsc_to_tgt_rsp_req       = true;
3014            r_llsc_to_tgt_rsp_data      = 1;
3015            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
3016            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
3017            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
3018            r_llsc_fsm                      = LLSC_IDLE;
3019          }
3020          break;
3021        }
3022        /////////////////
3023      case SC_RSP_TRUE:
3024        {
3025          if( !r_llsc_to_tgt_rsp_req ) {
3026            cmd_llsc_fifo_get       = true;
3027            r_llsc_cpt = 0;
3028            r_llsc_to_tgt_rsp_req       = true;
3029            r_llsc_to_tgt_rsp_data      = 0;
3030            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
3031            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
3032            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
3033            r_llsc_fsm                      = LLSC_IDLE;
3034          }
3035          break;
3036        }
3037        ///////////////////
3038      case LLSC_TRT_LOCK:         // read or write miss : check the Transaction Table
3039        {
3040          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
3041            size_t   index = 0;
3042            bool hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],index);
3043            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]);
3044            bool wok = !m_transaction_tab.full(index);
3045
3046            if ( hit_read || !wok || hit_write ) {  // missing line already requested or no space in TRT
3047              r_llsc_fsm = SC_WAIT;
3048            } else {
3049              r_llsc_trt_index = index;
3050              r_llsc_fsm       = LLSC_TRT_SET;
3051            }
3052          }
3053          break;
3054        }
3055        //////////////////
3056      case LLSC_TRT_SET:        // register the XRAM transaction in Transaction Table
3057        {
3058            if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
3059                std::vector<be_t> be_vector;
3060                std::vector<data_t> data_vector;
3061                be_vector.clear();
3062                data_vector.clear();
3063                for ( size_t i=0; i<m_words; i++ )
3064                {   
3065                    be_vector.push_back(0);
3066                    data_vector.push_back(0);
3067                }
3068
3069                m_transaction_tab.set(r_llsc_trt_index.read(),
3070                  true,
3071                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
3072                  m_cmd_llsc_srcid_fifo.read(),
3073                  m_cmd_llsc_trdid_fifo.read(),
3074                  m_cmd_llsc_pktid_fifo.read(),
3075                  false,
3076                  0,
3077                  0,
3078                  be_vector,
3079                  data_vector);
3080#ifdef TDEBUG
3081        std::cout << sc_time_stamp() << " " << name() << " LLSC_TRT_SET transaction table : " << std::endl;
3082        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
3083          m_transaction_tab.print(i);
3084#endif
3085
3086                r_llsc_fsm = LLSC_XRAM_REQ;       
3087          }
3088          break;
3089        }
3090        ///////////////////
3091      case LLSC_XRAM_REQ:       // request the IXR_CMD FSM to fetch the missing line
3092        {
3093          if ( !r_llsc_to_ixr_cmd_req ) {
3094            r_llsc_to_ixr_cmd_req        = true;
3095            r_llsc_to_ixr_cmd_write      = false;
3096            r_llsc_to_ixr_cmd_trdid      = r_llsc_trt_index.read();
3097            r_llsc_to_ixr_cmd_nline      = m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()];
3098            r_llsc_fsm                   = SC_WAIT;
3099          }
3100          break;
3101        }
3102    } // end switch r_llsc_fsm
3103
3104
3105    //////////////////////////////////////////////////////////////////////////////
3106    //          INIT_CMD FSM
3107    //////////////////////////////////////////////////////////////////////////////
3108    // The INIT_CMD fsm controls the VCI CMD initiator port, used to update
3109    // or invalidate cache lines in L1 caches.
3110    // It implements a round-robin priority between the two following requests:
3111    // - r_write_to_init_cmd_req : update request from WRITE FSM
3112    // - r_xram_rsp_to_init_cmd_req : invalidate request from XRAM_RSP FSM
3113    // The inval request is a single cell VCI write command containing the
3114    // index of the line to be invalidated.
3115    // The update request is a multi-cells VCI write command : The first cell
3116    // contains the index of the cache line to be updated. The second cell contains
3117    // the index of the first modified word in the line. The following cells
3118    // contain the data.
3119    ///////////////////////////////////////////////////////////////////////////////
3120
3121    switch ( r_init_cmd_fsm.read() ) {
3122
3123      ////////////////////////
3124      case INIT_CMD_UPDT_IDLE:  // Invalidate requests have highest priority
3125        {
3126
3127          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3128               r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3129            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3130            m_cpt_inval++;
3131          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3132            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3133            m_cpt_inval++;
3134          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
3135                      r_write_to_init_cmd_multi_req.read() ) {
3136            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3137            m_cpt_update++;
3138          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3139            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3140            m_cpt_inval++;
3141          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3142                      r_llsc_to_init_cmd_multi_req.read()  ) {
3143            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3144            m_cpt_update++;
3145          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3146            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3147            m_cpt_inval++;
3148          }
3149          break;
3150        }
3151        /////////////////////////
3152      case INIT_CMD_INVAL_IDLE: // Update requests have highest priority
3153        {
3154          if ( m_write_to_init_cmd_inst_fifo.rok() ||
3155               r_write_to_init_cmd_multi_req.read() ) {
3156            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3157            m_cpt_update++;
3158          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3159            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3160            m_cpt_inval++;
3161          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3162                      r_llsc_to_init_cmd_multi_req.read()  ) {
3163            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3164            m_cpt_update++;
3165          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3166            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3167            m_cpt_inval++;
3168          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3169                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3170            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3171            m_cpt_inval++;
3172          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3173            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3174            m_cpt_inval++;
3175          }
3176          break;
3177        }
3178        /////////////////////////
3179      case INIT_CMD_SC_UPDT_IDLE:       // Update requests for SCs have highest priority
3180        {
3181          if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
3182               r_llsc_to_init_cmd_multi_req.read()  ) {
3183            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3184            m_cpt_update++;
3185          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
3186            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
3187            m_cpt_inval++;
3188          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
3189                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
3190            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3191            m_cpt_inval++;
3192          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
3193            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
3194            m_cpt_inval++;
3195          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
3196                      r_write_to_init_cmd_multi_req.read() ) {
3197            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3198            m_cpt_update++;
3199          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
3200            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
3201            m_cpt_inval++;
3202          }
3203          break;
3204        }
3205        ////////////////////////
3206      case INIT_CMD_INVAL_NLINE:        // send the cache line index
3207        {
3208          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ){
3209            if ( p_vci_ini.cmdack ) {
3210              m_cpt_inval_mult++;
3211              r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
3212              xram_rsp_to_init_cmd_fifo_get = true;
3213            }
3214          } else {
3215            if( r_xram_rsp_to_init_cmd_multi_req.read() ){
3216              r_xram_rsp_to_init_cmd_multi_req = false;
3217            }
3218            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
3219          }
3220          break;
3221        }
3222        ////////////////////////
3223      case INIT_CMD_XRAM_BRDCAST:       // send the cache line index
3224        {
3225          if ( p_vci_ini.cmdack ) {
3226            m_cpt_inval_brdcast++;
3227            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
3228            r_xram_rsp_to_init_cmd_brdcast_req = false;
3229          }
3230          break;
3231        }
3232        /////////////////////////
3233      case INIT_CMD_WRITE_BRDCAST:
3234        {
3235          if( p_vci_ini.cmdack ) {
3236            m_cpt_inval_brdcast++;
3237            r_write_to_init_cmd_brdcast_req = false;
3238            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
3239          }
3240          break;
3241        }
3242        /////////////////////////
3243      case INIT_CMD_UPDT_NLINE: // send the cache line index
3244        {
3245          if ( m_write_to_init_cmd_inst_fifo.rok() ) {
3246            if ( p_vci_ini.cmdack ){
3247              m_cpt_update_mult++;
3248              r_init_cmd_fsm = INIT_CMD_UPDT_INDEX;
3249            }
3250          } else {
3251            if ( r_write_to_init_cmd_multi_req.read() ){
3252              r_write_to_init_cmd_multi_req = false;
3253            }
3254            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
3255          }
3256          break;
3257        }
3258        /////////////////////////
3259      case INIT_CMD_UPDT_INDEX: // send the first word index
3260        {
3261          r_init_cmd_cpt    = 0;
3262          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_UPDT_DATA;
3263          break;
3264        }
3265        ////////////////////////
3266      case INIT_CMD_UPDT_DATA:  // send the data
3267        {
3268          if ( p_vci_ini.cmdack ) {
3269            if ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) ) {
3270              r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
3271              write_to_init_cmd_fifo_get = true;
3272            } else {
3273              r_init_cmd_cpt = r_init_cmd_cpt.read() + 1;
3274            }
3275          }
3276          break;
3277        }
3278        /////////////////////////
3279      case INIT_CMD_SC_BRDCAST:
3280        {
3281          if( p_vci_ini.cmdack ) {
3282            m_cpt_inval_brdcast++;
3283            r_llsc_to_init_cmd_brdcast_req = false;
3284            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
3285          }
3286          break;
3287        }
3288        /////////////////////////
3289      case INIT_CMD_SC_UPDT_NLINE:      // send the cache line index
3290        {
3291          if ( m_llsc_to_init_cmd_inst_fifo.rok() ){
3292            if ( p_vci_ini.cmdack ){
3293              m_cpt_update_mult++;
3294              r_init_cmd_fsm = INIT_CMD_SC_UPDT_INDEX;
3295            }
3296          } else {
3297            if( r_llsc_to_init_cmd_multi_req.read() ){
3298              r_llsc_to_init_cmd_multi_req = false;
3299            }
3300            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
3301          }
3302          break;
3303        }
3304        /////////////////////////
3305      case INIT_CMD_SC_UPDT_INDEX:      // send the first word index
3306        {
3307          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA;
3308          break;
3309        }
3310        ////////////////////////
3311      case INIT_CMD_SC_UPDT_DATA:       // send the data
3312        {
3313          if ( p_vci_ini.cmdack ) {
3314            if(r_llsc_to_init_cmd_is_long.read()){
3315                r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA_HIGH;
3316            } else {
3317                llsc_to_init_cmd_fifo_get = true;
3318                r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3319            }
3320          }
3321          break;
3322        }
3323        ////////////////////////
3324      case INIT_CMD_SC_UPDT_DATA_HIGH:  // send the data upper
3325        {
3326          if ( p_vci_ini.cmdack ) {
3327              llsc_to_init_cmd_fifo_get = true;
3328              r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
3329          }
3330          break;
3331        }
3332
3333
3334    } // end switch r_init_cmd_fsm
3335
3336    /////////////////////////////////////////////////////////////////////
3337    //          TGT_RSP FSM
3338    /////////////////////////////////////////////////////////////////////
3339    // The TGT_RSP fsm sends the responses on the VCI target port
3340    // with a round robin priority between six requests :
3341    // - r_read_to_tgt_rsp_req
3342    // - r_write_to_tgt_rsp_req
3343    // - r_llsc_to_tgt_rsp_req
3344    // - r_cleanup_to_tgt_rsp_req
3345    // - r_init_rsp_to_tgt_rsp_req
3346    // - r_xram_rsp_to_tgt_rsp_req
3347    // The  ordering is :  read > write > llsc > cleanup > xram > init
3348    /////////////////////////////////////////////////////////////////////
3349
3350    switch ( r_tgt_rsp_fsm.read() ) {
3351
3352      ///////////////////////
3353      case TGT_RSP_READ_IDLE:           // write requests have the highest priority
3354        {
3355          if      ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3356          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3357          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3358            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3359            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3360          }
3361          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3362          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3363          else if ( r_read_to_tgt_rsp_req     ) {
3364            r_tgt_rsp_fsm = TGT_RSP_READ;
3365            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3366          }
3367          break;
3368        }
3369        ////////////////////////
3370      case TGT_RSP_WRITE_IDLE:          // llsc requests have the highest priority
3371        {
3372          if      ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3373          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3374            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3375            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3376          }
3377          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3378          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3379          else if ( r_read_to_tgt_rsp_req     ) {
3380            r_tgt_rsp_fsm = TGT_RSP_READ;
3381            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3382          }
3383
3384          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3385          break;
3386        }
3387        ///////////////////////
3388      case TGT_RSP_LLSC_IDLE:           // cleanup requests have the highest priority
3389        {
3390          if ( r_xram_rsp_to_tgt_rsp_req )  {
3391            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3392            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3393          }
3394          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3395          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3396          else if ( r_read_to_tgt_rsp_req     ) {
3397            r_tgt_rsp_fsm = TGT_RSP_READ;
3398            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3399          }
3400          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3401          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3402          break;
3403        }
3404      case TGT_RSP_XRAM_IDLE:           // init requests have the highest priority
3405        {
3406
3407          if      ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3408          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3409          else if ( r_read_to_tgt_rsp_req     ) {
3410            r_tgt_rsp_fsm = TGT_RSP_READ;
3411            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3412          }
3413          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3414          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3415          else if ( r_xram_rsp_to_tgt_rsp_req )  {
3416            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3417            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3418          }
3419          break;
3420        }
3421        ///////////////////////
3422      case TGT_RSP_INIT_IDLE:           // cleanup requests have the highest priority
3423        {
3424          if      ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3425          else if ( r_read_to_tgt_rsp_req     ) {
3426            r_tgt_rsp_fsm = TGT_RSP_READ;
3427            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3428          }
3429          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3430          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3431          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3432            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3433            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3434          }
3435          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3436          break;
3437        }
3438        ///////////////////////
3439      case TGT_RSP_CLEANUP_IDLE:                // read requests have the highest priority
3440        {
3441          if      ( r_read_to_tgt_rsp_req     ) {
3442            r_tgt_rsp_fsm = TGT_RSP_READ;
3443            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
3444          }
3445          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
3446          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
3447          else if ( r_xram_rsp_to_tgt_rsp_req ) {
3448            r_tgt_rsp_fsm = TGT_RSP_XRAM;
3449            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
3450          }
3451          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
3452          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
3453          break;
3454        }
3455        ///////////////////////
3456      case TGT_RSP_READ:                // send the response
3457        {
3458          if ( p_vci_tgt.rspack ) {
3459            if ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) ) {
3460              r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
3461              r_read_to_tgt_rsp_req = false;
3462            } else {
3463              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
3464            }
3465          }
3466          break;
3467        }
3468        ///////////////////
3469      case TGT_RSP_WRITE:               // send the write acknowledge
3470        {
3471          if ( p_vci_tgt.rspack ) {
3472            r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE;
3473            r_write_to_tgt_rsp_req = false;
3474          }
3475          break;
3476        }
3477        ///////////////////
3478      case TGT_RSP_CLEANUP:             // send the write acknowledge
3479        {
3480          if ( p_vci_tgt.rspack ) {
3481            r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE;
3482            r_cleanup_to_tgt_rsp_req = false;
3483          }
3484          break;
3485        }
3486        //////////////////
3487      case TGT_RSP_LLSC:                // send one atomic word response
3488        {
3489          if ( p_vci_tgt.rspack ) {
3490            r_tgt_rsp_fsm = TGT_RSP_LLSC_IDLE;
3491            r_llsc_to_tgt_rsp_req = false;
3492          }
3493          break;
3494        }
3495
3496        ///////////////////////
3497      case TGT_RSP_XRAM:                // send the response
3498        {
3499          if ( p_vci_tgt.rspack ) {
3500            if ( r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1)) {
3501              r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
3502              r_xram_rsp_to_tgt_rsp_req = false;
3503            } else {
3504              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
3505            }
3506          }
3507          break;
3508        }
3509        ///////////////////
3510      case TGT_RSP_INIT:                // send the pending write acknowledge
3511        {
3512          if ( p_vci_tgt.rspack ) {
3513            r_tgt_rsp_fsm = TGT_RSP_INIT_IDLE;
3514            r_init_rsp_to_tgt_rsp_req = false;
3515          }
3516          break;
3517        }
3518    } // end switch tgt_rsp_fsm
3519    ////////////////////////////////////////////////////////////////////////////////////
3520    //          NEW ALLOC_UPT FSM
3521    ////////////////////////////////////////////////////////////////////////////////////
3522    // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT).
3523    // with a round robin priority between three FSMs : INIT_RSP > WRITE > XRAM_RSP > CLEANUP
3524    // - The WRITE FSM initiates update transactions and sets  new entry in UPT.
3525    // - The XRAM_RSP FSM initiates inval transactions and sets  new entry in UPT.
3526    // - The INIT_RSP FSM complete those trasactions and erase the UPT entry.
3527    // - The CLEANUP  FSM decrement an entry in UPT.
3528    // The resource is always allocated.
3529    /////////////////////////////////////////////////////////////////////////////////////
3530
3531    switch ( r_alloc_upt_fsm.read() ) {
3532
3533      ////////////////////////
3534      case ALLOC_UPT_INIT_RSP:
3535        if ( (r_init_rsp_fsm.read() != INIT_RSP_UPT_LOCK) &&
3536             (r_init_rsp_fsm.read() != INIT_RSP_UPT_CLEAR) )
3537        {
3538          if      ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3539                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3540          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3541          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3542          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3543                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3544        }
3545        break;
3546
3547        /////////////////////
3548      case ALLOC_UPT_WRITE:
3549        if ( (r_write_fsm.read() != WRITE_UPT_LOCK) &&
3550             (r_write_fsm.read() != WRITE_INVAL_LOCK))
3551        {
3552          if      (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3553          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3554          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3555                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3556          else if (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3557        }
3558        break;
3559
3560        ////////////////////////
3561      case ALLOC_UPT_XRAM_RSP:
3562        if (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
3563        {
3564          if       (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)       r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3565          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3566                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3567          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3568          else if ((r_write_fsm.read() == WRITE_UPT_LOCK)   ||
3569                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3570        }
3571        break;
3572
3573        //////////////////////////
3574      case ALLOC_UPT_CLEANUP:
3575        if(r_cleanup_fsm.read() != CLEANUP_UPT_LOCK )
3576        {
3577          if      ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
3578                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
3579          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3580          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3581                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3582          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3583        }
3584        break;
3585       
3586        //////////////////////////
3587      case ALLOC_UPT_LLSC:
3588        if( (r_llsc_fsm.read() != SC_UPT_LOCK) &&
3589            (r_llsc_fsm.read() != SC_INVAL_LOCK))
3590        {
3591          if      (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
3592          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
3593                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
3594          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
3595          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
3596        }
3597        break;
3598
3599    } // end switch r_alloc_upt_fsm
3600
3601    ////////////////////////////////////////////////////////////////////////////////////
3602    //          ALLOC_DIR FSM
3603    ////////////////////////////////////////////////////////////////////////////////////
3604    // The ALLOC_DIR FSM allocates the access to the directory and
3605    // the data cache with a round robin priority between 5 user FSMs :
3606    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
3607    // The ressource is always allocated.
3608    /////////////////////////////////////////////////////////////////////////////////////
3609
3610    switch ( r_alloc_dir_fsm.read() ) {
3611
3612      ////////////////////
3613      case ALLOC_DIR_READ:
3614        if ( ( (r_read_fsm.read() != READ_DIR_LOCK) &&
3615              (r_read_fsm.read() != READ_TRT_LOCK)  &&
3616              (r_read_fsm.read() != READ_HEAP_LOCK))
3617            ||
3618            ( (r_read_fsm.read()        == READ_HEAP_LOCK) &&
3619              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_READ) )
3620            ||
3621            ( (r_read_fsm.read()      == READ_TRT_LOCK)  &&
3622              (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)    )  )
3623        {
3624          if        (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3625          else if   (r_llsc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3626          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3627          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3628        }
3629        break;
3630
3631        /////////////////////
3632      case ALLOC_DIR_WRITE:
3633        if ( ( (r_write_fsm.read() != WRITE_DIR_LOCK)     &&
3634              (r_write_fsm.read() != WRITE_TRT_LOCK)     &&
3635              (r_write_fsm.read() != WRITE_DIR_HIT_READ) &&
3636              (r_write_fsm.read() != WRITE_DIR_HIT) &&
3637              (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3638              (r_write_fsm.read() != WRITE_INVAL_LOCK) &&
3639              (r_write_fsm.read() != WRITE_UPT_LOCK) &&
3640              (r_write_fsm.read() != WRITE_HEAP_LOCK))
3641            ||
3642            ( (r_write_fsm.read()       == WRITE_HEAP_LOCK) &&
3643              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_WRITE) )
3644            ||
3645            ( (r_write_fsm.read()     == WRITE_TRT_LOCK) &&
3646              (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)   )   )
3647        {
3648          if        (r_llsc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3649          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3650          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3651          else if   (r_read_fsm.read() == READ_DIR_LOCK)                r_alloc_dir_fsm = ALLOC_DIR_READ;
3652        }
3653        break;
3654
3655        ////////////////////
3656      case ALLOC_DIR_LLSC:
3657        if ( ((r_llsc_fsm.read() != SC_DIR_LOCK)       &&
3658              (r_llsc_fsm.read() != SC_DIR_HIT_READ )  &&
3659              (r_llsc_fsm.read() != SC_DIR_HIT_WRITE ) &&
3660              (r_llsc_fsm.read() != LLSC_TRT_LOCK )    &&
3661              (r_llsc_fsm.read() != SC_TRT_LOCK)       &&
3662              (r_llsc_fsm.read() != SC_INVAL_LOCK)     &&
3663              (r_llsc_fsm.read() != SC_UPT_LOCK)       &&
3664              (r_llsc_fsm.read() != SC_HEAP_LOCK))
3665            ||
3666            ( (r_llsc_fsm.read()       == SC_HEAP_LOCK) &&
3667              (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) )
3668            ||
3669            ( (r_llsc_fsm.read()      == LLSC_TRT_LOCK ) &&
3670              (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC)    ) )
3671        {
3672          if      (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3673          else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)  r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3674          else if (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3675          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3676        }
3677        break;
3678
3679        ///////////////////////
3680      case ALLOC_DIR_CLEANUP:
3681        if ( (r_cleanup_fsm.read() != CLEANUP_DIR_LOCK) &&
3682            (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) )
3683        {
3684          if        (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3685          else if   (r_read_fsm.read() == READ_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_READ;
3686          else if   (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3687          else if   (r_llsc_fsm.read() == SC_DIR_LOCK)              r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3688        }
3689        break;
3690        ////////////////////////
3691      case ALLOC_DIR_XRAM_RSP:
3692        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_LOCK)  &&
3693            (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)   &&
3694            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK))
3695        {
3696          if      (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3697          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3698          else if (r_llsc_fsm.read() == SC_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3699          else if (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3700        }
3701        break;
3702
3703    } // end switch alloc_dir_fsm
3704
3705    ////////////////////////////////////////////////////////////////////////////////////
3706    //          ALLOC_TRT FSM
3707    ////////////////////////////////////////////////////////////////////////////////////
3708    // The ALLOC_TRT fsm allocates the access to the Transaction Table (write buffer)
3709    // with a round robin priority between 4 user FSMs :
3710    // The cyclic priority is READ > WRITE > LLSC > XRAM_RSP
3711    // The ressource is always allocated.
3712    ///////////////////////////////////////////////////////////////////////////////////
3713
3714    switch (r_alloc_trt_fsm) {
3715
3716      ////////////////////
3717      case ALLOC_TRT_READ:
3718        if ( r_read_fsm.read() != READ_TRT_LOCK )
3719        {
3720          if      ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3721                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3722          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3723                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3724          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3725          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3726                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) )    r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3727        }
3728        break;
3729        /////////////////////
3730      case ALLOC_TRT_WRITE:
3731        if ( (r_write_fsm.read() != WRITE_TRT_LOCK) &&
3732             (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3733             (r_write_fsm.read() != WRITE_INVAL_LOCK))
3734        {
3735          if      ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3736                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3737          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3738          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3739                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3740          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3741        }
3742        break;
3743        ////////////////////
3744      case ALLOC_TRT_LLSC:
3745        if ( (r_llsc_fsm.read() != LLSC_TRT_LOCK) &&
3746             (r_llsc_fsm.read() != SC_TRT_LOCK) &&
3747             (r_llsc_fsm.read() != SC_INVAL_LOCK))
3748        {
3749          if      (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3750          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3751                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3752          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3753          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)     ||
3754                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3755        }
3756        break;
3757        ////////////////////////
3758      case ALLOC_TRT_XRAM_RSP:
3759        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)  &&
3760            (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_UPDT)   &&
3761            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)) {
3762          if      ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3763                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3764          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3765          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)    ||
3766                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3767          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3768                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3769        }
3770        break;
3771        ////////////////////////
3772      case ALLOC_TRT_IXR_RSP:
3773        if ( (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_ERASE) &&
3774            (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ) ) {
3775          if      (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3776          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3777                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3778          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
3779                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3780          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3781        }
3782        break;
3783
3784    } // end switch alloc_trt_fsm
3785
3786    ////////////////////////////////////////////////////////////////////////////////////
3787    //          ALLOC_HEAP FSM
3788    ////////////////////////////////////////////////////////////////////////////////////
3789    // The ALLOC_HEAP FSM allocates the access to the heap
3790    // with a round robin priority between 5 user FSMs :
3791    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
3792    // The ressource is always allocated.
3793    /////////////////////////////////////////////////////////////////////////////////////
3794
3795    switch ( r_alloc_heap_fsm.read() ) {
3796
3797      ////////////////////
3798      case ALLOC_HEAP_READ:
3799        if (  (r_read_fsm.read() != READ_HEAP_LOCK) &&
3800              (r_read_fsm.read() != READ_HEAP_ERASE)     )
3801        {
3802          if        (r_write_fsm.read() == WRITE_HEAP_LOCK)         r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
3803          else if   (r_llsc_fsm.read() == SC_HEAP_LOCK)             r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3804          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3805          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3806        }
3807        break;
3808
3809        /////////////////////
3810      case ALLOC_HEAP_WRITE:
3811        if (  (r_write_fsm.read() != WRITE_HEAP_LOCK)   &&
3812              (r_write_fsm.read() != WRITE_UPT_REQ)     &&
3813              (r_write_fsm.read() != WRITE_UPDATE)  )
3814        {
3815          if        (r_llsc_fsm.read() == SC_HEAP_LOCK)             r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3816          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3817          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3818          else if   (r_read_fsm.read() == READ_HEAP_LOCK)               r_alloc_heap_fsm = ALLOC_HEAP_READ;
3819        }
3820        break;
3821
3822        ////////////////////
3823      case ALLOC_HEAP_LLSC:
3824        if (  (r_llsc_fsm.read() != SC_HEAP_LOCK)  &&
3825              (r_llsc_fsm.read() != SC_UPT_REQ )    &&
3826              (r_llsc_fsm.read() != SC_UPDATE)  )
3827        {
3828          if      (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3829          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3830          else if (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
3831          else if (r_write_fsm.read() == WRITE_HEAP_LOCK)         r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
3832        }
3833        break;
3834
3835        ///////////////////////
3836      case ALLOC_HEAP_CLEANUP:
3837        if ( (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) &&
3838            (r_cleanup_fsm.read() != CLEANUP_HEAP_SEARCH)&&
3839            (r_cleanup_fsm.read() != CLEANUP_HEAP_CLEAN)    )
3840        {
3841          if        (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
3842          else if   (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
3843          else if   (r_write_fsm.read() == WRITE_HEAP_LOCK)         r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
3844          else if   (r_llsc_fsm.read() == SC_HEAP_LOCK)             r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3845        }
3846        break;
3847        ////////////////////////
3848      case ALLOC_HEAP_XRAM_RSP:
3849        if ( r_xram_rsp_fsm.read() != XRAM_RSP_HEAP_ERASE )
3850        {
3851          if        (r_read_fsm.read() == READ_HEAP_LOCK)               r_alloc_heap_fsm = ALLOC_HEAP_READ;
3852          else if   (r_write_fsm.read() == WRITE_HEAP_LOCK)         r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
3853          else if   (r_llsc_fsm.read() == SC_HEAP_LOCK)             r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
3854          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
3855        }
3856        break;
3857
3858    } // end switch alloc_heap_fsm
3859
3860
3861    ////////////////////////////////////////////////////////////////////////////////////
3862    //          TGT_CMD to READ FIFO
3863    ////////////////////////////////////////////////////////////////////////////////////
3864
3865    if ( cmd_read_fifo_put ) {
3866      if ( cmd_read_fifo_get ) {
3867        m_cmd_read_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3868        m_cmd_read_length_fifo.put_and_get(p_vci_tgt.plen.read()>>2);
3869        m_cmd_read_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3870        m_cmd_read_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3871        m_cmd_read_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3872      } else {
3873        m_cmd_read_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3874        m_cmd_read_length_fifo.simple_put(p_vci_tgt.plen.read()>>2);
3875        m_cmd_read_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3876        m_cmd_read_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3877        m_cmd_read_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3878      }
3879    } else {
3880      if ( cmd_read_fifo_get ) {
3881        m_cmd_read_addr_fifo.simple_get();
3882        m_cmd_read_length_fifo.simple_get();
3883        m_cmd_read_srcid_fifo.simple_get();
3884        m_cmd_read_trdid_fifo.simple_get();
3885        m_cmd_read_pktid_fifo.simple_get();
3886      }
3887    }
3888    /////////////////////////////////////////////////////////////////////
3889    //          TGT_CMD to WRITE FIFO
3890    /////////////////////////////////////////////////////////////////////
3891
3892    if ( cmd_write_fifo_put ) {
3893      if ( cmd_write_fifo_get ) {
3894        m_cmd_write_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3895        m_cmd_write_eop_fifo.put_and_get(p_vci_tgt.eop.read());
3896        m_cmd_write_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3897        m_cmd_write_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3898        m_cmd_write_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3899        m_cmd_write_data_fifo.put_and_get(p_vci_tgt.wdata.read());
3900        m_cmd_write_be_fifo.put_and_get(p_vci_tgt.be.read());
3901      } else {
3902        m_cmd_write_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3903        m_cmd_write_eop_fifo.simple_put(p_vci_tgt.eop.read());
3904        m_cmd_write_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3905        m_cmd_write_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3906        m_cmd_write_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3907        m_cmd_write_data_fifo.simple_put(p_vci_tgt.wdata.read());
3908        m_cmd_write_be_fifo.simple_put(p_vci_tgt.be.read());
3909      }
3910    } else {
3911      if ( cmd_write_fifo_get ) {
3912        m_cmd_write_addr_fifo.simple_get();
3913        m_cmd_write_eop_fifo.simple_get();
3914        m_cmd_write_srcid_fifo.simple_get();
3915        m_cmd_write_trdid_fifo.simple_get();
3916        m_cmd_write_pktid_fifo.simple_get();
3917        m_cmd_write_data_fifo.simple_get();
3918        m_cmd_write_be_fifo.simple_get();
3919      }
3920    }
3921    ////////////////////////////////////////////////////////////////////////////////////
3922    //          TGT_CMD to LLSC FIFO
3923    ////////////////////////////////////////////////////////////////////////////////////
3924
3925    if ( cmd_llsc_fifo_put ) {
3926      if ( cmd_llsc_fifo_get ) {
3927        m_cmd_llsc_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3928        m_cmd_llsc_eop_fifo.put_and_get(p_vci_tgt.eop.read());
3929        m_cmd_llsc_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3930        m_cmd_llsc_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3931        m_cmd_llsc_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3932        m_cmd_llsc_wdata_fifo.put_and_get(p_vci_tgt.wdata.read());
3933      } else {
3934        m_cmd_llsc_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3935        m_cmd_llsc_eop_fifo.simple_put(p_vci_tgt.eop.read());
3936        m_cmd_llsc_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3937        m_cmd_llsc_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3938        m_cmd_llsc_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3939        m_cmd_llsc_wdata_fifo.simple_put(p_vci_tgt.wdata.read());
3940      }
3941    } else {
3942      if ( cmd_llsc_fifo_get ) {
3943        m_cmd_llsc_addr_fifo.simple_get();
3944        m_cmd_llsc_eop_fifo.simple_get();
3945        m_cmd_llsc_srcid_fifo.simple_get();
3946        m_cmd_llsc_trdid_fifo.simple_get();
3947        m_cmd_llsc_pktid_fifo.simple_get();
3948        m_cmd_llsc_wdata_fifo.simple_get();
3949      }
3950    }
3951    ////////////////////////////////////////////////////////////////////////////////////
3952    //          WRITE to INIT_CMD FIFO
3953    ////////////////////////////////////////////////////////////////////////////////////
3954
3955    if ( write_to_init_cmd_fifo_put ) {
3956      if ( write_to_init_cmd_fifo_get ) {
3957        m_write_to_init_cmd_inst_fifo.put_and_get(write_to_init_cmd_fifo_inst);
3958        m_write_to_init_cmd_srcid_fifo.put_and_get(write_to_init_cmd_fifo_srcid);
3959      } else {
3960        m_write_to_init_cmd_inst_fifo.simple_put(write_to_init_cmd_fifo_inst);
3961        m_write_to_init_cmd_srcid_fifo.simple_put(write_to_init_cmd_fifo_srcid);
3962      }
3963    } else {
3964      if ( write_to_init_cmd_fifo_get ) {
3965        m_write_to_init_cmd_inst_fifo.simple_get();
3966        m_write_to_init_cmd_srcid_fifo.simple_get();
3967      }
3968    }
3969    ////////////////////////////////////////////////////////////////////////////////////
3970    //          XRAM_RSP to INIT_CMD FIFO
3971    ////////////////////////////////////////////////////////////////////////////////////
3972
3973    if ( xram_rsp_to_init_cmd_fifo_put ) {
3974      if ( xram_rsp_to_init_cmd_fifo_get ) {
3975        m_xram_rsp_to_init_cmd_inst_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_inst);
3976        m_xram_rsp_to_init_cmd_srcid_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_srcid);
3977      } else {
3978        m_xram_rsp_to_init_cmd_inst_fifo.simple_put(xram_rsp_to_init_cmd_fifo_inst);
3979        m_xram_rsp_to_init_cmd_srcid_fifo.simple_put(xram_rsp_to_init_cmd_fifo_srcid);
3980      }
3981    } else {
3982      if ( xram_rsp_to_init_cmd_fifo_get ) {
3983        m_xram_rsp_to_init_cmd_inst_fifo.simple_get();
3984        m_xram_rsp_to_init_cmd_srcid_fifo.simple_get();
3985      }
3986    }
3987    ////////////////////////////////////////////////////////////////////////////////////
3988    //          LLSC to INIT_CMD FIFO
3989    ////////////////////////////////////////////////////////////////////////////////////
3990
3991    if ( llsc_to_init_cmd_fifo_put ) {
3992      if ( llsc_to_init_cmd_fifo_get ) {
3993        m_llsc_to_init_cmd_inst_fifo.put_and_get(llsc_to_init_cmd_fifo_inst);
3994        m_llsc_to_init_cmd_srcid_fifo.put_and_get(llsc_to_init_cmd_fifo_srcid);
3995      } else {
3996        m_llsc_to_init_cmd_inst_fifo.simple_put(llsc_to_init_cmd_fifo_inst);
3997        m_llsc_to_init_cmd_srcid_fifo.simple_put(llsc_to_init_cmd_fifo_srcid);
3998      }
3999    } else {
4000      if ( llsc_to_init_cmd_fifo_get ) {
4001        m_llsc_to_init_cmd_inst_fifo.simple_get();
4002        m_llsc_to_init_cmd_srcid_fifo.simple_get();
4003      }
4004    }
4005
4006
4007  //////////////////////////////////////////////////////////////
4008    m_cpt_cycles++;
4009
4010  } // end transition()
4011
4012  /////////////////////////////
4013  tmpl(void)::genMoore()
4014    /////////////////////////////
4015  {
4016    ////////////////////////////////////////////////////////////
4017    // Command signals on the p_vci_ixr port
4018    ////////////////////////////////////////////////////////////
4019
4020
4021    p_vci_ixr.be      = 0xF;
4022    p_vci_ixr.pktid   = 0;
4023    p_vci_ixr.srcid   = m_srcid_ixr;
4024    p_vci_ixr.cons    = false;
4025    p_vci_ixr.wrap    = false;
4026    p_vci_ixr.contig  = true;
4027    p_vci_ixr.clen    = 0;
4028    p_vci_ixr.cfixed  = false;
4029
4030    if ( r_ixr_cmd_fsm.read() == IXR_CMD_READ_NLINE ) {
4031      p_vci_ixr.cmd     = vci_param::CMD_READ;
4032      p_vci_ixr.cmdval  = true;
4033      p_vci_ixr.address = (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4);
4034      p_vci_ixr.plen    = m_words*4;
4035      p_vci_ixr.wdata   = 0x00000000;
4036      p_vci_ixr.trdid   = r_read_to_ixr_cmd_trdid.read();
4037      p_vci_ixr.eop     = true;
4038    }
4039    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_LLSC_NLINE ) {
4040      if(r_llsc_to_ixr_cmd_write.read()){
4041        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4042        p_vci_ixr.cmdval  = true;
4043        p_vci_ixr.address = (addr_t)((r_llsc_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4044        p_vci_ixr.plen    = m_words*4;
4045        p_vci_ixr.wdata   = r_llsc_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4046        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
4047        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4048      } else {
4049        p_vci_ixr.cmd     = vci_param::CMD_READ;
4050        p_vci_ixr.cmdval  = true;
4051        p_vci_ixr.address = (addr_t)(r_llsc_to_ixr_cmd_nline.read()*m_words*4);
4052        p_vci_ixr.plen    = m_words*4;
4053        p_vci_ixr.wdata   = 0x00000000;
4054        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
4055        p_vci_ixr.eop     = true;
4056      }
4057    }
4058    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_WRITE_NLINE ) {
4059      if(r_write_to_ixr_cmd_write.read()){
4060        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4061        p_vci_ixr.cmdval  = true;
4062        p_vci_ixr.address = (addr_t)((r_write_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4063        p_vci_ixr.plen    = m_words*4;
4064        p_vci_ixr.wdata   = r_write_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4065        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
4066        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4067      } else {
4068        p_vci_ixr.cmd     = vci_param::CMD_READ;
4069        p_vci_ixr.cmdval  = true;
4070        p_vci_ixr.address = (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4);
4071        p_vci_ixr.plen    = m_words*4;
4072        p_vci_ixr.wdata   = 0x00000000;
4073        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
4074        p_vci_ixr.eop     = true;
4075      }
4076    }
4077    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_XRAM_DATA ) {
4078      p_vci_ixr.cmd     = vci_param::CMD_WRITE;
4079      p_vci_ixr.cmdval  = true;
4080      p_vci_ixr.address = (addr_t)((r_xram_rsp_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
4081      p_vci_ixr.plen    = m_words*4;
4082      p_vci_ixr.wdata   = r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
4083      p_vci_ixr.trdid   = r_xram_rsp_to_ixr_cmd_trdid.read();
4084      p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
4085    } else {
4086      p_vci_ixr.cmdval  = false;
4087      p_vci_ixr.address = 0;
4088      p_vci_ixr.plen    = 0;
4089      p_vci_ixr.wdata   = 0;
4090      p_vci_ixr.trdid   = 0;
4091      p_vci_ixr.eop     = false;
4092    }
4093
4094    ////////////////////////////////////////////////////
4095    // Response signals on the p_vci_ixr port
4096    ////////////////////////////////////////////////////
4097
4098    if ( ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&
4099          (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ)) ||
4100        (r_ixr_rsp_fsm.read() == IXR_RSP_ACK) ) p_vci_ixr.rspack = true;
4101    else                                        p_vci_ixr.rspack = false;
4102
4103    ////////////////////////////////////////////////////
4104    // Command signals on the p_vci_tgt port
4105    ////////////////////////////////////////////////////
4106
4107    switch ((tgt_cmd_fsm_state_e)r_tgt_cmd_fsm.read()) {
4108      case TGT_CMD_IDLE:
4109        p_vci_tgt.cmdack  = false;
4110        break;
4111      case TGT_CMD_READ:
4112        p_vci_tgt.cmdack  = m_cmd_read_addr_fifo.wok();
4113        break;
4114      case TGT_CMD_READ_EOP:
4115        p_vci_tgt.cmdack  = true;
4116        break;
4117      case TGT_CMD_WRITE:
4118        p_vci_tgt.cmdack  = m_cmd_write_addr_fifo.wok();
4119        break;
4120      case TGT_CMD_ATOMIC:
4121        p_vci_tgt.cmdack  = m_cmd_llsc_addr_fifo.wok();
4122        break;
4123      default:
4124        p_vci_tgt.cmdack = false;
4125        break;
4126    }
4127
4128    ////////////////////////////////////////////////////
4129    // Response signals on the p_vci_tgt port
4130    ////////////////////////////////////////////////////
4131    switch ( r_tgt_rsp_fsm.read() ) {
4132
4133      case TGT_RSP_READ_IDLE:
4134      case TGT_RSP_WRITE_IDLE:
4135      case TGT_RSP_LLSC_IDLE:
4136      case TGT_RSP_XRAM_IDLE:
4137      case TGT_RSP_INIT_IDLE:
4138      case TGT_RSP_CLEANUP_IDLE:
4139        p_vci_tgt.rspval  = false;
4140        p_vci_tgt.rsrcid  = 0;
4141        p_vci_tgt.rdata   = 0;
4142        p_vci_tgt.rpktid  = 0;
4143        p_vci_tgt.rtrdid  = 0;
4144        p_vci_tgt.rerror  = 0;
4145        p_vci_tgt.reop    = false;     
4146        break;
4147      case TGT_RSP_READ:
4148        p_vci_tgt.rspval   = true;
4149        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
4150        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
4151        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
4152        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
4153        p_vci_tgt.rerror   = 0;
4154        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) );
4155        break;
4156      case TGT_RSP_WRITE:
4157        p_vci_tgt.rspval   = true;
4158        p_vci_tgt.rdata    = 0;
4159        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
4160        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
4161        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
4162        p_vci_tgt.rerror   = 0;
4163        p_vci_tgt.reop     = true;
4164        break;
4165      case TGT_RSP_CLEANUP:
4166        p_vci_tgt.rspval   = true;
4167        p_vci_tgt.rdata    = 0;
4168        p_vci_tgt.rsrcid   = r_cleanup_to_tgt_rsp_srcid.read();
4169        p_vci_tgt.rtrdid   = r_cleanup_to_tgt_rsp_trdid.read();
4170        p_vci_tgt.rpktid   = r_cleanup_to_tgt_rsp_pktid.read();
4171        p_vci_tgt.rerror   = 0;
4172        p_vci_tgt.reop     = true;
4173        break;
4174      case TGT_RSP_LLSC:
4175        p_vci_tgt.rspval   = true;
4176        p_vci_tgt.rdata    = r_llsc_to_tgt_rsp_data.read();
4177        p_vci_tgt.rsrcid   = r_llsc_to_tgt_rsp_srcid.read();
4178        p_vci_tgt.rtrdid   = r_llsc_to_tgt_rsp_trdid.read();
4179        p_vci_tgt.rpktid   = r_llsc_to_tgt_rsp_pktid.read();
4180        p_vci_tgt.rerror   = 0;
4181        p_vci_tgt.reop     = true;
4182        break;
4183      case TGT_RSP_XRAM:
4184        p_vci_tgt.rspval   = true;
4185        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
4186        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
4187        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
4188        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
4189        p_vci_tgt.rerror   = 0;
4190        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));
4191        break;
4192      case TGT_RSP_INIT:
4193        p_vci_tgt.rspval   = true;
4194        p_vci_tgt.rdata    = 0;
4195        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
4196        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
4197        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
4198        p_vci_tgt.rerror   = 0;
4199        p_vci_tgt.reop     = true;     
4200        break;
4201    } // end switch r_tgt_rsp_fsm
4202
4203    ///////////////////////////////////////////////////
4204    // Command signals on the p_vci_ini port
4205    ///////////////////////////////////////////////////
4206
4207    p_vci_ini.cmd     = vci_param::CMD_WRITE;
4208    p_vci_ini.srcid   = m_srcid_ini;
4209    p_vci_ini.pktid   = 0;
4210    p_vci_ini.cons    = true;
4211    p_vci_ini.wrap    = false;
4212    p_vci_ini.contig  = false;
4213    p_vci_ini.clen    = 0;
4214    p_vci_ini.cfixed  = false;
4215
4216    switch ( r_init_cmd_fsm.read() ) {
4217
4218      case INIT_CMD_UPDT_IDLE:
4219      case INIT_CMD_INVAL_IDLE:
4220      case INIT_CMD_SC_UPDT_IDLE:
4221        p_vci_ini.cmdval  = false;
4222        p_vci_ini.address = 0;
4223        p_vci_ini.wdata   = 0;
4224        p_vci_ini.be      = 0;
4225        p_vci_ini.plen    = 0;
4226        p_vci_ini.trdid   = 0;
4227        p_vci_ini.eop     = false;
4228        break;
4229      case INIT_CMD_INVAL_NLINE:
4230        p_vci_ini.cmdval  = m_xram_rsp_to_init_cmd_inst_fifo.rok();
4231        if(m_xram_rsp_to_init_cmd_inst_fifo.rok()){
4232          if(m_xram_rsp_to_init_cmd_inst_fifo.read()) {
4233            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]+4);
4234          } else {
4235            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]);
4236          }
4237        } else p_vci_ini.address = 0; // prevent segmentation faults by reading an empty fifo
4238        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
4239        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
4240        p_vci_ini.plen    = 4;
4241        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
4242        p_vci_ini.eop     = true;
4243        break;
4244      case INIT_CMD_XRAM_BRDCAST:
4245        p_vci_ini.cmdval  = true;
4246        p_vci_ini.address = BROADCAST_ADDR;
4247        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
4248        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
4249        p_vci_ini.plen    = 4;
4250        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
4251        p_vci_ini.eop     = true;
4252        break;
4253
4254      case INIT_CMD_WRITE_BRDCAST:
4255        p_vci_ini.cmdval  = true;
4256        p_vci_ini.address = BROADCAST_ADDR;
4257        p_vci_ini.wdata   = (addr_t)r_write_to_init_cmd_nline.read();
4258        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32) & 0x3);
4259        p_vci_ini.plen    = 4 ;
4260        p_vci_ini.eop     = true;
4261        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4262        break;
4263      case INIT_CMD_UPDT_NLINE:
4264        p_vci_ini.cmdval  = m_write_to_init_cmd_inst_fifo.rok();
4265        if(m_write_to_init_cmd_inst_fifo.rok()){
4266          if(m_write_to_init_cmd_inst_fifo.read()) {
4267            p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
4268          } else {
4269            p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
4270          }
4271        } else {
4272          p_vci_ini.address = 0;
4273        }
4274        p_vci_ini.wdata   = (uint32_t)r_write_to_init_cmd_nline.read();
4275        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32 ) & 0x3);
4276        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4277        p_vci_ini.eop     = false;
4278        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4279        break;
4280      case INIT_CMD_UPDT_INDEX:
4281        p_vci_ini.cmdval  = true;
4282        if(m_write_to_init_cmd_inst_fifo.read()) {
4283          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
4284        } else {
4285          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
4286        }
4287        p_vci_ini.wdata   = r_write_to_init_cmd_index.read();
4288        p_vci_ini.be      = 0xF;
4289        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4290        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4291        p_vci_ini.eop     = false;
4292        break;
4293      case INIT_CMD_UPDT_DATA:
4294        p_vci_ini.cmdval  = true;
4295        if(m_write_to_init_cmd_inst_fifo.read()) {
4296          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 12);
4297        } else {
4298          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 8);
4299        }
4300        p_vci_ini.wdata   = r_write_to_init_cmd_data[r_init_cmd_cpt.read() +
4301          r_write_to_init_cmd_index.read()].read();
4302        p_vci_ini.be      = r_write_to_init_cmd_be[r_init_cmd_cpt.read() +
4303            r_write_to_init_cmd_index.read()].read()  ;
4304        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
4305        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
4306        p_vci_ini.eop     = ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) );
4307        break;
4308
4309      case INIT_CMD_SC_BRDCAST:
4310        p_vci_ini.cmdval  = true;
4311        p_vci_ini.address = BROADCAST_ADDR;
4312        p_vci_ini.wdata   = (addr_t)r_llsc_to_init_cmd_nline.read();
4313        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32) & 0x3);
4314        p_vci_ini.plen    = 4 ;
4315        p_vci_ini.eop     = true;
4316        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4317        break;
4318      case INIT_CMD_SC_UPDT_NLINE:
4319        p_vci_ini.cmdval  = m_llsc_to_init_cmd_inst_fifo.rok();
4320        if(m_llsc_to_init_cmd_inst_fifo.rok()){
4321          if( m_llsc_to_init_cmd_inst_fifo.read() ) {
4322            p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 12);
4323          } else {
4324            p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 8);
4325          }
4326        } else {
4327          p_vci_ini.address = 0;
4328        }
4329        p_vci_ini.wdata   = (uint32_t)r_llsc_to_init_cmd_nline.read();
4330        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32 ) & 0x3);
4331        if(r_llsc_to_init_cmd_is_long.read()){
4332            p_vci_ini.plen    = 4 * 4;
4333        } else {
4334            p_vci_ini.plen    = 4 * 3;
4335        }
4336        p_vci_ini.eop     = false;
4337        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4338        break;
4339      case INIT_CMD_SC_UPDT_INDEX:
4340        p_vci_ini.cmdval  = true;
4341        if( m_llsc_to_init_cmd_inst_fifo.read() ) {
4342          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 12);
4343        } else {
4344          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 8);
4345        }
4346        p_vci_ini.wdata   = r_llsc_to_init_cmd_index.read();
4347        p_vci_ini.be      = 0xF;
4348        if(r_llsc_to_init_cmd_is_long.read()){
4349            p_vci_ini.plen    = 4 * 4;
4350        } else {
4351            p_vci_ini.plen    = 4 * 3;
4352        }
4353        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4354        p_vci_ini.eop     = false;
4355        break;
4356      case INIT_CMD_SC_UPDT_DATA:
4357        p_vci_ini.cmdval  = true;
4358        if( m_llsc_to_init_cmd_inst_fifo.read() ) {
4359          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 12);
4360        } else {
4361          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 8);
4362        }
4363        p_vci_ini.wdata   = r_llsc_to_init_cmd_wdata.read();
4364        p_vci_ini.be      = 0xF;
4365        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4366        if(r_llsc_to_init_cmd_is_long.read()){
4367            p_vci_ini.plen    = 4 * 4;
4368            p_vci_ini.eop     = false;
4369        } else {
4370            p_vci_ini.plen    = 4 * 3;
4371            p_vci_ini.eop     = true;
4372        }
4373        break;
4374      case INIT_CMD_SC_UPDT_DATA_HIGH:
4375        p_vci_ini.cmdval  = true;
4376        if( m_llsc_to_init_cmd_inst_fifo.read() ) {
4377          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 12);
4378        } else {
4379          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 8);
4380        }
4381        p_vci_ini.wdata   = r_llsc_to_init_cmd_wdata_high.read();
4382        p_vci_ini.be      = 0xF;
4383        p_vci_ini.plen    = 4 * 4;
4384        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
4385        p_vci_ini.eop     = true;
4386        break;
4387
4388    } // end switch r_init_cmd_fsm
4389
4390    //////////////////////////////////////////////////////
4391    // Response signals on the p_vci_ini port
4392    //////////////////////////////////////////////////////
4393
4394    if ( r_init_rsp_fsm.read() == INIT_RSP_IDLE ) p_vci_ini.rspack  = true;
4395    else                                          p_vci_ini.rspack  = false;
4396
4397    //////////////////////////////////////////////////////
4398    // Response signals on the p_vci_tgt_cleanup port
4399    //////////////////////////////////////////////////////
4400    p_vci_tgt_cleanup.rspval = false;
4401    p_vci_tgt_cleanup.rsrcid = 0;
4402    p_vci_tgt_cleanup.rdata  = 0;
4403    p_vci_tgt_cleanup.rpktid = 0;
4404    p_vci_tgt_cleanup.rtrdid = 0;
4405    p_vci_tgt_cleanup.rerror = 0;
4406    p_vci_tgt_cleanup.reop   = false;
4407    p_vci_tgt_cleanup.cmdack = false ;
4408
4409    switch(r_cleanup_fsm.read()){
4410      case CLEANUP_IDLE:
4411        {
4412          p_vci_tgt_cleanup.cmdack = true ;
4413          break;
4414        }
4415      case CLEANUP_RSP:
4416        {
4417          p_vci_tgt_cleanup.rspval = true;
4418          p_vci_tgt_cleanup.rdata  = 0;
4419          p_vci_tgt_cleanup.rsrcid = r_cleanup_srcid.read();
4420          p_vci_tgt_cleanup.rpktid = r_cleanup_pktid.read();
4421          p_vci_tgt_cleanup.rtrdid = r_cleanup_trdid.read();
4422          p_vci_tgt_cleanup.rerror = 0;
4423          p_vci_tgt_cleanup.reop   = 1;
4424          break;
4425        }
4426
4427    }
4428
4429  } // end genMoore()
4430
4431}} // end name space
4432
4433// Local Variables:
4434// tab-width: 4
4435// c-basic-offset: 4
4436// c-file-offsets:((innamespace . 0)(inline-open . 0))
4437// indent-tabs-mode: nil
4438// End:
4439
4440// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
4441
Note: See TracBrowser for help on using the repository browser.