source: trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp @ 143

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

fix bug in ccxcachev4, save cpu_info in memcachev4

  • 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: 199.6 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, SoC
24 *         Alain Greiner <alain.greiner@lip6.fr>, 2008
25 *
26 * Maintainers: alain eric.guthmuller@polytechnique.edu nipo
27 */
28
29/////////////////////////////////////////////////////////////////////////////
30// History
31// - 25/04/2008
32//   The existing vci_xcache component has been extended to include
33//   a VCI target port to support a directory based coherence protocol.
34//   Two types of packets can be send by the L2 cache to the L1 cache
35//   * INVALIDATE packets : length = 1
36//   * UPDATE packets : length = n + 2   
37//   The CLEANUP packets are sent by the L1 cache to the L2 cache,
38//   to signal a replaced cache line.
39// - 12/08/2008
40//   The vci_cc_xcache_wrapper component instanciates directly the processsor
41//   iss, in order to supress the processor/cache interface.
42//   According to the VCI advanced specification, this component uses one
43//   word VCI CMD packets for MISS transactions, and accept one word VCI RSP
44//   packets for Write burst  transactions.
45//   The write buffer has been modified to use the WriteBuffer object.
46//   A VCI write burst is constructed when two conditions are satisfied :
47//   The processor make strictly successive write requests, and they are
48//   in the same cache line. The write buffer performs re-ordering, to
49//   respect the contiguous addresses VCI constraint. In case of several
50//   WRITE_WORD requests in the same word, only the last request is conserved.
51//   In case of several WRITE_HALF or WRITE_WORD requests in the same word,
52//   the requests are merged in the same word. In case of uncached write
53//   requests, each request is transmited as a single VCI transaction.
54//   Both the data & instruction caches can be flushed in one single cycle.
55///////////////////////////////////////////////////////////////////////////////
56
57#include <iomanip>
58#include "arithmetics.h"
59#include "size.h"
60#include "../include/vci_cc_xcache_wrapper_v4.h"
61
62// =====[ DEBUG ]====================================
63
64#define ASSERT_VERBOSE
65#define ASSERT_NCYCLES m_cpt_total_cycles
66
67#include "debug.h"
68
69#if CC_XCACHE_WRAPPER_DEBUG
70# define PRINTF(msg...) PRINTF_COND(m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN,msg)
71#else
72# define PRINTF(msg...)
73#endif
74
75// =====[ FIFO_RSP ]=================================
76
77#if   (CC_XCACHE_WRAPPER_FIFO_RSP==1)
78# define CACHE_MISS_BUF_ALLOC             do { \
79                                              r_icache_miss_buf = new std::queue<data_t> [m_nb_icache]; \
80                                              r_dcache_miss_buf = new std::queue<data_t> [m_nb_dcache]; \
81                                          } while (0)
82# define CACHE_MISS_BUF_DEALLOC           do { \
83                                              delete [] r_icache_miss_buf; \
84                                              delete [] r_dcache_miss_buf; \
85                                          } while (0)
86# define CACHE_MISS_BUF_RESET(c)          do { \
87                                              for (uint32_t x=0; x<m_nb_##c##cache; ++x) { \
88                                                  while (r_##c##cache_miss_buf[x].size()>0) { \
89                                                      r_##c##cache_miss_buf[x].pop(); \
90                                                  } \
91                                              } \
92                                          } while (0)
93# define CACHE_MISS_BUF_REQ_INIT(c,x)     
94# define CACHE_MISS_BUF_RSP_VAL(c,x,n)    (r_##c##cache_miss_buf[x].size()>0)
95# define CACHE_MISS_BUF_RSP_ACK(c,x)      (r_##c##cache_miss_buf[x].size()<2)
96# define CACHE_MISS_BUF_RSP_DATA(c,x,n)   r_##c##cache_miss_buf[x].front()
97# define CACHE_MISS_BUF_RSP_POP(c,x)      do {                                            \
98                                              r_##c##cache_miss_buf[x].pop(); \
99                                          } while (0)
100# define CACHE_MISS_BUF_RSP_PUSH(c,x,n,d) do { \
101                                              r_##c##cache_miss_buf[x].push(d); \
102                                          } while (0)
103# define CACHE_MISS_BUF_RSP_PRINT(c)      do { \
104                                              for (uint32_t x=0; x<m_nb_##c##cache; ++x) { \
105                                                  PRINTF("    * cache_miss_buf - size : %d\n",r_##c##cache_miss_buf[x].size()); \
106                                              } \
107                                          } while (0)
108#elif (CC_XCACHE_WRAPPER_FIFO_RSP==2)
109# define CACHE_MISS_BUF_ALLOC             
110# define CACHE_MISS_BUF_DEALLOC           
111# define CACHE_MISS_BUF_RESET(c)          do {                          \
112                                              while (r_##c##cache_miss_buf.size()>0) { \
113                                                  r_##c##cache_miss_buf.pop(); \
114                                              }                         \
115                                          } while (0)
116# define CACHE_MISS_BUF_REQ_INIT(c,x)     
117# define CACHE_MISS_BUF_RSP_VAL(c,x,n)    ((r_##c##cache_miss_buf.size()>0) and (r_##c##cache_miss_buf.front().num_cache==x))
118# define CACHE_MISS_BUF_RSP_ACK(c,x)      (r_##c##cache_miss_buf.size()<2)
119# define CACHE_MISS_BUF_RSP_DATA(c,x,n)   r_##c##cache_miss_buf.front().data
120# define CACHE_MISS_BUF_RSP_POP(c,x)      do {                                            \
121                                              r_##c##cache_miss_buf.pop(); \
122                                          } while (0)
123# define CACHE_MISS_BUF_RSP_PUSH(c,x,n,d) do { \
124                                              miss_buf_t miss_buf;      \
125                                              miss_buf.data = d;        \
126                                              miss_buf.num_cache = x;   \
127                                              r_##c##cache_miss_buf.push(miss_buf); \
128                                          } while (0)
129# define CACHE_MISS_BUF_RSP_PRINT(c)      do { \
130                                              PRINTF("    * cache_miss_buf - size : %d\n",r_##c##cache_miss_buf.size()); \
131                                          } while (0)
132#else                                     
133# define CACHE_MISS_BUF_ALLOC             do { \
134                                              r_icache_miss_val = new bool   * [m_nb_icache]; \
135                                              r_icache_miss_buf = new data_t * [m_nb_icache]; \
136                                              for (uint32_t x=0; x<m_nb_icache;++x) { \
137                                                  r_icache_miss_val [x] = new bool   [m_icache_words]; \
138                                                  r_icache_miss_buf [x] = new data_t [m_icache_words]; \
139                                              } \
140                                              r_dcache_miss_val = new bool   * [m_nb_dcache]; \
141                                              r_dcache_miss_buf = new data_t * [m_nb_dcache]; \
142                                              for (uint32_t x=0; x<m_nb_dcache;++x) { \
143                                                  r_dcache_miss_val [x] = new bool   [m_dcache_words]; \
144                                                  r_dcache_miss_buf [x] = new data_t [m_dcache_words]; \
145                                              } \
146                                          } while (0)
147# define CACHE_MISS_BUF_DEALLOC           do { \
148                                              for (uint32_t x=0; x<m_nb_icache;++x) { \
149                                                  delete [] r_icache_miss_val[x]; \
150                                                  delete [] r_icache_miss_buf[x]; \
151                                              } \
152                                              delete [] r_icache_miss_val; \
153                                              delete [] r_icache_miss_buf; \
154                                              for (uint32_t x=0; x<m_nb_dcache;++x) { \
155                                                  delete [] r_dcache_miss_val[x]; \
156                                                  delete [] r_dcache_miss_buf[x]; \
157                                              } \
158                                              delete [] r_dcache_miss_val; \
159                                              delete [] r_dcache_miss_buf; \
160                                          } while (0)
161# define CACHE_MISS_BUF_RESET(c)           
162# define CACHE_MISS_BUF_REQ_INIT(c,x)     do { \
163                                              for (uint32_t i=0; i<m_##c##cache_words;++i) \
164                                                  r_##c##cache_miss_val[x][i] = false; \
165                                          } while (0)
166# define CACHE_MISS_BUF_RSP_VAL(c,x,n)    r_##c##cache_miss_val[x][n]
167# define CACHE_MISS_BUF_RSP_ACK(c,x)      true
168# define CACHE_MISS_BUF_RSP_DATA(c,x,n)   r_##c##cache_miss_buf[x][n]
169# define CACHE_MISS_BUF_RSP_POP(c,x)         
170# define CACHE_MISS_BUF_RSP_PUSH(c,x,n,d) do { \
171                                              r_##c##cache_miss_val[x][n] = true; \
172                                              r_##c##cache_miss_buf[x][n] = d; \
173                                          } while (0)
174# define CACHE_MISS_BUF_RSP_PRINT(c)      do { \
175                                              for (uint32_t x=0; x<m_nb_##c##cache;++x) \
176                                                  for (uint32_t i=0; i<m_##c##cache_words;++i) \
177                                                      PRINTF("%d %x |",r_##c##cache_miss_val[x][i],r_##c##cache_miss_buf[x][i]); PRINTF("\n"); \
178                                          } while (0)
179#endif
180
181// =====[ MULTI_CACHE ]==============================
182
183#if (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
184# define get_num_icache(     addr,num_cpu)   get_num_cache     (addr)         
185# define get_num_icache_only(addr,num_cpu)   get_num_cache_only(addr)         
186# define set_num_icache(     addr,num_cache) set_num_cache     (addr,num_cache)
187# define set_num_icache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
188# define get_num_dcache(     addr)           get_num_cache     (addr)         
189# define get_num_dcache_only(addr)           get_num_cache_only(addr)         
190# define set_num_dcache(     addr,num_cache) set_num_cache     (addr,num_cache)
191# define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
192#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
193# define get_num_icache(     addr,num_cpu)   num_cpu
194# define get_num_icache_only(addr,num_cpu)   num_cpu
195# define set_num_icache(     addr,num_cache) do  {} while (0)
196# define set_num_icache_only(addr,num_cache) addr
197# define get_num_dcache(     addr)           get_num_cache     (addr)         
198# define get_num_dcache_only(addr)           get_num_cache_only(addr)         
199# define set_num_dcache(     addr,num_cache) set_num_cache     (addr,num_cache)
200# define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
201#else
202#error "Invalid value to CC_XCACHE_WRAPPER_MULTI_CACHE"
203#endif
204
205namespace soclib {
206namespace caba {
207    namespace {
208
209        const char *dcache_fsm_state_str[] = {
210            "DCACHE_IDLE",
211            "DCACHE_WRITE_UPDT",
212            "DCACHE_MISS_VICTIM",
213            "DCACHE_MISS_WAIT",
214            "DCACHE_MISS_UPDT",
215            "DCACHE_UNC_WAIT",
216            "DCACHE_SC_WAIT",
217            "DCACHE_INVAL",
218            "DCACHE_SYNC",
219            "DCACHE_ERROR",
220            "DCACHE_CC_CHECK",
221            "DCACHE_CC_INVAL",
222            "DCACHE_CC_UPDT",
223            "DCACHE_CC_CLEANUP",
224        };
225        const char *icache_fsm_state_str[] = {
226            "ICACHE_IDLE",
227            "ICACHE_MISS_VICTIM",
228            "ICACHE_MISS_WAIT",
229            "ICACHE_MISS_UPDT",
230            "ICACHE_UNC_WAIT",
231            "ICACHE_ERROR",
232            "ICACHE_CC_CLEANUP",
233            "ICACHE_CC_CHECK",
234            "ICACHE_CC_INVAL",
235            "ICACHE_CC_UPDT",
236        };
237        const char *cmd_fsm_state_str[] = {
238            "CMD_IDLE",
239            "CMD_INS_MISS",
240            "CMD_INS_UNC",
241            "CMD_DATA_MISS",
242            "CMD_DATA_UNC",
243            "CMD_DATA_WRITE",
244            "CMD_DATA_SC",
245        };
246        const char *rsp_fsm_state_str[] = {
247            "RSP_IDLE",
248            "RSP_INS_MISS",
249            "RSP_INS_UNC",
250            "RSP_DATA_MISS",
251            "RSP_DATA_UNC",
252            "RSP_DATA_WRITE",
253            "RSP_DATA_SC",
254        };
255        const char *tgt_fsm_state_str[] = {
256            "TGT_IDLE",
257            "TGT_UPDT_WORD",
258            "TGT_UPDT_DATA",
259            "TGT_REQ_BROADCAST",
260            "TGT_REQ_ICACHE",
261            "TGT_REQ_DCACHE",
262            "TGT_RSP_BROADCAST",
263            "TGT_RSP_ICACHE",
264            "TGT_RSP_DCACHE",
265        };
266
267        const char *cleanup_fsm_state_str[] = {
268            "CLEANUP_IDLE",
269            "CLEANUP_REQ",
270            "CLEANUP_RSP_DCACHE",
271            "CLEANUP_RSP_ICACHE",
272        };
273    }
274
275typedef long long unsigned int blob_t;
276
277#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
278
279    using soclib::common::uint32_log2;
280
281    /////////////////////////////////
282    tmpl(/**/)::VciCcXCacheWrapperV4(
283    /////////////////////////////////
284            sc_module_name name,
285            int proc_id,
286            const soclib::common::MappingTable &mtp,
287            const soclib::common::MappingTable &mtc,
288            const soclib::common::IntTab &initiator_index_rw,
289            const soclib::common::IntTab &initiator_index_c,
290            const soclib::common::IntTab &target_index,
291            size_t nb_cpu,
292            size_t nb_dcache,
293            size_t icache_ways,
294            size_t icache_sets,
295            size_t icache_words,
296            size_t dcache_ways,
297            size_t dcache_sets,
298            size_t dcache_words,
299            size_t wbuf_nwords,
300            size_t wbuf_nlines,
301            size_t wbuf_timeout
302                                     )
303        :
304            soclib::caba::BaseModule(name),
305
306            p_clk       ("clk"),
307            p_resetn    ("resetn"),
308            p_vci_ini_rw("vci_ini_rw"),
309            p_vci_ini_c ("vci_ini_c"),
310            p_vci_tgt   ("vci_tgt"),
311
312            m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
313            m_segment(mtc.getSegment(target_index)),
314            m_srcid_rw(mtp.indexForId(initiator_index_rw)),
315            m_srcid_c(mtc.indexForId(initiator_index_c)),
316
317            m_nb_cpu(nb_cpu),
318#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
319            m_nb_icache(nb_dcache),
320#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
321            m_nb_icache(m_nb_cpu),
322#endif
323            m_nb_dcache(nb_dcache),
324            m_nb_cache((m_nb_dcache>m_nb_icache)?m_nb_dcache:m_nb_icache),
325            m_dcache_ways(dcache_ways),
326            m_dcache_words(dcache_words),
327            m_dcache_words_shift(uint32_log2(dcache_words)+uint32_log2(sizeof(data_t))),
328            m_dcache_yzmask((~0)<<m_dcache_words_shift),
329            m_icache_ways(icache_ways),
330            m_icache_words(icache_words),
331            m_icache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))),
332            m_icache_yzmask((~0)<<m_icache_words_shift),
333            m_cache_words((dcache_words)?dcache_words:icache_words),
334
335            r_cpu_prior("r_cpu_prior"),
336
337            r_vci_cmd_fsm("r_vci_cmd_fsm"),
338            r_vci_cmd_min("r_vci_cmd_min"),
339            r_vci_cmd_max("r_vci_cmd_max"),
340            r_vci_cmd_cpt("r_vci_cmd_cpt"),
341            r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"),
342            r_vci_cmd_num_cache("r_vci_cmd_num_cache"),
343
344            r_vci_rsp_fsm("r_vci_rsp_fsm"),
345            r_vci_rsp_cpt("r_vci_rsp_cpt"),
346          //s_vci_rsp_ack("s_vci_rsp_ack"),
347            r_vci_rsp_num_cache("r_vci_rsp_num_cache"),
348
349#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
350            r_cache_word("r_cache_word"),
351#endif
352
353            r_vci_tgt_fsm("r_vci_tgt_fsm"),
354            r_tgt_iaddr("r_tgt_iaddr"),
355            r_tgt_daddr("r_tgt_daddr"),
356            r_tgt_word("r_tgt_word"),
357            r_tgt_update("r_tgt_update"),
358            r_tgt_update_data("r_tgt_update_data"),
359         // r_tgt_brdcast("r_tgt_brdcast"),
360            r_tgt_srcid("r_tgt_srcid"),
361            r_tgt_pktid("r_tgt_pktid"),
362            r_tgt_trdid("r_tgt_trdid"),
363         // r_tgt_plen("r_tgt_plen"),
364            r_tgt_num_cache("r_tgt_num_cache"),
365
366            r_cleanup_fsm("r_cleanup_fsm"),
367            r_cleanup_num_cache("r_cleanup_num_cache"),
368            r_cleanup_icache("r_cleanup_icache"),
369
370            m_num_cache_LSB(uint32_log2(icache_words) + uint32_log2(sizeof(data_t))),
371            m_num_cache_MSB(uint32_log2(nb_dcache) + m_num_cache_LSB)
372            {
373                // Size of word is 32 bits
374                ASSERT((icache_words*vci_param::B) < (1<<vci_param::K),
375                       "Need more PLEN bits.");
376
377                ASSERT((vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines/m_nb_dcache)),
378                       "Need more TRDID bits.");
379
380                ASSERT(uint32_log2(nb_dcache) <= (1<<vci_param::P),
381                       "Need more PKTID bits.");
382               
383                ASSERT(IS_POW_OF_2(m_nb_dcache),
384                       "nb_dcache must be a power of 2.");
385
386                ASSERT(IS_POW_OF_2(m_nb_cpu) and (m_nb_cpu <= m_nb_dcache) and (m_nb_cpu > 0),
387                       "nb cpu must be a multiple of nb cache.");
388
389                ASSERT(IS_POW_OF_2(m_icache_ways) and (m_nb_icache <= m_icache_ways),
390                       "nb icache ways must be a multiple of nb cache.");
391
392                ASSERT(IS_POW_OF_2(m_dcache_ways) and (m_nb_dcache <= m_dcache_ways),
393                       "nb dcache ways must be a multiple of nb cache.");
394
395                ASSERT(icache_words == dcache_words,
396                       "icache_words must be equal at dcache_words.");
397
398                ASSERT(IS_POW_OF_2(wbuf_nlines) and (m_nb_dcache <= wbuf_nlines),
399                       "wbuf_nlines must be a multiple of nb cache.");
400
401                // FIXME : s'adapter à la taille des requêtes XTN_READ/XTN_WRITE
402                ASSERT((m_nb_dcache == 1) or (dcache_words >= 16),
403                       "When multi cache is activated, need 4 bits (16 word) to the cache set .");
404
405                if (m_nb_cpu > 1)
406                    ASSERT(CC_XCACHE_MULTI_CPU!=0,
407                           "Macro CC_XCACHE_MULTI_CPU in wbuf must be set at 1.");
408
409                p_irq = new sc_in<bool> * [m_nb_cpu];
410                for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
411                    p_irq [num_cpu] = new sc_in<bool> [iss_t::n_irq];
412
413                m_iss = new iss_t * [m_nb_cpu];
414                for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
415                {
416                    std::ostringstream iss_name("");
417                    iss_name << this->name() << "_" << num_cpu;
418
419                    m_iss[num_cpu] = new iss_t (iss_name.str().c_str(), proc_id+num_cpu);
420                }
421               
422                CACHE_MISS_BUF_ALLOC;
423
424                r_icache_lock          = new sc_signal<uint32_t>[m_nb_icache];
425                r_dcache_lock          = new sc_signal<uint32_t>[m_nb_dcache];
426                r_dcache_sync          = new sc_signal<bool>    [m_nb_dcache];
427
428                r_icache_fsm           = new sc_signal<int>     [m_nb_icache];
429                r_icache_fsm_save      = new sc_signal<int>     [m_nb_icache];
430                r_icache_addr_save     = new sc_signal<addr_40> [m_nb_icache];
431                r_icache_miss_req      = new sc_signal<bool>    [m_nb_icache];
432                r_icache_miss_way      = new sc_signal<size_t>  [m_nb_icache];
433                r_icache_miss_set      = new sc_signal<size_t>  [m_nb_icache];
434                r_icache_unc_req       = new sc_signal<bool>    [m_nb_icache];
435                r_icache_cleanup_req   = new sc_signal<bool>    [m_nb_icache];
436                r_icache_cleanup_line  = new sc_signal<addr_40> [m_nb_icache];
437                r_icache_inval_rsp     = new sc_signal<bool>    [m_nb_icache];
438                r_icache_update_addr   = new sc_signal<size_t>  [m_nb_icache];
439                r_icache_buf_unc_valid = new sc_signal<bool>    [m_nb_icache];
440
441                r_dcache_fsm           = new sc_signal<int>     [m_nb_dcache];
442                r_dcache_fsm_save      = new sc_signal<int>     [m_nb_dcache];
443                r_dcache_addr_save     = new sc_signal<addr_40> [m_nb_dcache];
444                r_dcache_wdata_save    = new sc_signal<data_t>  [m_nb_dcache];
445                r_dcache_rdata_save    = new sc_signal<data_t>  [m_nb_dcache];
446                r_dcache_type_save     = new sc_signal<int>     [m_nb_dcache];
447                r_dcache_be_save       = new sc_signal<be_t>    [m_nb_dcache];
448                r_dcache_cached_save   = new sc_signal<bool>    [m_nb_dcache];
449                r_dcache_cleanup_req   = new sc_signal<bool>    [m_nb_dcache];
450                r_dcache_cleanup_line  = new sc_signal<addr_40> [m_nb_dcache];
451                r_dcache_miss_req      = new sc_signal<bool>    [m_nb_dcache];
452                r_dcache_miss_way      = new sc_signal<size_t>  [m_nb_dcache];
453                r_dcache_miss_set      = new sc_signal<size_t>  [m_nb_dcache];
454                r_dcache_unc_req       = new sc_signal<bool>    [m_nb_dcache];
455                r_dcache_sc_req        = new sc_signal<bool>    [m_nb_dcache];
456                r_dcache_inval_rsp     = new sc_signal<bool>    [m_nb_dcache];
457                r_dcache_update_addr   = new sc_signal<size_t>  [m_nb_dcache];
458                r_dcache_previous_unc  = new sc_signal<bool>    [m_nb_dcache];
459
460                r_dcache_num_cpu_save  = new sc_signal<uint32_t>   [m_nb_dcache];
461                r_dcache_ll_data       = new sc_signal<data_64>  * [m_nb_dcache];
462                r_dcache_ll_addr       = new sc_signal<addr_40>  * [m_nb_dcache];
463                r_dcache_ll_valid      = new sc_signal<bool>     * [m_nb_dcache];
464                for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
465                {
466                    r_dcache_ll_data    [num_cache] = new sc_signal<data_64>  [m_nb_cpu];
467                    r_dcache_ll_addr    [num_cache] = new sc_signal<addr_40>  [m_nb_cpu];
468                    r_dcache_ll_valid   [num_cache] = new sc_signal<bool>     [m_nb_cpu];
469                }
470
471                r_tgt_icache_req       = new sc_signal<bool>    [m_nb_icache];
472                r_tgt_icache_rsp       = new sc_signal<bool>    [m_nb_icache];
473                r_tgt_dcache_req       = new sc_signal<bool>    [m_nb_dcache];
474                r_tgt_dcache_rsp       = new sc_signal<bool>    [m_nb_dcache];
475
476                r_tgt_buf              = new data_t             [m_cache_words];
477                r_tgt_be               = new be_t               [m_cache_words];
478
479                r_vci_rsp_ins_error    = new sc_signal<bool>    [m_nb_icache];
480                r_vci_rsp_data_error   = new sc_signal<bool>    [m_nb_dcache];
481
482                ireq                   = new typename iss_t::InstructionRequest  [m_nb_icache];
483                irsp                   = new typename iss_t::InstructionResponse [m_nb_icache];
484                ireq_cached            = new bool                                [m_nb_icache];
485                ireq_num_cpu           = new uint32_t                            [m_nb_dcache];
486
487                dreq                   = new typename iss_t::DataRequest         [m_nb_dcache];
488                drsp                   = new typename iss_t::DataResponse        [m_nb_dcache];
489                dreq_cached            = new bool                                [m_nb_dcache];
490                dreq_num_cpu           = new uint32_t                            [m_nb_dcache];
491
492                m_cpt_icache_access = new uint32_t [m_nb_icache];
493                m_cpt_dcache_access = new uint32_t [m_nb_dcache];
494
495               
496                m_cpt_fsm_dcache  = new uint32_t * [m_nb_dcache];
497                m_cpt_fsm_icache  = new uint32_t * [m_nb_icache];
498                for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
499                    m_cpt_fsm_dcache[num_cache]  = new uint32_t [soclib::common::size(dcache_fsm_state_str )];
500                for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
501                    m_cpt_fsm_icache[num_cache]  = new uint32_t [soclib::common::size(icache_fsm_state_str )];
502                m_cpt_fsm_cmd     = new uint32_t [soclib::common::size(cmd_fsm_state_str    )];
503                m_cpt_fsm_rsp     = new uint32_t [soclib::common::size(rsp_fsm_state_str    )];
504                m_cpt_fsm_tgt     = new uint32_t [soclib::common::size(tgt_fsm_state_str    )];
505                m_cpt_fsm_cleanup = new uint32_t [soclib::common::size(cleanup_fsm_state_str)];
506
507                m_cpt_frz_cycles  = new uint32_t [m_nb_cpu];
508                // r_icache_fsm("r_icache_fsm"),
509                // r_icache_fsm_save("r_icache_fsm_save"),
510                // r_icache_addr_save("r_icache_addr_save"),
511                // r_icache_miss_req("r_icache_miss_req"),
512                // r_icache_miss_way("r_icache_miss_way"),
513                // r_icache_miss_set("r_icache_miss_set"),
514                // r_icache_unc_req("r_icache_unc_req"),
515                // r_icache_cleanup_req("r_icache_cleanup_req"),
516                // r_icache_cleanup_line("r_icache_cleanup_line"),
517                // r_icache_inval_rsp("r_icache_inval_rsp"),
518                // r_icache_update_addr("r_icache_update_addr"),
519                // r_icache_buf_unc_valid("r_icache_buf_unc_valid"),
520
521                // r_dcache_fsm("r_dcache_fsm"),
522                // r_dcache_fsm_save("r_dcache_fsm_save"),
523                // r_dcache_addr_save("r_dcache_addr_save"),
524                // r_dcache_wdata_save("r_dcache_wdata_save"),
525                // r_dcache_rdata_save("r_dcache_rdata_save"),
526                // r_dcache_type_save("r_dcache_type_save"),
527                // r_dcache_be_save("r_dcache_be_save"),
528                // r_dcache_cached_save("r_dcache_cached_save"),
529                // r_dcache_cleanup_req("r_dcache_cleanup_req"),
530                // r_dcache_cleanup_line("r_dcache_cleanup_line"),
531                // r_dcache_miss_req("r_dcache_miss_req"),
532                // r_dcache_miss_way("r_dcache_miss_way"),
533                // r_dcache_miss_set("r_dcache_miss_set"),
534                // r_dcache_unc_req("r_dcache_unc_req"),
535                // r_dcache_sc_req("r_dcache_sc_req"),
536                // r_dcache_inval_rsp("r_dcache_inval_rsp"),
537                // r_dcache_update_addr("r_dcache_update_addr"),
538                // r_dcache_ll_data("r_dcache_ll_data"),
539                // r_dcache_ll_addr("r_dcache_ll_addr"),
540                // r_dcache_ll_valid("r_dcache_ll_valid"),
541                // r_dcache_previous_unc("r_dcache_previous_unc"),
542
543                // r_tgt_icache_req("r_tgt_icache_req"),
544                // r_tgt_icache_rsp("r_tgt_icache_rsp"),
545
546                // r_tgt_dcache_req("r_tgt_dcache_req"),
547                // r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
548
549                // r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
550                // r_vci_rsp_data_error("r_vci_rsp_data_error"),
551
552                size_t _icache_ways  = icache_ways /m_nb_icache;
553                size_t _icache_sets  = icache_sets ;
554                size_t _dcache_ways  = dcache_ways /m_nb_dcache;
555                size_t _dcache_sets  = dcache_sets ;
556                size_t _icache_words = icache_words;
557                size_t _dcache_words = dcache_words;
558
559                size_t _wbuf_nwords  = wbuf_nwords ;
560                size_t _wbuf_nlines  = wbuf_nlines /m_nb_dcache;
561                size_t _wbuf_timeout = wbuf_timeout;
562
563
564#if CC_XCACHE_WRAPPER_VERBOSE
565                std::cout << "<VciCcXCacheWrapperV4> Parameters :" << std::endl;
566                std::cout << "  * nb_cpu             : " << nb_cpu << std::endl;
567                std::cout << "  * nb_cache           : " << m_nb_icache << " icache(s), " << m_nb_dcache << " dcache(s)" << std::endl;
568                std::cout << "  * icache (total)     : " <<  icache_ways << " way(s), " <<  icache_sets << " set(s), " <<  icache_words << " word(s)" << std::endl;
569                std::cout << "  * icache (per cache) : " << _icache_ways << " way(s), " << _icache_sets << " set(s), " << _icache_words << " word(s)" << std::endl;
570                std::cout << "  * dcache (total)     : " <<  dcache_ways << " way(s), " <<  dcache_sets << " set(s), " <<  dcache_words << " word(s)" << std::endl;
571                std::cout << "  * dcache (per cache) : " << _dcache_ways << " way(s), " << _dcache_sets << " set(s), " << _dcache_words << " word(s)" << std::endl;
572                std::cout << "  * wbuf   (total)     : " <<  wbuf_nlines << " line(s), " <<  wbuf_nwords << " word(s), timeout : " <<  wbuf_timeout << std::endl;
573                std::cout << "  * wbuf   (per cache) : " << _wbuf_nlines << " line(s), " << _wbuf_nwords << " word(s), timeout : " << _wbuf_timeout << std::endl;
574#endif
575
576                r_icache = new GenericCache<vci_addr_t>  * [m_nb_icache];
577                r_dcache = new GenericCache<vci_addr_t>  * [m_nb_dcache];
578                r_wbuf   = new MultiWriteBuffer<addr_40> * [m_nb_dcache];
579
580               for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
581                {
582                    r_icache [num_cache] = new GenericCache<vci_addr_t>  ("icache", _icache_ways, _icache_sets, _icache_words);
583                }
584               for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
585                {
586                    r_dcache [num_cache] = new GenericCache<vci_addr_t>  ("dcache", _dcache_ways, _dcache_sets, _dcache_words);
587                    r_wbuf   [num_cache] = new MultiWriteBuffer<addr_40> ("r_wbuf", _wbuf_nwords, _wbuf_nlines, _wbuf_timeout, _dcache_words);
588                }
589
590                m_num_cache_LSB_mask = 0;
591                for (uint32_t i=0; i<m_num_cache_LSB; ++i)
592                {
593                    m_num_cache_LSB_mask <<= 1;
594                    m_num_cache_LSB_mask  |= 1;
595                }
596                m_num_cache_mask = 0;
597                for (uint32_t i=0; i<(m_num_cache_MSB-m_num_cache_LSB); ++i)
598                {
599                    m_num_cache_mask <<= 1;
600                    m_num_cache_mask  |= 1;
601                }
602
603                SC_METHOD(transition);
604                dont_initialize();
605                sensitive << p_clk.pos();
606
607                SC_METHOD(genMoore);
608                dont_initialize();
609                sensitive << p_clk.neg();
610
611                typename iss_t::CacheInfo cache_info;
612                cache_info.has_mmu          = false;
613                cache_info.icache_line_size = icache_words*sizeof(data_t);
614                cache_info.icache_assoc     = icache_ways;
615                cache_info.icache_n_lines   = icache_sets;
616                cache_info.dcache_line_size = dcache_words*sizeof(data_t);
617                cache_info.dcache_assoc     = dcache_ways;
618                cache_info.dcache_n_lines   = dcache_sets;
619
620                for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
621                    m_iss[num_cpu]->setCacheInfo(cache_info);
622               
623#if CC_XCACHE_WRAPPER_STOP_SIMULATION
624                m_stop_simulation               = false;
625                m_stop_simulation_nb_frz_cycles = new uint32_t [m_nb_cpu];
626                for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
627                m_stop_simulation_nb_frz_cycles [num_cpu] = 0;
628#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
629
630#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
631                log_transaction_file_icache = new std::ofstream [m_nb_cpu];
632                log_transaction_file_dcache = new std::ofstream [m_nb_cpu];
633                for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
634                {
635                    {
636                        std::ostringstream filename("");
637                        filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_icache-" << proc_id << "_" << num_cpu << ".log";
638                        log_transaction_file_icache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
639                    }
640                    {
641                        std::ostringstream filename("");
642                        filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_dcache-" << proc_id << "_" << num_cpu << ".log";
643                        log_transaction_file_dcache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
644                    }
645                }
646
647                {
648                    std::ostringstream filename("");
649                    filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cmd-" << proc_id << ".log";
650                    log_transaction_file_cmd.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
651                }
652                {
653                    std::ostringstream filename("");
654                    filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_tgt-" << proc_id << ".log";
655                    log_transaction_file_tgt.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
656                }
657                {
658                    std::ostringstream filename("");
659                    filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cleanup-" << proc_id << ".log";
660                    log_transaction_file_cleanup.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
661                }
662#endif
663            } // end constructor
664
665    ///////////////////////////////////
666    tmpl(/**/)::~VciCcXCacheWrapperV4()
667    ///////////////////////////////////
668    {
669        delete [] m_stop_simulation_nb_frz_cycles;
670
671#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
672        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
673        {
674            log_transaction_file_dcache[num_cpu].close();
675            log_transaction_file_icache[num_cpu].close();
676        }
677        delete [] log_transaction_file_dcache;
678        delete [] log_transaction_file_icache;
679
680        log_transaction_file_cmd    .close();
681        log_transaction_file_tgt    .close();
682        log_transaction_file_cleanup.close();
683#endif
684
685        delete [] r_icache_lock         ;
686        delete [] r_dcache_lock         ;
687        delete [] r_dcache_sync         ;
688
689        delete [] r_icache_fsm          ;
690        delete [] r_icache_fsm_save     ;
691        delete [] r_icache_addr_save    ;
692        delete [] r_icache_miss_req     ;
693        delete [] r_icache_miss_way     ;
694        delete [] r_icache_miss_set     ;
695        delete [] r_icache_unc_req      ;
696        delete [] r_icache_cleanup_req  ;
697        delete [] r_icache_cleanup_line ;
698        delete [] r_icache_inval_rsp    ;
699        delete [] r_icache_update_addr  ;
700        delete [] r_icache_buf_unc_valid;
701
702        delete [] r_dcache_fsm          ;
703        delete [] r_dcache_fsm_save     ;
704        delete [] r_dcache_addr_save    ;
705        delete [] r_dcache_wdata_save   ;
706        delete [] r_dcache_rdata_save   ;
707        delete [] r_dcache_type_save    ;
708        delete [] r_dcache_be_save      ;
709        delete [] r_dcache_cached_save  ;
710        delete [] r_dcache_cleanup_req  ;
711        delete [] r_dcache_cleanup_line ;
712        delete [] r_dcache_miss_req     ;
713        delete [] r_dcache_miss_way     ;
714        delete [] r_dcache_miss_set     ;
715        delete [] r_dcache_unc_req      ;
716        delete [] r_dcache_sc_req       ;
717        delete [] r_dcache_inval_rsp    ;
718        delete [] r_dcache_update_addr  ;
719        delete [] r_dcache_previous_unc ;
720
721        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
722        {
723            delete [] r_dcache_ll_data    [num_cache];
724            delete [] r_dcache_ll_addr    [num_cache];
725            delete [] r_dcache_ll_valid   [num_cache];
726        }
727        delete [] r_dcache_num_cpu_save ;
728        delete [] r_dcache_ll_data      ;
729        delete [] r_dcache_ll_addr      ;
730        delete [] r_dcache_ll_valid     ;
731
732        delete [] r_tgt_icache_req      ;
733        delete [] r_tgt_icache_rsp      ;
734        delete [] r_tgt_dcache_req      ;
735        delete [] r_tgt_dcache_rsp      ;
736
737        delete [] r_tgt_be ;
738        delete [] r_tgt_buf;
739
740        delete [] r_vci_rsp_ins_error   ;
741        delete [] r_vci_rsp_data_error  ;
742
743        delete [] ireq           ;
744        delete [] irsp           ;
745        delete [] ireq_cached    ;
746        delete [] ireq_num_cpu   ;
747        delete [] dreq           ;
748        delete [] drsp           ;
749        delete [] dreq_cached    ;
750        delete [] dreq_num_cpu   ;
751
752        delete [] m_cpt_frz_cycles;
753
754        delete [] m_cpt_icache_access   ;
755        delete [] m_cpt_dcache_access   ;
756
757        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
758        delete [] m_cpt_fsm_dcache [num_cache];
759        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
760        delete [] m_cpt_fsm_icache [num_cache];
761       
762        delete [] m_cpt_fsm_dcache ;
763        delete [] m_cpt_fsm_icache ;
764        delete [] m_cpt_fsm_cmd    ;
765        delete [] m_cpt_fsm_rsp    ;
766        delete [] m_cpt_fsm_tgt    ;
767        delete [] m_cpt_fsm_cleanup;
768
769        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
770        {
771            delete r_icache [num_cache];
772        }
773        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
774        {
775            delete r_wbuf   [num_cache];
776            delete r_dcache [num_cache];
777        }
778        delete [] r_wbuf;
779        delete [] r_icache;
780        delete [] r_dcache;
781
782
783        CACHE_MISS_BUF_DEALLOC;
784
785        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
786        {
787            delete    m_iss [num_cpu];
788            delete [] p_irq [num_cpu];
789        }
790        delete [] m_iss;
791        delete [] p_irq;
792    }
793
794    ////////////////////////
795    tmpl(void)::print_cpi()
796    ////////////////////////
797    {
798        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
799        std::cout << "CPU " << m_srcid_rw << " : CPI = "
800                  << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]) << std::endl ;
801    }
802    ////////////////////////
803    tmpl(void)::print_stats()
804    ////////////////////////
805    {
806        uint32_t m_cpt_data_read_cached  = m_cpt_data_read-m_cpt_data_read_uncached;
807        uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached;
808        std::cout << "------------------------------------" << std:: dec << std::endl;
809        std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
810        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
811        {
812            float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]);
813
814            std::cout << "- CPI                            : [" << num_cpu << "] "<< (float)m_cpt_total_cycles/run_cycles << std::endl ;
815            std::cout << "- IPC                            : [" << num_cpu << "] "<< (float)run_cycles/m_cpt_total_cycles << std::endl ;
816        }
817        std::cout << "- DATA READ *                    : " << m_cpt_data_read << std::endl ;
818        std::cout << "  + Uncached                     : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ;
819        std::cout << "  + Cached and miss              : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl;
820        std::cout << "- DATA WRITE *                   : " << m_cpt_data_write << std::endl ;
821        std::cout << "  + Uncached                     : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ;
822        std::cout << "  + Cached and miss              : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl;
823        // std::cout << "- WRITE RATE                     : " << (float)m_cpt_data_write/run_cycles << std::endl;
824        // std::cout << "- UNCACHED READ RATE             : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ;
825        // std::cout << "- CACHED WRITE RATE              : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ;
826        // std::cout << "- IMISS_RATE                     : " << (float)m_cpt_ins_miss/run_cycles << std::endl;
827        // std::cout << "- DMISS RATE                     : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ;
828        // std::cout << "- INS MISS COST                  : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
829        // std::cout << "- IMISS TRANSACTION              : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
830        // std::cout << "- DMISS COST                     : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
831        // std::cout << "- DMISS TRANSACTION              : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
832        // std::cout << "- UNC COST                       : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl;
833        // std::cout << "- UNC TRANSACTION                : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
834        // std::cout << "- WRITE COST                     : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl;
835        // std::cout << "- WRITE TRANSACTION              : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl;
836        // std::cout << "- WRITE LENGTH                   : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl;
837
838        std::cout << "- CC_UPDATE_ICACHE               : " << m_cpt_cc_update_icache  << std::endl;
839        std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl;
840        std::cout << "- CC_UPDATE_DCACHE               : " << m_cpt_cc_update_dcache  << std::endl;
841        std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl;
842        uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache;
843        std::cout << "- CC_INVALID                     : " << m_cpt_cc_inval << std::endl;
844        std::cout << "  + ICACHE Only                  : " << (float)m_cpt_cc_inval_icache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
845        std::cout << "  + DCACHE Only                  : " << (float)m_cpt_cc_inval_dcache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
846        std::cout << "  + BROADCAST                    : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl;
847
848        uint32_t m_cpt_icache_access_all = 0;
849        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
850            m_cpt_icache_access_all += m_cpt_icache_access [num_cache];
851
852        std::cout << "- ICACHE ACCESS                  : " << m_cpt_icache_access_all << std::endl;
853        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
854            std::cout << "  + [" << num_cache << "] : " << m_cpt_icache_access [num_cache] << " (" << (float)m_cpt_icache_access [num_cache]*100.0/(float)m_cpt_icache_access_all << "%)" << std::endl;
855
856        uint32_t m_cpt_dcache_access_all = 0;
857        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
858            m_cpt_dcache_access_all += m_cpt_dcache_access [num_cache];
859
860        std::cout << "- DCACHE ACCESS                  : " << m_cpt_dcache_access_all << std::endl;
861        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
862            std::cout << "  + [" << num_cache << "] : " << m_cpt_dcache_access [num_cache] << " (" << (float)m_cpt_dcache_access [num_cache]*100.0/(float)m_cpt_dcache_access_all << "%)" << std::endl;
863
864        std::cout << "- DCACHE FSM" << std::endl;
865        for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
866        {
867            std::cout << "  + "  << dcache_fsm_state_str[i] << " :\t ";
868            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
869                std::cout << m_cpt_fsm_dcache [num_cache][i] << ", ";
870            std::cout << std::endl;
871        }
872        std::cout << "- ICACHE FSM" << std::endl;
873        for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
874        {
875            std::cout << "  + "  << icache_fsm_state_str[i] << " :\t ";
876            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
877                std::cout << m_cpt_fsm_icache [num_cache][i] << ", ";
878            std::cout << std::endl;
879        }
880        std::cout << "- CMD FSM" << std::endl;
881        for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i)
882            std::cout << "  + " << cmd_fsm_state_str[i] << " :\t " << m_cpt_fsm_cmd [i] << std::endl;
883        std::cout << "- RSP FSM" << std::endl;
884        for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i)
885            std::cout << "  + " << rsp_fsm_state_str[i] << " :\t " << m_cpt_fsm_rsp [i] << std::endl;
886        std::cout << "- TGT FSM" << std::endl;
887        for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i)
888            std::cout << "  + "  << tgt_fsm_state_str[i] << " :\t " << m_cpt_fsm_tgt [i] << std::endl;
889        std::cout << "- CLEANUP FSM" << std::endl;
890        for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i)
891            std::cout << "  + "  << cleanup_fsm_state_str[i] << " :\t " << m_cpt_fsm_cleanup [i] << std::endl;
892
893        std::cout << "* : accepted or not by the cache" << std::endl ;
894
895        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
896            r_wbuf[num_cache]->printStatistics();
897    }
898
899    ////////////////////////////////////
900    tmpl(void)::print_trace(size_t mode)
901    ////////////////////////////////////
902    {
903        // b0 : write buffer print trace
904        // b1 : write buffer verbose
905        // b2 : dcache print trace
906        // b3 : icache print trace
907
908        typename iss_t::InstructionRequest  ireq;
909        typename iss_t::DataRequest         dreq;
910
911        std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl;
912
913        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
914        {
915            m_iss[num_cpu]->getRequests( ireq, dreq );
916            std::cout << ireq << std::endl;
917            std::cout << dreq << std::endl;
918        }
919        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
920        std::cout << "  " << icache_fsm_state_str[r_icache_fsm[num_cache]] << std::endl;
921        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
922        std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm[num_cache]] << std::endl;
923           
924        std::cout << "  " << cmd_fsm_state_str[r_vci_cmd_fsm]
925                  << "  " << rsp_fsm_state_str[r_vci_rsp_fsm]
926                  << "  " << tgt_fsm_state_str[r_vci_tgt_fsm]
927                  << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
928
929        if(mode & 0x1)
930        {
931            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
932                r_wbuf[num_cache]->printTrace((mode>>1)&1);
933        }
934        if(mode & 0x4)
935        {
936            std::cout << "  Data cache" << std::endl;
937            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
938                r_dcache[num_cache]->printTrace();
939        }
940        if(mode & 0x8)
941        {
942            std::cout << "  Instruction cache" << std::endl;
943            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
944                r_icache[num_cache]->printTrace();
945        }
946    }
947
948    //////////////////////////
949    tmpl(void)::transition()
950    //////////////////////////
951    {
952        if ( not p_resetn.read() ) {
953
954            r_cpu_prior = 0;
955
956            for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
957                m_iss[num_cpu]->reset();
958
959            // FSM states
960            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
961            {
962                r_icache_fsm [num_cache] = ICACHE_IDLE;
963
964                r_icache_lock[num_cache] = m_nb_cpu;
965            }
966            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
967            {
968                r_dcache_fsm [num_cache] = DCACHE_IDLE;
969
970                r_dcache_lock[num_cache] = m_nb_cpu;
971                r_dcache_sync[num_cache] = false;
972            }
973
974            r_vci_cmd_fsm = CMD_IDLE;
975            r_vci_rsp_fsm = RSP_IDLE;
976            r_vci_tgt_fsm = TGT_IDLE;
977            r_cleanup_fsm = CLEANUP_IDLE;
978
979            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
980            {
981            // write buffer & caches
982            r_icache[num_cache]->reset();
983
984            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
985            r_icache_miss_req    [num_cache] = false;
986            r_icache_unc_req     [num_cache] = false;
987            r_icache_cleanup_req [num_cache] = false;
988
989            // internal messages in DCACHE et ICACHE FSMs
990            r_icache_inval_rsp   [num_cache] = false;
991
992            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
993            r_icache_buf_unc_valid [num_cache] = false;
994
995            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
996            r_tgt_icache_req     [num_cache] = false;
997            r_tgt_icache_rsp     [num_cache] = false;
998
999            r_vci_rsp_ins_error  [num_cache] = false;
1000            }// end for num_cache
1001
1002            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1003            {
1004            // write buffer & caches
1005            r_wbuf  [num_cache]->reset();
1006            r_dcache[num_cache]->reset();
1007
1008            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
1009            r_dcache_miss_req    [num_cache] = false;
1010            r_dcache_unc_req     [num_cache] = false;
1011            r_dcache_sc_req      [num_cache] = false;
1012            r_dcache_cleanup_req [num_cache] = false;
1013            r_dcache_previous_unc[num_cache] = false;
1014
1015            // internal messages in DCACHE et ICACHE FSMs
1016            r_dcache_inval_rsp   [num_cache] = false;
1017
1018            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
1019            for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
1020                r_dcache_ll_valid      [num_cache][num_cpu] = false;
1021
1022            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
1023            r_tgt_dcache_req     [num_cache] = false;
1024            r_tgt_dcache_rsp     [num_cache] = false;
1025
1026            r_vci_rsp_data_error [num_cache] = false;
1027            }// end for num_cache
1028
1029#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
1030            r_cache_word         = 0;
1031#endif
1032
1033            r_vci_cmd_dcache_prior = false;
1034
1035            CACHE_MISS_BUF_RESET(i);
1036            CACHE_MISS_BUF_RESET(d);
1037
1038            // activity counters
1039            m_cpt_dcache_data_read  = 0;
1040            m_cpt_dcache_data_write = 0;
1041            m_cpt_dcache_dir_read   = 0;
1042            m_cpt_dcache_dir_write  = 0;
1043            m_cpt_icache_data_read  = 0;
1044            m_cpt_icache_data_write = 0;
1045            m_cpt_icache_dir_read   = 0;
1046            m_cpt_icache_dir_write  = 0;
1047
1048            m_cpt_cc_update_icache             = 0;
1049            m_cpt_cc_update_dcache             = 0;
1050            m_cpt_cc_inval_broadcast           = 0;
1051            m_cpt_cc_inval_icache              = 0;
1052            m_cpt_cc_inval_dcache              = 0;
1053            m_cpt_cc_update_icache_word_useful = 0;
1054            m_cpt_cc_update_dcache_word_useful = 0;
1055
1056            for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
1057            m_cpt_frz_cycles [num_cpu]  = 0;
1058            m_cpt_total_cycles = 0;
1059
1060            m_cpt_data_read            = 0;
1061            m_cpt_data_read_miss       = 0;
1062            m_cpt_data_read_uncached   = 0;
1063            m_cpt_data_write           = 0;
1064            m_cpt_data_write_miss      = 0;
1065            m_cpt_data_write_uncached  = 0;
1066
1067            m_cpt_ins_miss     = 0;
1068
1069            m_cost_write_frz = 0;
1070            m_cost_data_miss_frz = 0;
1071            m_cost_unc_read_frz = 0;
1072            m_cost_ins_miss_frz = 0;
1073
1074            m_cpt_imiss_transaction = 0;
1075            m_cpt_dmiss_transaction = 0;
1076            m_cpt_unc_transaction = 0;
1077            m_cpt_data_write_transaction = 0;
1078
1079            m_cost_imiss_transaction = 0;
1080            m_cost_dmiss_transaction = 0;
1081            m_cost_unc_transaction = 0;
1082            m_cost_write_transaction = 0;
1083            m_length_write_transaction = 0;
1084
1085            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1086            {
1087                m_cpt_icache_access [num_cache] = 0;
1088
1089                for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
1090                    m_cpt_fsm_icache  [num_cache][i] = 0;
1091            }
1092            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1093            {
1094                m_cpt_dcache_access [num_cache] = 0;
1095
1096                for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
1097                    m_cpt_fsm_dcache  [num_cache][i] = 0;
1098            }
1099
1100            for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str    ); ++i)
1101                m_cpt_fsm_cmd     [i] = 0;
1102            for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str    ); ++i)
1103                m_cpt_fsm_rsp     [i] = 0;
1104            for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str    ); ++i)
1105                m_cpt_fsm_tgt     [i] = 0;
1106            for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str); ++i)
1107                m_cpt_fsm_cleanup [i] = 0;
1108
1109            return;
1110        }
1111
1112        // printf("%d\n",(uint32_t)m_cpt_total_cycles);
1113
1114        PRINTF("--------------------------------------------\n");
1115        PRINTF("  * CC_XCACHE_WRAPPER \"%s\" Transition - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
1116        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1117        PRINTF("    * fsm dcache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,dcache_fsm_state_str[r_dcache_fsm[num_cache]],r_dcache_lock[num_cache].read(),(blob_t)r_dcache_addr_save[num_cache].read(),(blob_t)set_num_dcache_only(r_dcache_addr_save[num_cache].read(),num_cache));
1118        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1119        PRINTF("    * fsm icache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,icache_fsm_state_str[r_icache_fsm[num_cache]],r_icache_lock[num_cache].read(),(blob_t)r_icache_addr_save[num_cache].read(),(blob_t)set_num_icache_only(r_icache_addr_save[num_cache].read(),num_cache));
1120        PRINTF("    * fsm cmd                 = (%.2d) %s\n",r_vci_cmd_num_cache.read(), cmd_fsm_state_str[r_vci_cmd_fsm]);
1121        PRINTF("    * fsm rsp                 = (%.2d) %s\n",r_vci_rsp_num_cache.read(), rsp_fsm_state_str[r_vci_rsp_fsm]);
1122        PRINTF("    * fsm tgt                 = (%.2d) %s - i %llx d %llx\n",r_tgt_num_cache.read(), tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_iaddr.read(),(blob_t)r_tgt_daddr.read());
1123      //PRINTF("    * fsm tgt                 =      %s - %llx\n",tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_addr.read());
1124        PRINTF("    * fsm cleanup             = (%.2d) %s\n",r_cleanup_num_cache.read(), cleanup_fsm_state_str[r_cleanup_fsm]);
1125        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1126        {
1127            for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
1128                PRINTF("    * ll info                 : [%.2d][%.2d] %d %llx (%llx) %llx\n"
1129                       ,num_cache
1130                       ,num_cpu
1131                       ,          r_dcache_ll_valid [num_cache][num_cpu].read()
1132                       ,(blob_t)r_dcache_ll_addr  [num_cache][num_cpu].read()
1133                       ,(blob_t)set_num_dcache_only(r_dcache_ll_addr [num_cache][num_cpu].read(),num_cache)
1134                       ,(blob_t)r_dcache_ll_data [num_cache][num_cpu].read());
1135
1136            PRINTF("    * dcache_previous_unc     : [%.2d] %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
1137
1138#if CC_XCACHE_WRAPPER_DEBUG
1139            if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
1140                r_wbuf[num_cache]->printTrace(1);
1141#endif
1142        }
1143        // CACHE_MISS_BUF_RSP_PRINT(i);
1144        // CACHE_MISS_BUF_RSP_PRINT(d);
1145
1146        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1147        m_cpt_fsm_dcache  [num_cache][r_dcache_fsm[num_cache]] ++;
1148        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1149        m_cpt_fsm_icache  [num_cache][r_icache_fsm[num_cache]] ++;
1150        m_cpt_fsm_cmd     [r_vci_cmd_fsm] ++;
1151        m_cpt_fsm_rsp     [r_vci_rsp_fsm] ++;
1152        m_cpt_fsm_tgt     [r_vci_tgt_fsm] ++;
1153        m_cpt_fsm_cleanup [r_cleanup_fsm] ++;
1154
1155        m_cpt_total_cycles++;
1156
1157        /////////////////////////////////////////////////////////////////////
1158        // The TGT_FSM controls the following ressources:
1159        // - r_vci_tgt_fsm
1160        // - r_tgt_buf[nwords]
1161        // - r_tgt_be[nwords]
1162        // - r_tgt_update
1163        // - r_tgt_word
1164        // - r_tgt_addr
1165        // - r_tgt_srcid
1166        // - r_tgt_trdid
1167        // - r_tgt_pktid
1168        // All VCI commands must be CMD_WRITE.
1169        // If the VCI address offset is null, the command is an invalidate
1170        // request. It is an update request otherwise.
1171        // The VCI_TGT FSM stores the external request arguments in the
1172        // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
1173        // & r_tgt_dcache_req flip-flops to signal the external request to
1174        // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
1175        // of the update or invalidate request in the RSP state.
1176        // -  for an invalidate request the VCI packet length is 1 word.
1177        // The WDATA field contains the line index (i.e. the Z & Y fields).
1178        // -  for an update request the VCI packet length is (n+2) words.
1179        // The WDATA field of the first VCI word contains the line number.
1180        // The WDATA field of the second VCI word contains the word index.
1181        // The WDATA field of the n following words contains the values.
1182        // -  for both invalidate & update requests, the VCI response
1183        // is one single word.
1184        // In case of errors in the VCI command packet, the simulation
1185        // is stopped with an error message.
1186        /////////////////////////////////////////////////////////////////////
1187
1188        switch(r_vci_tgt_fsm) {
1189
1190            case TGT_IDLE:
1191                if ( p_vci_tgt.cmdval.read() )
1192                {
1193                    PRINTF("    * <TGT> Request\n");
1194
1195                    addr_40 address = p_vci_tgt.address.read();
1196
1197                    if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE)
1198                    {
1199                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1200                        std::cout << "coherence request is not a write" << std::endl;
1201                        std::cout << "address = " << std::hex << address << std::dec << std::endl;
1202                        std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
1203                        exit(0);
1204                    }
1205
1206                    // multi-update or multi-invalidate for data type
1207                    if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) )
1208                    {
1209                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1210                        std::cout << "out of segment coherence request" << std::endl;
1211                        std::cout << "address = " << std::hex << address << std::dec << std::endl;
1212                        std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
1213                        exit(0);
1214                    }
1215
1216                    addr_40 tgt_addr  = ((((addr_40)p_vci_tgt.be.read() & 0x3) << 32) | ((addr_40) p_vci_tgt.wdata.read())) << (addr_40)m_dcache_words_shift;
1217                    // * m_dcache_words * 4;
1218
1219                    addr_40 tgt_iaddr = tgt_addr;
1220                    addr_40 tgt_daddr = tgt_addr;
1221
1222                    PRINTF("    * <TGT> srcid            : %d\n",(uint32_t)p_vci_tgt.srcid.read());
1223                    PRINTF("    * <TGT> trdid            : %d\n",(uint32_t)p_vci_tgt.trdid.read());
1224                    PRINTF("    * <TGT> pktid            : %d\n",(uint32_t)p_vci_tgt.pktid.read());
1225                    PRINTF("    * <TGT> address (before) : %llx\n",(blob_t)tgt_iaddr);
1226
1227                    r_tgt_srcid     = p_vci_tgt.srcid.read();
1228                    r_tgt_trdid     = p_vci_tgt.trdid.read();
1229                    r_tgt_pktid     = p_vci_tgt.pktid.read();
1230                 // r_tgt_plen      = p_vci_tgt.plen.read();
1231                   
1232                    // BROADCAST
1233                    if ( (address&0x3) == 0x3 )   // broadcast invalidate for data or instruction type
1234                    {
1235                        if ( not p_vci_tgt.eop.read() )
1236                        {
1237                            std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1238                            std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
1239                            exit(0);
1240                        }
1241                        r_tgt_update = false;
1242                        // r_tgt_brdcast= true;
1243                        r_vci_tgt_fsm = TGT_REQ_BROADCAST;
1244                        uint32_t tgt_num_cache;
1245                        tgt_num_cache = get_num_icache(tgt_iaddr,0); // none effect (else CC_XCACHE_WRAPPER_MULTI_CACHE==1)
1246                        tgt_num_cache = get_num_dcache(tgt_daddr);
1247                        r_tgt_num_cache = tgt_num_cache;
1248
1249                        PRINTF("    * <TGT> REQ_BROADCAST\n");
1250                        PRINTF("    * <TGT> num_cache (data) : %d\n",tgt_num_cache);
1251
1252                        m_cpt_cc_inval_broadcast++ ;
1253
1254#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1255                        {
1256                            log_transaction_file_tgt
1257                                << "[" << m_cpt_total_cycles << "] "
1258                                << "BROADCAST  "
1259                                << std::hex
1260                                << " L " << std::setw(10) << (blob_t)tgt_addr
1261                                << std::dec
1262                                << " - " << tgt_num_cache
1263                                << std::endl;
1264                        }
1265#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1266
1267                    }
1268                    else                    // multi-update or multi-invalidate for data type
1269                    {
1270                        uint32_t cell = address - m_segment.baseAddress(); // addr_40
1271                        // r_tgt_brdcast = false;
1272
1273                        if (cell == 0)
1274                        {                                       // invalidate data
1275                            if ( not p_vci_tgt.eop.read() )
1276                            {
1277                                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1278                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
1279                                exit(0);
1280                            }
1281                            r_tgt_update = false;
1282                            r_vci_tgt_fsm = TGT_REQ_DCACHE;
1283                            uint32_t tgt_num_cache = get_num_dcache(tgt_daddr); // static partionnement
1284                            r_tgt_num_cache = tgt_num_cache;
1285                           
1286                            PRINTF("    * <TGT> REQ_DCACHE\n");
1287                            PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
1288
1289                            m_cpt_cc_inval_dcache++ ;
1290
1291#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1292                            {
1293                                log_transaction_file_tgt
1294                                    << "[" << m_cpt_total_cycles << "] "
1295                                    << "INVAL DATA "
1296                                    << std::hex
1297                                    << " L " << std::setw(10) << (blob_t)tgt_addr
1298                                    << std::dec
1299                                    << " - " << tgt_num_cache
1300                                    << std::endl;
1301                            }
1302#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1303
1304                        }
1305                        else if (cell == 4)                     // invalidate instruction
1306                        {                         
1307                            if ( not p_vci_tgt.eop.read() )
1308                            {
1309                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
1310                                std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
1311                                exit(0);
1312                            }
1313                            r_tgt_update = false;
1314                            r_vci_tgt_fsm = TGT_REQ_ICACHE;
1315                            uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
1316                            uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
1317                            r_tgt_num_cache = tgt_num_cache;
1318                           
1319                            PRINTF("    * <TGT> REQ_ICACHE\n");
1320                            PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
1321
1322                            m_cpt_cc_inval_icache++ ;
1323
1324#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1325                            {
1326                                log_transaction_file_tgt
1327                                    << "[" << m_cpt_total_cycles << "] "
1328                                    << "INVAL INS  "
1329                                    << std::hex
1330                                    << " L " << std::setw(10) << (blob_t)tgt_addr
1331                                    << std::dec
1332                                    << " - " << tgt_num_cache
1333                                    << std::endl;
1334                            }
1335#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1336
1337                        }
1338                        else if ( (cell == 8) or (cell==12) )    // update data or instruction
1339                        {                               
1340                            if ( p_vci_tgt.eop.read() )
1341                            {
1342                                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
1343                                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
1344                                exit(0);
1345                            }
1346                            if(cell == 8)
1347                            {
1348                                m_cpt_cc_update_dcache++;
1349                                r_tgt_update_data = true;
1350
1351                                uint32_t tgt_num_cache = get_num_dcache(tgt_daddr);
1352                                r_tgt_num_cache = tgt_num_cache;
1353                               
1354                                PRINTF("    * <TGT> UPDT_WORD DATA\n");
1355                                PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
1356
1357#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1358                                {
1359                                    log_transaction_file_tgt
1360                                        << "[" << m_cpt_total_cycles << "] "
1361                                        << "UPT DATA   "
1362                                        << std::hex
1363                                        << " L " << std::setw(10) << (blob_t)tgt_addr
1364                                        << std::dec
1365                                        << " - " << tgt_num_cache
1366                                        << std::endl;
1367                                }
1368#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1369                            }
1370                            else
1371                            {
1372                                m_cpt_cc_update_icache++;
1373                                r_tgt_update_data = false;
1374
1375                                uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
1376                                uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
1377                                r_tgt_num_cache = tgt_num_cache;
1378                               
1379                                PRINTF("    * <TGT> UPDT_WORD INSTRUCTION\n");
1380                                PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
1381
1382#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1383                                {
1384                                    log_transaction_file_tgt
1385                                        << "[" << m_cpt_total_cycles << "] "
1386                                        << "UPT INS    "
1387                                        << std::hex
1388                                        << " L " << std::setw(10) << (blob_t)tgt_addr
1389                                        << std::dec
1390                                        << " - " << tgt_num_cache
1391                                        << std::endl;
1392                                }
1393#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
1394                            }
1395                            r_tgt_update = true;
1396                            r_vci_tgt_fsm = TGT_UPDT_WORD;
1397                        }
1398
1399                    } // end if address
1400                   
1401                    r_tgt_iaddr      = tgt_iaddr;
1402                    r_tgt_daddr      = tgt_daddr;
1403                    PRINTF("    * <TGT> address (after)  : i %llx, d %llx\n",(blob_t)tgt_iaddr,(blob_t)tgt_daddr);
1404
1405                } // end if cmdval
1406                break;
1407
1408            case TGT_UPDT_WORD:
1409                if (p_vci_tgt.cmdval.read())
1410                {
1411                    if ( p_vci_tgt.eop.read() )
1412                    {
1413                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1414                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
1415                        exit(0);
1416                    }
1417                    for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0;
1418                    r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
1419#ifdef COHERENCE_DEBUG
1420                    std::cout << "PROC " << m_srcid_rw << " update, line : " << std::hex << r_tgt_daddr.read() << " word : " << p_vci_tgt.wdata.read() << std::dec << std::endl;
1421#endif
1422                    r_vci_tgt_fsm = TGT_UPDT_DATA;
1423                }
1424                break;
1425
1426            case TGT_UPDT_DATA:
1427                if (p_vci_tgt.cmdval.read())
1428                {
1429                    size_t word = r_tgt_word.read();
1430                    if ( word >= m_cache_words )
1431                    {
1432                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
1433                        std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
1434                        exit(0);
1435                    }
1436#ifdef COHERENCE_DEBUG
1437                    std::cout << "PROC " << m_srcid_rw << " update, data : " << p_vci_tgt.wdata.read() << " be : " << std::hex << p_vci_tgt.be.read() << std::dec << std::endl;
1438#endif
1439
1440                    r_tgt_buf[word] = p_vci_tgt.wdata.read();
1441                    r_tgt_be [word] = p_vci_tgt.be.read();
1442
1443                    if (p_vci_tgt.be.read())
1444                    {
1445                        if(r_tgt_update_data.read())
1446                            m_cpt_cc_update_dcache_word_useful++ ;
1447                        else
1448                            m_cpt_cc_update_icache_word_useful++ ;
1449                    }
1450
1451                    r_tgt_word = word + 1;
1452                    if (p_vci_tgt.eop.read()){
1453#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
1454                      uint32_t word=0;
1455                      for (; word<m_cache_words; ++word)
1456                          if (r_tgt_be[word] != 0)
1457                              break;
1458                      r_cache_word = word;
1459#endif
1460                      if(r_tgt_update_data.read()){
1461                        r_vci_tgt_fsm = TGT_REQ_DCACHE;
1462                      } else {
1463                        r_vci_tgt_fsm = TGT_REQ_ICACHE;
1464                      }
1465                    }
1466                }
1467                break;
1468
1469            case TGT_REQ_BROADCAST:
1470                {
1471                    bool tgt_icache_req;
1472
1473#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
1474                    tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
1475#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
1476                    tgt_icache_req = false;
1477                    for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1478                        tgt_icache_req |= r_tgt_icache_req[num_cache].read();
1479#endif
1480                    if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
1481                    {
1482                        r_vci_tgt_fsm = TGT_RSP_BROADCAST;
1483
1484#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
1485                        r_tgt_icache_req[r_tgt_num_cache] = true;
1486#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
1487                        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1488                        r_tgt_icache_req[      num_cache] = true;
1489#endif
1490
1491                        r_tgt_dcache_req[r_tgt_num_cache] = true;
1492                    }
1493                }
1494                break;
1495                ////////////////////
1496            case TGT_REQ_ICACHE:
1497                {
1498                    // Request treated by the icache
1499                    if ( not r_tgt_icache_req[r_tgt_num_cache].read() )
1500                    {
1501                        r_vci_tgt_fsm = TGT_RSP_ICACHE;
1502                        r_tgt_icache_req[r_tgt_num_cache] = true;
1503                    }
1504                    break;
1505                }
1506
1507            case TGT_REQ_DCACHE:
1508                {
1509                    // Request treated by the dcache
1510
1511                    if ( not r_tgt_dcache_req[r_tgt_num_cache].read() )
1512                    {
1513                        r_vci_tgt_fsm = TGT_RSP_DCACHE;
1514                        r_tgt_dcache_req[r_tgt_num_cache] = true;
1515                    }
1516                    break;
1517                }
1518            case TGT_RSP_BROADCAST:
1519                {
1520                    PRINTF("      * <TGT> dcache[%d] : %d - %d\n",(uint32_t)r_tgt_num_cache, (uint32_t)r_tgt_dcache_req[r_tgt_num_cache].read(),(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
1521                    for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1522                        PRINTF("      * <TGT> icache[%d] : %d - %d\n",(uint32_t)num_cache, (uint32_t)r_tgt_icache_req[num_cache].read(),(uint32_t)r_tgt_icache_rsp[num_cache].read());
1523
1524                    bool tgt_icache_req;
1525                   
1526#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
1527                    tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
1528#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
1529                    tgt_icache_req = false;
1530                    for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1531                        tgt_icache_req |= r_tgt_icache_req[num_cache].read();
1532#endif
1533                    if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
1534                    {
1535                        bool     tgt_icache_rsp;
1536                        uint32_t tgt_icache_rsp_num_cache;
1537                       
1538#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
1539                        tgt_icache_rsp_num_cache = r_tgt_num_cache;
1540                        tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
1541#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
1542                        tgt_icache_rsp_num_cache = 0;
1543                        for (;tgt_icache_rsp_num_cache<m_nb_icache; ++tgt_icache_rsp_num_cache)
1544                        {
1545                            PRINTF("      * <TGT> icache[%d] : %d\n",(uint32_t)tgt_icache_rsp_num_cache, (uint32_t)r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read());
1546                           
1547                            if (r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read())
1548                                break;
1549                        }
1550
1551                        tgt_icache_rsp = (tgt_icache_rsp_num_cache<m_nb_icache);
1552#endif
1553
1554                        PRINTF("      * <TGT> icache_rsp [%d] : %d\n",tgt_icache_rsp_num_cache,(uint32_t) tgt_icache_rsp);
1555                        PRINTF("      * <TGT> dcache_rsp [%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t) r_tgt_dcache_rsp[r_tgt_num_cache]);
1556
1557                        if (tgt_icache_rsp or r_tgt_dcache_rsp[r_tgt_num_cache])
1558                        {
1559                            // Have send one response
1560                            if ( p_vci_tgt.rspack.read())
1561                            {
1562                                // reset dcache if activated
1563                                if (r_tgt_dcache_rsp[r_tgt_num_cache])
1564                                    r_tgt_dcache_rsp[r_tgt_num_cache] = false;
1565                                else
1566                                    // reset one icache
1567                                    r_tgt_icache_rsp[tgt_icache_rsp_num_cache] = false;
1568                            }
1569                        }
1570
1571                        // // one response
1572                        // if ( not r_tgt_icache_rsp[r_tgt_num_cache] or not r_tgt_dcache_rsp[r_tgt_num_cache] )
1573                        // {
1574                        //     if ( p_vci_tgt.rspack.read() )
1575                        //     {
1576                        //         r_vci_tgt_fsm = TGT_IDLE;
1577                        //         r_tgt_icache_rsp[r_tgt_num_cache] = false;
1578                        //         r_tgt_dcache_rsp[r_tgt_num_cache] = false;
1579                        //     }
1580                        // }
1581                       
1582                        // // if data and instruction have the inval line, need two responses 
1583                        // if ( r_tgt_icache_rsp[r_tgt_num_cache] and r_tgt_dcache_rsp[r_tgt_num_cache] )
1584                        // {
1585                        //     if ( p_vci_tgt.rspack.read() )
1586                        //     {
1587                        //         r_tgt_icache_rsp[r_tgt_num_cache] = false; // only reset one for respond the second time
1588                        //     }
1589                        // }
1590
1591                        PRINTF("      * <TGT> icache_rsp    : %d\n",(uint32_t) r_tgt_icache_rsp[r_tgt_num_cache]);
1592                        PRINTF("      * <TGT> dcache_rsp[%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
1593                        // if there is no need for a response
1594                        if (not tgt_icache_rsp and not r_tgt_dcache_rsp[r_tgt_num_cache] )
1595                        {
1596                            r_vci_tgt_fsm = TGT_IDLE;
1597                        }
1598                       
1599                    }
1600                    break;
1601                }
1602                ////////////////////
1603            case TGT_RSP_ICACHE:
1604                {
1605                    bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp[r_tgt_num_cache].read()) and not r_tgt_icache_req[r_tgt_num_cache].read();
1606
1607                    PRINTF("      * <TGT> RSP_ICACHE : transaction : %d ((%d or not %d) and not %d)\n",transaction_rsp
1608                           ,(int)p_vci_tgt.rspack.read()
1609                           ,(int)r_tgt_icache_rsp[r_tgt_num_cache].read()
1610                           ,(int)r_tgt_icache_req[r_tgt_num_cache].read()
1611                           );
1612
1613                    if (transaction_rsp)
1614                    {
1615                        r_vci_tgt_fsm = TGT_IDLE;
1616                        r_tgt_icache_rsp[r_tgt_num_cache] = false;
1617                    }
1618                    break;
1619                }
1620
1621            case TGT_RSP_DCACHE:
1622                {
1623                    bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp[r_tgt_num_cache].read()) and not r_tgt_dcache_req[r_tgt_num_cache].read();
1624
1625                    PRINTF("      * <TGT> RSP_DCACHE : transaction : %d\n",transaction_rsp);
1626
1627                    if (transaction_rsp)
1628                    {
1629                        r_vci_tgt_fsm = TGT_IDLE;
1630                        r_tgt_dcache_rsp[r_tgt_num_cache] = false;
1631                    }
1632                    break;
1633                }
1634        } // end switch TGT_FSM
1635
1636        /////////////////////////////////////////////////////////////////////
1637        // Interface between CPU and CACHE FSM
1638        ///////////////////////////////////////////////////////////////////////
1639
1640        uint32_t ireq_num_cache [m_nb_cpu];
1641        uint32_t dreq_num_cache [m_nb_cpu];
1642        bool     have_sync = false;
1643
1644        {
1645            typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
1646            typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
1647
1648            for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1649            {
1650                ireq [num_cache] = _ireq;
1651              //irsp [num_cache] = _irsp;
1652            }
1653            for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
1654            {
1655                dreq [num_cache] = _dreq;
1656              //drsp [num_cache] = _drsp;
1657               
1658                have_sync |= r_dcache_sync [num_cache];
1659            }
1660        }
1661
1662        for (uint32_t _num_cpu=0; _num_cpu<m_nb_cpu; ++_num_cpu)
1663        {
1664            // round robin priority
1665            uint32_t num_cpu = (r_cpu_prior+_num_cpu)%m_nb_cpu;
1666
1667            typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
1668            typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
1669           
1670            m_iss[num_cpu]->getRequests(_ireq, _dreq);
1671
1672            addr_40  addr;
1673            uint32_t num_cache;
1674
1675            addr      = (addr_40)_ireq.addr;
1676            num_cache = get_num_icache(addr,num_cpu);
1677
1678            // test if already used
1679            if (not ireq[num_cache].valid and
1680                (r_icache_lock [num_cache] == m_nb_cpu) or
1681                (r_icache_lock [num_cache] == num_cpu))
1682            {
1683                bool valid = _ireq.valid;
1684
1685                if (valid)
1686                {
1687                    PRINTF("    * <CPU2CACHE> ICACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
1688                    ireq_num_cache [num_cpu  ] = num_cache;
1689                    r_icache_lock [num_cache] = num_cpu;
1690                }
1691                else
1692                {
1693                    PRINTF("    * <CPU2CACHE> ICACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
1694                    ireq_num_cache [num_cpu] = m_nb_icache;
1695                }
1696
1697                ireq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_ireq.addr];
1698                ireq_num_cpu   [num_cache] = num_cpu;
1699                ireq           [num_cache] = _ireq;
1700                ireq           [num_cache].addr = addr;
1701            }
1702            else
1703            {
1704                PRINTF("    * <CPU2CACHE> ICACHE : No transaction (cpu %d)\n",num_cpu);
1705
1706                ireq_num_cache [num_cpu] = m_nb_icache;
1707            }
1708
1709            addr      = (addr_40)_dreq.addr;
1710            num_cache = get_num_dcache(addr);
1711
1712            // test if already used
1713            if (not dreq[num_cache].valid and
1714                not have_sync and
1715                (r_dcache_lock [num_cache] == m_nb_cpu) or
1716                (r_dcache_lock [num_cache] == num_cpu))
1717            {
1718                bool valid = _dreq.valid;
1719
1720                if (valid)
1721                {
1722                    PRINTF("    * <CPU2CACHE> DCACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
1723                    dreq_num_cache [num_cpu  ] = num_cache;
1724                    r_dcache_lock [num_cache] = num_cpu;
1725                }
1726                else
1727                {
1728                    PRINTF("    * <CPU2CACHE> DCACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
1729                    dreq_num_cache [num_cpu] = m_nb_dcache;
1730                }
1731
1732                dreq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_dreq.addr];
1733                dreq_num_cpu   [num_cache] = num_cpu;
1734                dreq           [num_cache] = _dreq;
1735                dreq           [num_cache].addr = addr;
1736            }
1737            else
1738            {
1739                PRINTF("    * <CPU2CACHE> DCACHE : No transaction (cpu %d)\n",num_cpu);
1740
1741                dreq_num_cache [num_cpu] = m_nb_dcache;
1742            }
1743
1744
1745#if CC_XCACHE_WRAPPER_DEBUG
1746        if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
1747        {
1748            std::cout << "    * <CPU2CACHE> Instruction Request   : " << ireq_num_cache[num_cpu] << " - " << _ireq << std::endl
1749                      << "    * <CPU2CACHE> Data        Request   : " << dreq_num_cache[num_cpu] << " - " << _dreq << std::endl;
1750        }
1751#endif
1752        }
1753
1754        // round robin priority
1755        r_cpu_prior = (r_cpu_prior+1)%m_nb_cpu;
1756
1757        /////////////////////////////////////////////////////////////////////
1758        // The ICACHE FSM controls the following ressources:
1759        // - r_icache_fsm
1760        // - r_icache_fsm_save
1761        // - r_icache instruction cache access
1762        // - r_icache_addr_save
1763        // - r_icache_miss_req set
1764        // - r_icache_unc_req set
1765        // - r_icache_buf_unc_valid set
1766        // - r_vci_rsp_icache_miss_ok reset
1767        // - r_vci_rsp_ins_error reset
1768        // - r_tgt_icache_req reset
1769        // - ireq & irsp structures for communication with the processor
1770        //
1771        // 1/ External requests (update or invalidate) have highest priority.
1772        //    They are taken into account in the IDLE and WAIT states.
1773        //    As external hit should be extremly rare on the ICACHE,
1774        //    all external requests are handled as invalidate...
1775        //    In case of external request the ICACHE FSM goes to the CC_CHECK
1776        //    state to test the external hit, and returns in the
1777        //    pre-empted state after completion.
1778        // 2/ Processor requests are taken into account only in the IDLE state.
1779        //    In case of MISS, or in case of uncached instruction, the FSM
1780        //    writes the missing address line in the  r_icache_addr_save register
1781        //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
1782        //    These request flip-flops are reset by the VCI_RSP FSM
1783        //    when the VCI transaction is completed and the r_icache_buf_unc_valid
1784        //    is set in case of uncached access.
1785        //    In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
1786        //    flip-flop. It is reset by the ICACHE FSM.
1787        ///////////////////////////////////////////////////////////////////////
1788       
1789        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
1790        {
1791            typename iss_t::InstructionRequest  _ireq = ireq [num_cache];
1792            typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER;
1793
1794        switch(r_icache_fsm[num_cache]) {
1795            /////////////////
1796            case ICACHE_IDLE:
1797                {
1798                    if ( r_tgt_icache_req[num_cache] ) {   // external request
1799                        // if ( _ireq.valid ) m_cost_ins_miss_frz++;
1800                        r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
1801                        r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache];
1802                        break;
1803                    }
1804                    if ( _ireq.valid ) {
1805                        data_t   icache_ins         = 0;
1806                        bool     icache_hit         = false;
1807                        bool     icache_cached      = ireq_cached  [num_cache];
1808                        // uint32_t icache_num_cpu     = ireq_num_cpu [num_cache];
1809                        bool     icache_cleanup_hit = r_icache_cleanup_req[num_cache] and (((addr_40)_ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line[num_cache].read());
1810
1811                        // icache_hit & icache_ins evaluation
1812                        if ( icache_cached ) {
1813                            icache_hit = r_icache[num_cache]->read((vci_addr_t) _ireq.addr, &icache_ins);
1814                        } else {
1815                            // if uncache, again in the icache_miss_buf
1816                            icache_hit = (r_icache_buf_unc_valid[num_cache] and ((addr_40) _ireq.addr == (addr_40)r_icache_addr_save[num_cache]));
1817                            icache_ins = CACHE_MISS_BUF_RSP_DATA(i,num_cache,0);
1818
1819                            if (icache_hit)
1820                                CACHE_MISS_BUF_RSP_POP(i,num_cache);
1821                        }
1822
1823                        PRINTF("    * <ICACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache, icache_hit, icache_cached, icache_cleanup_hit);
1824
1825                        // ASSERT( not (icache_hit and icache_cleanup_hit),
1826                        //         "Icache hit and icache_cleanup_hit");
1827
1828                        if (icache_hit and icache_cleanup_hit)
1829                        {
1830                            PRINTF("    * <ICACHE [%d]> Warning : icache hit and icache_cleanup_hit\n",num_cache);
1831                            icache_hit = false;
1832                        }
1833                        else
1834                        {
1835                            if ( not icache_hit and not icache_cleanup_hit)
1836                            {
1837                                m_cpt_ins_miss++;
1838                                m_cost_ins_miss_frz++;
1839                                r_icache_addr_save[num_cache] = (addr_40) _ireq.addr;
1840                               
1841                                CACHE_MISS_BUF_REQ_INIT(i,num_cache);
1842                               
1843                                if ( icache_cached )
1844                                {
1845                                    r_icache_fsm     [num_cache] = ICACHE_MISS_VICTIM;
1846                                    r_icache_miss_req[num_cache] = true;
1847                                   
1848                                }
1849                                else
1850                                {
1851                                    r_icache_fsm    [num_cache] = ICACHE_UNC_WAIT;
1852                                    r_icache_unc_req[num_cache] = true;
1853                                }
1854                            }
1855                            else
1856                            {
1857                                r_icache_buf_unc_valid[num_cache] = false;
1858                            }
1859                            m_cpt_icache_dir_read += m_icache_ways;
1860                            m_cpt_icache_data_read += m_icache_ways;
1861                        }
1862
1863                        _irsp.valid          = icache_hit;
1864                        _irsp.instruction    = icache_ins;
1865                    }
1866                    break;
1867                }
1868                //////////////////////
1869            case ICACHE_MISS_VICTIM:
1870                {
1871                    if (not r_icache_cleanup_req[num_cache])
1872                    {
1873                        size_t     way;
1874                        size_t     set;
1875                        vci_addr_t addr = (vci_addr_t) r_icache_addr_save[num_cache].read();
1876                        vci_addr_t victim;
1877                       
1878                        r_icache_cleanup_req [num_cache] = r_icache[num_cache]->victim_select(addr, &victim, &way, &set );
1879                        r_icache_cleanup_line[num_cache] = (addr_40) victim;
1880                        r_icache_miss_way    [num_cache] = way;
1881                        r_icache_miss_set    [num_cache] = set;
1882                       
1883                        r_icache_fsm         [num_cache] = ICACHE_MISS_WAIT;
1884                    }
1885                    break;
1886                }
1887                //////////////////////
1888            case ICACHE_MISS_WAIT:
1889                {
1890                    m_cost_ins_miss_frz++;
1891                    if ( r_tgt_icache_req[num_cache] ) {   // external request
1892                        r_icache_fsm      [num_cache] = ICACHE_CC_CHECK;
1893                        r_icache_fsm_save [num_cache] = r_icache_fsm[num_cache].read();
1894                        break;
1895                    }
1896
1897                    bool val = CACHE_MISS_BUF_RSP_VAL(i,num_cache,0);
1898
1899                    PRINTF("    * <ICACHE [%d]> val                  : %d\n",num_cache,val);
1900
1901                    if (val)
1902                    {
1903                        PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp   : %d\n",num_cache,(int) r_icache_inval_rsp  [num_cache]);
1904                        PRINTF("    * <ICACHE [%d]> r_vci_rsp_ins_error  : %d\n",num_cache,(int) r_vci_rsp_ins_error [num_cache]);
1905                        PRINTF("    * <ICACHE [%d]> r_icache_cleanup_req : %d\n",num_cache,(int) r_icache_cleanup_req[num_cache]);
1906
1907                        // Miss read response and no invalidation
1908                        if ( r_vci_rsp_ins_error [num_cache]) {
1909                            r_icache_fsm[num_cache] = ICACHE_ERROR;
1910                        } else {
1911                            r_icache_update_addr[num_cache] = 0;
1912                            r_icache_fsm        [num_cache] = ICACHE_MISS_UPDT;
1913                        }
1914                    }
1915                    break;
1916                }
1917                /////////////////////
1918            case ICACHE_UNC_WAIT:
1919                {
1920                    m_cost_ins_miss_frz++;
1921                    if ( r_tgt_icache_req[num_cache] ) {   // external request
1922                        r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
1923                        r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache].read();
1924                        break;
1925                    }
1926
1927                    bool ok = CACHE_MISS_BUF_RSP_VAL(i,num_cache,0);
1928
1929                    PRINTF("    * <ICACHE [%d]> ok                   : %d\n",num_cache,ok);
1930                    PRINTF("    * <ICACHE [%d]> error                : %d\n",num_cache,(uint32_t)r_vci_rsp_ins_error [num_cache]);
1931
1932                    if (ok)
1933                    {
1934                        if ( r_vci_rsp_ins_error [num_cache]) {
1935                            r_icache_fsm[num_cache] = ICACHE_ERROR;
1936                        } else {
1937                            r_icache_fsm [num_cache] = ICACHE_IDLE;
1938                            r_icache_buf_unc_valid[num_cache] = true;
1939                        }
1940                    }
1941                    break;
1942                }
1943                //////////////////
1944            case ICACHE_ERROR:
1945                {
1946                    if ( (addr_40)_ireq.addr == (addr_40)r_icache_addr_save[num_cache] ) {
1947                        _irsp.error          = true;
1948                        _irsp.valid          = true;
1949                    }
1950                    r_icache_fsm        [num_cache] = ICACHE_IDLE;
1951                    r_vci_rsp_ins_error [num_cache] = false;
1952                    break;
1953                }
1954                //////////////////////
1955            case ICACHE_MISS_UPDT:
1956                {
1957                    size_t     word =              r_icache_update_addr[num_cache].read();
1958                    vci_addr_t addr = (vci_addr_t) r_icache_addr_save  [num_cache].read();
1959                    size_t     way  = r_icache_miss_way[num_cache].read();
1960                    size_t     set  = r_icache_miss_set[num_cache].read();
1961
1962                    bool val = CACHE_MISS_BUF_RSP_VAL(i,num_cache,word);
1963
1964                    if (val)
1965                    {
1966                        PRINTF("    * <ICACHE [%d]> rsp_val            : %d/%d\n",num_cache,(int)r_icache_update_addr[num_cache],(int)m_icache_words);
1967                        PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp : %d\n"   ,num_cache,(int)r_icache_inval_rsp[num_cache]);
1968                        PRINTF("    * <ICACHE [%d]> ins                : %x\n"   ,num_cache,(int)CACHE_MISS_BUF_RSP_DATA(i,num_cache,word));
1969
1970                        // m_cpt_icache_dir_write++;
1971                        // m_cpt_icache_data_write++;
1972                        // if ( _ireq.valid ) m_cost_ins_miss_frz++;
1973
1974                        // if need invalid rsp, don't modify the cache, but pop the buf_rsp
1975                        if (not r_icache_inval_rsp[num_cache])
1976                            r_icache[num_cache]->write(way, set, word, CACHE_MISS_BUF_RSP_DATA(i,num_cache,word));
1977
1978                        CACHE_MISS_BUF_RSP_POP(i,num_cache);
1979
1980                        r_icache_update_addr[num_cache] = ++word;
1981                           
1982                        // if last word, finish the update
1983                        if (word >= m_icache_words)
1984                        {
1985                            // in all case (inval_rsp or not), update the victim tag
1986                            r_icache[num_cache]->victim_update_tag(addr, way, set);
1987
1988                            // Last word : if previous invalid_rsp, can cleanup, else update the TAG
1989                            if (r_icache_inval_rsp[num_cache])
1990                            {
1991                                r_icache_inval_rsp[num_cache] = false;
1992                                r_icache_fsm      [num_cache] = ICACHE_CC_CLEANUP;
1993                            }
1994                            else
1995                            {
1996                                r_icache_fsm [num_cache] = ICACHE_IDLE;
1997                            }
1998                        }
1999                    }
2000
2001                    break;
2002                }
2003                ////////////////////
2004            case ICACHE_CC_CLEANUP:
2005                {
2006                    // cleanup
2007                    if(not r_icache_cleanup_req[num_cache]){
2008                        r_icache_cleanup_req [num_cache] = true;
2009                        r_icache_cleanup_line[num_cache] = r_icache_addr_save[num_cache].read() >> m_icache_words_shift;
2010                        r_icache_fsm         [num_cache] = ICACHE_IDLE;
2011
2012                        m_cpt_icache_dir_read += m_icache_ways;
2013                        r_icache[num_cache]->inval((addr_40)r_icache_addr_save[num_cache]);
2014                    }
2015                    break;
2016                }
2017                /////////////////////
2018            case ICACHE_CC_CHECK:   // read directory in case of invalidate or update request
2019                {
2020
2021                    m_cpt_icache_dir_read  += m_icache_ways;
2022                    m_cpt_icache_data_read += m_icache_ways;
2023                    addr_40 ad = r_tgt_iaddr;
2024                    data_t  icache_rdata = 0;
2025
2026                    PRINTF("    * <ICACHE [%d]> CC_CHECK\n",num_cache);
2027
2028                    if((r_icache_fsm_save[num_cache] == ICACHE_MISS_WAIT) and
2029                       ((r_icache_addr_save[num_cache].read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) {
2030                        PRINTF("    * <ICACHE [%d]> have request, need inval rsp\n",num_cache);
2031
2032                        r_icache_inval_rsp[num_cache] = true;
2033                        r_tgt_icache_req  [num_cache] = false;
2034                        if(r_tgt_update){    // Also send a cleanup and answer
2035                            PRINTF("    * <ICACHE [%d]> send a cleanup and answer\n",num_cache);
2036                            r_tgt_icache_rsp[num_cache] = true;
2037                        } else {            // Also send a cleanup but don't answer
2038                            PRINTF("    * <ICACHE [%d]> send a cleanup and but don't answer\n",num_cache);
2039                            r_tgt_icache_rsp[num_cache] = false;
2040                        }
2041                        r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
2042                    } else {
2043                        bool    icache_hit   = r_icache[num_cache]->read(ad, &icache_rdata);
2044
2045                        PRINTF("    * <ICACHE [%d]> have no request, hit cache : %d\n",num_cache,icache_hit);
2046
2047                        if ( icache_hit and r_tgt_update)
2048                        {
2049#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2050                            uint32_t word  = r_cache_word;
2051                            data_t   mask  = vci_param::be2mask(r_tgt_be[word]);
2052                            data_t   rdata = 0;
2053
2054                            r_icache[num_cache]->read(ad+word*4,&rdata);
2055                            r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata);
2056                           
2057                            word ++;
2058#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2059                            for (; word<m_icache_words; ++word)
2060                                if (r_tgt_be[word] != 0)
2061                                    break;
2062#endif
2063
2064                            if (word==m_icache_words)
2065                            {
2066                                r_icache_fsm[num_cache] = ICACHE_CC_UPDT;
2067
2068#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2069                                for (word=0; word<m_icache_words; ++word)
2070                                    if (r_tgt_be[word] != 0)
2071                                        break;
2072#else
2073                                word = 0;
2074#endif
2075                            }
2076                            r_cache_word = word;
2077#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2078                            r_icache_fsm[num_cache] = ICACHE_CC_UPDT;
2079                            // complete the line buffer in case of update
2080                            for(size_t i=0; i<m_icache_words; i++){
2081                                data_t rdata = 0;
2082                                r_icache[num_cache]->read(ad + i*4,&rdata);
2083                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
2084                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
2085                            }
2086#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2087                        } else if ( icache_hit and not r_tgt_update) {
2088                            r_icache_fsm[num_cache] = ICACHE_CC_INVAL;
2089                        } else { // instruction not found (can happen)
2090                            r_tgt_icache_req[num_cache] = false;
2091                            if(r_tgt_update){
2092                                r_tgt_icache_rsp[num_cache] = true;
2093                            } else {
2094                                r_tgt_icache_rsp[num_cache] = false;
2095                            }
2096                            r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
2097                        }
2098                    }
2099                    break;
2100                }
2101                /////////////////////
2102            case ICACHE_CC_INVAL: 
2103                {                       
2104                    addr_40 ad  = r_tgt_iaddr;
2105                    // if ( _ireq.valid ) m_cost_ins_miss_frz++;
2106                    m_cpt_icache_dir_read += m_icache_ways;
2107                    r_tgt_icache_rsp[num_cache] = true;
2108                    r_icache[num_cache]->inval(ad);
2109                    r_tgt_icache_req[num_cache] = false;
2110                    r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache];
2111                    break;
2112                }   
2113                /////////////////////
2114            case ICACHE_CC_UPDT:
2115                {                       
2116                    addr_40 ad = r_tgt_iaddr.read();
2117                    m_cpt_icache_dir_write++;
2118                    m_cpt_icache_data_write++;
2119
2120#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2121                    uint32_t word  = r_cache_word;
2122
2123                    if(r_tgt_be[word])
2124                        r_icache[num_cache]->write(ad+word*4, r_tgt_buf[word]);
2125
2126                    word ++;
2127#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2128                    for (; word<m_icache_words; ++word)
2129                        if (r_tgt_be[word] != 0)
2130                            break;
2131#endif
2132
2133                    if (word==m_icache_words)
2134                    {
2135                        r_tgt_icache_req[num_cache] = false;
2136                        r_tgt_icache_rsp[num_cache] = true;
2137                        r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache].read();
2138                        word = 0;
2139                    }
2140                    r_cache_word = word;
2141#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2142                    data_t* buf    = r_tgt_buf;
2143                    for(size_t i=0; i<m_icache_words;i++){
2144                        if(r_tgt_be[i]) r_icache[num_cache]->write( ad + i*4, buf[i]);
2145                    }
2146                    r_tgt_icache_req [num_cache] = false;
2147                    r_tgt_icache_rsp [num_cache] = true;
2148                    r_icache_fsm     [num_cache] = r_icache_fsm_save[num_cache].read();
2149#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2150
2151                    break;
2152                }   
2153
2154        }// end switch r_icache_fsm
2155
2156        irsp [num_cache] = _irsp;
2157        if (_ireq.valid and _irsp.valid)
2158        {
2159            PRINTF("    * <CPU2CACHE> Transaction between cpu %d and Icache %d (unlock)\n",r_icache_lock [num_cache].read(),num_cache);
2160
2161            r_icache_lock       [num_cache] = m_nb_cpu;
2162            m_cpt_icache_access [num_cache] ++;
2163        }
2164
2165        }// end for num_cache
2166
2167        //////////////////////////////////////////////////////////////////////://///////////
2168        // The DCACHE FSM controls the following ressources:
2169        // - r_dcache_fsm
2170        // - r_dcache_fsm_save
2171        // - r_dcache (data cache access)
2172        // - r_dcache_addr_save
2173        // - r_dcache_wdata_save
2174        // - r_dcache_rdata_save
2175        // - r_dcache_type_save
2176        // - r_dcache_be_save
2177        // - r_dcache_cached_save
2178        // - r_dcache_miss_req set
2179        // - r_dcache_unc_req set
2180        // - r_dcache_cleanup_req set
2181        // - r_vci_rsp_data_error reset
2182        // - r_tgt_dcache_req reset
2183        // - r_wbuf write
2184        // - dreq & drsp structures for communication with the processor
2185        //
2186        // 1/ EXTERNAL REQUEST :
2187        //    There is an external request when the tgt_dcache req flip-flop is set,
2188        //    requesting a line invalidation or a line update.
2189        //    External requests are taken into account in the states  IDLE, WRITE_REQ, 
2190        //    UNC_WAIT, MISS_WAIT, and have the highest priority :
2191        //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
2192        //    goes to the CC_CHECK state to execute the requested action, and returns to the
2193        //    pre-empted state.
2194        //  2/ PROCESSOR REQUEST :
2195        //   In order to support VCI write burst, the processor requests are taken into account
2196        //   in the WRITE_REQ state as well as in the IDLE state.
2197        //   - In the IDLE state, the processor request cannot be satisfied if
2198        //   there is a cached read miss, or an uncached read.
2199        //   - In the WRITE_REQ state, the request cannot be satisfied if
2200        //   there is a cached read miss, or an uncached read,
2201        //   or when the write buffer is full.
2202        //   - In all other states, the processor request is not satisfied.
2203        //
2204        //   The cache access takes into account the cacheability_table.
2205        //   In case of processor request, there is five conditions to exit the IDLE state:
2206        //   - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal),
2207        //     then to the MISS_UPDT state, and finally to the IDLE state.
2208        //   - UNCACHED READ  => to the UNC_WAIT state (waiting the r_miss_ok signal),
2209        //     and to the IDLE state.
2210        //   - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state.
2211        //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
2212        //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
2213        //
2214        // Error handling :  Read Bus Errors are synchronous events, but
2215        // Write Bus Errors are asynchronous events (processor is not frozen).
2216        // - If a Read Bus Error is detected, the VCI_RSP FSM sets the
2217        //   r_vci_rsp_data_error flip-flop, and the synchronous error is signaled
2218        //   by the DCACHE FSM.
2219        // - If a Write Bus Error is detected, the VCI_RSP FSM  signals
2220        //   the asynchronous error using the setWriteBerr() method.
2221        ///////////////////////////////////////////////////////////////////////////////////
2222
2223        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
2224        {
2225            typename iss_t::DataRequest  _dreq = dreq [num_cache];
2226            typename iss_t::DataResponse _drsp = ISS_DRSP_INITIALIZER;
2227
2228        switch ( r_dcache_fsm[num_cache]) {
2229
2230                /////////////////
2231            case DCACHE_IDLE:
2232                {
2233                    if ( r_tgt_dcache_req[num_cache]) {   // external request
2234                        r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
2235                        r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
2236                        break;
2237                    }
2238
2239                    if ( _dreq.valid ) {
2240                        PRINTF("    * <DCACHE [%d]> Have dreq\n",num_cache);
2241
2242                        data_t      dcache_rdata       = 0;
2243                        // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE}
2244                        bool        dcache_cached      = dreq_cached  [num_cache];
2245                        uint32_t    dcache_num_cpu     = dreq_num_cpu [num_cache];
2246                        bool        dcache_hit         = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
2247                        bool        dcache_cleanup_hit = r_dcache_cleanup_req[num_cache] and (((addr_40)_dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line[num_cache].read());
2248
2249                        PRINTF("    * <DCACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache,dcache_hit, dcache_cached, dcache_cleanup_hit);
2250                       
2251                        m_cpt_dcache_data_read += m_dcache_ways;
2252                        m_cpt_dcache_dir_read  += m_dcache_ways;
2253
2254                        switch( _dreq.type ) {
2255                            case iss_t::DATA_READ:
2256                            case iss_t::DATA_LL:
2257                                {
2258                                    m_cpt_data_read++; // new dcache read
2259
2260                                    if (dcache_hit) // no special test for uncached read, because it's always miss
2261                                        {
2262                                            // address is in the cache : return the word
2263                                            r_dcache_fsm [num_cache] = DCACHE_IDLE;
2264
2265                                            _drsp.valid   = true;
2266                                            _drsp.rdata   = dcache_rdata; // return read data (cf dcache_hit)
2267                                           
2268                                            // if the request is a Load Linked instruction, save request information
2269                                            if(_dreq.type == iss_t::DATA_LL)
2270                                                {
2271                                                    PRINTF("    * <DCACHE [%d]> ll_valid = true\n",num_cache);
2272
2273                                                    r_dcache_ll_valid  [num_cache][dcache_num_cpu] = true;
2274                                                    r_dcache_ll_data   [num_cache][dcache_num_cpu] = dcache_rdata;
2275                                                    r_dcache_ll_addr   [num_cache][dcache_num_cpu] = (vci_addr_t) _dreq.addr;
2276#ifdef COHERENCE_DEBUG
2277                                                    std::cout << "Value returned for LL at address : " << std::hex << _dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
2278                                                    r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
2279                                                    std::cout << "Value stored at this  address : " << std::hex << _dreq.addr << " data : " << std::dec << dcache_rdata<< std::endl;
2280#endif
2281                                                }
2282                                        }
2283                                    else
2284                                        {
2285                                            if (not dcache_cleanup_hit)
2286                                            {
2287                                                CACHE_MISS_BUF_REQ_INIT(d,num_cache);
2288                                               
2289                                                // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req)
2290                                                if ( dcache_cached ) {
2291                                                    m_cpt_data_read_miss++;
2292                                                    m_cost_data_miss_frz++;
2293                                                    r_dcache_miss_req [num_cache] = true;
2294                                                    r_dcache_fsm [num_cache] = DCACHE_MISS_VICTIM;
2295                                                   
2296                                                } else {
2297                                                    if (not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
2298                                                    {
2299                                                        r_dcache_previous_unc[num_cache] = true;
2300                                                       
2301                                                        m_cpt_data_read_uncached++;
2302                                                        m_cost_unc_read_frz++;
2303                                                        r_dcache_unc_req[num_cache] = true;
2304                                                        r_dcache_fsm    [num_cache] = DCACHE_UNC_WAIT;
2305                                                    }
2306                                                }
2307                                            }
2308                                        }
2309                                }
2310                                break;
2311                            case iss_t::DATA_SC:
2312                            {
2313                                PRINTF("    * <DCACHE [%d]> DATA_SC - ll_valid = %d, num_cpu = %d\n",num_cache,r_dcache_ll_valid[num_cache][dcache_num_cpu].read(),dcache_num_cpu);
2314
2315                                if (not r_dcache_previous_unc[num_cache].read() and not dcache_cleanup_hit) // strongly order to the uncached access
2316                                {
2317                                    //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode
2318                                    m_cost_unc_read_frz++;
2319                                   
2320                                    // if previous load linked (with the same address), make a transaction
2321                                    // else, keep in IDLE state and return 1 (no OK)
2322                                    if( r_dcache_ll_valid[num_cache][dcache_num_cpu].read() and
2323                                       (r_dcache_ll_addr [num_cache][dcache_num_cpu].read() == (vci_addr_t)_dreq.addr)){
2324                                        PRINTF("    * <DCACHE [%d]> have previous load linked\n",num_cache);
2325                                       
2326                                        r_dcache_previous_unc[num_cache] = true;
2327                                        r_dcache_sc_req      [num_cache] = true;
2328
2329                                        CACHE_MISS_BUF_REQ_INIT(d,num_cache);
2330
2331                                        r_dcache_fsm         [num_cache] = DCACHE_SC_WAIT;
2332                                    } else {
2333                                        PRINTF("    * <DCACHE [%d]> don't have previous load linked\n",num_cache);
2334                                       
2335                                        _drsp.valid = true;
2336                                        _drsp.rdata = 1; // SC rsp NOK
2337                                        r_dcache_ll_valid[num_cache][dcache_num_cpu] = false;
2338                                    }
2339                                }
2340
2341                                break;
2342                            }
2343                            case iss_t::XTN_READ:
2344                            case iss_t::XTN_WRITE:
2345                                {
2346                                    bool valid = false;
2347                                    // only DCACHE INVALIDATE and SYNC request are supported
2348                                    switch (_dreq.addr>>2)
2349                                        {
2350                                        case iss_t::XTN_DCACHE_INVAL :
2351                                            {
2352                                                valid = true;
2353                                                r_dcache_fsm[num_cache] = DCACHE_INVAL;
2354                                                break;
2355                                            }
2356                                        case iss_t::XTN_SYNC :
2357                                            {
2358                                                // Test if write buffer is already empty
2359                                                //  * gain : 1 cycle
2360                                                //  * cost : can be on the critical path
2361
2362                                                bool empty=true;
2363                                                for (uint32_t i=0; i<m_nb_dcache; ++i)
2364                                                    empty &= r_wbuf[i]->empty();
2365
2366                                                if (empty)
2367                                                    {
2368                                                        valid = true;
2369                                                        r_dcache_fsm [num_cache] = DCACHE_IDLE;
2370                                                    }
2371                                                else
2372                                                    {
2373                                                        valid = false;
2374                                                        r_dcache_fsm [num_cache] = DCACHE_SYNC;
2375                                                        r_dcache_sync[num_cache] = true;
2376                                                    }
2377                                                break;
2378                                            }
2379                                        default :
2380                                            {
2381                                                // std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
2382                                                // std::cout << "Unsupported  external access : " << (_dreq.addr>>2) << std::endl;
2383
2384                                                r_dcache_fsm [num_cache] = DCACHE_IDLE;
2385                                            }
2386                                        }//end switch (_dreq.addr>>2)
2387
2388                                    _drsp.valid = valid;
2389                                    _drsp.rdata = 0;
2390                                    break;
2391                                }
2392                            case iss_t::DATA_WRITE:
2393
2394                                PRINTF("    * <DCACHE [%d]> r_dcache_previous_unc : %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
2395
2396                                if (dcache_cached or not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
2397                                {
2398                                    bool valid;
2399                                    addr_40 addr = _dreq.addr;
2400                                    set_num_dcache(addr,num_cache);
2401
2402                                    // FIXME :
2403                                    //  * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface)
2404                                    //  * pour cela, virer le set_num_dcache !
2405                                    valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu);
2406                                    PRINTF("    * <DCACHE [%d]> r_wbuf valid          : %d\n",num_cache,valid);
2407
2408                                    if (valid)
2409                                    {
2410                                        m_cpt_data_write++;
2411                                       
2412                                        if (not dcache_cached)
2413                                        {
2414                                            r_dcache_previous_unc[num_cache] = true;
2415                                            m_cpt_data_write_uncached++;
2416                                        }
2417                                        else if (not dcache_hit)
2418                                            m_cpt_data_write_miss++;
2419                                       
2420                                        if (dcache_hit) {
2421                                            // update data cache
2422                                            r_dcache_fsm[num_cache] = DCACHE_WRITE_UPDT;
2423                                        } else {
2424                                            // write accepted
2425                                            r_dcache_fsm [num_cache] = DCACHE_IDLE;
2426                                        }
2427                                    }
2428
2429                                    _drsp.valid = valid;
2430                                    _drsp.rdata = 0;
2431                                }
2432                                break;
2433                        } // end switch _dreq.type
2434
2435                        r_dcache_addr_save   [num_cache] = (addr_40) _dreq.addr;
2436                        r_dcache_type_save   [num_cache] = _dreq.type;
2437                        r_dcache_wdata_save  [num_cache] = _dreq.wdata;
2438                        r_dcache_be_save     [num_cache] = _dreq.be;
2439                        r_dcache_rdata_save  [num_cache] = dcache_rdata;
2440                        r_dcache_cached_save [num_cache] = dcache_cached;
2441                        r_dcache_num_cpu_save[num_cache] = dcache_num_cpu;
2442   
2443                    } else {    // end if _dreq.valid
2444                        r_dcache_fsm [num_cache] = DCACHE_IDLE;
2445                    }
2446                   
2447                    break;
2448                }
2449                ///////////////////////
2450            case DCACHE_WRITE_UPDT:
2451                {
2452                    m_cpt_dcache_data_write++;
2453                    data_t mask = vci_param::be2mask(r_dcache_be_save[num_cache]);
2454                    data_t wdata = (mask & r_dcache_wdata_save[num_cache]) | (~mask & r_dcache_rdata_save[num_cache]);
2455                    vci_addr_t ad = r_dcache_addr_save[num_cache].read();
2456                    r_dcache[num_cache]->write(ad, wdata);
2457
2458                    r_dcache_fsm [num_cache] = DCACHE_IDLE;
2459
2460                    break;
2461                }
2462                //////////////////////
2463            case DCACHE_MISS_VICTIM:
2464                {
2465                    if (not r_dcache_cleanup_req[num_cache].read())
2466                     {
2467                         size_t     way;
2468                         size_t     set;
2469                         vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read();
2470                         vci_addr_t victim;
2471                         bool       victim_val = r_dcache[num_cache]->victim_select(addr, &victim, &way, &set );
2472                         
2473                         r_dcache_cleanup_req  [num_cache] = victim_val;
2474                         r_dcache_cleanup_line [num_cache] = (addr_40) victim;
2475                         r_dcache_miss_way     [num_cache] = way;
2476                         r_dcache_miss_set     [num_cache] = set;
2477                 
2478                         PRINTF("    * <DCACHE [%d]> MISS_VICTIM : Victim %d - %llx (way %d, set %d)\n",num_cache,victim_val, (blob_t)victim, (int)way, (int)set);
2479       
2480                         r_dcache_fsm          [num_cache] = DCACHE_MISS_WAIT;
2481                     }
2482                   
2483                    break;
2484                }
2485                //////////////////////
2486            case DCACHE_MISS_WAIT:
2487                {
2488
2489                    // if ( _dreq.valid ) m_cost_data_miss_frz++;
2490                    if ( r_tgt_dcache_req[num_cache].read() ) {   // external request
2491                        r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
2492                        r_dcache_fsm_save [num_cache] = r_dcache_fsm[num_cache];
2493                        break;
2494                    }
2495
2496                    bool val = CACHE_MISS_BUF_RSP_VAL(d,num_cache,0);
2497                    if (val)
2498                    {
2499                        // Miss read response and no invalidation
2500                        if (r_vci_rsp_data_error[num_cache])
2501                        {
2502                            r_dcache_fsm [num_cache] = DCACHE_ERROR;
2503                        }
2504                        else
2505                        {
2506                            r_dcache_update_addr[num_cache] = 0;
2507                            r_dcache_fsm        [num_cache] = DCACHE_MISS_UPDT;
2508                        }
2509                    }
2510                    break;
2511                }
2512                //////////////////////
2513            case DCACHE_MISS_UPDT:
2514                {
2515                    size_t     word = r_dcache_update_addr[num_cache].read();
2516                    vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read();
2517                    size_t     way  = r_dcache_miss_way[num_cache].read();
2518                    size_t     set  = r_dcache_miss_set[num_cache].read();
2519                   
2520                    PRINTF("    * <DCACHE [%d]> MISS_UPDT : Victim way %d, set %d\n",num_cache, (int)way, (int)set);
2521
2522                    if (CACHE_MISS_BUF_RSP_VAL(d,num_cache,word))
2523                    {
2524                        // m_cpt_dcache_dir_write++;
2525                        // if ( _dreq.valid ) m_cost_data_miss_frz++;
2526
2527                        // if need invalid rsp, don't modify the cache, but pop the buf_rsp
2528                        // (power save)
2529                        if (not r_dcache_inval_rsp[num_cache])
2530                        {
2531                            r_dcache[num_cache]->write(way, set, word, CACHE_MISS_BUF_RSP_DATA(d,num_cache,word));
2532                            m_cpt_dcache_data_write++;
2533                        }
2534
2535                        CACHE_MISS_BUF_RSP_POP(d,num_cache);
2536                        r_dcache_update_addr[num_cache] = ++word;
2537                           
2538                        // if last word, finish the update
2539                        if (word >= m_dcache_words)
2540                        {
2541                            // in all case (inval_rsp or not), update the victim tag
2542                            // because victim is already cleanup
2543                            r_dcache[num_cache]->victim_update_tag(addr, way, set);
2544
2545                            // Last word : if previous invalid_rsp, can cleanup, else update the TAG
2546                            if (r_dcache_inval_rsp[num_cache])
2547                            {
2548                                r_dcache_inval_rsp[num_cache] = false;
2549                                r_dcache_fsm      [num_cache] = DCACHE_CC_CLEANUP;
2550                            }
2551                            else
2552                            {
2553                                r_dcache_fsm [num_cache] = DCACHE_IDLE;
2554                            }
2555                        }
2556                    }
2557               
2558                    break;
2559                }
2560                ////////////////////
2561            case DCACHE_UNC_WAIT:
2562                {
2563                    // if ( _dreq.valid ) m_cost_unc_read_frz++;
2564                    if ( r_tgt_dcache_req[num_cache] ) {   // external request
2565                        r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
2566                        r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
2567                        break;
2568                    }
2569
2570                    bool ok = CACHE_MISS_BUF_RSP_VAL(d,num_cache,0);
2571
2572                    if (ok) {
2573                        if (r_vci_rsp_data_error[num_cache]) {
2574                            r_dcache_fsm[num_cache] = DCACHE_ERROR;
2575                        } else {
2576                            data_t rdata = CACHE_MISS_BUF_RSP_DATA(d,num_cache,0);
2577                            CACHE_MISS_BUF_RSP_POP(d,num_cache);
2578
2579                            if(_dreq.type == iss_t::DATA_LL){
2580                                PRINTF("    * <DCACHE [%d]> ll_valid = true\n",num_cache);
2581
2582                                r_dcache_ll_valid  [num_cache][r_dcache_num_cpu_save[num_cache]] = true;
2583                                r_dcache_ll_data   [num_cache][r_dcache_num_cpu_save[num_cache]] = rdata;
2584                                r_dcache_ll_addr   [num_cache][r_dcache_num_cpu_save[num_cache]] = (vci_addr_t) _dreq.addr;
2585                            }
2586                            r_dcache_fsm [num_cache] = DCACHE_IDLE;
2587
2588                            _drsp.valid = true;
2589                            _drsp.rdata = rdata;
2590                        }
2591                    }
2592                    break;
2593                }
2594                ////////////////////
2595            case DCACHE_SC_WAIT:
2596                {
2597                    // if ( _dreq.valid ) m_cost_unc_read_frz++;
2598                    if ( r_tgt_dcache_req[num_cache] ) {   // external request
2599                        r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
2600                        r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache];
2601                        break;
2602                    }
2603
2604                    bool ok = CACHE_MISS_BUF_RSP_VAL(d,num_cache,0);
2605
2606                    if (ok) {
2607                        if (r_vci_rsp_data_error[num_cache]) {
2608                            r_dcache_fsm [num_cache] = DCACHE_ERROR;
2609                        } else {
2610                            r_dcache_fsm [num_cache] = DCACHE_IDLE;
2611
2612                            _drsp.valid = true;
2613                            _drsp.rdata = CACHE_MISS_BUF_RSP_DATA(d,num_cache,0);
2614                            CACHE_MISS_BUF_RSP_POP(d,num_cache);
2615                            r_dcache_ll_valid [num_cache][r_dcache_num_cpu_save[num_cache]] = false;
2616                        }
2617                    }
2618                    break;
2619                }
2620
2621                //////////////////
2622            case DCACHE_ERROR:
2623                {
2624                    r_dcache_fsm        [num_cache] = DCACHE_IDLE;
2625
2626                    r_vci_rsp_data_error[num_cache] = false;
2627                    _drsp.error = true;
2628                    _drsp.valid = true;
2629                    break;
2630                }
2631                /////////////////   
2632            case DCACHE_INVAL:
2633                {
2634                    if ( r_tgt_dcache_req[num_cache].read() ) {   // external request
2635                        r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
2636                        r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache];
2637                        break;
2638                    }
2639                    if( not r_dcache_cleanup_req [num_cache].read() ){
2640                        m_cpt_dcache_dir_read += m_dcache_ways;
2641                        vci_addr_t  ad  = r_dcache_addr_save [num_cache].read();
2642                        r_dcache_cleanup_req  [num_cache] = r_dcache[num_cache]->inval(ad);
2643                        r_dcache_cleanup_line [num_cache] = r_dcache_addr_save [num_cache].read() >> m_dcache_words_shift;
2644
2645                        r_dcache_fsm          [num_cache] = DCACHE_IDLE;
2646                    }
2647                    break;
2648                }
2649            case DCACHE_SYNC :
2650                {
2651                    if ( r_tgt_dcache_req[num_cache] ) {   // external request
2652                        r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
2653                        r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
2654                        break;
2655                    }
2656
2657                    bool empty=true;
2658                    for (uint32_t i=0; i<m_nb_dcache; ++i)
2659                        empty &= r_wbuf[i]->empty();
2660                   
2661                    if (empty)
2662                    {
2663                        _drsp.valid = true; // end, can accept the sync request
2664                        r_dcache_fsm [num_cache] = DCACHE_IDLE;
2665                        r_dcache_sync[num_cache] = false;
2666                    }
2667                    break;
2668                }
2669                /////////////////////
2670            case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
2671                {
2672                    addr_40  ad          = r_tgt_daddr;
2673                    data_t  dcache_rdata = 0;
2674
2675                    PRINTF("    * <DCACHE [%d]> CC_CHECK\n",num_cache);
2676
2677                    //
2678                    if((r_dcache_fsm_save[num_cache] == DCACHE_MISS_WAIT) and
2679                       ((r_dcache_addr_save[num_cache].read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) {
2680                        PRINTF("    * <DCACHE [%d]> have request, need inval rsp\n",num_cache);
2681
2682                        r_dcache_inval_rsp[num_cache] = true;
2683                        r_tgt_dcache_req  [num_cache] = false;
2684                        if(r_tgt_update){    // Also send a cleanup and answer
2685                            PRINTF("    * <DCACHE [%d]> send a cleanup and answer\n",num_cache);
2686                            r_tgt_dcache_rsp[num_cache]     = true;
2687                        } else {            // Also send a cleanup but don't answer
2688                            PRINTF("    * <DCACHE [%d]> send a cleanup and but don't answer\n",num_cache);
2689                            r_tgt_dcache_rsp[num_cache]     = false;
2690                        }
2691                        r_dcache_fsm[num_cache] = r_dcache_fsm_save[num_cache];
2692                    } else {
2693                        bool    dcache_hit   = r_dcache[num_cache]->read(ad, &dcache_rdata);
2694
2695                        PRINTF("    * <DCACHE [%d]> have no request, hit cache : %d, update : %d\n",num_cache,dcache_hit,(uint32_t)r_tgt_update);
2696
2697                        m_cpt_dcache_data_read += m_dcache_ways;
2698                        m_cpt_dcache_dir_read += m_dcache_ways;
2699
2700#ifdef COHERENCE_DEBUG
2701                        std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_CHECK, hit ? : " << dcache_hit << std::endl;
2702#endif
2703                        if ( dcache_hit and r_tgt_update )
2704                        {
2705#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2706                            uint32_t word  = r_cache_word;
2707                            data_t   mask  = vci_param::be2mask(r_tgt_be[word]);
2708                            data_t   rdata = 0;
2709
2710                            r_dcache[num_cache]->read(ad+word*4,&rdata);
2711                           
2712                            r_tgt_buf[word] = (mask & r_tgt_buf[word]) | (~mask & rdata);
2713
2714                            word ++;
2715#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2716                            for (; word<m_dcache_words; ++word)
2717                                if (r_tgt_be[word] != 0)
2718                                    break;
2719#endif
2720
2721                            if (word==m_dcache_words)
2722                            {
2723                                r_dcache_fsm[num_cache] = DCACHE_CC_UPDT;
2724#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2725                                for (word=0; word<m_dcache_words; ++word)
2726                                    if (r_tgt_be[word] != 0)
2727                                        break;
2728#else
2729                                word = 0;
2730#endif
2731                            }
2732                            r_cache_word = word;
2733#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2734                            // complete the line buffer in case of update
2735                            for(size_t i=0; i<m_dcache_words; i++){
2736                                data_t rdata = 0;
2737                                r_dcache[num_cache]->read(ad + i*4,&rdata);
2738                                data_t mask = vci_param::be2mask(r_tgt_be[i]);
2739                                r_tgt_buf[i] = (mask & r_tgt_buf[i]) | (~mask & rdata);
2740                            }
2741                            r_dcache_fsm[num_cache] = DCACHE_CC_UPDT;
2742#endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2743                        } else if ( dcache_hit and not r_tgt_update ) {
2744                            r_dcache_fsm[num_cache] = DCACHE_CC_INVAL;
2745                        } else {
2746                            if(r_tgt_update){
2747                                r_tgt_dcache_rsp[num_cache] = true;
2748                            } else {
2749                                r_tgt_dcache_rsp[num_cache] = false;
2750                            }
2751                            r_tgt_dcache_req[num_cache] = false;
2752                            r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
2753                        }
2754                    }
2755                    break;
2756                }
2757                ///////////////////
2758            case DCACHE_CC_UPDT:    // update directory and data cache       
2759                {
2760                    addr_40 ad = r_tgt_daddr;
2761
2762                    m_cpt_dcache_dir_write++;
2763                    m_cpt_dcache_data_write++;
2764
2765# ifdef COHERENCE_DEBUG
2766                    std::cout << "PROC " << m_srcid_rw << " DCACHE_CC_UPDT, update : " << std::endl;
2767# endif
2768
2769#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2770                    uint32_t word  = r_cache_word;
2771                   
2772                    if(r_tgt_be[word])
2773                        r_dcache[num_cache]->write(ad+word*4, r_tgt_buf[word]);
2774# ifdef COHERENCE_DEBUG
2775                    std::cout << " address " << std::hex << ad+word*4 << " data " << std::dec << r_tgt_buf[word] << std::endl;
2776                    data_t rdata = 0xAAAAAAAA;
2777                    r_dcache[num_cache]->read(ad+word*4,&rdata);
2778                    std::cout << "data written " << rdata << std::endl;
2779# endif
2780
2781                    word ++;
2782#if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
2783                    for (; word<m_dcache_words; ++word)
2784                        if (r_tgt_be[word] != 0)
2785                            break;
2786#endif
2787                   
2788                    if (word==m_dcache_words)
2789                    {
2790                        r_tgt_dcache_req[num_cache] = false;
2791                        r_tgt_dcache_rsp[num_cache] = true;
2792                        r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
2793                        word = 0;
2794                    }
2795                    r_cache_word = word;
2796#else //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2797                    data_t* buf = r_tgt_buf;
2798                    for(size_t i=0; i<m_dcache_words; i++){
2799                        if(r_tgt_be[i]) {
2800                            r_dcache[num_cache]->write( ad + i*4, buf[i]);
2801# ifdef COHERENCE_DEBUG
2802                            std::cout << " address " << std::hex << ad+i*4 << " data " << std::dec << buf[i] << std::endl;
2803                            data_t rdata = 0xAAAAAAAA;
2804                            r_dcache[num_cache]->read(ad + i*4,&rdata);
2805                            std::cout << "data written " << rdata << std::endl;
2806# endif //CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
2807                        }
2808                    }
2809                    r_tgt_dcache_req[num_cache] = false;
2810                    r_tgt_dcache_rsp[num_cache] = true;
2811                    r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
2812#endif
2813                    break;
2814                }
2815                /////////////////////
2816            case DCACHE_CC_INVAL:   // invalidate a cache line
2817                {
2818                    addr_40  ad      = r_tgt_daddr;
2819                    r_tgt_dcache_rsp[num_cache] = true;
2820                    r_dcache        [num_cache]->inval(ad);
2821                    r_tgt_dcache_req[num_cache] = false;
2822                    r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
2823                    break;
2824                }
2825                ///////////////////
2826            case DCACHE_CC_CLEANUP:   
2827                {
2828                    // cleanup
2829                    if(not r_dcache_cleanup_req[num_cache]){
2830                        r_dcache_cleanup_req  [num_cache] = true;
2831                        r_dcache_cleanup_line [num_cache] = r_dcache_addr_save[num_cache].read() >> m_dcache_words_shift;
2832                        r_dcache_fsm          [num_cache] = DCACHE_IDLE;
2833
2834                        m_cpt_dcache_dir_read += m_dcache_ways;
2835                        r_dcache[num_cache]->inval((addr_40)r_dcache_addr_save[num_cache]);
2836                    }
2837                    break;
2838                }   
2839
2840        } // end switch r_dcache_fsm
2841       
2842        ////////// write buffer state update  /////////////
2843        // The update() method must be called at each cycle to update the internal state.
2844        // All pending write requests must be locked in case of SYNC
2845
2846        // bool have_sync=(r_dcache_fsm[num_cache] == DCACHE_SYNC);
2847#if   (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==1)
2848        r_wbuf[num_cache]->update_multi_scan      (have_sync);
2849#elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==2)
2850        r_wbuf[num_cache]->update_round_robin_scan(have_sync);
2851#elif (CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME==3)
2852        r_wbuf[num_cache]->update_one_scan        (have_sync);
2853#else
2854        r_wbuf[num_cache]->update                 (have_sync);
2855#endif
2856
2857        drsp [num_cache] = _drsp;
2858        if (_dreq.valid and _drsp.valid)
2859        {
2860            PRINTF("    * <CPU2CACHE> Transaction between cpu %d and Dcache %d (unlock)\n",r_dcache_lock [num_cache].read(),num_cache);
2861
2862            r_dcache_lock       [num_cache] = m_nb_cpu;
2863            m_cpt_dcache_access [num_cache] ++;
2864        }
2865
2866        }// end for num_cache
2867
2868        /////////// execute one iss cycle /////////////////////////////////////////////
2869
2870        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
2871        {
2872            // Test if the resquest is accepted
2873            typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER;
2874            typename iss_t::DataResponse        _drsp = ISS_DRSP_INITIALIZER;
2875
2876            if (ireq_num_cache[num_cpu]<m_nb_icache)
2877                _irsp = irsp[ireq_num_cache[num_cpu]];
2878            if (dreq_num_cache[num_cpu]<m_nb_dcache)
2879                _drsp = drsp[dreq_num_cache[num_cpu]];
2880
2881#if CC_XCACHE_WRAPPER_STOP_SIMULATION  or CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
2882            typename iss_t::InstructionRequest  _ireq = ISS_IREQ_INITIALIZER;
2883            typename iss_t::DataRequest         _dreq = ISS_DREQ_INITIALIZER;
2884
2885            if (ireq_num_cache[num_cpu]<m_nb_icache)
2886                _ireq = ireq[ireq_num_cache[num_cpu]];
2887            if (dreq_num_cache[num_cpu]<m_nb_dcache)
2888                _dreq = dreq[dreq_num_cache[num_cpu]];
2889#endif
2890
2891#if CC_XCACHE_WRAPPER_DEBUG
2892            if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
2893            {
2894
2895                std::cout << "    * CPU                    : " << num_cpu << std::endl
2896                          << "      * Instruction Cache    : " << ireq_num_cache[num_cpu] << ", valid : " << (ireq_num_cache[num_cpu]<m_nb_icache) << std::endl
2897                          << "      * Instruction Request  : " << _ireq << std::endl
2898                          << "      * Instruction Response : " << _irsp << std::endl
2899                          << "      * Data        Cache    : " << dreq_num_cache[num_cpu] << ", valid : " << (dreq_num_cache[num_cpu]<m_nb_dcache) << std::endl
2900                          << "      * Data        Request  : " << _dreq << std::endl
2901                          << "      * Data        Response : " << _drsp << std::endl;
2902            }
2903#endif
2904
2905            if ((_ireq.valid and not _irsp.valid) or
2906                (_dreq.valid and not _drsp.valid))
2907            {
2908                m_cpt_frz_cycles [num_cpu]++;
2909#if CC_XCACHE_WRAPPER_STOP_SIMULATION
2910                m_stop_simulation_nb_frz_cycles [num_cpu]++;
2911               
2912                if (m_stop_simulation and (m_stop_simulation_nb_frz_cycles [num_cpu]>= m_stop_simulation_nb_frz_cycles_max))
2913                {
2914                    std::cout << std::dec << "CC_XCACHE_WRAPPER \"" << name() << "\" (" << num_cpu << ") : cycle " << m_cpt_total_cycles << ", the cpu is frozen since " << m_stop_simulation_nb_frz_cycles [num_cpu]<< " cycles." << std::endl;
2915                    ASSERT(false,"CPU : anormal activity"); // exit
2916                }
2917            }
2918            else
2919            {
2920                m_stop_simulation_nb_frz_cycles [num_cpu] = 0; // reinit counter
2921#endif //CC_XCACHE_WRAPPER_STOP_SIMULATION
2922            }
2923           
2924#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
2925            if (_ireq.valid and _irsp.valid)
2926            {
2927                log_transaction_file_icache [num_cpu]
2928                    << "[" << m_cpt_total_cycles << "]"
2929                    << std::hex
2930                    << " @ "     << std::setw(8) << (uint32_t)_ireq.addr
2931                    << " ("      << std::setw(8) << (uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu])
2932                    << " - L "     << std::setw(8) <<((uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu])&m_icache_yzmask) << ")"
2933                    << " I "     << std::setw(8) << (uint32_t)_irsp.instruction
2934                    << " error "                 << (uint32_t)_irsp.error
2935                    << std::dec
2936                    << std::endl;
2937            }
2938
2939            if (_dreq.valid and _drsp.valid)
2940            {
2941                log_transaction_file_dcache [num_cpu]
2942                    << "[" << m_cpt_total_cycles << "]"
2943                    << std::hex
2944                    << " @ "     << std::setw(8) << (uint32_t)_dreq.addr
2945                    << " ("      << std::setw(8) << (uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu])
2946                    << " - L "   << std::setw(8) <<((uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu])&m_dcache_yzmask) << ")"
2947                    << " be "    << std::setw(1) << (uint32_t)_dreq.be
2948                    << " W "     << std::setw(8) << (uint32_t)_dreq.wdata
2949                    << " R "     << std::setw(8) << (uint32_t)_drsp.rdata
2950                    << " error "                 << (uint32_t)_drsp.error
2951                    << std::dec
2952                    << " "  << type_str(_dreq.type);
2953               
2954                if ((_dreq.type == iss_t::XTN_READ) or
2955                    (_dreq.type == iss_t::XTN_WRITE))
2956                    //log_transaction_file_dcache [num_cpu] << xtn_str(_dreq.addr>>2);
2957                    switch (_dreq.addr>>2)
2958                    {
2959                    case iss_t::XTN_DCACHE_INVAL : log_transaction_file_dcache [num_cpu]<< " INVAL"; break;
2960                    case iss_t::XTN_SYNC         : log_transaction_file_dcache [num_cpu]<< " SYNC"; break;
2961                    default                      : log_transaction_file_dcache [num_cpu]<< " invalid"; break;
2962                    }
2963               
2964                log_transaction_file_dcache [num_cpu]<< std::endl;
2965            }
2966#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
2967           
2968            {
2969                uint32_t it = 0;
2970                for (size_t i=0; i<(size_t)iss_t::n_irq; i++)
2971                    if(p_irq[num_cpu][i].read()) it |= (1<<i);
2972               
2973                m_iss[num_cpu]->executeNCycles(1, _irsp, _drsp, it);
2974            }
2975        }//end num_cpu
2976
2977        ////////////////////////////////////////////////////////////////////////////
2978        // This CLEANUP FSM controls the transmission of the cleanup transactions
2979        // on the coherence network. It controls the following ressources:
2980        // - r_cleanup_fsm
2981        // - r_dcache_cleanup_req (reset)
2982        // - r_icache_cleanup_req (reset)
2983        //
2984        // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
2985        // - Instruction Cleanup  : r_icache_cleanup_req
2986        // - Data Cleanup         : r_dcache_cleanup_req
2987        // In case of simultaneous requests, the data request have highest priority.
2988        // There is only one cleanup transaction at a given time (sequencial behavior)
2989        // because the same FSM controls both command & response.
2990        // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only
2991        // when the response packet is received.
2992        // Error handling :
2993        // As the coherence trafic is controled by hardware, errors are not reported
2994        // to software : In case of errors, the simulation stops.
2995        ////////////////////////////////////////////////////////////////////////////
2996
2997        switch (r_cleanup_fsm) {
2998
2999            case CLEANUP_IDLE:
3000            {
3001                uint32_t num_cache          = 0;
3002                bool     cleanup_dcache_req = false;
3003                bool     cleanup_icache_req = false;
3004
3005                // dcache is prior
3006                for (uint32_t i=0; i<m_nb_dcache; ++i)
3007                {
3008                    PRINTF("      * <CLEANUP> dcache_cleanup_req : [%d] %d\n",i,(int)r_dcache_cleanup_req[i]);
3009                    cleanup_dcache_req |= r_dcache_cleanup_req[i];
3010                    if (cleanup_dcache_req)
3011                    {
3012                        PRINTF("      * <CLEANUP> ... find\n");
3013                        num_cache=i;
3014                        break;
3015                    }
3016                }
3017 
3018                if (not cleanup_dcache_req)
3019                for (uint32_t i=0; i<m_nb_icache; ++i)
3020                {
3021                    PRINTF("      * <CLEANUP> icache_cleanup_req : [%d] %d\n",i,(int)r_icache_cleanup_req[i]);
3022
3023                    cleanup_icache_req |= r_icache_cleanup_req[i];
3024                    if (cleanup_icache_req)
3025                    {
3026                        PRINTF("      * <CLEANUP> ... find\n");
3027                        num_cache=i;
3028                        break;
3029                    }
3030                }
3031
3032                PRINTF("      * <CLEANUP> cleanup_icache_req : %d\n",cleanup_icache_req);
3033                PRINTF("      * <CLEANUP> cleanup_dcache_req : %d\n",cleanup_dcache_req);
3034                PRINTF("      * <CLEANUP> num_cache          : %d\n",num_cache);
3035
3036                if (cleanup_icache_req or cleanup_dcache_req)
3037                {
3038                    r_cleanup_fsm       = CLEANUP_REQ;
3039                    r_cleanup_icache    = cleanup_icache_req;
3040                    r_cleanup_num_cache = num_cache;
3041
3042                    PRINTF("      * <CLEANUP> address            : %llx\n",((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache))));
3043
3044#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3045                    log_transaction_file_cleanup
3046                        << "[" << m_cpt_total_cycles << "] "
3047                        << ((cleanup_icache_req)?("icache "):("dcache "))
3048                        << num_cache << " : "
3049                        << std::hex
3050                        << " L "     << std::setw(10) << ((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache)))
3051                        // << " (" << std::setw(10) << addr << ")"
3052                        << std::dec
3053                        << std::endl;
3054#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3055
3056                }
3057                break;
3058            }
3059            case CLEANUP_REQ:
3060            {
3061                if ( p_vci_ini_c.cmdack )
3062                {
3063                    if (r_cleanup_icache)
3064                        r_cleanup_fsm = CLEANUP_RSP_ICACHE;
3065                    else
3066                        r_cleanup_fsm = CLEANUP_RSP_DCACHE;
3067                }
3068                break;
3069            }
3070            case CLEANUP_RSP_DCACHE:
3071            {
3072                if ( p_vci_ini_c.rspval )
3073                {
3074                    PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
3075                    PRINTF("      * <CLEANUP> rpktid : %d, r_cleanup_num_cache : %d\n",(uint32_t)p_vci_ini_c.rpktid.read(), (uint32_t)r_cleanup_num_cache);
3076
3077                    ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_DATA_CLEANUP),
3078                           "illegal response packet received for a cleanup transaction");
3079                    ASSERT(p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL,
3080                           "error signaled in a cleanup response" );
3081                    ASSERT(p_vci_ini_c.rpktid.read() == (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache,
3082                           "invalid pktid in a cleanup response");
3083
3084                    r_cleanup_fsm = CLEANUP_IDLE;
3085                    r_dcache_cleanup_req[r_cleanup_num_cache] = false;
3086                    // m_cpt_cc_cleanup_data++;
3087                }
3088                break;
3089            }
3090            case CLEANUP_RSP_ICACHE:
3091            {
3092                if ( p_vci_ini_c.rspval )
3093                {
3094                    PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
3095
3096                    ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_INS_CLEANUP),
3097                           "illegal response packet received for a cleanup transaction");
3098                    ASSERT(p_vci_ini_c.rerror.read() == vci_param::ERR_NORMAL,
3099                           "error signaled in a cleanup response" );
3100                   
3101                    r_cleanup_fsm = CLEANUP_IDLE;
3102                    r_icache_cleanup_req[r_cleanup_num_cache] = false;
3103                    // m_cpt_cc_cleanup_ins++;
3104                }
3105                break;
3106            }
3107        } // end switch r_cleanup_fsm   
3108
3109        ////////////////////////////////////////////////////////////////////////////
3110        // The VCI_CMD FSM controls the following ressources:
3111        // - r_vci_cmd_fsm
3112        // - r_vci_cmd_min
3113        // - r_vci_cmd_max
3114        // - r_vci_cmd_cpt
3115        // - wbuf (reset)
3116        // - r_icache_miss_req (reset)
3117        // - r_icache_unc_req (reset)
3118        // - r_dcache_miss_req (reset)
3119        // - r_dcache_sc_req (reset)
3120        //
3121        // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
3122        // There is 7 request types, with the following priorities :
3123        // 1 - Data Read Miss         : r_dcache_miss_req and miss in the write buffer
3124        // 2 - Data Read Uncachable   : r_dcache_unc_req  and miss in the write buffer
3125        // 3 - Instruction Miss       : r_icache_miss_req and miss in the write buffer
3126        // 4 - Instruction Uncachable : r_icache_unc_req  and miss in the write buffer
3127        // 5 - Data Write             : r_wbuf.rok()     
3128        // 6 - Data Store Conditionnal: r_dcache_sc_req
3129        // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM
3130        // and RSP_FSM exit simultaneously the IDLE state.
3131        //
3132        // VCI formats:
3133        // According to the VCI advanced specification, all read requests packets
3134        // (read Uncached, Miss data, Miss instruction) are one word packets.
3135        // For write burst packets, all words must be in the same cache line,
3136        // and addresses must be contiguous (the BE field is 0 in case of "holes").
3137        //////////////////////////////////////////////////////////////////////////////
3138
3139        r_vci_cmd_dcache_prior = not r_vci_cmd_dcache_prior;
3140
3141        switch (r_vci_cmd_fsm) {
3142
3143            case CMD_IDLE:
3144                {
3145                // if (r_vci_rsp_fsm != RSP_IDLE) break;
3146
3147                size_t  wbuf_min   = 0;
3148                size_t  wbuf_max   = 0;
3149#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3150                addr_40 wbuf_addr  = 0;
3151                size_t  wbuf_index = 0;
3152#endif
3153                r_vci_cmd_cpt = 0;
3154
3155                // Requests :
3156
3157                // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req
3158
3159                bool     dcache_miss_req      = false;
3160                bool     icache_miss_req      = false;
3161                uint32_t dcache_miss_num_cache = 0;
3162                uint32_t icache_miss_num_cache = 0;
3163                addr_40  addr = 0;
3164
3165                {
3166                    for (; dcache_miss_num_cache<m_nb_dcache; ++dcache_miss_num_cache)
3167                    {
3168                        dcache_miss_req = r_dcache_miss_req[dcache_miss_num_cache];
3169                        if (dcache_miss_req)
3170                            break;
3171                    }
3172                    for (; icache_miss_num_cache<m_nb_icache; ++icache_miss_num_cache)
3173                    {
3174                        icache_miss_req = r_icache_miss_req[icache_miss_num_cache];
3175                        if (icache_miss_req)
3176                            break;
3177                    }
3178
3179                    PRINTF("      * <CMD> icache_miss_req (before) : %d\n",icache_miss_req);
3180                    PRINTF("      * <CMD> dcache_miss_req (before) : %d\n",dcache_miss_req);
3181
3182#if   (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==1)
3183                    //  1) one access with static priority (dcache prior)
3184                    icache_miss_req &= not dcache_miss_req;
3185#elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==2)
3186                    //  2) one access with static priority (icache prior)
3187                    dcache_miss_req &= not icache_miss_req;
3188#elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==3)
3189                    //  3) one access with round robin priority
3190                    dcache_miss_req = ((dcache_miss_req and not icache_miss_req) or // only dcache
3191                                       (dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior
3192                    icache_miss_req &= not dcache_miss_req;
3193// #elif (CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY==4)
3194//                     //  4) two access authorized
3195//                     dcache_miss_req =  r_dcache_miss_req[cache_miss_num_cache];
3196//                     icache_miss_req =  r_icache_miss_req[cache_miss_num_cache];
3197#else
3198#error "Invalid value to CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY"
3199#endif
3200
3201                    PRINTF("      * <CMD> icache_miss_req (after ) : %d\n",icache_miss_req);
3202                    PRINTF("      * <CMD> dcache_miss_req (after ) : %d\n",dcache_miss_req);
3203
3204                    PRINTF("      * <CMD> icache_miss_num_cache    : %d\n",icache_miss_num_cache);
3205                    PRINTF("      * <CMD> dcache_miss_num_cache    : %d\n",dcache_miss_num_cache);
3206
3207                    if (icache_miss_req or dcache_miss_req)
3208                    {
3209                        addr = (icache_miss_req)?r_icache_addr_save[icache_miss_num_cache].read():r_dcache_addr_save[dcache_miss_num_cache].read();
3210
3211                        PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
3212
3213                        if (icache_miss_req)
3214                        {
3215                            // FIXME :
3216                            // si wbuf contient des addresses partionné, set_num_icache puis get_num_dcache
3217                            // dcache_miss_num_cache = icache_miss_num_cache;
3218                            set_num_icache(addr,icache_miss_num_cache);
3219                            // get_num_dcache(addr,dcache_miss_num_cache);
3220                        }
3221                        else
3222                            set_num_dcache(addr,dcache_miss_num_cache);
3223
3224                        PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
3225                    }
3226                }
3227
3228                uint32_t dcache_unc_num_cache = 0;
3229                for (; dcache_unc_num_cache<m_nb_dcache; ++dcache_unc_num_cache)
3230                    if (r_dcache_unc_req[dcache_unc_num_cache])
3231                        break;
3232                uint32_t icache_unc_num_cache = 0;
3233                for (; icache_unc_num_cache<m_nb_icache; ++icache_unc_num_cache)
3234                    if (r_icache_unc_req[icache_unc_num_cache])
3235                        break;
3236                uint32_t dcache_sc_num_cache = 0;
3237                for (; dcache_sc_num_cache<m_nb_dcache; ++dcache_sc_num_cache)
3238                    if (r_dcache_sc_req[dcache_sc_num_cache])
3239                        break;
3240                uint32_t dcache_write_num_cache = 0;
3241                for (; dcache_write_num_cache<m_nb_dcache; ++dcache_write_num_cache)
3242                {
3243#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3244                    if ( r_wbuf[dcache_write_num_cache]->debug_rok(&wbuf_min, &wbuf_max, &wbuf_addr, &wbuf_index))
3245                        break;
3246#else
3247                    if ( r_wbuf[dcache_write_num_cache]->rok(&wbuf_min, &wbuf_max))
3248                        break;
3249#endif
3250                }
3251               
3252                // 1 - Data Read
3253                if (dcache_miss_req and r_wbuf[dcache_miss_num_cache]->miss(addr))
3254                {
3255                    r_vci_cmd_fsm       = CMD_DATA_MISS;
3256                    r_vci_cmd_num_cache = dcache_miss_num_cache;
3257                    r_dcache_miss_req[dcache_miss_num_cache] = false;
3258                    m_cpt_dmiss_transaction++;
3259
3260
3261#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3262                    {
3263                        log_transaction_file_cmd
3264                            << "[" << m_cpt_total_cycles << "] "
3265                            << "CMD DATA MISS  "
3266                            << "(" << dcache_miss_num_cache << ") "
3267                            << std::hex
3268                            << " @ " << std::setw(10) << (blob_t)addr
3269                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3270                            << std::dec
3271                            << std::endl;
3272                    }
3273#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3274
3275                }
3276
3277                // 2 - Data Read Uncachable
3278                else if (dcache_unc_num_cache < m_nb_dcache) // have r_dcache_unc_req
3279                {
3280                    r_vci_cmd_fsm       = CMD_DATA_UNC;
3281                    r_vci_cmd_num_cache = dcache_unc_num_cache;
3282                    r_dcache_unc_req[dcache_unc_num_cache] = false;
3283                    // m_cpt_data_unc_transaction++;
3284
3285#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3286                    {
3287                        addr_40 addr = (addr_40) r_dcache_addr_save[dcache_unc_num_cache].read() & ~0x3;
3288                        set_num_dcache(addr,dcache_unc_num_cache);
3289                       
3290                        log_transaction_file_cmd
3291                            << "[" << m_cpt_total_cycles << "] "
3292                            << "CMD DATA UNC   "
3293                            << "(" << dcache_unc_num_cache << ") "
3294                            << std::hex
3295                            << " @ " << std::setw(10) << (blob_t)addr
3296                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3297                            << std::dec
3298                            << std::endl;
3299                    }
3300#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3301                }
3302
3303                // 3 - Instruction Miss
3304                else if (icache_miss_req and r_wbuf[icache_miss_num_cache]->miss(addr))
3305              //else if (icache_miss_req and r_wbuf[dcache_miss_num_cache]->miss(addr))
3306                {
3307                    r_vci_cmd_fsm       = CMD_INS_MISS;
3308                    r_vci_cmd_num_cache = icache_miss_num_cache;
3309                    r_icache_miss_req[icache_miss_num_cache] = false;
3310                    m_cpt_imiss_transaction++;
3311
3312#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3313                    {
3314                        log_transaction_file_cmd
3315                            << "[" << m_cpt_total_cycles << "] "
3316                            << "CMD INS  MISS  "
3317                            << "(" << icache_miss_num_cache << ") "
3318                            << std::hex
3319                            << " @ " << std::setw(10) << (blob_t)addr
3320                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
3321                            << std::dec
3322                            << std::endl;
3323                    }
3324#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3325                }
3326
3327                // 4 - Instruction Uncachable
3328                else if (icache_unc_num_cache < m_nb_icache) // have r_icache_unc_req
3329                {
3330                    r_vci_cmd_fsm       = CMD_INS_UNC;
3331                    r_vci_cmd_num_cache = icache_unc_num_cache;
3332                    r_icache_unc_req[icache_unc_num_cache] = false;
3333                 // m_cpt_ins_unc_transaction++;
3334
3335#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3336                    {
3337                        addr_40 addr = (addr_40) r_icache_addr_save[icache_unc_num_cache].read() & ~0x3;
3338                        set_num_dcache(addr,icache_unc_num_cache);
3339                       
3340                        log_transaction_file_cmd
3341                            << "[" << m_cpt_total_cycles << "] "
3342                            << "CMD INS  UNC   "
3343                            << "(" << icache_unc_num_cache << ") "
3344                            << std::hex
3345                            << " @ " << std::setw(10) << (blob_t)addr
3346                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
3347                            << std::dec
3348                            << std::endl;
3349                    }
3350#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3351                }
3352
3353                // 5 - Data Write
3354                else if (dcache_write_num_cache < m_nb_dcache) // have r_wbuf.rok(&wbuf_min, &wbuf_max)
3355                {
3356                    r_vci_cmd_num_cache = dcache_write_num_cache;
3357                    r_vci_cmd_fsm       = CMD_DATA_WRITE;
3358                    r_vci_cmd_cpt       = wbuf_min;
3359                    r_vci_cmd_min       = wbuf_min;
3360                    r_vci_cmd_max       = wbuf_max;
3361                    m_cpt_data_write_transaction++;
3362                    m_length_write_transaction += (wbuf_max-wbuf_min+1);
3363
3364#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3365                    {
3366                        addr_40 addr = (addr_40) wbuf_addr&~0x3;
3367                       
3368                        log_transaction_file_cmd
3369                            << "[" << m_cpt_total_cycles << "] "
3370                            << "CMD DATA WRITE "
3371                            << "(" << dcache_write_num_cache << ") "
3372                            << std::hex
3373                            << " @ " << std::setw(10) << (blob_t)addr
3374                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3375                            << " [" << wbuf_min << ":" << wbuf_max << "]"
3376                            << " {" << wbuf_index << "}"
3377                            << std::dec
3378                            << std::endl;
3379                    }
3380#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3381                }
3382
3383                // 6 - Data Store Conditionnal
3384                else if (dcache_sc_num_cache < m_nb_dcache) // have r_dcache_sc_req
3385                {
3386                    r_vci_cmd_fsm       = CMD_DATA_SC;
3387                    r_vci_cmd_num_cache = dcache_sc_num_cache;
3388                    r_vci_cmd_max       = 1;
3389                    m_cpt_unc_transaction++;
3390                    r_dcache_sc_req[dcache_sc_num_cache] = false;
3391
3392#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3393                    {
3394                        addr_40 addr = (addr_40) r_dcache_addr_save[dcache_sc_num_cache].read() & ~0x3;
3395                        set_num_dcache(addr,dcache_sc_num_cache);
3396                       
3397                        log_transaction_file_cmd
3398                            << "[" << m_cpt_total_cycles << "] "
3399                            << "CMD DATA SC    "
3400                            << "(" << dcache_sc_num_cache << ") "
3401                            << std::hex
3402                            << " @ " << std::setw(10) << (blob_t)addr
3403                            << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3404                            << std::dec
3405                            << std::endl;
3406                    }
3407#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3408                }
3409
3410                break;
3411                }
3412            case CMD_DATA_WRITE:
3413                if ( p_vci_ini_rw.cmdack.read() ) {
3414                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
3415                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
3416                        r_vci_cmd_fsm = CMD_IDLE ;
3417                        r_wbuf[r_vci_cmd_num_cache]->sent() ;
3418                    }
3419                }
3420                break;
3421
3422            case CMD_DATA_SC:
3423                if ( p_vci_ini_rw.cmdack.read() ) {
3424                    r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
3425                    if (r_vci_cmd_cpt == r_vci_cmd_max) {
3426                        r_vci_cmd_fsm = CMD_IDLE ;
3427                    }
3428                }
3429                break;
3430            case CMD_INS_MISS:
3431            case CMD_INS_UNC:
3432            case CMD_DATA_MISS:
3433            case CMD_DATA_UNC:
3434                if ( p_vci_ini_rw.cmdack.read() ) {
3435                    r_vci_cmd_fsm = CMD_IDLE;
3436                }
3437                break;
3438
3439        } // end  switch r_vci_cmd_fsm
3440
3441        //////////////////////////////////////////////////////////////////////////
3442        // The VCI_RSP FSM controls the following ressources:
3443        // - r_vci_rsp_fsm:
3444        // - r_icache_miss_buf[m_icache_words]
3445        // - r_dcache_miss_buf[m_dcache_words]
3446        // - r_vci_rsp_data_error set
3447        // - r_vci_rsp_ins_error set
3448        // - r_vci_rsp_cpt
3449        // In order to have only one active VCI transaction, this VCI_RSP_FSM
3450        // is synchronized with the VCI_CMD FSM, and both FSMs exit the
3451        // IDLE state simultaneously.
3452        //
3453        // VCI formats:
3454        // This component accepts single word or multi-word response packets for
3455        // write response packets.
3456        //
3457        // Error handling:
3458        // This FSM analyzes the VCI error code and signals directly the
3459        // Write Bus Error.
3460        // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error
3461        // flip_flop and the error is signaled by the DCACHE FSM. 
3462        // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
3463        // flip_flop and the error is signaled by the DCACHE FSM. 
3464        // In case of Cleanup Error, the simulation stops with an error message...
3465        //////////////////////////////////////////////////////////////////////////
3466
3467        switch (r_vci_rsp_fsm) {
3468
3469            case RSP_IDLE:
3470
3471                if( p_vci_ini_rw.rspval.read() )
3472                {
3473                    PRINTF("      * <RSP> have rsp - trdid : %x - num_cache : %d\n",(uint32_t)p_vci_ini_rw.rtrdid.read(),(uint32_t)p_vci_ini_rw.rpktid.read());
3474
3475                    ASSERT(p_vci_ini_rw.rpktid.read() <= (1<<vci_param::P),
3476                           "invalid pktid in a cleanup response");
3477
3478                    r_vci_rsp_cpt = 0;
3479
3480                    if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 )
3481                    {
3482                        r_vci_rsp_fsm = RSP_DATA_WRITE;
3483
3484#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3485                        {
3486                            log_transaction_file_cmd
3487                                << "[" << m_cpt_total_cycles << "] "
3488                                << "RSP DATA WRITE "
3489                                << "(" << p_vci_ini_rw.rpktid.read() << ") "
3490                                << "{" << (p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1))) << "}"
3491                                << std::endl;
3492                        }
3493#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3494                    }
3495                    else
3496                    {
3497                        switch (p_vci_ini_rw.rtrdid.read())
3498                        {
3499                        case TYPE_INS_MISS     :
3500                            {
3501                                r_vci_rsp_fsm = RSP_INS_MISS;
3502
3503#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3504                                {
3505                                    log_transaction_file_cmd
3506                                        << "[" << m_cpt_total_cycles << "] "
3507                                        << "RSP INS  MISS  "
3508                                        << "(" << p_vci_ini_rw.rpktid.read() << ") "
3509                                        << std::endl;
3510                                }
3511#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3512
3513                                break;
3514                            }
3515                        case TYPE_INS_UNC      :
3516                            {
3517                                r_vci_rsp_fsm = RSP_INS_UNC;
3518
3519#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3520                                {
3521                                    log_transaction_file_cmd
3522                                        << "[" << m_cpt_total_cycles << "] "
3523                                        << "RSP INS  UNC   "
3524                                        << "(" << p_vci_ini_rw.rpktid.read() << ") "
3525                                        << std::endl;
3526                                }
3527#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3528
3529                                break;
3530                            }
3531                        case TYPE_DATA_MISS    :
3532                            {
3533                                r_vci_rsp_fsm = RSP_DATA_MISS;
3534
3535#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3536                                {
3537                                    log_transaction_file_cmd
3538                                        << "[" << m_cpt_total_cycles << "] "
3539                                        << "RSP DATA MISS  "
3540                                        << "(" << p_vci_ini_rw.rpktid.read() << ") "
3541                                        << std::endl;
3542                                }
3543#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3544
3545                                break;
3546                            }
3547                        case TYPE_DATA_UNC     :
3548                            {
3549                                r_vci_rsp_fsm = RSP_DATA_UNC;
3550
3551#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3552                                {
3553                                    log_transaction_file_cmd
3554                                        << "[" << m_cpt_total_cycles << "] "
3555                                        << "RSP DATA UNC   "
3556                                        << "(" << p_vci_ini_rw.rpktid.read() << ") "
3557                                        << std::endl;
3558                                }
3559#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3560
3561                                break;
3562                            }
3563                        case TYPE_DATA_SC      :
3564                            {
3565                                r_vci_rsp_fsm = RSP_DATA_SC;
3566
3567#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3568                                {
3569                                    log_transaction_file_cmd
3570                                        << "[" << m_cpt_total_cycles << "] "
3571                                        << "RSP DATA SC    "
3572                                        << "(" << p_vci_ini_rw.rpktid.read() << ") "
3573                                        << std::endl;
3574                                }
3575#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3576
3577                                break;
3578                            }
3579                        default :
3580                            {
3581                                ASSERT(false, "Unexpected response");
3582                            }
3583                        }
3584                    }
3585
3586                    r_vci_rsp_num_cache = p_vci_ini_rw.rpktid.read();
3587                }
3588                break;
3589
3590            case RSP_INS_MISS:
3591
3592                m_cost_imiss_transaction++;
3593                PRINTF("      * <RSP> rspval/ack : %d - %d\n",(uint32_t)p_vci_ini_rw.rspval.read(), (uint32_t)s_vci_rsp_ack);
3594
3595                if (p_vci_ini_rw.rspval.read() and s_vci_rsp_ack)
3596                {
3597                    PRINTF("      * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words);
3598                    PRINTF("      * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read());
3599
3600                    ASSERT( (r_vci_rsp_cpt < m_icache_words),
3601                            "The VCI response packet for instruction miss is too long" );
3602                    r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
3603                    CACHE_MISS_BUF_RSP_PUSH(i,r_vci_rsp_num_cache,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read());
3604                    if ( p_vci_ini_rw.reop.read() )
3605                    {
3606                        PRINTF("      * <RSP> have reop\n");
3607
3608                        ASSERT( ((r_vci_rsp_cpt == m_icache_words - 1) or
3609                                 p_vci_ini_rw.rerror.read() or
3610                                 (r_vci_rsp_ins_error[r_vci_rsp_num_cache].read()&0x1)),
3611                                "The VCI response packet for instruction miss is too short");
3612                        r_vci_rsp_cpt    = 0;
3613                        r_vci_rsp_fsm    = RSP_IDLE;
3614
3615                    }
3616                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
3617                }
3618                break;
3619
3620            case RSP_INS_UNC:
3621
3622                m_cost_imiss_transaction++;
3623                if (p_vci_ini_rw.rspval.read() and s_vci_rsp_ack)
3624                {
3625                    ASSERT(p_vci_ini_rw.reop.read(),
3626                           "illegal VCI response packet for uncached instruction");
3627
3628                    CACHE_MISS_BUF_RSP_PUSH(i,r_vci_rsp_num_cache,0,(data_t)p_vci_ini_rw.rdata.read());
3629
3630                    r_vci_rsp_fsm = RSP_IDLE;
3631
3632                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
3633                }
3634                break;
3635
3636            case RSP_DATA_MISS:
3637
3638                m_cost_dmiss_transaction++;
3639                if (p_vci_ini_rw.rspval.read() and s_vci_rsp_ack)
3640                {
3641                    PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
3642
3643                    ASSERT(r_vci_rsp_cpt < m_dcache_words,
3644                           "illegal VCI response packet for data read miss");
3645                    r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
3646
3647                    CACHE_MISS_BUF_RSP_PUSH(d,r_vci_rsp_num_cache,r_vci_rsp_cpt,(data_t)p_vci_ini_rw.rdata.read());
3648
3649                    if ( p_vci_ini_rw.reop.read() ) {
3650                        ASSERT( ((r_vci_rsp_cpt == m_dcache_words - 1)
3651                                 or (p_vci_ini_rw.rerror.read()&0x1)
3652                                 or r_vci_rsp_data_error[r_vci_rsp_num_cache].read()),
3653                                "illegal VCI response packet for data read miss");
3654                        r_vci_rsp_cpt     = 0;
3655                        r_vci_rsp_fsm     = RSP_IDLE;
3656                    }
3657                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
3658                }
3659                break;
3660
3661            case RSP_DATA_WRITE:
3662                m_cost_write_transaction++;
3663                if (p_vci_ini_rw.rspval.read())
3664                {
3665                    PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
3666
3667                    ASSERT(p_vci_ini_rw.reop.read(),
3668                           "A VCI response packet must contain one flit for a write transaction");
3669                    r_vci_rsp_fsm = RSP_IDLE;
3670                    uint32_t wbuf_index = p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1));
3671                    bool cached = r_wbuf[r_vci_rsp_num_cache]->completed(wbuf_index);
3672
3673                    PRINTF("      * <RSP> cached : %d\n",cached);
3674
3675                    if (not cached)
3676                        r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
3677
3678                    if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL)
3679                        m_iss[r_wbuf[r_vci_rsp_num_cache]->getCpuId(wbuf_index)]->setWriteBerr();
3680                }
3681                break;
3682
3683            case RSP_DATA_UNC:
3684                m_cost_unc_transaction++;
3685                if (p_vci_ini_rw.rspval.read() and s_vci_rsp_ack)
3686                {
3687                    ASSERT(p_vci_ini_rw.reop.read(),
3688                           "illegal VCI response packet for data read uncached");
3689
3690                    CACHE_MISS_BUF_RSP_PUSH(d,r_vci_rsp_num_cache,0,(data_t)p_vci_ini_rw.rdata.read());
3691
3692                    r_vci_rsp_fsm = RSP_IDLE;
3693                    r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
3694
3695                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
3696                }
3697                break;
3698
3699            case RSP_DATA_SC:
3700                m_cost_unc_transaction++;
3701                if (p_vci_ini_rw.rspval.read() and s_vci_rsp_ack)
3702                {
3703                    ASSERT(p_vci_ini_rw.reop.read(),
3704                           "illegal VCI response packet for data SC");
3705
3706                    CACHE_MISS_BUF_RSP_PUSH(d,r_vci_rsp_num_cache,0,(data_t)p_vci_ini_rw.rdata.read());
3707
3708                    r_vci_rsp_fsm = RSP_IDLE;
3709                    r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
3710
3711                    if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
3712                }
3713                break;
3714
3715        } // end switch r_vci_rsp_fsm
3716
3717   } // end transition()
3718
3719    //////////////////////////////////////////////////////////////////////////////////
3720    tmpl(void)::genMoore()
3721    //////////////////////////////////////////////////////////////////////////////////
3722    {
3723        PRINTF("--------------------------------------------\n");
3724        PRINTF("  * CC_XCACHE_WRAPPER \"%s\" genMoore - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
3725
3726        // VCI initiator response
3727        switch ( r_cleanup_fsm.read() ) {
3728            case CLEANUP_IDLE:
3729                p_vci_ini_c.rspack  = false;
3730                p_vci_ini_c.cmdval  = false;
3731                p_vci_ini_c.address = 0;
3732                p_vci_ini_c.wdata   = 0;
3733                p_vci_ini_c.be      = 0;
3734                p_vci_ini_c.plen    = 0;
3735                p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
3736                p_vci_ini_c.trdid   = 0;
3737                p_vci_ini_c.pktid   = 0;
3738                p_vci_ini_c.srcid   = 0;
3739                p_vci_ini_c.cons    = false;
3740                p_vci_ini_c.wrap    = false;
3741                p_vci_ini_c.contig  = false;
3742                p_vci_ini_c.clen    = 0;
3743                p_vci_ini_c.cfixed  = false;
3744                p_vci_ini_c.eop     = false;
3745                break;
3746
3747            case CLEANUP_REQ:
3748                {
3749                addr_40 addr;
3750                if (r_cleanup_icache)
3751                {
3752                    addr = r_icache_cleanup_line[r_cleanup_num_cache].read()<<m_icache_words_shift;
3753                    set_num_icache(addr,r_cleanup_num_cache);
3754
3755                    PRINTF("      * <CLEANUP> icache             : %llx\n",(blob_t)addr);
3756                }
3757                else
3758                {
3759                    addr = r_dcache_cleanup_line[r_cleanup_num_cache].read()<<m_dcache_words_shift;
3760                    set_num_dcache(addr,r_cleanup_num_cache);
3761
3762                    PRINTF("      * <CLEANUP> dcache             : %llx\n",(blob_t)addr);
3763                }
3764
3765                p_vci_ini_c.rspack  = false;
3766                p_vci_ini_c.cmdval  = true;
3767                p_vci_ini_c.address = addr;
3768                p_vci_ini_c.wdata   = 0;
3769                p_vci_ini_c.be      = 0xF;
3770                p_vci_ini_c.plen    = 4;
3771                p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
3772                p_vci_ini_c.trdid   = (r_cleanup_icache)?TYPE_INS_CLEANUP:TYPE_DATA_CLEANUP;
3773                p_vci_ini_c.pktid   = (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache;
3774                p_vci_ini_c.srcid   = m_srcid_c;
3775                p_vci_ini_c.cons    = false;
3776                p_vci_ini_c.wrap    = false;
3777                p_vci_ini_c.contig  = false;
3778                p_vci_ini_c.clen    = 0;
3779                p_vci_ini_c.cfixed  = false;
3780                p_vci_ini_c.eop     = true;
3781
3782                break;
3783                }
3784
3785           case CLEANUP_RSP_DCACHE:
3786                p_vci_ini_c.rspack  = true;
3787                p_vci_ini_c.cmdval  = false;
3788                p_vci_ini_c.address = 0;
3789                p_vci_ini_c.wdata  = 0;
3790                p_vci_ini_c.be     = 0;
3791                p_vci_ini_c.plen   = 0;
3792                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
3793                p_vci_ini_c.trdid  = 0;
3794                p_vci_ini_c.pktid  = 0;
3795                p_vci_ini_c.srcid  = 0;
3796                p_vci_ini_c.cons   = false;
3797                p_vci_ini_c.wrap   = false;
3798                p_vci_ini_c.contig = false;
3799                p_vci_ini_c.clen   = 0;
3800                p_vci_ini_c.cfixed = false;
3801                p_vci_ini_c.eop = false;
3802                break;
3803
3804           case CLEANUP_RSP_ICACHE:
3805                p_vci_ini_c.rspack  = true;
3806                p_vci_ini_c.cmdval  = false;
3807                p_vci_ini_c.address = 0;
3808                p_vci_ini_c.wdata  = 0;
3809                p_vci_ini_c.be     = 0;
3810                p_vci_ini_c.plen   = 0;
3811                p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
3812                p_vci_ini_c.trdid  = 0;
3813                p_vci_ini_c.pktid  = 0;
3814                p_vci_ini_c.srcid  = 0;
3815                p_vci_ini_c.cons   = false;
3816                p_vci_ini_c.wrap   = false;
3817                p_vci_ini_c.contig = false;
3818                p_vci_ini_c.clen   = 0;
3819                p_vci_ini_c.cfixed = false;
3820                p_vci_ini_c.eop = false;
3821                break;
3822           } // end switch r_cleanup_fsm
3823
3824        // VCI initiator command
3825
3826        switch (r_vci_cmd_fsm.read() ) {
3827            case CMD_IDLE:
3828                {
3829                p_vci_ini_rw.cmdval  = false;
3830                p_vci_ini_rw.address = 0;
3831                p_vci_ini_rw.wdata   = 0;
3832                p_vci_ini_rw.be      = 0;
3833                p_vci_ini_rw.plen    = 0;
3834                p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
3835                p_vci_ini_rw.trdid   = 0;
3836                p_vci_ini_rw.pktid   = 0;
3837                p_vci_ini_rw.srcid   = 0;
3838                p_vci_ini_rw.cons    = false;
3839                p_vci_ini_rw.wrap    = false;
3840                p_vci_ini_rw.contig  = false;
3841                p_vci_ini_rw.clen    = 0;
3842                p_vci_ini_rw.cfixed  = false;
3843                p_vci_ini_rw.eop     = false;
3844
3845                break;
3846                }
3847            case CMD_DATA_UNC:
3848                {
3849                p_vci_ini_rw.cmdval = true;
3850
3851                addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
3852                set_num_dcache(addr,r_vci_cmd_num_cache);
3853
3854                PRINTF("      * <CMD> DATA_UNC   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
3855
3856                p_vci_ini_rw.address = addr;
3857                switch( r_dcache_type_save[r_vci_cmd_num_cache] ) {
3858                    case iss_t::DATA_READ:
3859                        p_vci_ini_rw.wdata = 0;
3860                        p_vci_ini_rw.be  = r_dcache_be_save[r_vci_cmd_num_cache].read();
3861                        p_vci_ini_rw.cmd = vci_param::CMD_READ;
3862                        break;
3863                    case iss_t::DATA_LL:
3864                        p_vci_ini_rw.wdata = 0;
3865                        p_vci_ini_rw.be  = 0xF;
3866                        p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ;
3867                        break;
3868                    default:
3869                        ASSERT(false,"this should not happen");
3870                }
3871                p_vci_ini_rw.plen = 4;
3872                p_vci_ini_rw.trdid  = TYPE_DATA_UNC;   // data cache uncached read
3873                p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
3874                p_vci_ini_rw.srcid  = m_srcid_rw;
3875                p_vci_ini_rw.cons   = false;
3876                p_vci_ini_rw.wrap   = false;
3877                p_vci_ini_rw.contig = true;
3878                p_vci_ini_rw.clen   = 0;
3879                p_vci_ini_rw.cfixed = false;
3880                p_vci_ini_rw.eop    = true;
3881
3882                break;
3883                }
3884            case CMD_DATA_SC:
3885                {
3886                p_vci_ini_rw.cmdval = true;
3887
3888                addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
3889                set_num_dcache(addr,r_vci_cmd_num_cache);
3890
3891                PRINTF("      * <CMD> DATA_SC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
3892
3893                p_vci_ini_rw.address = addr;
3894                if(r_vci_cmd_max.read() == 3){
3895                    ASSERT(false, "Not handled yet");
3896                } else { // r_vci_cmd_cpt == 1
3897                    switch(r_vci_cmd_cpt.read()){
3898                        case 0:
3899                            p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data[r_vci_cmd_num_cache][r_dcache_num_cpu_save[r_vci_cmd_num_cache]].read() & 0xFFFFFFFF);
3900                            break;
3901                        case 1:
3902                            p_vci_ini_rw.wdata = r_dcache_wdata_save[r_vci_cmd_num_cache].read();
3903                            break;
3904                    }
3905                }
3906                p_vci_ini_rw.be     = 0xF;
3907                p_vci_ini_rw.cmd    = vci_param::CMD_STORE_COND;
3908                p_vci_ini_rw.plen   = 4*(r_vci_cmd_max.read()+1);
3909                p_vci_ini_rw.trdid  = TYPE_DATA_SC;   // data cache uncached read
3910                p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
3911                p_vci_ini_rw.srcid  = m_srcid_rw;
3912                p_vci_ini_rw.cons   = true;
3913                p_vci_ini_rw.wrap   = false;
3914                p_vci_ini_rw.contig = false;
3915                p_vci_ini_rw.clen   = 0;
3916                p_vci_ini_rw.cfixed = false;
3917                p_vci_ini_rw.eop    = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
3918
3919                break;
3920                }
3921            case CMD_DATA_WRITE:
3922                {
3923                p_vci_ini_rw.cmdval  = true;
3924
3925                addr_40 addr       = (addr_40) r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt)&~0x3;
3926
3927                PRINTF("      * <CMD> DATA_WRITE : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
3928
3929                p_vci_ini_rw.address = addr;
3930                p_vci_ini_rw.wdata   = r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt);
3931                p_vci_ini_rw.be      = r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt);
3932                p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
3933                p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
3934                p_vci_ini_rw.trdid   = r_wbuf[r_vci_cmd_num_cache]->getIndex() + (1<<(vci_param::T-1));
3935                p_vci_ini_rw.pktid   = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
3936                p_vci_ini_rw.srcid   = m_srcid_rw;
3937                p_vci_ini_rw.cons    = false;
3938                p_vci_ini_rw.wrap    = false;
3939                p_vci_ini_rw.contig  = true;
3940                p_vci_ini_rw.clen    = 0;
3941                p_vci_ini_rw.cfixed  = false;
3942                p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
3943
3944                break;
3945                }
3946            case CMD_DATA_MISS:
3947                {
3948                p_vci_ini_rw.cmdval = true;
3949
3950                addr_40 addr = r_dcache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_dcache_yzmask;
3951                set_num_dcache(addr,r_vci_cmd_num_cache);
3952
3953                PRINTF("      * <CMD> DATA_MISS  : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
3954
3955                p_vci_ini_rw.address = addr;
3956                p_vci_ini_rw.be     = 0xF;
3957                p_vci_ini_rw.plen   = m_dcache_words << 2;
3958                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
3959                p_vci_ini_rw.trdid  = TYPE_DATA_MISS;   // data cache cached read
3960                p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
3961                p_vci_ini_rw.srcid  = m_srcid_rw;
3962                p_vci_ini_rw.cons   = false;
3963                p_vci_ini_rw.wrap   = false;
3964                p_vci_ini_rw.contig = true;
3965                p_vci_ini_rw.clen   = 0;
3966                p_vci_ini_rw.cfixed = false;
3967                p_vci_ini_rw.eop = true;
3968
3969                break;
3970                }
3971            case CMD_INS_MISS:
3972                {
3973                p_vci_ini_rw.cmdval = true;
3974
3975                addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_icache_yzmask;
3976                set_num_icache(addr,r_vci_cmd_num_cache);
3977
3978                PRINTF("      * <CMD> INS_MISS   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
3979
3980                p_vci_ini_rw.address = addr;
3981                p_vci_ini_rw.be     = 0xF;
3982                p_vci_ini_rw.plen   = m_icache_words << 2;
3983                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
3984                p_vci_ini_rw.trdid  = TYPE_INS_MISS;   // ins cache cached read
3985                p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
3986                p_vci_ini_rw.srcid  = m_srcid_rw;
3987                p_vci_ini_rw.cons   = false;
3988                p_vci_ini_rw.wrap   = false;
3989                p_vci_ini_rw.contig = true;
3990                p_vci_ini_rw.clen   = 0;
3991                p_vci_ini_rw.cfixed = false;
3992                p_vci_ini_rw.eop = true;
3993
3994                break;
3995                }
3996            case CMD_INS_UNC:
3997                {
3998                p_vci_ini_rw.cmdval = true;
3999
4000                addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
4001                set_num_icache(addr,r_vci_cmd_num_cache);
4002
4003                PRINTF("      * <CMD> INS_UNC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4004
4005                p_vci_ini_rw.address = addr;
4006                p_vci_ini_rw.be     = 0xF;
4007                p_vci_ini_rw.plen   = 4;
4008                p_vci_ini_rw.cmd    = vci_param::CMD_READ;
4009                p_vci_ini_rw.trdid  = TYPE_INS_UNC;   // ins cache uncached read
4010                p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4011                p_vci_ini_rw.srcid  = m_srcid_rw;
4012                p_vci_ini_rw.cons   = false;
4013                p_vci_ini_rw.wrap   = false;
4014                p_vci_ini_rw.contig = true;
4015                p_vci_ini_rw.clen   = 0;
4016                p_vci_ini_rw.cfixed = false;
4017                p_vci_ini_rw.eop = true;
4018
4019                break;
4020                }
4021        } // end switch r_vci_cmd_fsm
4022
4023        {
4024            bool ack;
4025           
4026            switch (r_vci_rsp_fsm.read() ) {
4027            case RSP_DATA_WRITE : ack = true; break;
4028            case RSP_INS_MISS   :
4029            case RSP_INS_UNC    : ack = CACHE_MISS_BUF_RSP_ACK(i,r_vci_rsp_num_cache); break;
4030            case RSP_DATA_MISS  :
4031            case RSP_DATA_UNC   :
4032            case RSP_DATA_SC    : ack = CACHE_MISS_BUF_RSP_ACK(d,r_vci_rsp_num_cache); break;
4033               
4034            case RSP_IDLE       :
4035            default             : ack = false; break;
4036               
4037            } // end switch r_vci_cmd_fsm
4038           
4039            s_vci_rsp_ack       = ack;
4040            p_vci_ini_rw.rspack = ack;
4041
4042            PRINTF("      * <RSP> rspack : %d\n", ack);
4043        }
4044
4045        // VCI_TGT
4046
4047        // PRINTF("      * <TGT> srcid : %d\n", r_tgt_srcid.read());
4048
4049        switch ( r_vci_tgt_fsm.read() ) {
4050
4051            case TGT_IDLE:
4052            case TGT_UPDT_WORD:
4053            case TGT_UPDT_DATA:
4054                p_vci_tgt.cmdack  = true;
4055                p_vci_tgt.rspval  = false;
4056                break;
4057
4058            case TGT_RSP_BROADCAST:
4059                {
4060                    bool tgt_icache_req;
4061                    bool tgt_icache_rsp;
4062
4063#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
4064                    tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
4065                    tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
4066#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
4067                    tgt_icache_req = false;
4068                    tgt_icache_rsp = false;
4069                    for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
4070                    {
4071                        tgt_icache_req |= r_tgt_icache_req[num_cache].read();
4072                        tgt_icache_rsp |= r_tgt_icache_rsp[num_cache].read();
4073                    }
4074#endif
4075
4076                    bool rspval = ((not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
4077                                   and (tgt_icache_rsp | r_tgt_dcache_rsp[r_tgt_num_cache]));
4078
4079                    PRINTF("      * <TGT> RSP_BROADCAST : rspval : %d (i %d %d, d %d %d)\n",rspval,tgt_icache_req,tgt_icache_rsp, r_tgt_dcache_req[r_tgt_num_cache].read(), r_tgt_dcache_rsp[r_tgt_num_cache].read());
4080                   
4081                    p_vci_tgt.cmdack  = false;
4082                    p_vci_tgt.rspval  = rspval;
4083                    p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4084                    p_vci_tgt.rpktid  = r_tgt_pktid.read();
4085                    p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4086                    p_vci_tgt.rdata   = 0;
4087                    p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4088                    p_vci_tgt.reop    = true;
4089                    break;
4090                }
4091            case TGT_RSP_ICACHE:
4092                {
4093                    bool rspval = not r_tgt_icache_req[r_tgt_num_cache].read() and r_tgt_icache_rsp[r_tgt_num_cache].read();
4094
4095                    PRINTF("      * <TGT> RSP_ICACHE : rspval : %d\n",rspval);
4096
4097                    p_vci_tgt.cmdack  = false;
4098                    p_vci_tgt.rspval  = rspval;
4099                    p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4100                    p_vci_tgt.rpktid  = r_tgt_pktid.read();
4101                    p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4102                    p_vci_tgt.rdata   = 0;
4103                    p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4104                    p_vci_tgt.reop    = true;
4105                    break;
4106                }
4107            case TGT_RSP_DCACHE:
4108                {
4109                    bool rspval = not r_tgt_dcache_req[r_tgt_num_cache].read() and r_tgt_dcache_rsp[r_tgt_num_cache].read();
4110
4111                    PRINTF("      * <TGT> RSP_DCACHE : rspval : %d\n",rspval);
4112                   
4113                    p_vci_tgt.cmdack  = false;
4114                    p_vci_tgt.rspval  = rspval;
4115                    p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4116                    p_vci_tgt.rpktid  = r_tgt_pktid.read();
4117                    p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4118                    p_vci_tgt.rdata   = 0;
4119                    p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4120                    p_vci_tgt.reop    = true;
4121                    break;
4122                }
4123            case TGT_REQ_BROADCAST:
4124            case TGT_REQ_ICACHE:
4125            case TGT_REQ_DCACHE:
4126                p_vci_tgt.cmdack  = false;
4127                p_vci_tgt.rspval  = false;
4128                break;
4129
4130        } // end switch TGT_FSM
4131    } // end genMoore()
4132
4133    //////////////////////////////////////////////////////////////////////////////////
4134    tmpl(void)::stop_simulation (uint32_t nb_frz_cycles)
4135    //////////////////////////////////////////////////////////////////////////////////
4136    {
4137#if CC_XCACHE_WRAPPER_STOP_SIMULATION
4138        if (nb_frz_cycles == 0)
4139            {
4140                PRINTF("CC_XCACHE_WRAPPER \"%s\" : don't stop the simulation.\n",name().c_str());
4141                m_stop_simulation = false;
4142            }
4143        else
4144            {
4145                PRINTF("CC_XCACHE_WRAPPER \"%s\" : stop the simulation after %d cycles.\n",name().c_str(),nb_frz_cycles);
4146                m_stop_simulation = true;
4147                m_stop_simulation_nb_frz_cycles_max = nb_frz_cycles;
4148            }
4149#else
4150        std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_STOP_SIMULATION is unset, you can't use stop_simulation." << std::endl;
4151#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
4152       
4153    }
4154
4155    //////////////////////////////////////////////////////////////////////////////////
4156    tmpl(uint32_t)::get_num_cache(addr_40 & addr)
4157    //////////////////////////////////////////////////////////////////////////////////
4158    {
4159        uint32_t num_cache = get_num_cache_only(addr);
4160
4161        addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
4162                ((addr>>m_num_cache_MSB)<<m_num_cache_LSB)); // set MSB
4163
4164        return num_cache;
4165    }
4166
4167    //////////////////////////////////////////////////////////////////////////////////
4168    tmpl(uint32_t)::get_num_cache_only(addr_40 addr)
4169    //////////////////////////////////////////////////////////////////////////////////
4170    {
4171        return (addr>>m_num_cache_LSB)&m_num_cache_mask;
4172    }
4173
4174    //////////////////////////////////////////////////////////////////////////////////
4175    tmpl(void)::set_num_cache(addr_40 & addr, uint32_t num_cache)
4176    //////////////////////////////////////////////////////////////////////////////////
4177    {
4178        addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
4179                ((addr_40)num_cache << m_num_cache_LSB) |
4180                ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
4181    }
4182
4183    //////////////////////////////////////////////////////////////////////////////////
4184    // FIXME : mettre le type addr_40
4185    tmpl(sc_dt::sc_uint<40>)::set_num_cache_only(addr_40 addr, uint32_t num_cache)
4186    //////////////////////////////////////////////////////////////////////////////////
4187    {
4188        return ((addr&m_num_cache_LSB_mask) | // keep LSB
4189                ((addr_40)num_cache << m_num_cache_LSB) |
4190                ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
4191    }
4192
4193
4194}} // end namespace
4195
4196// Local Variables:
4197// tab-width: 4
4198// c-basic-offset: 4
4199// c-file-offsets:((innamespace . 0)(inline-open . 0))
4200// indent-tabs-mode: nil
4201// End:
4202
4203// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.