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

Last change on this file since 138 was 138, checked in by guthmull, 13 years ago

Handle bad accesses cleanly : transmit all accesses to the xram and handle rerror in responses. The simulation is no more stopped and gdb can be used for debug.

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