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

Last change on this file since 134 was 134, checked in by kane, 13 years ago

add multi write buffer in cc_xcache_v4

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