source: trunk/modules/vci_cc_xcache_wrapper_v4_cmp/caba/source/src/vci_cc_xcache_wrapper_v4_cmp.cpp @ 154

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

Re add vci_cc_xcache_wrapper_v4 "multi-cache" edition and (1) fix error (2) add direction MWBUF_VHDL_TESTBENCH to generate a testbench for the multi_write_buffer VHDL model.

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