source: trunk/modules/vci_mem_cache_v1/caba/source/src/vci_mem_cache_v1.cpp @ 85

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

Add SC randomization to V1

  • 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: 139.4 KB
Line 
1/* -*- c++ -*-
2 * File         : vci_mem_cache_v1.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 choichillon.christophe@gmail.com
28 */
29#include "../include/vci_mem_cache_v1.h"
30
31#define VHDL_ACCURATE
32
33//#define IDEBUG
34//#define DEBUG_VCI_MEM_CACHE 2
35#define RANDOMIZE_SC
36
37namespace soclib { namespace caba {
38
39#ifdef DEBUG_VCI_MEM_CACHE
40  const char *tgt_cmd_fsm_str[] = {
41    "TGT_CMD_IDLE",
42    "TGT_CMD_READ",
43    "TGT_CMD_READ_EOP",
44    "TGT_CMD_WRITE",
45    "TGT_CMD_ATOMIC",
46  };
47  const char *tgt_rsp_fsm_str[] = {
48    "TGT_RSP_READ_IDLE",
49    "TGT_RSP_WRITE_IDLE",
50    "TGT_RSP_LLSC_IDLE",
51    "TGT_RSP_XRAM_IDLE",
52    "TGT_RSP_INIT_IDLE",
53    "TGT_RSP_CLEANUP_IDLE",
54    "TGT_RSP_READ_TEST",
55    "TGT_RSP_READ_WORD",
56    "TGT_RSP_READ_LINE",
57    "TGT_RSP_WRITE",
58    "TGT_RSP_LLSC",
59    "TGT_RSP_XRAM_TEST",
60    "TGT_RSP_XRAM_WORD",
61    "TGT_RSP_XRAM_LINE",
62    "TGT_RSP_INIT",
63    "TGT_RSP_CLEANUP",
64  };
65  const char *init_cmd_fsm_str[] = {
66    "INIT_CMD_INVAL_IDLE",
67    "INIT_CMD_INVAL_SEL",
68    "INIT_CMD_INVAL_NLINE",
69    "INIT_CMD_UPDT_IDLE",
70    "INIT_CMD_UPDT_SEL",
71    "INIT_CMD_BRDCAST",
72    "INIT_CMD_UPDT_NLINE",
73    "INIT_CMD_UPDT_INDEX",
74    "INIT_CMD_UPDT_DATA",
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_RSP",
87    "READ_TRT_LOCK",
88    "READ_TRT_SET",
89    "READ_XRAM_REQ",
90  };
91  const char *write_fsm_str[] = {
92    "WRITE_IDLE",
93    "WRITE_NEXT",
94    "WRITE_DIR_LOCK",
95    "WRITE_DIR_HIT_READ",
96    "WRITE_DIR_HIT",
97    "WRITE_DIR_HIT_RSP",
98    "WRITE_UPT_LOCK",
99    "WRITE_WAIT_UPT",
100    "WRITE_UPDATE",
101    "WRITE_RSP",
102    "WRITE_TRT_LOCK",
103    "WRITE_TRT_DATA",
104    "WRITE_TRT_SET",
105    "WRITE_WAIT_TRT",
106    "WRITE_XRAM_REQ",
107    "WRITE_TRT_WRITE_LOCK",
108    "WRITE_INVAL_LOCK",
109    "WRITE_DIR_INVAL",
110    "WRITE_INVAL",
111    "WRITE_XRAM_SEND",
112  };
113  const char *ixr_rsp_fsm_str[] = {
114    "IXR_RSP_IDLE",
115    "IXR_RSP_ACK",
116    "IXR_RSP_TRT_ERASE",
117    "IXR_RSP_TRT_READ",
118  };
119  const char *xram_rsp_fsm_str[] = {
120    "XRAM_RSP_IDLE",
121    "XRAM_RSP_TRT_COPY",
122    "XRAM_RSP_TRT_DIRTY",
123    "XRAM_RSP_DIR_LOCK",
124    "XRAM_RSP_DIR_UPDT",
125    "XRAM_RSP_DIR_RSP",
126    "XRAM_RSP_INVAL_LOCK",
127    "XRAM_RSP_INVAL_WAIT",
128    "XRAM_RSP_INVAL",
129    "XRAM_RSP_WRITE_DIRTY",
130  };
131  const char *ixr_cmd_fsm_str[] = {
132    "IXR_CMD_READ_IDLE",
133    "IXR_CMD_WRITE_IDLE",
134    "IXR_CMD_LLSC_IDLE",
135    "IXR_CMD_XRAM_IDLE",
136    "IXR_CMD_READ_NLINE",
137    "IXR_CMD_WRITE_NLINE",
138    "IXR_CMD_LLSC_NLINE",
139    "IXR_CMD_XRAM_DATA",
140  };
141  const char *llsc_fsm_str[] = {
142    "LLSC_IDLE",
143    "LL_DIR_LOCK",
144    "LL_DIR_HIT",
145    "LL_RSP",
146    "SC_DIR_LOCK",
147    "SC_DIR_HIT",
148    "SC_RSP_FALSE",
149    "SC_RSP_TRUE",
150    "LLSC_TRT_LOCK",
151    "LLSC_TRT_SET",
152    "LLSC_XRAM_REQ",
153  };
154  const char *cleanup_fsm_str[] = {
155    "CLEANUP_IDLE",
156    "CLEANUP_DIR_LOCK",
157    "CLEANUP_DIR_WRITE",
158    "CLEANUP_UPT_LOCK",
159    "CLEANUP_UPT_WRITE",
160    "CLEANUP_WRITE_RSP",
161    "CLEANUP_RSP",
162  };
163  const char *alloc_dir_fsm_str[] = {
164    "ALLOC_DIR_READ",
165    "ALLOC_DIR_WRITE",
166    "ALLOC_DIR_LLSC",
167    "ALLOC_DIR_CLEANUP",
168    "ALLOC_DIR_XRAM_RSP",
169  };
170  const char *alloc_trt_fsm_str[] = {
171    "ALLOC_TRT_READ",
172    "ALLOC_TRT_WRITE",
173    "ALLOC_TRT_LLSC",
174    "ALLOC_TRT_XRAM_RSP",
175    "ALLOC_TRT_IXR_RSP",
176  };
177  const char *alloc_upt_fsm_str[] = {
178    "ALLOC_UPT_WRITE",
179    "ALLOC_UPT_XRAM_RSP",
180    "ALLOC_UPT_INIT_RSP",
181    "ALLOC_UPT_CLEANUP",
182  };
183#endif
184
185#define tmpl(x) template<typename vci_param> x VciMemCacheV1<vci_param>
186
187  using soclib::common::uint32_log2;
188
189  ////////////////////////////////
190  //    Constructor
191  ////////////////////////////////
192
193  tmpl(/**/)::VciMemCacheV1(
194      sc_module_name name,
195      const soclib::common::MappingTable &mtp,
196      const soclib::common::MappingTable &mtc,
197      const soclib::common::MappingTable &mtx,
198      const soclib::common::IntTab &vci_ixr_index,
199      const soclib::common::IntTab &vci_ini_index,
200      const soclib::common::IntTab &vci_tgt_index,
201      const soclib::common::IntTab &vci_tgt_index_cleanup,
202      size_t nways,
203      size_t nsets,
204      size_t nwords)
205
206    : soclib::caba::BaseModule(name),
207
208    p_clk("clk"),
209    p_resetn("resetn"),
210    p_vci_tgt("vci_tgt"),
211    p_vci_tgt_cleanup("vci_tgt_cleanup"),
212    p_vci_ini("vci_ini"),
213    p_vci_ixr("vci_ixr"),
214
215    m_initiators( 32 ),
216    m_ways( nways ),
217    m_sets( nsets ),
218    m_words( nwords ),
219    m_srcid_ixr( mtx.indexForId(vci_ixr_index) ),
220    m_srcid_ini( mtc.indexForId(vci_ini_index) ),
221    m_seglist(mtp.getSegmentList(vci_tgt_index)),
222    m_cseglist(mtc.getSegmentList(vci_tgt_index_cleanup)),
223    m_coherence_table( mtc.getCoherenceTable<vci_addr_t>() ),
224    m_atomic_tab( m_initiators ),
225    m_transaction_tab( TRANSACTION_TAB_LINES, nwords ),
226    m_update_tab( UPDATE_TAB_LINES ),
227    m_cache_directory( nways, nsets, nwords, vci_param::N ),
228#define L2 soclib::common::uint32_log2
229    m_x( L2(m_words), 2),
230    m_y( L2(m_sets), L2(m_words) + 2),
231    m_z( vci_param::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
232    m_nline( vci_param::N - L2(m_words) - 2, L2(m_words) + 2),
233#undef L2
234
235    //  FIFOs
236    m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
237    m_cmd_read_word_fifo("m_cmd_read_word_fifo", 4),
238    m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
239    m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
240    m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
241
242    m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
243    m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
244    m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
245    m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
246    m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
247    m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
248    m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
249
250    m_cmd_llsc_addr_fifo("m_cmd_llsc_addr_fifo",4),
251    m_cmd_llsc_sc_fifo("m_cmd_llsc_sc_fifo",4),
252    m_cmd_llsc_srcid_fifo("m_cmd_llsc_srcid_fifo",4),
253    m_cmd_llsc_trdid_fifo("m_cmd_llsc_trdid_fifo",4),
254    m_cmd_llsc_pktid_fifo("m_cmd_llsc_pktid_fifo",4),
255    m_cmd_llsc_wdata_fifo("m_cmd_llsc_wdata_fifo",4),
256
257    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
258    nseg(0),   
259    ncseg(0),   
260    r_read_fsm("r_read_fsm"),
261    r_write_fsm("r_write_fsm"),
262    r_init_rsp_fsm("r_init_rsp_fsm"),
263    r_cleanup_fsm("r_cleanup_fsm"),
264    r_llsc_fsm("r_llsc_fsm"),
265    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
266    r_xram_rsp_fsm("r_xram_rsp_fsm"),
267    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
268    r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
269    r_init_cmd_fsm("r_init_cmd_fsm"),
270    r_alloc_dir_fsm("r_alloc_dir_fsm"),
271    r_alloc_trt_fsm("r_alloc_trt_fsm"),
272    r_alloc_upt_fsm("r_alloc_upt_fsm")
273    {
274      assert(IS_POW_OF_2(nsets));
275      assert(IS_POW_OF_2(nwords));
276      assert(IS_POW_OF_2(nways));
277      assert(nsets);
278      assert(nwords);
279      assert(nways);
280      assert(nsets <= 1024);
281      assert(nwords <= 32);
282      assert(nways <= 32);
283
284
285      // Get the segments associated to the MemCache
286      std::list<soclib::common::Segment>::iterator seg;
287
288      for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++) {
289        nseg++;
290      }
291      for(seg = m_cseglist.begin(); seg != m_cseglist.end() ; seg++) {
292        ncseg++;
293      }
294
295      m_seg = new soclib::common::Segment*[nseg];
296      size_t i = 0;
297      for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) {
298        m_seg[i] = &(*seg);
299        i++;
300      }
301      m_cseg = new soclib::common::Segment*[ncseg];
302      i = 0;
303      for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) {
304          m_cseg[i] = &(*seg);
305          i++;
306      }
307
308      // Memory cache allocation & initialisation
309      m_cache_data = new data_t**[nways];
310      for ( size_t i=0 ; i<nways ; ++i ) {
311        m_cache_data[i] = new data_t*[nsets];
312      }
313      for ( size_t i=0; i<nways; ++i ) {
314        for ( size_t j=0; j<nsets; ++j ) {
315          m_cache_data[i][j] = new data_t[nwords];
316          for ( size_t k=0; k<nwords; k++){
317            m_cache_data[i][j][k]=0;
318          }     
319        }
320      }
321
322      // Allocation for IXR_RSP FSM
323      r_ixr_rsp_to_xram_rsp_rok     = new sc_signal<bool>[TRANSACTION_TAB_LINES];
324
325      // Allocation for XRAM_RSP FSM
326      r_xram_rsp_victim_data        = new sc_signal<data_t>[nwords];
327      r_xram_rsp_to_tgt_rsp_data    = new sc_signal<data_t>[nwords];
328      r_xram_rsp_to_tgt_rsp_val     = new sc_signal<bool>[nwords];
329      r_xram_rsp_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
330
331      // Allocation for READ FSM
332      r_read_data                               = new sc_signal<data_t>[nwords];
333      r_read_to_tgt_rsp_data            = new sc_signal<data_t>[nwords];
334      r_read_to_tgt_rsp_val             = new sc_signal<bool>[nwords];
335
336      // Allocation for WRITE FSM
337      r_write_data                              = new sc_signal<data_t>[nwords];
338      r_write_be                                = new sc_signal<be_t>[nwords];
339      r_write_to_init_cmd_data          = new sc_signal<data_t>[nwords];
340      r_write_to_init_cmd_we            = new sc_signal<bool>[nwords];
341      r_write_to_ixr_cmd_data       = new sc_signal<data_t>[nwords];
342
343      // Simulation
344
345      SC_METHOD(transition);
346      dont_initialize();
347      sensitive << p_clk.pos();
348
349      SC_METHOD(genMoore);
350      dont_initialize();
351      sensitive << p_clk.neg();
352
353    } // end constructor
354
355  /////////////////////////////////////////
356  // This function prints the statistics
357  /////////////////////////////////////////
358
359  tmpl(void)::print_stats()
360  {
361    std::cout << "----------------------------------" << std::dec << std::endl;
362    std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl
363      << "- READ RATE            = " << (double)m_cpt_read/m_cpt_cycles << std::endl
364      << "- READ MISS RATE       = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
365      << "- WRITE RATE           = " << (double)m_cpt_write/m_cpt_cycles << std::endl
366      << "- WRITE MISS RATE      = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
367      << "- WRITE BURST LENGTH   = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
368      << "- UPDATE RATE          = " << (double)m_cpt_update/m_cpt_cycles << std::endl
369      << "- UPDATE ARITY         = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
370      << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
371      << "- INVAL MULTICAST ARITY= " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
372      << "- INVAL BROADCAST RATE = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
373      << "- SAVE DIRTY RATE      = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
374      << "- CLEANUP RATE         = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
375      << "- LL RATE              = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
376      << "- SC RATE              = " << (double)m_cpt_sc/m_cpt_cycles << std::endl;
377  }
378
379  /////////////////////////////////
380  tmpl(/**/)::~VciMemCacheV1()
381    /////////////////////////////////
382  {
383    for(size_t i=0; i<m_ways ; i++){
384      for(size_t j=0; j<m_sets ; j++){
385        delete [] m_cache_data[i][j];
386      }
387    }
388    for(size_t i=0; i<m_ways ; i++){
389      delete [] m_cache_data[i];
390    }
391    delete [] m_cache_data;
392    delete [] m_coherence_table;
393
394    delete [] r_ixr_rsp_to_xram_rsp_rok;
395
396    delete [] r_xram_rsp_victim_data;
397    delete [] r_xram_rsp_to_tgt_rsp_data;
398    delete [] r_xram_rsp_to_tgt_rsp_val;
399    delete [] r_xram_rsp_to_ixr_cmd_data;
400
401    delete [] r_read_data;
402    delete [] r_read_to_tgt_rsp_data;
403    delete [] r_read_to_tgt_rsp_val;
404
405    delete [] r_write_data;
406    delete [] r_write_be;
407    delete [] r_write_to_init_cmd_data;
408  }
409
410  //////////////////////////////////
411  tmpl(void)::transition()
412    //////////////////////////////////
413  {
414    using soclib::common::uint32_log2;
415    //  RESET         
416    if ( ! p_resetn.read() ) {
417
418      //     Initializing FSMs
419      r_tgt_cmd_fsm     = TGT_CMD_IDLE;
420      r_tgt_rsp_fsm     = TGT_RSP_READ_IDLE;
421      r_init_cmd_fsm    = INIT_CMD_INVAL_IDLE;
422      r_init_rsp_fsm    = INIT_RSP_IDLE;
423      r_read_fsm        = READ_IDLE;
424      r_write_fsm       = WRITE_IDLE;
425      r_llsc_fsm        = LLSC_IDLE;
426      r_cleanup_fsm     = CLEANUP_IDLE;
427      r_alloc_dir_fsm   = ALLOC_DIR_READ;
428      r_alloc_trt_fsm   = ALLOC_TRT_READ;
429      r_alloc_upt_fsm   = ALLOC_UPT_WRITE;
430      r_ixr_rsp_fsm     = IXR_RSP_IDLE;
431      r_xram_rsp_fsm    = XRAM_RSP_IDLE;
432      r_ixr_cmd_fsm     = IXR_CMD_READ_IDLE;
433
434      //  Initializing Tables
435      m_cache_directory.init();
436      m_atomic_tab.init();     
437      m_transaction_tab.init();
438
439      // initializing FIFOs and communication Buffers
440
441      m_cmd_read_addr_fifo.init();
442      m_cmd_read_word_fifo.init();
443      m_cmd_read_srcid_fifo.init();
444      m_cmd_read_trdid_fifo.init();
445      m_cmd_read_pktid_fifo.init();
446
447      m_cmd_write_addr_fifo.init();
448      m_cmd_write_eop_fifo.init();
449      m_cmd_write_srcid_fifo.init();
450      m_cmd_write_trdid_fifo.init();
451      m_cmd_write_pktid_fifo.init();
452      m_cmd_write_data_fifo.init();
453
454      m_cmd_llsc_addr_fifo.init();
455      m_cmd_llsc_srcid_fifo.init();
456      m_cmd_llsc_trdid_fifo.init();
457      m_cmd_llsc_pktid_fifo.init();
458      m_cmd_llsc_wdata_fifo.init();
459      m_cmd_llsc_sc_fifo.init();
460
461      r_read_to_tgt_rsp_req         = false;
462      r_read_to_ixr_cmd_req         = false;
463
464      r_write_to_tgt_rsp_req    = false;
465      r_write_to_ixr_cmd_req    = false;
466      r_write_to_init_cmd_req   = false;
467
468      r_cleanup_to_tgt_rsp_req  = false;
469
470      r_init_rsp_to_tgt_rsp_req = false;
471
472      r_llsc_lfsr                       = -1;
473      r_llsc_to_tgt_rsp_req         = false;
474      r_llsc_to_ixr_cmd_req         = false;
475
476      for(size_t i=0; i<TRANSACTION_TAB_LINES ; i++){
477        r_ixr_rsp_to_xram_rsp_rok[i] = false;
478      }
479
480      r_xram_rsp_to_tgt_rsp_req     = false;
481      r_xram_rsp_to_init_cmd_req    = false;
482      r_xram_rsp_to_ixr_cmd_req     = false;
483      r_xram_rsp_trt_index              = 0;
484
485      r_ixr_cmd_cpt         = 0;
486
487      r_copies_limit        = 3;
488
489      // Activity counters
490      m_cpt_cycles                  = 0;
491      m_cpt_read                    = 0;
492      m_cpt_read_miss       = 0;
493      m_cpt_write                   = 0;
494      m_cpt_write_miss      = 0;
495      m_cpt_write_cells     = 0;
496      m_cpt_write_dirty     = 0;
497      m_cpt_update                  = 0;
498      m_cpt_update_mult     = 0;
499      m_cpt_inval_brdcast       = 0;
500      m_cpt_inval                   = 0;
501      m_cpt_inval_mult          = 0;
502      m_cpt_cleanup                 = 0;
503      m_cpt_ll                      = 0;
504      m_cpt_sc                      = 0;
505
506      return;
507    }
508
509    bool    cmd_read_fifo_put = false;
510    bool    cmd_read_fifo_get = false;
511
512    bool    cmd_write_fifo_put = false;
513    bool    cmd_write_fifo_get = false;
514
515    bool    cmd_llsc_fifo_put = false;
516    bool    cmd_llsc_fifo_get = false;
517
518#if DEBUG_VCI_MEM_CACHE == 1
519    std::cout << "---------------------------------------------" << std::dec << std::endl;
520    std::cout << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
521      << " - TGT_CMD FSM   = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
522      << " - TGT_RSP FSM   = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
523      << " - INIT_CMD FSM  = " << init_cmd_fsm_str[r_init_cmd_fsm] << std::endl
524      << " - INIT_RSP FSM  = " << init_rsp_fsm_str[r_init_rsp_fsm] << std::endl
525      << " - READ FSM      = " << read_fsm_str[r_read_fsm] << std::endl
526      << " - WRITE FSM     = " << write_fsm_str[r_write_fsm] << std::endl
527      << " - LLSC FSM      = " << llsc_fsm_str[r_llsc_fsm] << std::endl
528      << " - CLEANUP FSM   = " << cleanup_fsm_str[r_cleanup_fsm] << std::endl
529      << " - IXR_CMD FSM   = " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] << std::endl
530      << " - IXR_RSP FSM   = " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] << std::endl
531      << " - XRAM_RSP FSM  = " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl
532      << " - ALLOC_DIR FSM = " << alloc_dir_fsm_str[r_alloc_dir_fsm] << std::endl
533      << " - ALLOC_TRT FSM = " << alloc_trt_fsm_str[r_alloc_trt_fsm] << std::endl
534      << " - ALLOC_UPT FSM = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl;
535#elif DEBUG_VCI_MEM_CACHE == 2
536    std::cout << "---------------------------------------------" << std::dec << std::endl;
537    std::cout << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
538      << " - TGT_CMD FSM   = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
539      << " - TGT_RSP FSM   = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
540      << " - INIT_CMD FSM  = " << init_cmd_fsm_str[r_init_cmd_fsm] << std::endl
541      << " - INIT_RSP FSM  = " << init_rsp_fsm_str[r_init_rsp_fsm] << std::endl
542      << " - READ FSM      = " << read_fsm_str[r_read_fsm] << std::endl
543      << " - WRITE FSM     = " << write_fsm_str[r_write_fsm] << std::endl
544      << " - LLSC FSM      = " << llsc_fsm_str[r_llsc_fsm] << std::endl
545      << " - CLEANUP FSM   = " << cleanup_fsm_str[r_cleanup_fsm] << std::endl
546      << " - IXR_CMD FSM   = " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] << std::endl
547      << " - IXR_RSP FSM   = " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] << std::endl
548      << " - XRAM_RSP FSM  = " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl
549      << " - ALLOC_DIR FSM = " << alloc_dir_fsm_str[r_alloc_dir_fsm] << std::endl
550      << " - ALLOC_TRT FSM = " << alloc_trt_fsm_str[r_alloc_trt_fsm] << std::endl
551      << " - ALLOC_UPT FSM = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl;
552    std::cout << " - UPDATE/INVAL TABLE : " << std::endl;
553    m_update_tab.print();
554    std::cout << " - TRANSACTION TABLE = : " << std::endl;
555    for (unsigned int i = 0 ; i < m_transaction_tab.size() ; i++){
556      m_transaction_tab.print(i);
557    }
558#endif
559
560
561
562    ////////////////////////////////////////////////////////////////////////////////////
563    //          TGT_CMD FSM
564    ////////////////////////////////////////////////////////////////////////////////////
565    // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
566    //
567    // There is 4 types of packets for the m_mem_segment :
568    // - READ    : a READ request has a length of 1 VCI cell. It can be a single word
569    //             or an entire cache line, depending on the PLEN value.
570    // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
571    //             concern words in a same line.
572    // - LL      : The LL request has a length of 1 cell.
573    // - SC      : The SC request has a length of 1 cell.
574    //             The WDATA field contains the data to write.
575    //
576    ////////////////////////////////////////////////////////////////////////////////////
577
578    switch ( r_tgt_cmd_fsm.read() ) {
579
580      //////////////////
581      case TGT_CMD_IDLE:
582        {
583          if ( p_vci_tgt.cmdval ) {
584            assert( (p_vci_tgt.srcid.read() < m_initiators)
585                && "VCI_MEM_CACHE error in VCI_MEM_CACHE : The received SRCID is larger than 31");
586
587            bool reached = false;
588            for ( size_t index = 0 ; index < nseg && !reached ; index++)
589            {
590//              if ( m_seg[index]->contains((addr_t)(p_vci_tgt.address.read())) ) {
591              if ( m_seg[index]->contains(p_vci_tgt.address.read()) ) {
592                reached = true;
593                r_index = index;
594              }
595            }
596
597
598            if ( !reached )
599            {
600              std::cout << "VCI_MEM_CACHE Out of segment access in VCI_MEM_CACHE" << std::endl;
601              std::cout << "Faulty address = " << std::hex << (addr_t)(p_vci_tgt.address.read()) << std::endl;
602              std::cout << "Faulty initiator = " << std::dec << p_vci_tgt.srcid.read() << std::endl;
603              exit(0);
604            }
605            else if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ )
606            {
607              r_tgt_cmd_fsm = TGT_CMD_READ;
608            }
609            else if (( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )) //&& ( p_vci_tgt.trdid.read() == 0x0 ))
610            { 
611              r_tgt_cmd_fsm = TGT_CMD_WRITE;
612            }
613            else if ((p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) ||
614                (p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND) )
615            {
616              r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
617            }
618          }
619          break;
620        }
621        //////////////////
622      case TGT_CMD_READ:
623
624        {
625          assert(((p_vci_tgt.plen.read() == 4) || (p_vci_tgt.plen.read() == m_words*4))
626              && "VCI_MEM_CACHE All read request to the MemCache must have PLEN = 4 or PLEN = 4*nwords");
627
628          if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() ) {
629            cmd_read_fifo_put = true;
630            if ( p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
631            else                  r_tgt_cmd_fsm = TGT_CMD_READ_EOP;             
632          }
633          break;
634        }
635        //////////////////////
636      case TGT_CMD_READ_EOP:
637        {
638          if ( p_vci_tgt.cmdval && p_vci_tgt.eop ){
639            r_tgt_cmd_fsm = TGT_CMD_IDLE;
640          }
641          break;
642        }
643        ///////////////////
644      case TGT_CMD_WRITE:
645        {
646
647          if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() ) {
648            cmd_write_fifo_put = true;
649            if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
650
651          }
652          break;
653        }
654        ////////////////////
655      case TGT_CMD_ATOMIC:
656        {
657          assert(p_vci_tgt.eop && "Memory Cache Error: LL or SC command with length > 1 ");
658
659          if ( p_vci_tgt.cmdval && m_cmd_llsc_addr_fifo.wok() ) {
660            cmd_llsc_fifo_put = true;
661            r_tgt_cmd_fsm = TGT_CMD_IDLE;
662          }
663          break;
664        }
665    } // end switch tgt_cmd_fsm
666
667    /////////////////////////////////////////////////////////////////////////
668    //          INIT_RSP FSM
669    /////////////////////////////////////////////////////////////////////////
670    // This FSM controls the response to the update or invalidate requests
671    // sent by the memory cache to the L1 caches :
672    //
673    // - update request initiated by the WRITE FSM. 
674    //   The FSM decrements the proper entry in the Update/Inval Table.
675    //   It sends a request to the TGT_RSP FSM to complete the pending
676    //   write transaction (acknowledge response to the writer processor),
677    //   and clear the UPT entry when all responses have been received. 
678    // - invalidate request initiated by the XRAM_RSP FSM.
679    //   The FSM decrements the proper entry in the Update/Inval_Table,
680    //   and clear the entry when all responses have been received.
681    //
682    // All those response packets are one word, compact
683    // packets complying with the VCI advanced format.
684    // The index in the Table is defined in the RTRDID field, and
685    // the Transaction type is defined in the Update/Inval Table.
686    /////////////////////////////////////////////////////////////////////
687
688    switch ( r_init_rsp_fsm.read() ) {
689
690      ///////////////////
691      case INIT_RSP_IDLE:
692        {
693
694          if ( p_vci_ini.rspval ) {
695
696            assert ( ( p_vci_ini.rtrdid.read() < m_update_tab.size() )
697                && "VCI_MEM_CACHE UPT index too large in VCI response paquet received by memory cache" );
698            assert ( p_vci_ini.reop
699                && "VCI_MEM_CACHE All response packets to update/invalidate requests must be one cell" );
700            r_init_rsp_upt_index = p_vci_ini.rtrdid.read();
701            r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
702          }
703          break;
704        }
705        ///////////////////////
706      case INIT_RSP_UPT_LOCK:   // decrement the number of expected responses
707        {
708
709          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) {
710            size_t count = 0;
711            bool valid  = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
712#ifdef IDEBUG
713        std::cout << sc_time_stamp() << " " << name() << " INIT_RSP_UPT_LOCK update table : " << std::endl;
714        m_update_tab.print();
715#endif
716            assert ( valid
717                && "VCI_MEM_CACHE Invalid UPT entry in VCI response paquet received by memory cache" );
718
719            if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
720            else              r_init_rsp_fsm = INIT_RSP_IDLE;
721          }
722          break;
723        }
724        ////////////////////////
725      case INIT_RSP_UPT_CLEAR:  // clear the UPT entry
726        {
727          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) {
728            r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
729            r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
730            r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
731            r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
732            bool need_rsp = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
733            if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
734            else            r_init_rsp_fsm = INIT_RSP_IDLE;
735            m_update_tab.clear(r_init_rsp_upt_index.read());
736#ifdef IDEBUG
737        std::cout << sc_time_stamp() << " " << name() << " INIT_RSP_UPT_CLEAR update table : " << std::endl;
738        m_update_tab.print();
739#endif
740          }
741          break;
742        }
743        //////////////////
744      case INIT_RSP_END:
745        {
746
747          if ( !r_init_rsp_to_tgt_rsp_req ) {
748            r_init_rsp_to_tgt_rsp_req = true;
749            r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
750            r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
751            r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
752            r_init_rsp_fsm = INIT_RSP_IDLE;
753          }
754          break;
755        }
756    } // end switch r_init_rsp_fsm
757
758    ////////////////////////////////////////////////////////////////////////////////////
759    //          READ FSM
760    ////////////////////////////////////////////////////////////////////////////////////
761    // The READ FSM controls the read requests sent by processors.
762    // It takes the lock protecting the cache directory to check the cache line status:
763    // - In case of HIT, the fsm copies the data (one line, or one single word)
764    //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
765    //   The requesting initiator is registered in the cache directory.
766    // - In case of MISS, the READ fsm takes the lock protecting the transaction tab.
767    //   If a read transaction to the XRAM for this line already exists,
768    //   or if the transaction tab is full, the fsm is stalled.
769    //   If a transaction entry is free, the READ fsm sends a request to the XRAM.
770    ////////////////////////////////////////////////////////////////////////////////////
771
772    switch ( r_read_fsm.read() ) {
773
774      ///////////////
775      case READ_IDLE:
776        {
777          if (m_cmd_read_addr_fifo.rok()) {
778            m_cpt_read++;
779#ifdef VHDL_ACCURATE
780            r_read_pass = false;
781#endif
782            r_read_fsm = READ_DIR_LOCK;
783          }
784          break;
785        }
786        ///////////////////
787      case READ_DIR_LOCK:       // check directory for hit / miss
788        {
789          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
790#ifdef VHDL_ACCURATE
791            if(!r_read_pass.read()){
792#endif
793              size_t way = 0;
794              DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
795#ifdef IDEBUG
796           std::cout << "In READ_DIR_LOCK printing the entry of address is : " << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
797           entry.print();
798           std::cout << "done" << std::endl;
799#endif
800
801              r_read_is_cnt   = entry.is_cnt;
802              r_read_dirty    = entry.dirty;
803              r_read_tag          = entry.tag;
804              r_read_lock         = entry.lock;
805              r_read_way          = way;
806              r_read_word         = m_cmd_read_word_fifo.read();
807              r_read_d_copies = entry.d_copies;
808              r_read_i_copies = entry.i_copies;
809              r_read_count    = entry.count;
810#ifdef VHDL_ACCURATE
811              r_read_pass     = true;
812#endif
813
814              // In case of hit, the read acces must be registered in the copies bit-vector
815              if( entry.valid )  {
816                r_read_fsm = READ_DIR_LOCK;
817              } else {
818                r_read_fsm = READ_TRT_LOCK;
819                m_cpt_read_miss++;
820              }
821
822#ifdef VHDL_ACCURATE
823            } else {
824              r_read_pass = false;
825              r_read_fsm = READ_DIR_HIT;
826            }
827#endif
828          }
829          break;
830        }
831        //////////////////
832      case READ_DIR_HIT:        // read hit : update the memory cache
833        {
834          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
835            // signals generation
836            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
837            bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
838            bool is_cnt = ((r_read_count.read() >= r_copies_limit.read()) && cached_read) || r_read_is_cnt.read();
839
840            // read data in the cache
841            size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
842            size_t way = r_read_way.read();
843            for ( size_t i=0 ; i<m_words ; i++ ) {
844              r_read_data[i] = m_cache_data[way][set][i];
845            }
846
847            // update the cache directory (for the copies)
848            DirectoryEntry entry;
849            entry.valid   = true;
850            entry.is_cnt  = is_cnt; // when we reach the limit of copies
851            entry.dirty   = r_read_dirty.read();
852            entry.tag     = r_read_tag.read();
853            entry.lock    = r_read_lock.read();
854            if(cached_read){  // Cached read, we update the copies vector
855              if(inst_read && !is_cnt){ // Instruction read, vector mode
856                assert(!(r_read_i_copies.read() & (0x1 << m_cmd_read_srcid_fifo.read())) && "MemCache Error : processor read on an already owned cache line");
857                entry.d_copies  = r_read_d_copies.read();
858                entry.i_copies  = r_read_i_copies.read() | (0x1 << m_cmd_read_srcid_fifo.read());
859                entry.count     = r_read_count.read() + 1;
860              }
861              if(!inst_read && !is_cnt){ // Data read, vector mode
862                assert(!(r_read_d_copies.read() & (0x1 << m_cmd_read_srcid_fifo.read())) && "MemCache Error : processor read on an already owned cache line");
863                entry.d_copies  = r_read_d_copies.read() | (0x1 << m_cmd_read_srcid_fifo.read());
864                entry.i_copies  = r_read_i_copies.read();
865                entry.count     = r_read_count.read() + 1;
866              }
867              if( is_cnt ) { // Counter mode
868                entry.count     = r_read_count.read() + 1;
869                entry.d_copies  = 0;
870                entry.i_copies  = 0;
871              }
872            } else { // Uncached read
873              entry.d_copies = r_read_d_copies.read();
874              entry.i_copies = r_read_i_copies.read();
875              entry.count    = r_read_count.read();
876            }
877#ifdef IDEBUG
878           std::cout << "In READ_DIR_HIT printing the entry of address is : " << std::endl;
879           entry.print();
880           std::cout << "done" << std::endl;
881#endif
882
883            m_cache_directory.write(set, way, entry);
884            r_read_fsm    = READ_RSP;
885          }
886          break;
887        }
888        //////////////
889      case READ_RSP:            //  request the TGT_RSP FSM to return data
890        {
891          if( !r_read_to_tgt_rsp_req ) {       
892            for ( size_t i=0 ; i<m_words ; i++ ) {
893              r_read_to_tgt_rsp_data[i] = r_read_data[i];
894              if ( r_read_word ) {      // single word
895                r_read_to_tgt_rsp_val[i] = (i == m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())]);
896              } else {                  // cache line
897                r_read_to_tgt_rsp_val[i] = true;
898              }
899            }
900            cmd_read_fifo_get           = true;
901            r_read_to_tgt_rsp_req       = true;
902            r_read_to_tgt_rsp_srcid     = m_cmd_read_srcid_fifo.read();
903            r_read_to_tgt_rsp_trdid     = m_cmd_read_trdid_fifo.read();
904            r_read_to_tgt_rsp_pktid     = m_cmd_read_pktid_fifo.read();
905            r_read_fsm                  = READ_IDLE; 
906          }
907          break;
908        }
909        ///////////////////
910      case READ_TRT_LOCK:       // read miss : check the Transaction Table
911        {
912          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
913#ifdef IDEBUG
914        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_LOCK " << std::endl;
915#endif
916            size_t index = 0;
917            bool   hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())], index);
918            bool   hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())]);
919            bool   wok = !m_transaction_tab.full(index);
920            if( hit_read || !wok || hit_write ) {  // missing line already requested or no space
921              r_read_fsm = READ_IDLE;
922            } else {                       // missing line is requested to the XRAM
923              r_read_trt_index = index;
924              r_read_fsm       = READ_TRT_SET;
925            }
926          }
927          break;
928        }
929        //////////////////
930      case READ_TRT_SET:
931        {
932          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
933            m_transaction_tab.set(r_read_trt_index.read(),
934                true,
935                m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
936                m_cmd_read_srcid_fifo.read(),
937                m_cmd_read_trdid_fifo.read(),
938                m_cmd_read_pktid_fifo.read(),
939                true,
940                m_cmd_read_word_fifo.read(),
941                m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
942                std::vector<be_t>(m_words,0),
943                std::vector<data_t>(m_words,0));
944#ifdef IDEBUG
945        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_SET transaction table : " << std::endl;
946        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
947          m_transaction_tab.print(i);
948#endif
949
950            r_read_fsm   = READ_XRAM_REQ;
951          }
952          break;
953        }
954        /////////////////////
955      case READ_XRAM_REQ:
956        {
957          if( !r_read_to_ixr_cmd_req ) {
958            cmd_read_fifo_get           = true;
959            r_read_to_ixr_cmd_req       = true;
960            r_read_to_ixr_cmd_nline     = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
961            r_read_to_ixr_cmd_trdid     = r_read_trt_index.read();
962            r_read_fsm                            = READ_IDLE;
963          }
964          break;
965        }
966    } // end switch read_fsm
967
968    ///////////////////////////////////////////////////////////////////////////////////
969    //          WRITE FSM
970    ///////////////////////////////////////////////////////////////////////////////////
971    // The WRITE FSM handles the write bursts sent by the processors.
972    // All addresses in a burst must be in the same cache line.
973    // A complete write burst is consumed in the FIFO & copied to a local buffer.
974    // Then the FSM takes the lock protecting the cache directory, to check
975    // if the line is in the cache.
976    //
977    // - In case of HIT, the cache is updated.
978    //   If there is no other copy, an acknowledge response is immediately
979    //   returned to the writing processor.
980    //   if the data is cached by other processoris, the FSM takes the lock
981    //   protecting the Update Table (UPT) to register this update transaction.
982    //   If the UPT is full, it releases the lock  and waits. Then, it sends
983    //   a multi-update request to all owners of the line (but the writer),
984    //   through the INIT_CMD FSM. In case of multi-update transaction, the WRITE FSM
985    //   does not respond to the writing processor, as this response will be sent by
986    //   the INIT_RSP FSM when all update responses have been received.
987    //
988    // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
989    //   table (TRT). If a read transaction to the XRAM for this line already exists,
990    //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
991    //   the WRITE FSM register a new transaction in TRT, and sends a read line request
992    //   to the XRAM. If the TRT is full, it releases the lock, and waits.
993    //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
994    /////////////////////////////////////////////////////////////////////////////////////
995
996    switch ( r_write_fsm.read() ) {
997
998      ////////////////
999      case WRITE_IDLE:  // copy first word of a write burst in local buffer     
1000        {
1001          if ( m_cmd_write_addr_fifo.rok()) {
1002            m_cpt_write++;
1003            m_cpt_write_cells++;
1004            // consume a word in the FIFO & write it in the local buffer
1005            cmd_write_fifo_get  = true;
1006            size_t index            = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
1007            r_write_address         = (addr_t)(m_cmd_write_addr_fifo.read());
1008            r_write_word_index  = index;
1009            r_write_word_count  = 1;
1010            r_write_data[index] = m_cmd_write_data_fifo.read();
1011            r_write_srcid           = m_cmd_write_srcid_fifo.read();
1012            r_write_trdid           = m_cmd_write_trdid_fifo.read();
1013            r_write_pktid           = m_cmd_write_pktid_fifo.read();
1014#ifdef VHDL_ACCURATE
1015            r_write_pass        = false;
1016#endif
1017
1018            // the be field must be set for all words
1019            for ( size_t i=0 ; i<m_words ; i++ ) {
1020              if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
1021              else                      r_write_be[i] = 0x0;
1022            }
1023            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1024                    r_write_byte=true;
1025            else    r_write_byte=false;
1026
1027            if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1028            else                               r_write_fsm = WRITE_NEXT;
1029          }
1030          break;
1031        }
1032        ////////////////
1033      case WRITE_NEXT:  // copy next word of a write burst in local buffer
1034        {
1035          if ( m_cmd_write_addr_fifo.rok() ) {
1036            m_cpt_write_cells++;
1037
1038            // check that the next word is in the same cache line
1039            assert( (m_nline[(vci_addr_t)(r_write_address.read())] == m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())]) 
1040                && "VCI_MEM_CACHE write error in vci_mem_cache : write burst over a line" );
1041            // consume a word in the FIFO & write it in the local buffer
1042            cmd_write_fifo_get=true;
1043            size_t index                = r_write_word_index.read() + r_write_word_count.read();
1044            r_write_be[index]       = m_cmd_write_be_fifo.read();
1045            r_write_data[index]     = m_cmd_write_data_fifo.read();
1046            r_write_word_count      = r_write_word_count.read() + 1;
1047            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
1048              r_write_byte=true;
1049            if ( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
1050          }
1051          break;
1052        }
1053        ////////////////////
1054      case WRITE_DIR_LOCK:      // access directory to check hit/miss
1055        {
1056          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) {
1057#ifdef VHDL_ACCURATE
1058            if (!r_write_pass.read()){
1059#endif
1060              size_t  way = 0;
1061              DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
1062
1063              // copy directory entry in local buffers in case of hit
1064              if ( entry.valid )  {     
1065                r_write_is_cnt    = entry.is_cnt;
1066                r_write_lock      = entry.lock;
1067                r_write_tag       = entry.tag;
1068                r_write_d_copies  = entry.d_copies;
1069                r_write_i_copies  = entry.i_copies;
1070                r_write_count     = entry.count;
1071                r_write_way       = way;
1072                r_write_fsm  = WRITE_DIR_LOCK;
1073                r_write_pass = true;
1074              } else {
1075                r_write_fsm = WRITE_TRT_LOCK;
1076                m_cpt_write_miss++;
1077              }
1078#ifdef VHDL_ACCURATE
1079           } else {
1080             if(r_write_is_cnt.read() && r_write_count.read()){
1081               r_write_fsm     = WRITE_DIR_HIT_READ;
1082             } else {
1083               if(r_write_byte.read())
1084                 r_write_fsm   = WRITE_DIR_HIT_READ;
1085               else {
1086                   bool owner     = (bool) (r_write_d_copies & (0x1 << r_write_srcid.read()));
1087                   bool no_update = (owner && (r_write_count == 1)) || (r_write_count==0);
1088                   if( no_update ) r_write_fsm  = WRITE_DIR_HIT_RSP;
1089                   else            r_write_fsm  = WRITE_DIR_HIT;
1090               }
1091             }
1092             r_write_pass = false;
1093           }
1094#endif
1095          }
1096          break;
1097        }
1098        ///////////////////
1099      case WRITE_DIR_HIT_READ:  // read the cache and complete the buffer (data, when be!=0xF)
1100        {
1101          // update local buffer
1102          size_t set    = m_y[(vci_addr_t)(r_write_address.read())];
1103          size_t way    = r_write_way.read();
1104          for(size_t i=0 ; i<m_words ; i++) {
1105            data_t mask      = 0;
1106            if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
1107            if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
1108            if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
1109            if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
1110            if(r_write_be[i].read()||r_write_is_cnt.read()) { // complete only if mask is not null (for energy consumption)
1111              r_write_data[i]  = (r_write_data[i].read() & mask) |
1112                (m_cache_data[way][set][i] & ~mask);
1113            }
1114          } // end for
1115
1116          if(r_write_is_cnt.read() && r_write_count.read()){
1117            r_write_fsm            = WRITE_TRT_WRITE_LOCK;
1118          } else {
1119              bool owner     = (bool) (r_write_d_copies.read() & (0x1 << r_write_srcid.read()));
1120              bool no_update = (owner && (r_write_count.read() == 1)) || (r_write_count.read()==0);
1121              if( no_update )   r_write_fsm    = WRITE_DIR_HIT_RSP;
1122              else              r_write_fsm    = WRITE_DIR_HIT;
1123          }
1124           break;
1125        }
1126        ///////////////////
1127      case WRITE_DIR_HIT:       // update the cache (data & dirty bit)
1128        {
1129          // update directory with Dirty bit
1130          DirectoryEntry entry;
1131          entry.valid       = true;
1132          entry.dirty       = true;
1133          entry.tag             = r_write_tag.read();
1134          entry.is_cnt      = r_write_is_cnt.read();
1135          entry.lock        = r_write_lock.read();
1136          entry.d_copies    = r_write_d_copies.read();
1137          entry.i_copies    = r_write_i_copies.read();
1138          entry.count       = r_write_count.read();
1139          size_t set        = m_y[(vci_addr_t)(r_write_address.read())];
1140          size_t way        = r_write_way.read();
1141          m_cache_directory.write(set, way, entry);
1142
1143          size_t nb_copies=0;
1144          for(size_t i=0; i<32 ; i++) {
1145            if( r_write_d_copies.read() & (1<<i) )
1146                nb_copies++;
1147          }
1148          for(size_t i=0; i<32 ; i++) {
1149            if( r_write_i_copies.read() & (1<<i) )
1150                nb_copies++;
1151          }
1152          assert((nb_copies == r_write_count.read()) && "MemCache Error, inconsistency in the directory");
1153
1154          // write data in cache
1155          for(size_t i=0 ; i<m_words ; i++) {
1156            if  ( r_write_be[i].read() ) {
1157              m_cache_data[way][set][i]  = r_write_data[i].read();
1158            }
1159          } // end for
1160
1161          // compute the actual number of copies & the modified bit vector
1162          bool owner = (bool) (r_write_d_copies.read() & (0x1 << r_write_srcid.read()));
1163          copy_t d_copies = r_write_d_copies.read() & ~(0x1 << r_write_srcid.read());
1164          r_write_d_copies      = d_copies;
1165          size_t count_signal   = r_write_count.read();
1166          if(owner){
1167            count_signal        = count_signal - 1;
1168          }
1169          r_write_count         = count_signal;
1170
1171          r_write_fsm = WRITE_UPT_LOCK;
1172          break;
1173        }
1174        ///////////////////
1175      case WRITE_DIR_HIT_RSP:   // update the cache (data & dirty bit) (no update)
1176        {
1177          // update directory with Dirty bit
1178          DirectoryEntry entry;
1179          entry.valid       = true;
1180          entry.dirty       = true;
1181          entry.tag             = r_write_tag.read();
1182          entry.is_cnt      = r_write_is_cnt.read();
1183          entry.lock        = r_write_lock.read();
1184          entry.d_copies    = r_write_d_copies.read();
1185          entry.i_copies    = r_write_i_copies.read();
1186          entry.count       = r_write_count.read();
1187          size_t set        = m_y[(vci_addr_t)(r_write_address.read())];
1188          size_t way        = r_write_way.read();
1189          m_cache_directory.write(set, way, entry);
1190
1191          size_t nb_copies=0;
1192          for(size_t i=0; i<32 ; i++) {
1193            if( r_write_d_copies.read() & (1<<i) )
1194                nb_copies++;
1195          }
1196          for(size_t i=0; i<32 ; i++) {
1197            if( r_write_i_copies.read() & (1<<i) )
1198                nb_copies++;
1199          }
1200          assert((nb_copies == r_write_count.read()) && "MemCache Error, inconsistency in the directory");
1201
1202          // write data in cache
1203          for(size_t i=0 ; i<m_words ; i++) {
1204            if  ( r_write_be[i].read() ) {
1205              m_cache_data[way][set][i]  = r_write_data[i].read();
1206            }
1207          } // end for
1208
1209          if ( !r_write_to_tgt_rsp_req.read() ) {
1210            r_write_to_tgt_rsp_req          = true;
1211            r_write_to_tgt_rsp_srcid    = r_write_srcid.read();
1212            r_write_to_tgt_rsp_trdid    = r_write_trdid.read();
1213            r_write_to_tgt_rsp_pktid    = r_write_pktid.read();
1214            r_write_fsm                         = WRITE_IDLE;
1215          } else {
1216            r_write_fsm = WRITE_RSP;
1217          }
1218          break;
1219        }
1220        /////////////////////
1221      case WRITE_UPT_LOCK:      // Try to register the request in Update Table
1222        {
1223
1224          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1225            bool          wok        = false;
1226            size_t        index      = 0;
1227            size_t        srcid      = r_write_srcid.read();
1228            size_t        trdid      = r_write_trdid.read();
1229            size_t        pktid      = r_write_pktid.read();
1230            addr_t            nline      = m_nline[(vci_addr_t)(r_write_address.read())];
1231            size_t        nb_copies  = r_write_count.read();
1232
1233            wok =m_update_tab.set(true, // it's an update transaction
1234                false,                  // it's not a broadcast
1235                true,                   // it needs a response
1236                srcid,
1237                trdid,
1238                pktid,
1239                nline,
1240                nb_copies,
1241                index);
1242#ifdef IDEBUG
1243            if(wok){
1244        std::cout << sc_time_stamp() << " " << name() << " WRITE_UPT_LOCK update table : " << std::endl;
1245        m_update_tab.print();
1246            }
1247#endif
1248            r_write_upt_index = index;
1249            //  releases the lock protecting Update Table if no entry...
1250            if ( wok ) r_write_fsm = WRITE_UPDATE;
1251            else       r_write_fsm = WRITE_WAIT_UPT;
1252          }
1253          break;
1254        }
1255        ////////////////////
1256      case WRITE_WAIT_UPT:      // release the lock protecting UPT
1257        {
1258          r_write_fsm = WRITE_UPT_LOCK;
1259          break;
1260        }
1261        //////////////////
1262      case WRITE_UPDATE:        // send a multi-update request to INIT_CMD fsm
1263        {
1264
1265          if ( !r_write_to_init_cmd_req ) {
1266            r_write_to_init_cmd_req      = true;
1267            r_write_to_init_cmd_brdcast  = false;
1268            r_write_to_init_cmd_trdid    = r_write_upt_index.read();
1269            r_write_to_init_cmd_nline    = m_nline[(vci_addr_t)(r_write_address.read())];
1270            r_write_to_init_cmd_index    = r_write_word_index.read();
1271            r_write_to_init_cmd_count    = r_write_word_count.read();
1272            r_write_to_init_cmd_d_copies = r_write_d_copies.read();
1273            r_write_to_init_cmd_i_copies = r_write_i_copies.read();
1274
1275            for(size_t i=0; i<m_words ; i++){
1276              if(r_write_be[i].read())  r_write_to_init_cmd_we[i]=true;
1277              else                      r_write_to_init_cmd_we[i]=false;
1278            }
1279
1280            size_t min = r_write_word_index.read();
1281            size_t max = r_write_word_index.read() + r_write_word_count.read();
1282            for (size_t i=min ; i<max ; i++) {
1283              r_write_to_init_cmd_data[i] = r_write_data[i];
1284            }
1285            r_write_fsm = WRITE_IDLE; // Response will be sent after receiving
1286            // all update responses
1287          }
1288          break;
1289        }
1290        ///////////////
1291      case WRITE_RSP:           // send a request to TGT_RSP FSM to acknowledge the write
1292        {
1293          if ( !r_write_to_tgt_rsp_req.read() ) {
1294            r_write_to_tgt_rsp_req          = true;
1295            r_write_to_tgt_rsp_srcid    = r_write_srcid.read();
1296            r_write_to_tgt_rsp_trdid    = r_write_trdid.read();
1297            r_write_to_tgt_rsp_pktid    = r_write_pktid.read();
1298            r_write_fsm                         = WRITE_IDLE;
1299          }
1300          break;
1301        }
1302        ////////////////////
1303      case WRITE_TRT_LOCK:      // Miss : check Transaction Table
1304        {
1305          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1306#ifdef IDEBUG
1307        std::cout << sc_time_stamp() << " " << name() << " READ_TRT_LOCK " << std::endl;
1308#endif
1309            size_t hit_index = 0;
1310            size_t wok_index = 0;
1311            bool hit_read  = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(r_write_address.read())],hit_index);
1312            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(r_write_address.read())]);
1313            bool wok = !m_transaction_tab.full(wok_index);
1314            if ( hit_read ) {   // register the modified data in TRT
1315              r_write_trt_index = hit_index;
1316              r_write_fsm       = WRITE_TRT_DATA;
1317            } else if ( wok && !hit_write ) {   // set a new entry in TRT
1318              r_write_trt_index = wok_index;
1319              r_write_fsm       = WRITE_TRT_SET;
1320            } else {            // wait an empty entry in TRT
1321              r_write_fsm       = WRITE_WAIT_TRT;
1322            }
1323          }
1324          break;
1325        }
1326        ////////////////////
1327      case WRITE_WAIT_TRT:      // release the lock protecting TRT
1328        {
1329          r_write_fsm = WRITE_DIR_LOCK;
1330          break;
1331        }
1332        ///////////////////
1333      case WRITE_TRT_SET:       // register a new transaction in TRT (Write Buffer)
1334        { 
1335          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
1336          {
1337            std::vector<be_t> be_vector;
1338            std::vector<data_t> data_vector;
1339            be_vector.clear();
1340            data_vector.clear();
1341            for ( size_t i=0; i<m_words; i++ )
1342            {
1343              be_vector.push_back(r_write_be[i]);
1344              data_vector.push_back(r_write_data[i]);
1345            }
1346            m_transaction_tab.set(r_write_trt_index.read(),
1347                true,                           // read request to XRAM
1348                m_nline[(vci_addr_t)(r_write_address.read())],
1349                r_write_srcid.read(),
1350                r_write_trdid.read(),
1351                r_write_pktid.read(),
1352                false,                          // not a processor read
1353                false,                          // not a single word
1354                0,                                      // word index
1355                be_vector,
1356                data_vector);
1357#ifdef IDEBUG
1358        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_SET transaction table : " << std::endl;
1359        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1360          m_transaction_tab.print(i);
1361#endif
1362
1363            r_write_fsm = WRITE_XRAM_REQ;
1364          }
1365          break;
1366        } 
1367        ///////////////////
1368      case WRITE_TRT_DATA:      // update an entry in TRT (Write Buffer)
1369        {
1370          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1371            std::vector<be_t> be_vector;
1372            std::vector<data_t> data_vector;
1373            be_vector.clear();
1374            data_vector.clear();
1375            for ( size_t i=0; i<m_words; i++ ) {
1376              be_vector.push_back(r_write_be[i]);
1377              data_vector.push_back(r_write_data[i]);
1378            }
1379            m_transaction_tab.write_data_mask(r_write_trt_index.read(),
1380                be_vector,
1381                data_vector);
1382            r_write_fsm = WRITE_RSP;
1383#ifdef IDEBUG
1384        std::cout << sc_time_stamp() << " " << name() << " WRITE_TRT_DATA transaction table : " << std::endl;
1385        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1386          m_transaction_tab.print(i);
1387#endif
1388
1389          }
1390          break;
1391        }
1392        ////////////////////
1393      case WRITE_XRAM_REQ:      // send a request to IXR_CMD FSM
1394        { 
1395
1396          if ( !r_write_to_ixr_cmd_req ) {
1397            r_write_to_ixr_cmd_req   = true;
1398            r_write_to_ixr_cmd_write = false;
1399            r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
1400            r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
1401            r_write_fsm              = WRITE_RSP;
1402          }
1403          break;
1404        }
1405        ////////////////////
1406      case WRITE_TRT_WRITE_LOCK:
1407        {
1408          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
1409            size_t wok_index = 0;
1410            bool wok = !m_transaction_tab.full(wok_index);
1411            if ( wok ) {        // set a new entry in TRT
1412              r_write_trt_index = wok_index;
1413              r_write_fsm       = WRITE_INVAL_LOCK;
1414            } else {            // wait an empty entry in TRT
1415              r_write_fsm       = WRITE_WAIT_TRT;
1416            }
1417          }
1418
1419          break;
1420        }
1421        ////////////////////
1422      case WRITE_INVAL_LOCK:
1423        {
1424          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
1425            bool        wok       = false;
1426            size_t      index     = 0;
1427            size_t      srcid     = r_write_srcid.read();
1428            size_t      trdid     = r_write_trdid.read();
1429            size_t      pktid     = r_write_pktid.read();
1430            addr_t          nline     = m_nline[(vci_addr_t)(r_write_address.read())];
1431            size_t      nb_copies = r_write_count.read();
1432
1433            wok =m_update_tab.set(false,        // it's an inval transaction
1434                true,                       // it's a broadcast
1435                true,                       // it needs a response
1436                srcid,
1437                trdid,
1438                pktid,
1439                nline,
1440                nb_copies,
1441                index);
1442#ifdef IDEBUG
1443            if(wok){
1444        std::cout << sc_time_stamp() << " " << name() << " WRITE_INVAL_LOCK update table : " << std::endl;
1445        m_update_tab.print();
1446            }
1447#endif
1448            r_write_upt_index = index;
1449            //  releases the lock protecting Update Table if no entry...
1450            if ( wok ) r_write_fsm = WRITE_DIR_INVAL;
1451            else       r_write_fsm = WRITE_WAIT_TRT;
1452          }
1453
1454          break;
1455        }
1456        ////////////////////
1457      case WRITE_DIR_INVAL:
1458        {
1459          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) ||
1460              (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) )
1461          {
1462            m_transaction_tab.set(r_write_trt_index.read(),
1463                false,                          // write request to XRAM
1464                m_nline[(vci_addr_t)(r_write_address.read())],
1465                0,
1466                0,
1467                0,
1468                false,                          // not a processor read
1469                false,                          // not a single word
1470                0,                                      // word index
1471                std::vector<be_t>(m_words,0),
1472                std::vector<data_t>(m_words,0));
1473#ifdef IDEBUG
1474        std::cout << sc_time_stamp() << " " << name() << " WRITE_DIR_INVAL transaction table : " << std::endl;
1475        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1476          m_transaction_tab.print(i);
1477#endif
1478
1479            // invalidate directory entry
1480            DirectoryEntry entry;
1481            entry.valid    = false;
1482            entry.dirty    = false;
1483            entry.tag      = 0;
1484            entry.is_cnt   = false;
1485            entry.lock     = false;
1486            entry.d_copies = 0;
1487            entry.i_copies = 0;
1488            entry.count    = 0;
1489            size_t set     = m_y[(vci_addr_t)(r_write_address.read())];
1490            size_t way     = r_write_way.read();
1491            m_cache_directory.write(set, way, entry);
1492
1493            r_write_fsm = WRITE_INVAL;
1494          } else {
1495            assert(false && "LOCK ERROR in WRITE_FSM, STATE = WRITE_DIR_INVAL");
1496          }
1497
1498          break;
1499        }
1500        ////////////////////
1501      case WRITE_INVAL:
1502        {
1503          if ( !r_write_to_init_cmd_req ) {
1504            r_write_to_init_cmd_req      = true;
1505            r_write_to_init_cmd_brdcast  = true;
1506            r_write_to_init_cmd_trdid    = r_write_upt_index.read();
1507            r_write_to_init_cmd_nline    = m_nline[(vci_addr_t)(r_write_address.read())];
1508            r_write_to_init_cmd_index    = 0;
1509            r_write_to_init_cmd_count    = 0;
1510            r_write_to_init_cmd_d_copies = 0;
1511            r_write_to_init_cmd_i_copies = 0;
1512
1513            for(size_t i=0; i<m_words ; i++){
1514              r_write_to_init_cmd_we[i]=false;
1515              r_write_to_init_cmd_data[i] = 0;
1516            }
1517            r_write_fsm = WRITE_XRAM_SEND;
1518            // all update responses
1519          }
1520
1521          break;
1522        }
1523        ////////////////////
1524      case WRITE_XRAM_SEND:
1525        {
1526          if ( !r_write_to_ixr_cmd_req ) {
1527            r_write_to_ixr_cmd_req     = true;
1528            r_write_to_ixr_cmd_write   = true;
1529            r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
1530            r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
1531            for(size_t i=0; i<m_words; i++){
1532              r_write_to_ixr_cmd_data[i] = r_write_data[i];
1533            }
1534            r_write_fsm                 = WRITE_IDLE;
1535          }
1536          break;
1537        }
1538    } // end switch r_write_fsm
1539
1540    ///////////////////////////////////////////////////////////////////////
1541    //          IXR_CMD FSM
1542    ///////////////////////////////////////////////////////////////////////
1543    // The IXR_CMD fsm controls the command packets to the XRAM :
1544    // - It sends a single cell VCI read to the XRAM in case of MISS request
1545    // posted by the READ, WRITE or LLSC FSMs : the TRDID field contains
1546    // the Transaction Tab index.
1547    // The VCI response is a multi-cell packet : the N cells contain
1548    // the N data words.
1549    // - It sends a multi-cell VCI write when the XRAM_RSP FSM request
1550    // to save a dirty line to the XRAM.
1551    // The VCI response is a single cell packet.
1552    // This FSM handles requests from the READ, WRITE, LLSC & XRAM_RSP FSMs
1553    // with a round-robin priority.
1554    ////////////////////////////////////////////////////////////////////////
1555
1556    switch ( r_ixr_cmd_fsm.read() ) {
1557      ////////////////////////
1558      case IXR_CMD_READ_IDLE:
1559        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1560        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1561        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1562        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1563        break;
1564        ////////////////////////
1565      case IXR_CMD_WRITE_IDLE:
1566        if      ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1567        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1568        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1569        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1570        break;
1571        ////////////////////////
1572      case IXR_CMD_LLSC_IDLE:
1573        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1574        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1575        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1576        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1577        break;
1578        ////////////////////////
1579      case IXR_CMD_XRAM_IDLE:
1580        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
1581        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
1582        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
1583        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
1584        break;
1585        /////////////////////////
1586      case IXR_CMD_READ_NLINE:
1587        if ( p_vci_ixr.cmdack ) {
1588          r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;           
1589          r_read_to_ixr_cmd_req = false;
1590        }
1591        break;
1592        //////////////////////////
1593      case IXR_CMD_WRITE_NLINE:
1594        if ( p_vci_ixr.cmdack ) {
1595          if( r_write_to_ixr_cmd_write.read()){
1596            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1597              r_ixr_cmd_cpt = 0;
1598              r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
1599              r_write_to_ixr_cmd_req = false;
1600            } else {
1601              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1602            }
1603          } else {
1604            r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;         
1605            r_write_to_ixr_cmd_req = false;
1606          }
1607        }
1608        break;
1609        /////////////////////////
1610      case IXR_CMD_LLSC_NLINE:
1611        if ( p_vci_ixr.cmdack ) {
1612          r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;           
1613          r_llsc_to_ixr_cmd_req = false;
1614        }
1615        break;
1616        ////////////////////////
1617      case IXR_CMD_XRAM_DATA:
1618        if ( p_vci_ixr.cmdack ) {
1619          if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
1620            r_ixr_cmd_cpt = 0;
1621            r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
1622            r_xram_rsp_to_ixr_cmd_req = false;
1623          } else {
1624            r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
1625          }
1626        }
1627        break;
1628
1629    } // end switch r_ixr_cmd_fsm
1630
1631    ////////////////////////////////////////////////////////////////////////////
1632    //                IXR_RSP FSM
1633    ////////////////////////////////////////////////////////////////////////////
1634    // The IXR_RSP FSM receives the response packets from the XRAM,
1635    // for both write transaction, and read transaction.
1636    //
1637    // - A response to a write request is a single-cell VCI packet.
1638    // The Transaction Tab index is contained in the RTRDID field.
1639    // The FSM takes the lock protecting the TRT, and the corresponding
1640    // entry is erased.
1641    // 
1642    // - A response to a read request is a multi-cell VCI packet.
1643    // The Transaction Tab index is contained in the RTRDID field.
1644    // The N cells contain the N words of the cache line in the RDATA field.
1645    // The FSM takes the lock protecting the TRT to store the line in the TRT
1646    // (taking into account the write requests already stored in the TRT).
1647    // When the line is completely written, the corresponding rok signal is set.
1648    ///////////////////////////////////////////////////////////////////////////////
1649
1650    switch ( r_ixr_rsp_fsm.read() ) {
1651
1652      ///////////////////
1653      case IXR_RSP_IDLE:        // test if it's a read or a write transaction
1654        {
1655          if ( p_vci_ixr.rspval ) {
1656            r_ixr_rsp_cpt   = 0;
1657            r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
1658            if ( p_vci_ixr.reop )  r_ixr_rsp_fsm = IXR_RSP_ACK;
1659            else                   r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
1660          }
1661          break; 
1662        }
1663        ////////////////////////
1664      case IXR_RSP_ACK:        // Acknowledge the vci response
1665        r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
1666        break;
1667        ////////////////////////
1668      case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
1669        {
1670          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP ) {
1671            m_transaction_tab.erase(r_ixr_rsp_trt_index.read());
1672            r_ixr_rsp_fsm = IXR_RSP_IDLE;
1673#ifdef IDEBUG
1674        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_ERASE transaction table : " << std::endl;
1675        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1676          m_transaction_tab.print(i);
1677#endif
1678
1679          }
1680          break;
1681        }
1682        ///////////////////////
1683      case IXR_RSP_TRT_READ:            // write data in the TRT
1684        {
1685          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&  p_vci_ixr.rspval ) {
1686            bool   eop          = p_vci_ixr.reop.read();
1687            data_t data         = p_vci_ixr.rdata.read();
1688            size_t index        = r_ixr_rsp_trt_index.read();
1689            assert( eop == (r_ixr_rsp_cpt.read() == (m_words-1))
1690                && "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
1691            m_transaction_tab.write_rsp(index, r_ixr_rsp_cpt.read(), data);
1692            r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1;
1693            if ( eop ) {
1694#ifdef IDEBUG
1695        std::cout << sc_time_stamp() << " " << name() << " IXR_RSP_TRT_READ transaction table : " << std::endl;
1696        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1697          m_transaction_tab.print(i);
1698#endif
1699
1700              r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
1701              r_ixr_rsp_fsm = IXR_RSP_IDLE;
1702            }
1703          }
1704          break;
1705        }
1706    } // end swich r_ixr_rsp_fsm
1707
1708
1709    ////////////////////////////////////////////////////////////////////////////
1710    //                XRAM_RSP FSM
1711    ////////////////////////////////////////////////////////////////////////////
1712    // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
1713    // The cache line has been written in the TRT buffer by the IXR_FSM.
1714    //
1715    // When a response is available, the corresponding TRT entry
1716    // is copied in a local buffer to be written in the cache.
1717    // Then, the FSM releases the lock protecting the TRT, and takes the lock
1718    // protecting the cache directory.
1719    // It selects a cache slot and writes the line in the cache.
1720    // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
1721    // FSM to return the cache line to the registered processor.
1722    // If there is no empty slot, a victim line is evicted, and
1723    // invalidate requests are sent to the L1 caches containing copies.
1724    // If this line is dirty, the XRAM_RSP FSM send a request to the IXR_CMD
1725    // FSM to save the victim line to the XRAM, and register the write transaction
1726    // in the TRT (using the entry previously used by the read transaction).
1727    ///////////////////////////////////////////////////////////////////////////////
1728
1729    switch ( r_xram_rsp_fsm.read() ) {
1730
1731      ///////////////////
1732      case XRAM_RSP_IDLE:       // test if there is a response with a round robin priority
1733        {
1734          size_t ptr   = r_xram_rsp_trt_index.read();
1735          size_t lines = TRANSACTION_TAB_LINES;
1736          for(size_t i=0; i<lines; i++){
1737            size_t index=(i+ptr+1)%lines;
1738            if(r_ixr_rsp_to_xram_rsp_rok[index]){
1739              r_xram_rsp_trt_index=index;
1740              r_ixr_rsp_to_xram_rsp_rok[index]=false;
1741              r_xram_rsp_fsm           = XRAM_RSP_DIR_LOCK;
1742              break;
1743#ifdef IDEBUG
1744        std::cout << "XRAM_RSP FSM in XRAM_RSP_IDLE state" << std::endl;
1745#endif
1746            }
1747          }
1748          break; 
1749        }
1750        ///////////////////////
1751      case XRAM_RSP_DIR_LOCK:   // Take the lock on the directory
1752        {
1753          if( r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP ) {
1754#ifdef VHDL_ACCURATE
1755            r_xram_rsp_pass          = false;
1756#endif
1757            r_xram_rsp_fsm           = XRAM_RSP_TRT_COPY;
1758#ifdef IDEBUG
1759        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_LOCK state" << std::endl;
1760#endif
1761          }
1762          break;
1763        }
1764        ///////////////////////
1765      case XRAM_RSP_TRT_COPY:           // Copy the TRT entry in the local buffer and eviction of a cache line
1766        {
1767          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) ) {
1768#ifdef VHDL_ACCURATE
1769            if (!r_xram_rsp_pass.read()){
1770#endif
1771              size_t index = r_xram_rsp_trt_index.read();
1772              TransactionTabEntry    trt_entry(m_transaction_tab.read(index)); 
1773
1774              r_xram_rsp_trt_buf.copy(trt_entry);  // TRT entry local buffer
1775
1776              // selects & extracts a victim line from cache
1777              size_t way = 0;
1778              size_t set = m_y[(vci_addr_t)(trt_entry.nline * m_words * 4)];
1779              DirectoryEntry victim(m_cache_directory.select(set, way));
1780
1781              for (size_t i=0 ; i<m_words ; i++) r_xram_rsp_victim_data[i] = m_cache_data[way][set][i];
1782
1783              bool inval = (victim.count && victim.valid) ;
1784
1785              r_xram_rsp_victim_d_copies = victim.d_copies;
1786              r_xram_rsp_victim_i_copies = victim.i_copies;
1787              r_xram_rsp_victim_count    = victim.count;
1788              r_xram_rsp_victim_way      = way;
1789              r_xram_rsp_victim_set      = set;
1790              r_xram_rsp_victim_nline    = victim.tag*m_sets + set;
1791              r_xram_rsp_victim_is_cnt   = victim.is_cnt;
1792              r_xram_rsp_victim_inval    = inval ;
1793              r_xram_rsp_victim_dirty    = victim.dirty;
1794
1795#ifdef VHDL_ACCURATE
1796              r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
1797#else
1798              r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
1799#endif
1800#ifdef IDEBUG
1801        std::cout << "XRAM_RSP FSM in XRAM_RSP_TRT_COPY state" << std::endl;
1802        std::cout << "Victim way : " << std::hex << way << " set " << std::hex << set << std::endl;
1803        victim.print();
1804#endif
1805#ifdef VHDL_ACCURATE
1806                r_xram_rsp_pass = true;
1807              }else{
1808                r_xram_rsp_pass = false;
1809                r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
1810              }
1811#endif
1812          }
1813          break;
1814        }
1815        ///////////////////////
1816      case XRAM_RSP_INVAL_LOCK:
1817        {
1818          if ( r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP ) {
1819#ifdef IDEBUG
1820        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state" << std::endl;
1821#endif
1822            size_t index;
1823            if(m_update_tab.search_inval(r_xram_rsp_trt_buf.nline, index)){
1824              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
1825#ifdef IDEBUG
1826        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
1827#endif
1828
1829            }
1830            else if(m_update_tab.is_full() && r_xram_rsp_victim_inval.read()){
1831              r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
1832#ifdef IDEBUG
1833        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl;
1834#endif
1835            }
1836            else {
1837              r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
1838#ifdef IDEBUG
1839        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_DIR_UPDT state" << std::endl;
1840#endif
1841            }
1842          }
1843          break;
1844        }
1845        ///////////////////////
1846      case XRAM_RSP_INVAL_WAIT:
1847        {
1848          r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
1849          break;
1850#ifdef IDEBUG
1851        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL_WAIT state" << std::endl;
1852#endif
1853        }
1854        ///////////////////////
1855      case XRAM_RSP_DIR_UPDT:           // updates the cache (both data & directory)
1856        {
1857          // signals generation
1858          bool inst_read = (r_xram_rsp_trt_buf.trdid & 0x2) && r_xram_rsp_trt_buf.proc_read; // It is an instruction read
1859          bool cached_read = (r_xram_rsp_trt_buf.trdid & 0x1) && r_xram_rsp_trt_buf.proc_read ;
1860          // update data
1861          size_t set   = r_xram_rsp_victim_set.read();
1862          size_t way   = r_xram_rsp_victim_way.read();
1863          for(size_t i=0; i<m_words ; i++){
1864            m_cache_data[way][set][i] = r_xram_rsp_trt_buf.wdata[i];
1865          }
1866          // compute dirty
1867          bool dirty = false;
1868          for(size_t i=0; i<m_words;i++){
1869            dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0);
1870          }
1871
1872          // update directory
1873          DirectoryEntry entry;
1874          entry.valid     = true;
1875          entry.is_cnt    = false;
1876          entry.lock      = false;
1877          entry.dirty     = dirty;
1878          entry.tag         = r_xram_rsp_trt_buf.nline / m_sets;
1879          if(cached_read) {
1880            if(inst_read) {
1881              entry.i_copies = 0x1 << r_xram_rsp_trt_buf.srcid;
1882              entry.d_copies = 0x0;
1883              entry.count    = 1;
1884            } else {
1885              entry.i_copies = 0x0;
1886              entry.d_copies = 0x1 << r_xram_rsp_trt_buf.srcid;
1887              entry.count    = 1;
1888            }
1889          } else {
1890            entry.d_copies = 0;
1891            entry.i_copies = 0;
1892            entry.count    = 0;
1893          }
1894          m_cache_directory.write(set, way, entry);
1895#ifdef IDEBUG
1896           std::cout << "printing the entry : " << std::endl;
1897           entry.print();
1898           std::cout << "done" << std::endl;
1899#endif
1900
1901#ifdef IDEBUG
1902        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_DIR_UPDT transaction table : " << std::endl;
1903        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1904          m_transaction_tab.print(i);
1905#endif
1906
1907          if(r_xram_rsp_victim_inval.read()){
1908            bool    brdcast = r_xram_rsp_victim_is_cnt.read();
1909            size_t index;
1910            size_t count_copies = r_xram_rsp_victim_count.read();
1911
1912            bool         wok = m_update_tab.set(false,  // it's an inval transaction
1913                brdcast,                          // set brdcast bit
1914                false,  // it does not need a response
1915                0,
1916                0,
1917                0,
1918                r_xram_rsp_victim_nline.read(),
1919                count_copies,
1920                index);
1921
1922#ifdef IDEBUG
1923            std::cout << "xram_rsp : record invalidation, time = " << std::dec << m_cpt_cycles << std::endl;
1924            m_update_tab.print();
1925#endif
1926            r_xram_rsp_upt_index = index;
1927            if(!wok) {
1928              assert(false && "mem_cache error : xram_rsp_dir_upt, an update_tab entry was free but write unsuccessful");
1929            }
1930          }
1931          // If the victim is not dirty, we erase the entry in the TRT
1932          if      (!r_xram_rsp_victim_dirty.read()){
1933          m_transaction_tab.erase(r_xram_rsp_trt_index.read());
1934
1935          }
1936          // Next state
1937          if      ( r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
1938          else if ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
1939          else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
1940          else                                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
1941          break;
1942        }
1943        ////////////////////////
1944      case XRAM_RSP_TRT_DIRTY:          // set the TRT entry (write line to XRAM) if the victim is dirty
1945        {
1946          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP ) {
1947            m_transaction_tab.set(r_xram_rsp_trt_index.read(),
1948                false,                          // write to XRAM
1949                r_xram_rsp_victim_nline.read(), // line index
1950                0,
1951                0,
1952                0,
1953                false,
1954                false,
1955                0,
1956                std::vector<be_t>(m_words,0),
1957                std::vector<data_t>(m_words,0) );
1958#ifdef IDEBUG
1959        std::cout << sc_time_stamp() << " " << name() << " XRAM_RSP_TRT_DIRTY transaction table : " << std::endl;
1960        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
1961          m_transaction_tab.print(i);
1962#endif
1963
1964            if      ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
1965            else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
1966            else                                            r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
1967          }
1968          break;
1969        }
1970        //////////////////////
1971      case XRAM_RSP_DIR_RSP:     // send a request to TGT_RSP FSM in case of read
1972        {
1973          if ( !r_xram_rsp_to_tgt_rsp_req ) {
1974            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
1975            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
1976            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
1977            for (size_t i=0; i < m_words; i++) {
1978              r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
1979              if( r_xram_rsp_trt_buf.single_word ) {
1980                r_xram_rsp_to_tgt_rsp_val[i] = (r_xram_rsp_trt_buf.word_index == i);
1981              } else {
1982                r_xram_rsp_to_tgt_rsp_val[i] = true;
1983              }
1984            }
1985            r_xram_rsp_to_tgt_rsp_req   = true;
1986
1987            if      ( r_xram_rsp_victim_inval ) r_xram_rsp_fsm = XRAM_RSP_INVAL;
1988            else if ( r_xram_rsp_victim_dirty ) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
1989            else                                r_xram_rsp_fsm = XRAM_RSP_IDLE;
1990
1991#ifdef IDEBUG
1992        std::cout << "XRAM_RSP FSM in XRAM_RSP_DIR_RSP state" << std::endl;
1993#endif
1994          }
1995          break;
1996        }
1997        ////////////////////
1998      case XRAM_RSP_INVAL:      // send invalidate request to INIT_CMD FSM
1999        {
2000          if( !r_xram_rsp_to_init_cmd_req ) {         
2001            r_xram_rsp_to_init_cmd_req      = true;
2002            r_xram_rsp_to_init_cmd_brdcast  = r_xram_rsp_victim_is_cnt.read();
2003            r_xram_rsp_to_init_cmd_nline    = r_xram_rsp_victim_nline.read();
2004            r_xram_rsp_to_init_cmd_trdid    = r_xram_rsp_upt_index;
2005            r_xram_rsp_to_init_cmd_d_copies = r_xram_rsp_victim_d_copies ;
2006            r_xram_rsp_to_init_cmd_i_copies = r_xram_rsp_victim_i_copies ;
2007            if ( r_xram_rsp_victim_dirty )  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
2008            else                                    r_xram_rsp_fsm = XRAM_RSP_IDLE;
2009#ifdef IDEBUG
2010        std::cout << "XRAM_RSP FSM in XRAM_RSP_INVAL state" << std::endl;
2011#endif
2012          }
2013          break;
2014        }
2015        //////////////////////////
2016      case XRAM_RSP_WRITE_DIRTY:        // send a write request to IXR_CMD FSM
2017        {
2018          if ( !r_xram_rsp_to_ixr_cmd_req ) {
2019            r_xram_rsp_to_ixr_cmd_req = true;
2020            r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
2021            r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
2022            for(size_t i=0; i<m_words ; i++) {
2023              r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
2024            }
2025            m_cpt_write_dirty++;
2026            r_xram_rsp_fsm = XRAM_RSP_IDLE;
2027#ifdef IDEBUG
2028        std::cout << "XRAM_RSP FSM in XRAM_RSP_WRITE_DIRTY state" << std::endl;
2029#endif
2030          }
2031          break;
2032        }
2033    } // end swich r_xram_rsp_fsm
2034
2035    ////////////////////////////////////////////////////////////////////////////////////
2036    //          CLEANUP FSM
2037    ////////////////////////////////////////////////////////////////////////////////////
2038    // The CLEANUP FSM handles the cleanup request from L1 caches.
2039    // It accesses the cache directory to update the list of copies.
2040    //
2041    ////////////////////////////////////////////////////////////////////////////////////
2042    switch ( r_cleanup_fsm.read() ) {
2043
2044      ///////////////////
2045      case CLEANUP_IDLE:
2046        {
2047
2048          if ( p_vci_tgt_cleanup.cmdval.read() ) {
2049            assert( (p_vci_tgt_cleanup.srcid.read() < m_initiators) &&
2050                "VCI_MEM_CACHE error in VCI_MEM_CACHE in the CLEANUP network : The received SRCID is larger than 31");
2051            bool reached = false;
2052            for ( size_t index = 0 ; index < ncseg && !reached ; index++ ){
2053              if ( m_cseg[index]->contains((addr_t)(p_vci_tgt_cleanup.address.read())) ){
2054                reached = true;
2055              }
2056            }
2057            if ( (p_vci_tgt_cleanup.cmd.read() == vci_param::CMD_WRITE) &&
2058                (((addr_t)(p_vci_tgt_cleanup.address.read())) != BROADCAST_ADDR) &&
2059                reached) {
2060
2061              m_cpt_cleanup++;
2062
2063              r_cleanup_nline      = (addr_t)(m_nline[(vci_addr_t)(p_vci_tgt_cleanup.address.read())]) ;
2064              r_cleanup_srcid      = p_vci_tgt_cleanup.srcid.read();
2065              r_cleanup_trdid      = p_vci_tgt_cleanup.trdid.read();
2066              r_cleanup_pktid      = p_vci_tgt_cleanup.pktid.read();
2067
2068#ifdef VHDL_ACCURATE
2069              r_cleanup_pass       = false;
2070#endif
2071              r_cleanup_fsm        = CLEANUP_DIR_LOCK;
2072            }
2073          }
2074          break;
2075        }
2076        //////////////////////
2077      case CLEANUP_DIR_LOCK:
2078        {
2079          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) {
2080#ifdef VHDL_ACCURATE
2081            if (!r_cleanup_pass.read()){
2082#endif
2083              // Read the directory
2084              size_t way = 0;
2085                  addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
2086              DirectoryEntry entry = m_cache_directory.read(cleanup_address , way);
2087#ifdef IDEBUG
2088           std::cout << "In CLEANUP_DIR_LOCK printing the entry of address is : " << std::hex << cleanup_address << std::endl;
2089           entry.print();
2090           std::cout << "done" << std::endl;
2091#endif
2092              r_cleanup_is_cnt    = entry.is_cnt;
2093              r_cleanup_dirty       = entry.dirty;
2094              r_cleanup_tag         = entry.tag;
2095              r_cleanup_lock        = entry.lock;
2096              r_cleanup_way         = way;
2097              r_cleanup_d_copies  = entry.d_copies;
2098              r_cleanup_i_copies  = entry.i_copies;
2099              r_cleanup_count     = entry.count;
2100
2101              // In case of hit, the copy must be cleaned in the copies bit-vector
2102              if( entry.valid )  {
2103                r_cleanup_fsm = CLEANUP_DIR_LOCK;
2104              } else {
2105                r_cleanup_fsm = CLEANUP_UPT_LOCK;
2106              }
2107#ifdef VHDL_ACCURATE
2108              r_cleanup_pass = true;
2109            }else{
2110              r_cleanup_pass = false;
2111              r_cleanup_fsm  = CLEANUP_DIR_WRITE;
2112            }
2113#endif
2114          }
2115          break;
2116        }
2117        ///////////////////////
2118      case CLEANUP_DIR_WRITE:
2119        {
2120          size_t way      = r_cleanup_way.read();
2121#define L2 soclib::common::uint32_log2
2122          size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
2123#undef L2
2124          bool cleanup_inst  = r_cleanup_trdid.read() & 0x1;
2125
2126          // update the cache directory (for the copies)
2127          DirectoryEntry entry;
2128          entry.valid   = true;
2129          entry.is_cnt  = r_cleanup_is_cnt.read();
2130          entry.dirty   = r_cleanup_dirty.read();
2131          entry.tag     = r_cleanup_tag.read();
2132          entry.lock    = r_cleanup_lock.read();
2133          if(r_cleanup_is_cnt.read()) { // Directory is a counter
2134            entry.count  = r_cleanup_count.read() -1;
2135            entry.i_copies = 0;
2136            entry.d_copies = 0;
2137            // response to the cache
2138            r_cleanup_fsm = CLEANUP_RSP;
2139          }
2140          else{                         // Directory is a vector
2141            if(cleanup_inst){           // Cleanup from a ICACHE
2142              if(r_cleanup_i_copies.read() & (0x1 << r_cleanup_srcid.read())){ // hit
2143                entry.count  = r_cleanup_count.read() -1;
2144                r_cleanup_fsm = CLEANUP_RSP;
2145              } else { // miss
2146                assert(false && "MemCache ERROR : Cleanup instruction hit but the line is not shared");
2147              }
2148              entry.i_copies  = r_cleanup_i_copies.read() & ~(0x1 << r_cleanup_srcid.read());
2149              entry.d_copies  = r_cleanup_d_copies.read();
2150            } else {                    // Cleanup from a DCACHE
2151              if(r_cleanup_d_copies.read() & (0x1 << r_cleanup_srcid.read())){ // hit
2152                entry.count  = r_cleanup_count.read() -1;
2153                r_cleanup_fsm = CLEANUP_RSP;
2154              } else { // miss
2155                assert(false && "MemCache ERROR : Cleanup data hit but the line is not shared");
2156              }
2157              entry.i_copies  = r_cleanup_i_copies.read();
2158              entry.d_copies  = r_cleanup_d_copies.read() & ~(0x1 << r_cleanup_srcid.read());
2159            }
2160          }
2161          m_cache_directory.write(set, way, entry); 
2162
2163          break;
2164        }
2165        /////////////////
2166      case CLEANUP_UPT_LOCK:
2167        {
2168          if( r_alloc_upt_fsm.read() == ALLOC_UPT_CLEANUP )
2169          {
2170            size_t index=0;
2171            bool hit_inval;
2172            hit_inval = m_update_tab.search_inval(r_cleanup_nline.read(),index);
2173            if(!hit_inval) {
2174#ifdef DEBUG_VCI_MEM_CACHE
2175              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;
2176#endif
2177              r_cleanup_fsm = CLEANUP_RSP;
2178            } else {
2179              r_cleanup_write_srcid = m_update_tab.srcid(index);
2180              r_cleanup_write_trdid = m_update_tab.trdid(index);
2181              r_cleanup_write_pktid = m_update_tab.pktid(index);
2182              r_cleanup_need_rsp    = m_update_tab.need_rsp(index);
2183              r_cleanup_fsm = CLEANUP_UPT_WRITE;
2184            }
2185            r_cleanup_index.write(index) ;
2186          }
2187          break;
2188        }
2189        /////////////////
2190      case CLEANUP_UPT_WRITE:
2191        {
2192          size_t count = 0;
2193          m_update_tab.decrement(r_cleanup_index.read(), count); // &count
2194          if(count == 0){
2195            m_update_tab.clear(r_cleanup_index.read());
2196#ifdef IDEBUG
2197        std::cout << sc_time_stamp() << " " << name() << " CLEANUP_UPT_WRITE update table : " << std::endl;
2198        m_update_tab.print();
2199#endif
2200
2201            if(r_cleanup_need_rsp.read()){
2202              r_cleanup_fsm = CLEANUP_WRITE_RSP ;
2203            } else {
2204              r_cleanup_fsm = CLEANUP_RSP;
2205            }
2206          } else {
2207            r_cleanup_fsm = CLEANUP_RSP ;
2208          }
2209          break;
2210        }
2211        /////////////////
2212      case CLEANUP_WRITE_RSP:
2213        {
2214          if( !r_cleanup_to_tgt_rsp_req.read()) {
2215            r_cleanup_to_tgt_rsp_req     = true;
2216            r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
2217            r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
2218            r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
2219            r_cleanup_fsm = CLEANUP_RSP;
2220          }
2221          break;
2222        }
2223        /////////////////
2224      case CLEANUP_RSP:
2225        {
2226          if(p_vci_tgt_cleanup.rspack)
2227            r_cleanup_fsm = CLEANUP_IDLE;
2228          break;
2229        }
2230    } // end switch cleanup fsm
2231
2232
2233    ////////////////////////////////////////////////////////////////////////////////////
2234    //          LLSC FSM
2235    ////////////////////////////////////////////////////////////////////////////////////
2236    // The LLSC FSM handles the LL & SC atomic access.
2237    //
2238    // For a LL :
2239    // It access the directory to check hit / miss.
2240    // - In case of hit, the LL request is registered in the Atomic Table and the
2241    // response is sent to the requesting processor.
2242    // - In case of miss, the LLSC FSM accesses the transaction table.
2243    // If a read transaction to the XRAM for this line already exists,
2244    // or if the transaction table is full, it returns to IDLE state.
2245    // Otherwise, a new transaction to the XRAM is initiated.
2246    // In both cases, the LL request is not consumed in the FIFO.
2247    //
2248    // For a SC :
2249    // It access the directory to check hit / miss.
2250    // - In case of hit, the Atomic Table is checked and the proper response
2251    // (true or false is sent to the requesting processor.
2252    // - In case of miss, the LLSC FSM accesses the transaction table.
2253    // If a read transaction to the XRAM for this line already exists,
2254    // or if the transaction table is full, it returns to IDLE state.
2255    // Otherwise, a new transaction to the XRAM is initiated.
2256    // In both cases, the SC request is not consumed in the FIFO.
2257    /////////////////////////////////////////////////////////////////////
2258
2259    switch ( r_llsc_fsm.read() ) {
2260
2261      ///////////////
2262      case LLSC_IDLE:           // test LL / SC
2263        {
2264          if( m_cmd_llsc_addr_fifo.rok() ) {
2265#ifdef VHDL_ACCURATE
2266            r_llsc_pass = false;
2267#endif
2268            if(m_cmd_llsc_sc_fifo.read()){
2269              m_cpt_sc++;
2270              r_llsc_fsm = SC_DIR_LOCK;
2271            }
2272            else{
2273              m_cpt_ll++;
2274              r_llsc_fsm = LL_DIR_LOCK;
2275            }
2276          }     
2277          break;
2278        }
2279        /////////////////
2280      case LL_DIR_LOCK:         // check directory for hit / miss
2281        {
2282          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
2283#ifdef VHDL_ACCURATE
2284            if (!r_llsc_pass.read()){
2285#endif
2286              size_t way = 0;
2287              DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
2288              r_llsc_is_cnt     = entry.is_cnt;
2289              r_llsc_dirty      = entry.dirty;
2290              r_llsc_tag        = entry.tag;
2291              r_llsc_way        = way;
2292              r_llsc_d_copies   = entry.d_copies;
2293              r_llsc_i_copies   = entry.i_copies ;
2294              r_llsc_count      = entry.count ;
2295
2296              if ( entry.valid )  r_llsc_fsm = LL_DIR_LOCK;
2297              else                r_llsc_fsm = LLSC_TRT_LOCK;
2298#ifdef VHDL_ACCURATE
2299              r_llsc_pass        = true;
2300            }else{
2301              r_llsc_pass        = false;
2302              r_llsc_fsm         = LL_DIR_HIT;
2303            }
2304#endif
2305          }
2306          break;
2307        }
2308        ////////////////
2309      case LL_DIR_HIT:          // read hit : update the memory cache
2310        {
2311          size_t way    = r_llsc_way.read();
2312          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2313          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2314
2315          // update directory (lock bit & copies)
2316          DirectoryEntry entry;
2317          entry.valid       = true;
2318          entry.is_cnt      = r_llsc_is_cnt.read();
2319          entry.dirty       = r_llsc_dirty.read();
2320          entry.lock        = true;
2321          entry.tag             = r_llsc_tag.read();
2322          entry.d_copies    = r_llsc_d_copies.read();
2323          entry.i_copies    = r_llsc_i_copies.read();
2324          entry.count       = r_llsc_count.read();
2325          m_cache_directory.write(set, way, entry);
2326
2327          // read data in cache
2328          r_llsc_data   = m_cache_data[way][set][word];
2329
2330          // set Atomic Table
2331          m_atomic_tab.set(m_cmd_llsc_srcid_fifo.read(), m_cmd_llsc_addr_fifo.read());
2332
2333          r_llsc_fsm    = LL_RSP;
2334          break;
2335        }
2336        ////////////
2337      case LL_RSP:              // request the TGT_RSP FSM to return data
2338        {
2339          if ( !r_llsc_to_tgt_rsp_req ) {
2340            cmd_llsc_fifo_get           = true;
2341            r_llsc_to_tgt_rsp_data      = r_llsc_data.read();
2342            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
2343            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
2344            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
2345            r_llsc_to_tgt_rsp_req       = true;
2346            r_llsc_fsm = LLSC_IDLE;
2347          }
2348          break;
2349        }
2350        /////////////////
2351      case SC_DIR_LOCK:
2352        {
2353          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
2354#ifdef VHDL_ACCURATE
2355            if(!r_llsc_pass.read()){
2356#endif
2357              size_t way = 0;
2358              DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
2359              bool ok = m_atomic_tab.isatomic(m_cmd_llsc_srcid_fifo.read(),m_cmd_llsc_addr_fifo.read());
2360              if( ok ) {
2361                r_llsc_is_cnt   = entry.is_cnt;
2362                r_llsc_dirty    = entry.dirty;
2363                r_llsc_tag      = entry.tag;
2364                r_llsc_way      = way;
2365                r_llsc_d_copies = entry.d_copies;
2366                r_llsc_i_copies = entry.i_copies;
2367                r_llsc_count    = entry.count;
2368              /* to avoid livelock, force the atomic access to fail (pseudo-)randomly */
2369                bool fail = (r_llsc_lfsr % (64) == 0);
2370                r_llsc_lfsr = (r_llsc_lfsr >> 1) ^ ((-(r_llsc_lfsr & 1)) & 0xd0000001);
2371#ifdef RANDOMIZE_SC
2372                if(fail){
2373#else
2374                if(0){
2375#endif
2376                  r_llsc_fsm = SC_RSP_FALSE;
2377                } else {
2378                  if ( entry.valid )  r_llsc_fsm = SC_DIR_LOCK;
2379                  else                r_llsc_fsm = LLSC_TRT_LOCK;
2380                }
2381              } else {
2382                r_llsc_fsm = SC_RSP_FALSE;
2383              }
2384#ifdef VHDL_ACCURATE
2385              r_llsc_pass       = true;
2386            }else{
2387              r_llsc_pass       = false;
2388              r_llsc_fsm        = SC_DIR_HIT;
2389            }
2390#endif
2391          }
2392          break;
2393        }
2394        ////////////////
2395      case SC_DIR_HIT:
2396        {
2397          size_t way    = r_llsc_way.read();
2398          size_t set    = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2399          size_t word   = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
2400
2401          // update directory (lock & dirty bits
2402          DirectoryEntry entry;
2403          entry.valid       = true;
2404          entry.is_cnt      = r_llsc_is_cnt.read();
2405          entry.dirty       = true;
2406          entry.lock        = true;
2407          entry.tag             = r_llsc_tag.read();
2408          entry.d_copies    = r_llsc_d_copies.read();
2409          entry.i_copies    = r_llsc_i_copies.read();
2410          entry.count       = r_llsc_count.read();
2411          m_cache_directory.write(set, way, entry);
2412
2413          // write data in cache
2414          m_cache_data[way][set][word] = m_cmd_llsc_wdata_fifo.read();
2415
2416          // reset Atomic Table
2417          m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
2418
2419          r_llsc_fsm = SC_RSP_TRUE;
2420          break;
2421        }
2422        //////////////////
2423      case SC_RSP_FALSE:
2424        {
2425          if( !r_llsc_to_tgt_rsp_req ) {
2426            cmd_llsc_fifo_get           = true;
2427            r_llsc_to_tgt_rsp_req       = true;
2428            r_llsc_to_tgt_rsp_data      = 1;
2429            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
2430            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
2431            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
2432            r_llsc_fsm                      = LLSC_IDLE;
2433          }
2434          break;
2435        }
2436        /////////////////
2437      case SC_RSP_TRUE:
2438        {
2439          if( !r_llsc_to_tgt_rsp_req ) {
2440            cmd_llsc_fifo_get       = true;
2441            r_llsc_to_tgt_rsp_req       = true;
2442            r_llsc_to_tgt_rsp_data      = 0;
2443            r_llsc_to_tgt_rsp_srcid     = m_cmd_llsc_srcid_fifo.read();
2444            r_llsc_to_tgt_rsp_trdid     = m_cmd_llsc_trdid_fifo.read();
2445            r_llsc_to_tgt_rsp_pktid     = m_cmd_llsc_pktid_fifo.read();
2446            r_llsc_fsm                      = LLSC_IDLE;
2447          }
2448          break;
2449        }
2450        ///////////////////
2451      case LLSC_TRT_LOCK:         // read or write miss : check the Transaction Table
2452        {
2453          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
2454            size_t   index = 0;
2455            bool hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],index);
2456            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]);
2457            bool wok = !m_transaction_tab.full(index);
2458
2459            if ( hit_read || !wok || hit_write ) {  // missing line already requested or no space in TRT
2460              r_llsc_fsm = LLSC_IDLE;
2461            } else {
2462              r_llsc_trt_index = index;
2463              r_llsc_fsm       = LLSC_TRT_SET;
2464            }
2465          }
2466          break;
2467        }
2468        //////////////////
2469      case LLSC_TRT_SET:        // register the XRAM transaction in Transaction Table
2470        {
2471          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
2472            bool proc_read = !m_cmd_llsc_sc_fifo.read();
2473            if(proc_read){
2474              m_transaction_tab.set(r_llsc_trt_index.read(),
2475                  true,
2476                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
2477                  m_cmd_llsc_srcid_fifo.read(),
2478                  m_cmd_llsc_trdid_fifo.read(),
2479                  m_cmd_llsc_pktid_fifo.read(),
2480                  true,
2481                  true,
2482                  m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())],
2483                  std::vector<be_t>(m_words,0),
2484                  std::vector<data_t>(m_words,0));
2485            }else{
2486              m_transaction_tab.set(r_llsc_trt_index.read(),
2487                  true,
2488                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
2489                  m_cmd_llsc_srcid_fifo.read(),
2490                  m_cmd_llsc_trdid_fifo.read(),
2491                  m_cmd_llsc_pktid_fifo.read(),
2492                  false,
2493                  false,
2494                  0,
2495                  std::vector<be_t>(m_words,0),
2496                  std::vector<data_t>(m_words,0));
2497            }
2498#ifdef IDEBUG
2499        std::cout << sc_time_stamp() << " " << name() << " LLSC_TRT_SET transaction table : " << std::endl;
2500        for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)
2501          m_transaction_tab.print(i);
2502#endif
2503
2504            r_llsc_fsm = LLSC_XRAM_REQ;
2505          }
2506          break;
2507        }
2508        ///////////////////
2509      case LLSC_XRAM_REQ:       // request the IXR_CMD FSM to fetch the missing line
2510        {
2511          if ( !r_llsc_to_ixr_cmd_req ) {
2512            r_llsc_to_ixr_cmd_req        = true;
2513            r_llsc_to_ixr_cmd_trdid      = r_llsc_trt_index.read();
2514            r_llsc_to_ixr_cmd_nline      = m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()];
2515            if( m_cmd_llsc_sc_fifo.read() ) {
2516              r_llsc_fsm                 = SC_RSP_FALSE;
2517            } else {
2518              cmd_llsc_fifo_get          = true;
2519              r_llsc_fsm                 = LLSC_IDLE;
2520            }
2521          }
2522          break;
2523        }
2524    } // end switch r_llsc_fsm
2525
2526
2527    //////////////////////////////////////////////////////////////////////////////
2528    //          INIT_CMD FSM
2529    //////////////////////////////////////////////////////////////////////////////
2530    // The INIT_CMD fsm controls the VCI CMD initiator port, used to update
2531    // or invalidate cache lines in L1 caches.
2532    // It implements a round-robin priority between the two following requests:
2533    // - r_write_to_init_cmd_req : update request from WRITE FSM
2534    // - r_xram_rsp_to_init_cmd_req : invalidate request from XRAM_RSP FSM
2535    // The inval request is a single cell VCI write command containing the
2536    // index of the line to be invalidated.
2537    // The update request is a multi-cells VCI write command : The first cell
2538    // contains the index of the cache line to be updated. The second cell contains
2539    // the index of the first modified word in the line. The following cells
2540    // contain the data.
2541    ///////////////////////////////////////////////////////////////////////////////
2542
2543    switch ( r_init_cmd_fsm.read() ) {
2544
2545      ////////////////////////
2546      case INIT_CMD_UPDT_IDLE:  // Invalidate requests have highest priority
2547        {
2548
2549          if ( r_xram_rsp_to_init_cmd_req.read() ) {
2550            r_init_cmd_fsm = INIT_CMD_INVAL_SEL;
2551            m_cpt_inval++;
2552          } else if ( r_write_to_init_cmd_req.read() ) {
2553            if(r_write_to_init_cmd_brdcast.read()){
2554              r_init_cmd_fsm = INIT_CMD_BRDCAST;
2555              m_cpt_inval++;
2556              m_cpt_inval_brdcast++;
2557            } else {
2558              r_init_cmd_fsm = INIT_CMD_UPDT_SEL;
2559              m_cpt_update++;
2560            }
2561          }
2562          break;
2563        }
2564        /////////////////////////
2565      case INIT_CMD_INVAL_IDLE: // Update requests have highest priority
2566        {
2567          if ( r_write_to_init_cmd_req.read() ) {
2568            if(r_write_to_init_cmd_brdcast.read()){
2569              r_init_cmd_fsm = INIT_CMD_BRDCAST;
2570              m_cpt_inval++;
2571              m_cpt_inval_brdcast++;
2572            } else {
2573              r_init_cmd_fsm = INIT_CMD_UPDT_SEL;
2574              m_cpt_update++;
2575            }
2576          } else if ( r_xram_rsp_to_init_cmd_req.read() ) {
2577            r_init_cmd_fsm = INIT_CMD_INVAL_SEL;
2578            m_cpt_inval++;
2579          }
2580          break;
2581        }
2582        ////////////////////////
2583      case INIT_CMD_INVAL_SEL:  // selects L1 caches
2584        {
2585          if(r_xram_rsp_to_init_cmd_brdcast.read()){
2586            m_cpt_inval_brdcast++;
2587            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
2588            break;
2589          }
2590          if ((r_xram_rsp_to_init_cmd_d_copies.read() == 0) &&
2591              (r_xram_rsp_to_init_cmd_i_copies.read() == 0)) {  // no more copies
2592            r_xram_rsp_to_init_cmd_req = false;
2593            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
2594            break;
2595          }
2596          m_cpt_inval_mult++;
2597          copy_t copies;
2598          bool inst = false;
2599          if(r_xram_rsp_to_init_cmd_i_copies.read()){
2600            copies = r_xram_rsp_to_init_cmd_i_copies.read();
2601            inst = true;
2602          } else {
2603            copies = r_xram_rsp_to_init_cmd_d_copies.read();
2604          }
2605          copy_t mask   = 0x1;
2606          for ( size_t i=0 ; i<8*sizeof(copy_t) ; i++ ) {
2607            if ( copies & mask ) {
2608              r_init_cmd_target = i;
2609              break;
2610            }
2611            mask = mask << 1;
2612          } // end for
2613          r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
2614          r_init_cmd_inst = inst;
2615          if(inst){
2616            r_xram_rsp_to_init_cmd_i_copies = copies & ~mask;
2617          } else {
2618            r_xram_rsp_to_init_cmd_d_copies = copies & ~mask;
2619          }
2620          break;
2621        }
2622        ////////////////////////
2623      case INIT_CMD_INVAL_NLINE:        // send the cache line index
2624        {
2625          if ( p_vci_ini.cmdack ) {
2626            if ( r_xram_rsp_to_init_cmd_brdcast.read() ) {
2627              r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
2628              r_xram_rsp_to_init_cmd_req = false;
2629            }
2630            else r_init_cmd_fsm = INIT_CMD_INVAL_SEL;
2631          }
2632          break;
2633        }
2634        ///////////////////////
2635     case INIT_CMD_UPDT_SEL:    // selects the next L1 cache
2636       {
2637         if ((r_write_to_init_cmd_i_copies.read() == 0) &&
2638             (r_write_to_init_cmd_d_copies.read() == 0)) {      // no more copies
2639           r_write_to_init_cmd_req = false;
2640           r_init_cmd_fsm    = INIT_CMD_UPDT_IDLE;
2641         } else {                                               // select the first target
2642           copy_t copies;
2643           bool inst = false;
2644           if(r_write_to_init_cmd_i_copies.read()){
2645             inst   = true;
2646             copies = r_write_to_init_cmd_i_copies.read();
2647           } else {
2648             copies = r_write_to_init_cmd_d_copies.read();
2649           }
2650           copy_t mask   = 0x1;
2651           for ( size_t i=0 ; i<8*sizeof(copy_t) ; i++ ) {
2652             if ( copies & mask ) {
2653               r_init_cmd_target = i;
2654               break;
2655             }
2656             mask = mask << 1;
2657           } // end for
2658           r_init_cmd_fsm    = INIT_CMD_UPDT_NLINE;
2659           r_init_cmd_inst = inst;
2660           if(inst){
2661             r_write_to_init_cmd_i_copies = copies & ~mask;
2662           } else {
2663             r_write_to_init_cmd_d_copies = copies & ~mask;
2664           }
2665           r_init_cmd_cpt    = 0;
2666           m_cpt_update_mult++;
2667         }
2668         break;
2669       }
2670       /////////////////////////
2671      case INIT_CMD_BRDCAST:
2672        {
2673          if( p_vci_ini.cmdack ) {
2674            r_write_to_init_cmd_req = false;
2675            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
2676          }
2677          break;
2678        }
2679        /////////////////////////
2680     case INIT_CMD_UPDT_NLINE:  // send the cache line index
2681       {
2682         if ( p_vci_ini.cmdack ){
2683             r_init_cmd_fsm = INIT_CMD_UPDT_INDEX;
2684         }
2685         break;
2686       }
2687        /////////////////////////
2688      case INIT_CMD_UPDT_INDEX: // send the first word index
2689        {
2690
2691          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_UPDT_DATA;
2692          break;
2693        }
2694        ////////////////////////
2695      case INIT_CMD_UPDT_DATA:  // send the data
2696        {
2697          if ( p_vci_ini.cmdack ) {
2698            if ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) ) {
2699              r_init_cmd_fsm = INIT_CMD_UPDT_SEL;
2700            } else {
2701              r_init_cmd_cpt = r_init_cmd_cpt.read() + 1;
2702            }
2703          }
2704          break;
2705        }
2706    } // end switch r_init_cmd_fsm
2707
2708    /////////////////////////////////////////////////////////////////////
2709    //          TGT_RSP FSM
2710    /////////////////////////////////////////////////////////////////////
2711    // The TGT_RSP fsm sends the responses on the VCI target port
2712    // with a round robin priority between six requests :
2713    // - r_read_to_tgt_rsp_req
2714    // - r_write_to_tgt_rsp_req
2715    // - r_llsc_to_tgt_rsp_req
2716    // - r_cleanup_to_tgt_rsp_req
2717    // - r_init_rsp_to_tgt_rsp_req
2718    // - r_xram_rsp_to_tgt_rsp_req
2719    // The  ordering is :  read > write > llsc > cleanup > xram > init
2720    /////////////////////////////////////////////////////////////////////
2721
2722    switch ( r_tgt_rsp_fsm.read() ) {
2723
2724      ///////////////////////
2725      case TGT_RSP_READ_IDLE:           // write requests have the highest priority
2726        {
2727
2728          if      ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2729          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2730          else if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2731          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2732          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2733          else if ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2734          break;
2735        }
2736        ////////////////////////
2737      case TGT_RSP_WRITE_IDLE:          // llsc requests have the highest priority
2738        {
2739
2740          if      ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2741          else if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2742          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2743          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2744          else if ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2745          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2746          break;
2747        }
2748        ///////////////////////
2749      case TGT_RSP_LLSC_IDLE:           // cleanup requests have the highest priority
2750        {
2751
2752          if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2753          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2754          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2755          else if ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2756          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2757          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2758          break;
2759        }
2760      case TGT_RSP_XRAM_IDLE:           // init requests have the highest priority
2761        {
2762
2763          if      ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2764          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2765          else if ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2766          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2767          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2768          else if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2769          break;
2770        }
2771        ///////////////////////
2772      case TGT_RSP_INIT_IDLE:           // cleanup requests have the highest priority
2773        {
2774          if      ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2775          else if ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2776          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2777          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2778          else if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2779          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2780          break;
2781        }
2782        ///////////////////////
2783      case TGT_RSP_CLEANUP_IDLE:                // read requests have the highest priority
2784        {
2785          if      ( r_read_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_READ_TEST;
2786          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
2787          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
2788          else if ( r_xram_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_XRAM_TEST;
2789          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
2790          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
2791          break;
2792        }
2793        ///////////////////////
2794      case TGT_RSP_READ_TEST:           // test if word or cache line
2795        {
2796          bool          line = true;
2797          size_t        index;
2798          for ( size_t i=0; i< m_words ; i++ ) {
2799            line = line && r_read_to_tgt_rsp_val[i];
2800            if ( r_read_to_tgt_rsp_val[i] ) index = i;
2801          }
2802          if ( line ) {
2803            r_tgt_rsp_cpt = 0;
2804            r_tgt_rsp_fsm = TGT_RSP_READ_LINE;
2805          } else {
2806            r_tgt_rsp_cpt = index;
2807            r_tgt_rsp_fsm = TGT_RSP_READ_WORD;
2808          }
2809          break;
2810        }
2811        ///////////////////////
2812      case TGT_RSP_READ_WORD:           // send one word response
2813        {
2814          if ( p_vci_tgt.rspack ) {
2815            r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
2816            r_read_to_tgt_rsp_req = false;
2817          }
2818          break;
2819        }
2820        ///////////////////////
2821      case TGT_RSP_READ_LINE:           // send one complete cache line
2822        {
2823          if ( p_vci_tgt.rspack ) {
2824            if ( r_tgt_rsp_cpt.read() == (m_words-1) ) {
2825              r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
2826              r_read_to_tgt_rsp_req = false;
2827            } else {
2828              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
2829            }
2830          }
2831          break;
2832        }
2833        ///////////////////
2834      case TGT_RSP_WRITE:               // send the write acknowledge
2835        {
2836          if ( p_vci_tgt.rspack ) {
2837            r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE;
2838            r_write_to_tgt_rsp_req = false;
2839          }
2840          break;
2841        }
2842        ///////////////////
2843      case TGT_RSP_CLEANUP:             // send the write acknowledge
2844        {
2845          if ( p_vci_tgt.rspack ) {
2846            r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE;
2847            r_cleanup_to_tgt_rsp_req = false;
2848          }
2849          break;
2850        }
2851        //////////////////
2852      case TGT_RSP_LLSC:                // send one atomic word response
2853        {
2854          if ( p_vci_tgt.rspack ) {
2855            r_tgt_rsp_fsm = TGT_RSP_LLSC_IDLE;
2856            r_llsc_to_tgt_rsp_req = false;
2857          }
2858          break;
2859        }
2860
2861      case TGT_RSP_XRAM_TEST:           // test if word or cache line
2862        {
2863          bool  line = true;
2864          size_t        index;
2865          for ( size_t i=0; i< m_words ; i++ ) {
2866            line = line && r_xram_rsp_to_tgt_rsp_val[i];
2867            if ( r_xram_rsp_to_tgt_rsp_val[i] ) index = i;
2868          }
2869          if ( line ) {
2870            r_tgt_rsp_cpt = 0;
2871            r_tgt_rsp_fsm = TGT_RSP_XRAM_LINE;
2872          } else {
2873            r_tgt_rsp_cpt = index;
2874            r_tgt_rsp_fsm = TGT_RSP_XRAM_WORD;
2875          }
2876          break;
2877        }
2878        ///////////////////////
2879      case TGT_RSP_XRAM_WORD:           // send one word response
2880        {
2881          if ( p_vci_tgt.rspack ) {
2882            r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
2883            r_xram_rsp_to_tgt_rsp_req = false;
2884          }
2885          break;
2886        }
2887        ///////////////////////
2888      case TGT_RSP_XRAM_LINE:           // send one complete cache line
2889        {
2890          if ( p_vci_tgt.rspack ) {
2891            if ( r_tgt_rsp_cpt.read() == (m_words-1) ) {
2892              r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
2893              r_xram_rsp_to_tgt_rsp_req = false;
2894            } else {
2895              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
2896            }
2897          }
2898          break;
2899        }
2900        ///////////////////
2901      case TGT_RSP_INIT:                // send the pending write acknowledge
2902        {
2903          if ( p_vci_tgt.rspack ) {
2904            r_tgt_rsp_fsm = TGT_RSP_INIT_IDLE;
2905            r_init_rsp_to_tgt_rsp_req = false;
2906          }
2907          break;
2908        }
2909    } // end switch tgt_rsp_fsm
2910    ////////////////////////////////////////////////////////////////////////////////////
2911    //          NEW ALLOC_UPT FSM
2912    ////////////////////////////////////////////////////////////////////////////////////
2913    // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT).
2914    // with a round robin priority between three FSMs : INIT_RSP > WRITE > XRAM_RSP > CLEANUP
2915    // - The WRITE FSM initiates update transactions and sets  new entry in UPT.
2916    // - The XRAM_RSP FSM initiates inval transactions and sets  new entry in UPT.
2917    // - The INIT_RSP FSM complete those trasactions and erase the UPT entry.
2918    // - The CLEANUP  FSM decrement an entry in UPT.
2919    // The resource is always allocated.
2920    /////////////////////////////////////////////////////////////////////////////////////
2921
2922    switch ( r_alloc_upt_fsm.read() ) {
2923
2924      ////////////////////////
2925      case ALLOC_UPT_INIT_RSP:
2926        if ( (r_init_rsp_fsm.read() != INIT_RSP_UPT_LOCK) &&
2927             (r_init_rsp_fsm.read() != INIT_RSP_UPT_CLEAR) )
2928        {
2929          if      ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
2930                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
2931          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
2932          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
2933        }
2934        break;
2935
2936        /////////////////////
2937      case ALLOC_UPT_WRITE:
2938        if ( (r_write_fsm.read() != WRITE_UPT_LOCK) &&
2939             (r_write_fsm.read() != WRITE_INVAL_LOCK))
2940        {
2941          if      (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
2942          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
2943          else if (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
2944        }
2945        break;
2946
2947        ////////////////////////
2948      case ALLOC_UPT_XRAM_RSP:
2949        if (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
2950        {
2951          if       (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)   r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
2952          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK) r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
2953          else if ((r_write_fsm.read() == WRITE_UPT_LOCK)   ||
2954                   (r_write_fsm.read() == WRITE_INVAL_LOCK))    r_alloc_upt_fsm = ALLOC_UPT_WRITE;
2955        }
2956        break;
2957
2958        //////////////////////////
2959      case ALLOC_UPT_CLEANUP:
2960        if(r_cleanup_fsm.read() != CLEANUP_UPT_LOCK)
2961        {
2962          if       (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
2963          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
2964                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
2965          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
2966        }
2967        break;
2968
2969    } // end switch r_alloc_upt_fsm
2970
2971    ////////////////////////////////////////////////////////////////////////////////////
2972    //          ALLOC_DIR FSM
2973    ////////////////////////////////////////////////////////////////////////////////////
2974    // The ALLOC_DIR FSM allocates the access to the directory and
2975    // the data cache with a round robin priority between 5 user FSMs :
2976    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
2977    // The ressource is always allocated.
2978    /////////////////////////////////////////////////////////////////////////////////////
2979
2980    switch ( r_alloc_dir_fsm.read() ) {
2981
2982      ////////////////////
2983      case ALLOC_DIR_READ:
2984        if ( ( (r_read_fsm.read() != READ_DIR_LOCK) &&
2985              (r_read_fsm.read() != READ_TRT_LOCK)     )
2986            ||
2987            ( (r_read_fsm.read()      == READ_TRT_LOCK)  &&
2988              (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)    )  )
2989        {
2990          if        (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
2991          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
2992                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
2993          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
2994          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
2995        }
2996        break;
2997
2998        /////////////////////
2999      case ALLOC_DIR_WRITE:
3000        if ( ( (r_write_fsm.read() != WRITE_DIR_LOCK)     &&
3001              (r_write_fsm.read() != WRITE_TRT_LOCK)     &&
3002              (r_write_fsm.read() != WRITE_DIR_HIT_READ) &&
3003              (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3004              (r_write_fsm.read() != WRITE_INVAL_LOCK) )
3005            ||
3006            ( (r_write_fsm.read()     == WRITE_TRT_LOCK) &&
3007              (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)   )   )
3008        {
3009          if        ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
3010                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3011          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3012          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3013          else if   (r_read_fsm.read() == READ_DIR_LOCK)                r_alloc_dir_fsm = ALLOC_DIR_READ;
3014        }
3015        break;
3016
3017        ////////////////////
3018      case ALLOC_DIR_LLSC:
3019        if ( ( (r_llsc_fsm.read() != LL_DIR_LOCK)    &&
3020              (r_llsc_fsm.read() != LL_DIR_HIT )    &&
3021              (r_llsc_fsm.read() != SC_DIR_LOCK)    &&
3022              (r_llsc_fsm.read() != SC_DIR_HIT )    &&
3023              (r_llsc_fsm.read() != LLSC_TRT_LOCK )    )
3024            ||
3025            ( (r_llsc_fsm.read()      == LLSC_TRT_LOCK ) &&
3026              (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC)    ) )
3027        {
3028          if      (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3029          else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)  r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3030          else if (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3031          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3032        }
3033        break;
3034
3035        ///////////////////////
3036      case ALLOC_DIR_CLEANUP:
3037        if ( (r_cleanup_fsm.read() != CLEANUP_DIR_LOCK) &&
3038            (r_cleanup_fsm.read() != CLEANUP_DIR_WRITE) )
3039        {
3040          if        (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
3041          else if   (r_read_fsm.read() == READ_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_READ;
3042          else if   (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3043          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) ||
3044                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3045        }
3046        break;
3047        ////////////////////////
3048      case ALLOC_DIR_XRAM_RSP:
3049        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_LOCK)  &&
3050            (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)   &&
3051            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK))
3052        {
3053          if      (r_read_fsm.read() == READ_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_READ;
3054          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
3055          else if ( (r_llsc_fsm.read() == LL_DIR_LOCK) ||
3056                    (r_llsc_fsm.read() == SC_DIR_LOCK))         r_alloc_dir_fsm = ALLOC_DIR_LLSC;
3057          else if (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
3058        }
3059        break;
3060
3061    } // end switch alloc_dir_fsm
3062
3063    ////////////////////////////////////////////////////////////////////////////////////
3064    //          ALLOC_TRT FSM
3065    ////////////////////////////////////////////////////////////////////////////////////
3066    // The ALLOC_TRT fsm allocates the access to the Transaction Table (write buffer)
3067    // with a round robin priority between 4 user FSMs :
3068    // The cyclic priority is READ > WRITE > LLSC > XRAM_RSP
3069    // The ressource is always allocated.
3070    ///////////////////////////////////////////////////////////////////////////////////
3071
3072    switch (r_alloc_trt_fsm) {
3073
3074      ////////////////////
3075      case ALLOC_TRT_READ:
3076        if ( r_read_fsm.read() != READ_TRT_LOCK )
3077        {
3078          if      ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3079                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3080          else if (r_llsc_fsm.read() == LLSC_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3081          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3082          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3083                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) )    r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3084        }
3085        break;
3086        /////////////////////
3087      case ALLOC_TRT_WRITE:
3088        if ( (r_write_fsm.read() != WRITE_TRT_LOCK) &&
3089             (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
3090             (r_write_fsm.read() != WRITE_INVAL_LOCK))
3091        {
3092          if      (r_llsc_fsm.read() == LLSC_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3093          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3094          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3095                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3096          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3097        }
3098        break;
3099        ////////////////////
3100      case ALLOC_TRT_LLSC:
3101        if ( r_llsc_fsm.read() != LLSC_TRT_LOCK )
3102        {
3103          if      (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3104          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3105                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3106          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3107          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)     ||
3108                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3109        }
3110        break;
3111        ////////////////////////
3112      case ALLOC_TRT_XRAM_RSP:
3113        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)  &&
3114            (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_UPDT)   &&
3115            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)) {
3116          if      ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
3117                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
3118          else if (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3119          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)    ||
3120                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3121          else if (r_llsc_fsm.read() == LLSC_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3122        }
3123        break;
3124        ////////////////////////
3125      case ALLOC_TRT_IXR_RSP:
3126        if ( (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_ERASE) &&
3127            (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ) ) {
3128          if      (r_read_fsm.read() == READ_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_READ;
3129          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
3130                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
3131          else if (r_llsc_fsm.read() == LLSC_TRT_LOCK)              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
3132          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
3133        }
3134        break;
3135
3136    } // end switch alloc_trt_fsm
3137
3138    ////////////////////////////////////////////////////////////////////////////////////
3139    //          TGT_CMD to READ FIFO
3140    ////////////////////////////////////////////////////////////////////////////////////
3141
3142    if ( cmd_read_fifo_put ) {
3143      if ( cmd_read_fifo_get ) {
3144        m_cmd_read_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3145        m_cmd_read_word_fifo.put_and_get((p_vci_tgt.plen.read() == 4));
3146        m_cmd_read_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3147        m_cmd_read_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3148        m_cmd_read_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3149      } else {
3150        m_cmd_read_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3151        m_cmd_read_word_fifo.simple_put((p_vci_tgt.plen.read() == 4));
3152        m_cmd_read_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3153        m_cmd_read_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3154        m_cmd_read_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3155      }
3156    } else {
3157      if ( cmd_read_fifo_get ) {
3158        m_cmd_read_addr_fifo.simple_get();
3159        m_cmd_read_word_fifo.simple_get();
3160        m_cmd_read_srcid_fifo.simple_get();
3161        m_cmd_read_trdid_fifo.simple_get();
3162        m_cmd_read_pktid_fifo.simple_get();
3163      }
3164    }
3165    /////////////////////////////////////////////////////////////////////
3166    //          TGT_CMD to WRITE FIFO
3167    /////////////////////////////////////////////////////////////////////
3168
3169    if ( cmd_write_fifo_put ) {
3170      if ( cmd_write_fifo_get ) {
3171        m_cmd_write_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3172        m_cmd_write_eop_fifo.put_and_get(p_vci_tgt.eop.read());
3173        m_cmd_write_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3174        m_cmd_write_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3175        m_cmd_write_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3176        m_cmd_write_data_fifo.put_and_get(p_vci_tgt.wdata.read());
3177        m_cmd_write_be_fifo.put_and_get(p_vci_tgt.be.read());
3178      } else {
3179        m_cmd_write_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3180        m_cmd_write_eop_fifo.simple_put(p_vci_tgt.eop.read());
3181        m_cmd_write_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3182        m_cmd_write_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3183        m_cmd_write_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3184        m_cmd_write_data_fifo.simple_put(p_vci_tgt.wdata.read());
3185        m_cmd_write_be_fifo.simple_put(p_vci_tgt.be.read());
3186      }
3187    } else {
3188      if ( cmd_write_fifo_get ) {
3189        m_cmd_write_addr_fifo.simple_get();
3190        m_cmd_write_eop_fifo.simple_get();
3191        m_cmd_write_srcid_fifo.simple_get();
3192        m_cmd_write_trdid_fifo.simple_get();
3193        m_cmd_write_pktid_fifo.simple_get();
3194        m_cmd_write_data_fifo.simple_get();
3195        m_cmd_write_be_fifo.simple_get();
3196      }
3197    }
3198    ////////////////////////////////////////////////////////////////////////////////////
3199    //          TGT_CMD to LLSC FIFO
3200    ////////////////////////////////////////////////////////////////////////////////////
3201
3202    if ( cmd_llsc_fifo_put ) {
3203      if ( cmd_llsc_fifo_get ) {
3204        m_cmd_llsc_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
3205        m_cmd_llsc_sc_fifo.put_and_get(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND);
3206        m_cmd_llsc_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
3207        m_cmd_llsc_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
3208        m_cmd_llsc_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
3209        m_cmd_llsc_wdata_fifo.put_and_get(p_vci_tgt.wdata.read());
3210      } else {
3211        m_cmd_llsc_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
3212        m_cmd_llsc_sc_fifo.simple_put(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND);
3213        m_cmd_llsc_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
3214        m_cmd_llsc_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
3215        m_cmd_llsc_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
3216        m_cmd_llsc_wdata_fifo.simple_put(p_vci_tgt.wdata.read());
3217      }
3218    } else {
3219      if ( cmd_llsc_fifo_get ) {
3220        m_cmd_llsc_addr_fifo.simple_get();
3221        m_cmd_llsc_sc_fifo.simple_get();
3222        m_cmd_llsc_srcid_fifo.simple_get();
3223        m_cmd_llsc_trdid_fifo.simple_get();
3224        m_cmd_llsc_pktid_fifo.simple_get();
3225        m_cmd_llsc_wdata_fifo.simple_get();
3226      }
3227    }
3228
3229  //////////////////////////////////////////////////////////////
3230    m_cpt_cycles++;
3231
3232  } // end transition()
3233
3234  /////////////////////////////
3235  tmpl(void)::genMoore()
3236    /////////////////////////////
3237  {
3238    ////////////////////////////////////////////////////////////
3239    // Command signals on the p_vci_ixr port
3240    ////////////////////////////////////////////////////////////
3241
3242
3243    p_vci_ixr.be      = 0xF;
3244    p_vci_ixr.pktid   = 0;
3245    p_vci_ixr.srcid   = m_srcid_ixr;
3246    p_vci_ixr.cons    = false;
3247    p_vci_ixr.wrap    = false;
3248    p_vci_ixr.contig  = true;
3249    p_vci_ixr.clen    = 0;
3250    p_vci_ixr.cfixed  = false;
3251
3252    if ( r_ixr_cmd_fsm.read() == IXR_CMD_READ_NLINE ) {
3253      p_vci_ixr.cmd     = vci_param::CMD_READ;
3254      p_vci_ixr.cmdval  = true;
3255      p_vci_ixr.address = (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4);
3256      p_vci_ixr.plen    = m_words*4;
3257      p_vci_ixr.wdata   = 0x00000000;
3258      p_vci_ixr.trdid   = r_read_to_ixr_cmd_trdid.read();
3259      p_vci_ixr.eop     = true;
3260    }
3261    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_LLSC_NLINE ) {
3262      p_vci_ixr.cmd     = vci_param::CMD_READ;
3263      p_vci_ixr.cmdval  = true;
3264      p_vci_ixr.address = (addr_t)(r_llsc_to_ixr_cmd_nline.read()*m_words*4);
3265      p_vci_ixr.plen    = m_words*4;
3266      p_vci_ixr.wdata   = 0x00000000;
3267      p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
3268      p_vci_ixr.eop     = true;
3269    }
3270    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_WRITE_NLINE ) {
3271      if(r_write_to_ixr_cmd_write.read()){
3272        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
3273        p_vci_ixr.cmdval  = true;
3274        p_vci_ixr.address = (addr_t)((r_write_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
3275        p_vci_ixr.plen    = m_words*4;
3276        p_vci_ixr.wdata   = r_write_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
3277        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
3278        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
3279      } else {
3280        p_vci_ixr.cmd     = vci_param::CMD_READ;
3281        p_vci_ixr.cmdval  = true;
3282        p_vci_ixr.address = (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4);
3283        p_vci_ixr.plen    = m_words*4;
3284        p_vci_ixr.wdata   = 0x00000000;
3285        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
3286        p_vci_ixr.eop     = true;
3287      }
3288    }
3289    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_XRAM_DATA ) {
3290      p_vci_ixr.cmd     = vci_param::CMD_WRITE;
3291      p_vci_ixr.cmdval  = true;
3292      p_vci_ixr.address = (addr_t)((r_xram_rsp_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
3293      p_vci_ixr.plen    = m_words*4;
3294      p_vci_ixr.wdata   = r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
3295      p_vci_ixr.trdid   = r_xram_rsp_to_ixr_cmd_trdid.read();
3296      p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
3297    } else {
3298      p_vci_ixr.cmdval  = false;
3299      p_vci_ixr.address = 0;
3300      p_vci_ixr.plen    = 0;
3301      p_vci_ixr.wdata   = 0;
3302      p_vci_ixr.trdid   = 0;
3303      p_vci_ixr.eop     = false;
3304    }
3305
3306    ////////////////////////////////////////////////////
3307    // Response signals on the p_vci_ixr port
3308    ////////////////////////////////////////////////////
3309
3310    if ( ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&
3311          (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ)) ||
3312        (r_ixr_rsp_fsm.read() == IXR_RSP_ACK) ) p_vci_ixr.rspack = true;
3313    else                                        p_vci_ixr.rspack = false;
3314
3315    ////////////////////////////////////////////////////
3316    // Command signals on the p_vci_tgt port
3317    ////////////////////////////////////////////////////
3318
3319    switch ((tgt_cmd_fsm_state_e)r_tgt_cmd_fsm.read()) {
3320      case TGT_CMD_IDLE:
3321        p_vci_tgt.cmdack  = false;
3322        break;
3323      case TGT_CMD_READ:
3324        p_vci_tgt.cmdack  = m_cmd_read_addr_fifo.wok();
3325        break;
3326      case TGT_CMD_READ_EOP:
3327        p_vci_tgt.cmdack  = true;
3328        break;
3329      case TGT_CMD_WRITE:
3330        p_vci_tgt.cmdack  = m_cmd_write_addr_fifo.wok();
3331        break;
3332      case TGT_CMD_ATOMIC:
3333        p_vci_tgt.cmdack  = m_cmd_llsc_addr_fifo.wok();
3334        break;
3335      default:
3336        p_vci_tgt.cmdack = false;
3337        break;
3338    }
3339
3340    ////////////////////////////////////////////////////
3341    // Response signals on the p_vci_tgt port
3342    ////////////////////////////////////////////////////
3343    switch ( r_tgt_rsp_fsm.read() ) {
3344
3345      case TGT_RSP_READ_IDLE:
3346      case TGT_RSP_WRITE_IDLE:
3347      case TGT_RSP_LLSC_IDLE:
3348      case TGT_RSP_XRAM_IDLE:
3349      case TGT_RSP_INIT_IDLE:
3350      case TGT_RSP_CLEANUP_IDLE:
3351      case TGT_RSP_READ_TEST:
3352      case TGT_RSP_XRAM_TEST:
3353
3354        p_vci_tgt.rspval  = false;
3355        p_vci_tgt.rsrcid  = 0;
3356        p_vci_tgt.rdata   = 0;
3357        p_vci_tgt.rpktid  = 0;
3358        p_vci_tgt.rtrdid  = 0;
3359        p_vci_tgt.rerror  = 0;
3360        p_vci_tgt.reop    = false;     
3361        break;
3362      case TGT_RSP_READ_LINE:
3363        p_vci_tgt.rspval   = true;
3364        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
3365        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
3366        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
3367        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
3368        p_vci_tgt.rerror   = 0;
3369        p_vci_tgt.reop     = (r_tgt_rsp_cpt.read() == (m_words-1));
3370        break;
3371      case TGT_RSP_READ_WORD:
3372        p_vci_tgt.rspval   = true;
3373        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
3374        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
3375        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
3376        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
3377        p_vci_tgt.rerror   = 0;
3378        p_vci_tgt.reop     = true;     
3379        break;
3380      case TGT_RSP_WRITE:
3381        p_vci_tgt.rspval   = true;
3382        p_vci_tgt.rdata    = 0;
3383        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
3384        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
3385        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
3386        p_vci_tgt.rerror   = 0;
3387        p_vci_tgt.reop     = true;
3388        break;
3389      case TGT_RSP_CLEANUP:
3390        p_vci_tgt.rspval   = true;
3391        p_vci_tgt.rdata    = 0;
3392        p_vci_tgt.rsrcid   = r_cleanup_to_tgt_rsp_srcid.read();
3393        p_vci_tgt.rtrdid   = r_cleanup_to_tgt_rsp_trdid.read();
3394        p_vci_tgt.rpktid   = r_cleanup_to_tgt_rsp_pktid.read();
3395        p_vci_tgt.rerror   = 0;
3396        p_vci_tgt.reop     = true;
3397        break;
3398      case TGT_RSP_LLSC:
3399        p_vci_tgt.rspval   = true;
3400        p_vci_tgt.rdata    = r_llsc_to_tgt_rsp_data.read();
3401        p_vci_tgt.rsrcid   = r_llsc_to_tgt_rsp_srcid.read();
3402        p_vci_tgt.rtrdid   = r_llsc_to_tgt_rsp_trdid.read();
3403        p_vci_tgt.rpktid   = r_llsc_to_tgt_rsp_pktid.read();
3404        p_vci_tgt.rerror   = 0;
3405        p_vci_tgt.reop     = true;
3406        break;
3407      case TGT_RSP_XRAM_LINE:
3408        p_vci_tgt.rspval   = true;
3409        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
3410        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
3411        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
3412        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
3413        p_vci_tgt.rerror   = 0;
3414        p_vci_tgt.reop     = (r_tgt_rsp_cpt.read() == (m_words-1));
3415        break;
3416      case TGT_RSP_XRAM_WORD:
3417        p_vci_tgt.rspval   = true;
3418        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
3419        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
3420        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
3421        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
3422        p_vci_tgt.rerror   = 0;
3423        p_vci_tgt.reop     = true;
3424        break;
3425      case TGT_RSP_INIT:
3426        p_vci_tgt.rspval   = true;
3427        p_vci_tgt.rdata    = 0;
3428        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
3429        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
3430        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
3431        p_vci_tgt.rerror   = 0;
3432        p_vci_tgt.reop     = true;     
3433        break;
3434    } // end switch r_tgt_rsp_fsm
3435
3436    ///////////////////////////////////////////////////
3437    // Command signals on the p_vci_ini port
3438    ///////////////////////////////////////////////////
3439
3440    p_vci_ini.cmd     = vci_param::CMD_WRITE;
3441    p_vci_ini.srcid   = m_srcid_ini;
3442    p_vci_ini.pktid   = 0;
3443    p_vci_ini.cons    = true;
3444    p_vci_ini.wrap    = false;
3445    p_vci_ini.contig  = false;
3446    p_vci_ini.clen    = 0;
3447    p_vci_ini.cfixed  = false;
3448
3449    switch ( r_init_cmd_fsm.read() ) {
3450
3451      case INIT_CMD_UPDT_IDLE:
3452      case INIT_CMD_INVAL_IDLE:
3453      case INIT_CMD_UPDT_SEL:
3454      case INIT_CMD_INVAL_SEL:
3455        p_vci_ini.cmdval  = false;
3456        p_vci_ini.address = 0;
3457        p_vci_ini.wdata   = 0;
3458        p_vci_ini.be      = 0;
3459        p_vci_ini.plen    = 0;
3460        p_vci_ini.trdid   = 0;
3461        p_vci_ini.eop     = false;
3462        break;
3463      case INIT_CMD_INVAL_NLINE:
3464        p_vci_ini.cmdval  = true;
3465        if(r_xram_rsp_to_init_cmd_brdcast.read())
3466          p_vci_ini.address = BROADCAST_ADDR;
3467        else {
3468          if(r_init_cmd_inst.read()) {
3469            p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()]+8);
3470          } else {
3471            p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()]);
3472          }
3473        }
3474        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
3475        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
3476        p_vci_ini.plen    = 4;
3477        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
3478        p_vci_ini.eop     = true;
3479        break;
3480      case INIT_CMD_BRDCAST:
3481        p_vci_ini.cmdval  = true;
3482        p_vci_ini.address = BROADCAST_ADDR;
3483        p_vci_ini.wdata   = (addr_t)r_write_to_init_cmd_nline.read();
3484        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32) & 0x3);
3485        p_vci_ini.plen    = 4 ;
3486        p_vci_ini.eop     = true;
3487        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
3488        break;
3489      case INIT_CMD_UPDT_NLINE:
3490        p_vci_ini.cmdval  = true;
3491        if(r_init_cmd_inst.read()){
3492          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 12);
3493        } else {
3494          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 4);
3495        }
3496        p_vci_ini.wdata   = (uint32_t)r_write_to_init_cmd_nline.read();
3497        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32 ) & 0x3);
3498        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
3499        p_vci_ini.eop     = false;
3500        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
3501        break;
3502      case INIT_CMD_UPDT_INDEX:
3503        p_vci_ini.cmdval  = true;
3504        if(r_init_cmd_inst.read()){
3505          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 12);
3506        } else {
3507          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 4);
3508        }
3509        p_vci_ini.wdata   = r_write_to_init_cmd_index.read();
3510        p_vci_ini.be      = 0xF;
3511        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
3512        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
3513        p_vci_ini.eop     = false;
3514        break;
3515      case INIT_CMD_UPDT_DATA:
3516        p_vci_ini.cmdval  = true;
3517        if(r_init_cmd_inst.read()){
3518          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 12);
3519        } else {
3520          p_vci_ini.address = (addr_t)(m_coherence_table[r_init_cmd_target.read()] + 4);
3521        }
3522        p_vci_ini.wdata   = r_write_to_init_cmd_data[r_init_cmd_cpt.read() +
3523          r_write_to_init_cmd_index.read()].read();
3524        if(r_write_to_init_cmd_we[r_init_cmd_cpt.read() +
3525            r_write_to_init_cmd_index.read()].read()) 
3526          p_vci_ini.be      = 0xF;
3527        else                    p_vci_ini.be      = 0x0;
3528        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
3529        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
3530        p_vci_ini.eop     = ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) );
3531        break;
3532    } // end switch r_init_cmd_fsm
3533
3534    //////////////////////////////////////////////////////
3535    // Response signals on the p_vci_ini port
3536    //////////////////////////////////////////////////////
3537
3538    if ( r_init_rsp_fsm.read() == INIT_RSP_IDLE ) p_vci_ini.rspack  = true;
3539    else                                          p_vci_ini.rspack  = false;
3540
3541    //////////////////////////////////////////////////////
3542    // Response signals on the p_vci_tgt_cleanup port
3543    //////////////////////////////////////////////////////
3544    p_vci_tgt_cleanup.rspval = false;
3545    p_vci_tgt_cleanup.rsrcid = 0;
3546    p_vci_tgt_cleanup.rdata  = 0;
3547    p_vci_tgt_cleanup.rpktid = 0;
3548    p_vci_tgt_cleanup.rtrdid = 0;
3549    p_vci_tgt_cleanup.rerror = 0;
3550    p_vci_tgt_cleanup.reop   = false;
3551
3552    switch(r_cleanup_fsm.read()){
3553      case CLEANUP_IDLE:
3554        {
3555          p_vci_tgt_cleanup.cmdack = true ;
3556          break;
3557        }
3558      case CLEANUP_DIR_LOCK:
3559        {
3560          p_vci_tgt_cleanup.cmdack = false ;
3561          break;
3562        }
3563      case CLEANUP_RSP:
3564        {
3565          p_vci_tgt_cleanup.rspval = true;
3566          p_vci_tgt_cleanup.rdata  = 0;
3567          p_vci_tgt_cleanup.rsrcid = r_cleanup_srcid.read();
3568          p_vci_tgt_cleanup.rpktid = r_cleanup_pktid.read();
3569          p_vci_tgt_cleanup.rtrdid = r_cleanup_trdid.read();
3570          p_vci_tgt_cleanup.rerror = 0;
3571          p_vci_tgt_cleanup.reop   = 1;
3572          break;
3573        }
3574
3575    }
3576
3577  } // end genMoore()
3578
3579}} // end name space
3580
3581// Local Variables:
3582// tab-width: 4
3583// c-basic-offset: 4
3584// c-file-offsets:((innamespace . 0)(inline-open . 0))
3585// indent-tabs-mode: nil
3586// End:
3587
3588// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
3589
Note: See TracBrowser for help on using the repository browser.