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

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

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

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

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

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