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

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

Fix uninitialized variable

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