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

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

Import TSAR modules in TSAR's own svn

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