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

Last change on this file since 116 was 116, checked in by alain, 13 years ago

Introducing a print_trace() method

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