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

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

In vci_cc_xcache_wrapper : (1) fix compilation directive, (2) replace std::queue by generic_fifo, (3) delete vci_cc_xcache_wrapper_v4_cmp

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