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

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

yAjout du multi_cache : plusieurs processeur peuvent ce partager le même cache L1.
2 remarques, (1) deux nouveaux paramètres : nb_cpu, nb_cache. Pour avoir un cache dont le comportement est identique à la version d'avant, mettre ces paramètres à 1.
(2) le port d'interruption est maintenant un tableau dépendant du nombre de processeur.
Voir le fichier "platforms/caba-ring-ccxcachev4_memcachev4-mips32el/top.cpp" pour plus de détails.

--Cette ligne, et les suivantes ci-dessous, seront ignorées--

M platforms/tsarv4_dspin_generic_32/tsarv4_dspin_generic_32_top.cpp
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/segmentation.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/top.cpp
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/configuration/default.cfg
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/configuration/gen_config.sh
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/dhrystone/dhry21a.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/define.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/matrix_multiplication/matrix_multiplication.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/common/common.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying/self_code_modifying.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/self_code_modifying/self_code_modifying.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark.h
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_sort.c
A platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_self_code_modifying.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/benchmark/benchmark_matrix_multiplication.c
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/soft/Makefile
M platforms/caba-ring-ccxcachev4_memcachev4-mips32el/Makefile
M platforms/tsarv4_vgmn_generic_32/tsarv4_vgmn_generic_32_top.cpp
M modules/vci_cc_xcache_wrapper_v4/caba/source/include/vci_cc_xcache_wrapper_v4.h
M modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp
M modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h
M modules/vci_mem_cache_v4/caba/source/include/mem_cache_directory_v4.h
M modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp

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