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

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

in vci_cc_xcache_wrapper_v4 : (1) Fix bug in MISS_VICTIM state, (2) add HIT after MISS, (3) add STORE after STORE

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