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

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

(1) add modif from previous version (before merging), (2) add two registers to manage priority (FSM CMD)

  • 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: 200.5 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()&1 == 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()&1 == 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          uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
3366          bool     find = false;
3367         
3368          size_t  _wbuf_min   = 0;
3369          size_t  _wbuf_max   = 0;
3370#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3371          addr_40 _wbuf_addr  = 0;
3372          size_t  _wbuf_index = 0;
3373#endif
3374         
3375          if (
3376#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3377              (r_wbuf[num_cache]->rok_info(&_wbuf_min, &_wbuf_max, &_wbuf_addr, &_wbuf_index)) and
3378#else
3379              (r_wbuf[num_cache]->rok     (&_wbuf_min, &_wbuf_max)) and
3380#endif                     
3381              (dcache_write_num_cache == m_nb_dcache))
3382            {
3383              find = true;
3384              dcache_write_num_cache = num_cache;
3385             
3386              PRINTF("      * <CMD> wbuf min, max            : %d, %d\n",(int)_wbuf_min,(int)_wbuf_max);
3387             
3388              wbuf_min   = _wbuf_min  ;
3389              wbuf_max   = _wbuf_max  ;
3390#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3391              wbuf_addr  = _wbuf_addr ;
3392              wbuf_index = _wbuf_index;
3393             
3394              PRINTF("      * <CMD> wbuf index               : %d\n",(int)_wbuf_index);
3395              PRINTF("      * <CMD> wbuf address             : %llx\n",(blob_t)_wbuf_addr);
3396#endif
3397            }
3398         
3399          PRINTF("      * <CMD> Test read after miss     : cache : %d, find : %d\n",dcache_write_num_cache, find);
3400         
3401#if MWBUF_VHDL_TESTBENCH
3402          vhdl_mwbuf_test_sent_val         [dcache_write_num_cache] = (vhdl_tb_t)1;
3403          vhdl_mwbuf_port_sent_val         [dcache_write_num_cache] = (vhdl_tb_t)find;
3404          vhdl_mwbuf_test_sent_word_min    [dcache_write_num_cache] = (vhdl_tb_t)find;
3405          vhdl_mwbuf_port_sent_word_min    [dcache_write_num_cache] = (vhdl_tb_t)wbuf_min;
3406          vhdl_mwbuf_test_sent_word_max    [dcache_write_num_cache] = (vhdl_tb_t)find;
3407          vhdl_mwbuf_port_sent_word_max    [dcache_write_num_cache] = (vhdl_tb_t)wbuf_max;
3408#endif               
3409        }
3410
3411      switch (r_vci_cmd_fsm) {
3412
3413      case CMD_IDLE:
3414        {
3415          // if (r_vci_rsp_fsm != RSP_IDLE) break;
3416
3417
3418          // Requests :
3419
3420          // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req
3421
3422          bool     dcache_miss_req      = false;
3423          bool     icache_miss_req      = false;
3424          uint32_t dcache_miss_num_cache = m_nb_dcache;
3425          uint32_t icache_miss_num_cache = m_nb_icache;
3426          addr_40  addr = 0;
3427
3428          bool     wbuf_imiss = false;
3429          bool     wbuf_dmiss = false;
3430     
3431          {
3432            for (uint32_t i=0; i<m_nb_dcache; ++i)
3433              {
3434                uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
3435
3436                dcache_miss_req = r_dcache_miss_req[num_cache];
3437                if (dcache_miss_req)
3438                {
3439                    dcache_miss_num_cache = num_cache;
3440                    break;
3441                }
3442              }
3443            for (uint32_t i=0; i<m_nb_icache; ++i)
3444              {
3445                uint32_t num_cache=(r_vci_cmd_num_icache_prior+i)%m_nb_icache;
3446
3447                icache_miss_req = r_icache_miss_req[num_cache];
3448                if (icache_miss_req)
3449                {
3450                    icache_miss_num_cache = num_cache;
3451                    break;
3452                }
3453              }
3454
3455            PRINTF("      * <CMD> icache_miss_req (before) : %d\n",icache_miss_req);
3456            PRINTF("      * <CMD> dcache_miss_req (before) : %d\n",dcache_miss_req);
3457
3458            //  one access with round robin priority
3459            dcache_miss_req = ((dcache_miss_req and not icache_miss_req) or // only dcache
3460                               (dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior
3461            icache_miss_req &= not dcache_miss_req;
3462
3463            PRINTF("      * <CMD> icache_miss_req (after ) : %d\n",icache_miss_req);
3464            PRINTF("      * <CMD> dcache_miss_req (after ) : %d\n",dcache_miss_req);
3465
3466            PRINTF("      * <CMD> icache_miss_num_cache    : %d\n",icache_miss_num_cache);
3467            PRINTF("      * <CMD> dcache_miss_num_cache    : %d\n",dcache_miss_num_cache);
3468
3469            if (icache_miss_req or dcache_miss_req)
3470              {
3471                addr = (icache_miss_req)?r_icache_addr_save[icache_miss_num_cache].read():r_dcache_addr_save[dcache_miss_num_cache].read();
3472
3473                PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
3474
3475                if (icache_miss_req)
3476                  {
3477                    // FIXME :
3478                    // si wbuf contient des addresses partionné, set_num_icache puis get_num_dcache
3479                    // dcache_miss_num_cache = icache_miss_num_cache;
3480                    set_num_icache(addr,icache_miss_num_cache);
3481                    // get_num_dcache(addr,dcache_miss_num_cache);
3482                  }
3483                else
3484                  set_num_dcache(addr,dcache_miss_num_cache);
3485
3486                PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
3487               
3488                uint32_t num_cache = get_num_dcache_only(addr);
3489
3490                wbuf_imiss = (icache_miss_req)?r_wbuf[num_cache]->miss(addr):false;
3491                wbuf_dmiss = (dcache_miss_req)?r_wbuf[num_cache]->miss(addr):false;
3492
3493#if MWBUF_VHDL_TESTBENCH
3494                vhdl_mwbuf_port_raw_test [num_cache] = (vhdl_tb_t)1;
3495                vhdl_mwbuf_port_raw_addr [num_cache] = (vhdl_tb_t)addr;
3496                vhdl_mwbuf_test_raw_miss [num_cache] = (vhdl_tb_t)1;
3497                vhdl_mwbuf_port_raw_miss [num_cache] = (dcache_miss_req)?(vhdl_tb_t)wbuf_dmiss:(vhdl_tb_t)wbuf_imiss;
3498#endif               
3499              }
3500          }
3501
3502          uint32_t dcache_unc_num_cache = m_nb_dcache;
3503          for (uint32_t i=0; i<m_nb_dcache; ++i)
3504          {
3505              uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
3506              if (r_dcache_unc_req[num_cache])
3507              {
3508                  dcache_unc_num_cache = num_cache;
3509                  break;
3510              }
3511          }
3512          uint32_t icache_unc_num_cache = m_nb_icache;
3513          for (uint32_t i=0; i<m_nb_icache; ++i)
3514          {
3515              uint32_t num_cache=(r_vci_cmd_num_icache_prior+i)%m_nb_icache;
3516              if (r_icache_unc_req[num_cache])
3517              {
3518                  icache_unc_num_cache = num_cache;
3519                  break;
3520              }
3521          }
3522          uint32_t dcache_sc_num_cache = m_nb_dcache;
3523          for (uint32_t i=0; i<m_nb_dcache; ++i)
3524          {
3525              uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
3526              if (r_dcache_sc_req[num_cache])
3527              {
3528                  dcache_sc_num_cache = num_cache;
3529                  break;
3530              }
3531          }
3532
3533          // 1 - Data Read
3534          if (wbuf_dmiss)
3535            // (dcache_miss_req and r_wbuf[dcache_miss_num_cache]->miss(addr))
3536            {
3537              r_vci_cmd_fsm       = CMD_DATA_MISS;
3538              r_vci_cmd_num_cache = dcache_miss_num_cache;
3539              r_dcache_miss_req[dcache_miss_num_cache] = false;
3540              m_cpt_dmiss_transaction++;
3541
3542
3543#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3544              if (generate_log_transaction_file_cmd)
3545                {
3546                  log_transaction_file_cmd
3547                    << "[" << m_cpt_total_cycles << "] "
3548                    << "CMD DATA MISS  "
3549                    << "(" << dcache_miss_num_cache << ") "
3550                    << std::hex
3551                    << " @ " << std::setw(10) << (blob_t)addr
3552                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3553                    << std::dec
3554                    << std::endl;
3555                }
3556#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3557
3558            }
3559
3560          // 2 - Data Read Uncachable
3561          else if (dcache_unc_num_cache < m_nb_dcache) // have r_dcache_unc_req
3562            {
3563              r_vci_cmd_fsm       = CMD_DATA_UNC;
3564              r_vci_cmd_num_cache = dcache_unc_num_cache;
3565              r_dcache_unc_req[dcache_unc_num_cache] = false;
3566              // m_cpt_data_unc_transaction++;
3567
3568#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3569              if (generate_log_transaction_file_cmd)
3570                {
3571                  addr_40 addr = (addr_40) r_dcache_addr_save[dcache_unc_num_cache].read() & ~0x3;
3572                  set_num_dcache(addr,dcache_unc_num_cache);
3573                       
3574                  log_transaction_file_cmd
3575                    << "[" << m_cpt_total_cycles << "] "
3576                    << "CMD DATA UNC   "
3577                    << "(" << dcache_unc_num_cache << ") "
3578                    << std::hex
3579                    << " @ " << std::setw(10) << (blob_t)addr
3580                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3581                    << std::dec
3582                    << std::endl;
3583                }
3584#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3585            }
3586
3587          // 3 - Instruction Miss
3588          else if (wbuf_imiss)
3589            //else if (icache_miss_req and r_wbuf[icache_miss_num_cache]->miss(addr))
3590            {
3591              r_vci_cmd_fsm       = CMD_INS_MISS;
3592              r_vci_cmd_num_cache = icache_miss_num_cache;
3593              r_icache_miss_req[icache_miss_num_cache] = false;
3594              m_cpt_imiss_transaction++;
3595
3596#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3597              if (generate_log_transaction_file_cmd)
3598                {
3599                  log_transaction_file_cmd
3600                    << "[" << m_cpt_total_cycles << "] "
3601                    << "CMD INS  MISS  "
3602                    << "(" << icache_miss_num_cache << ") "
3603                    << std::hex
3604                    << " @ " << std::setw(10) << (blob_t)addr
3605                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
3606                    << std::dec
3607                    << std::endl;
3608                }
3609#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3610            }
3611
3612          // 4 - Instruction Uncachable
3613          else if (icache_unc_num_cache < m_nb_icache) // have r_icache_unc_req
3614            {
3615              r_vci_cmd_fsm       = CMD_INS_UNC;
3616              r_vci_cmd_num_cache = icache_unc_num_cache;
3617              r_icache_unc_req[icache_unc_num_cache] = false;
3618              // m_cpt_ins_unc_transaction++;
3619
3620#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3621              if (generate_log_transaction_file_cmd)
3622                {
3623                  addr_40 addr = (addr_40) r_icache_addr_save[icache_unc_num_cache].read() & ~0x3;
3624                  set_num_dcache(addr,icache_unc_num_cache);
3625                       
3626                  log_transaction_file_cmd
3627                    << "[" << m_cpt_total_cycles << "] "
3628                    << "CMD INS  UNC   "
3629                    << "(" << icache_unc_num_cache << ") "
3630                    << std::hex
3631                    << " @ " << std::setw(10) << (blob_t)addr
3632                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
3633                    << std::dec
3634                    << std::endl;
3635                }
3636#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3637            }
3638
3639          // 5 - Data Write
3640          else if (dcache_write_num_cache < m_nb_dcache) // have r_wbuf.rok(&wbuf_min, &wbuf_max)
3641            {
3642              r_vci_cmd_num_cache = dcache_write_num_cache;
3643              r_vci_cmd_fsm       = CMD_DATA_WRITE;
3644              r_vci_cmd_cpt       = wbuf_min;
3645              r_vci_cmd_min       = wbuf_min;
3646              r_vci_cmd_max       = wbuf_max;
3647              m_cpt_data_write_transaction++;
3648              m_length_write_transaction += (wbuf_max-wbuf_min+1);
3649
3650#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3651              if (generate_log_transaction_file_cmd)
3652                {
3653                  addr_40 addr = (addr_40) wbuf_addr&~0x3;
3654                       
3655                  log_transaction_file_cmd
3656                    << "[" << m_cpt_total_cycles << "] "
3657                    << "CMD DATA WRITE "
3658                    << "(" << dcache_write_num_cache << ") "
3659                    << std::hex
3660                    << " @ " << std::setw(10) << (blob_t)addr
3661                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3662                    << " [" << wbuf_min << ":" << wbuf_max << "]"
3663                    << " {" << wbuf_index << "}"
3664                    << std::dec
3665                    << std::endl;
3666                }
3667#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3668            }
3669
3670          // 6 - Data Store Conditionnal
3671          else if (dcache_sc_num_cache < m_nb_dcache) // have r_dcache_sc_req
3672            {
3673              r_vci_cmd_fsm       = CMD_DATA_SC;
3674              r_vci_cmd_num_cache = dcache_sc_num_cache;
3675              r_vci_cmd_cpt       = 0;
3676              r_vci_cmd_min       = 0;
3677              r_vci_cmd_max       = 1;
3678              m_cpt_unc_transaction++;
3679              r_dcache_sc_req[dcache_sc_num_cache] = false;
3680
3681#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3682              if (generate_log_transaction_file_cmd)
3683                {
3684                  addr_40 addr = (addr_40) r_dcache_addr_save[dcache_sc_num_cache].read() & ~0x3;
3685                  set_num_dcache(addr,dcache_sc_num_cache);
3686                       
3687                  log_transaction_file_cmd
3688                    << "[" << m_cpt_total_cycles << "] "
3689                    << "CMD DATA SC    "
3690                    << "(" << dcache_sc_num_cache << ") "
3691                    << std::hex
3692                    << " @ " << std::setw(10) << (blob_t)addr
3693                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
3694                    << std::dec
3695                    << std::endl;
3696                }
3697#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3698            }
3699
3700          break;
3701        }
3702      case CMD_DATA_WRITE:
3703        if ( p_vci_ini_rw.cmdack.read() ) {
3704
3705#if MWBUF_VHDL_TESTBENCH
3706              vhdl_mwbuf_port_sent_word        [r_vci_cmd_num_cache] = (vhdl_tb_t)r_vci_cmd_cpt;
3707              vhdl_mwbuf_test_sent_addr        [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
3708              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);
3709              vhdl_mwbuf_test_sent_data        [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
3710              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);
3711              vhdl_mwbuf_test_sent_be          [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
3712              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);
3713              vhdl_mwbuf_test_sent_index       [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
3714              vhdl_mwbuf_port_sent_index       [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getIndex();
3715#endif
3716
3717          r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
3718          if (r_vci_cmd_cpt == r_vci_cmd_max) {
3719            r_vci_cmd_fsm = CMD_IDLE ;
3720            r_wbuf[r_vci_cmd_num_cache]->sent() ;
3721#if MWBUF_VHDL_TESTBENCH
3722            vhdl_mwbuf_port_sent_ack [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
3723#endif
3724          }
3725        }
3726        break;
3727
3728      case CMD_DATA_SC:
3729        if ( p_vci_ini_rw.cmdack.read() ) {
3730          r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
3731          if (r_vci_cmd_cpt == r_vci_cmd_max) {
3732            r_vci_cmd_fsm = CMD_IDLE ;
3733          }
3734        }
3735        break;
3736      case CMD_INS_MISS:
3737      case CMD_INS_UNC:
3738      case CMD_DATA_MISS:
3739      case CMD_DATA_UNC:
3740        if ( p_vci_ini_rw.cmdack.read() ) {
3741          r_vci_cmd_fsm = CMD_IDLE;
3742        }
3743        break;
3744
3745      } // end  switch r_vci_cmd_fsm
3746
3747        //////////////////////////////////////////////////////////////////////////
3748        // The VCI_RSP FSM controls the following ressources:
3749        // - r_vci_rsp_fsm:
3750        // - r_vci_rsp_fifo_icache[m_icache_words]
3751        // - r_vci_rsp_fifo_dcache[m_dcache_words]
3752        // - r_vci_rsp_data_error set
3753        // - r_vci_rsp_ins_error set
3754        // - r_vci_rsp_cpt
3755        // In order to have only one active VCI transaction, this VCI_RSP_FSM
3756        // is synchronized with the VCI_CMD FSM, and both FSMs exit the
3757        // IDLE state simultaneously.
3758        //
3759        // VCI formats:
3760        // This component accepts single word or multi-word response packets for
3761        // write response packets.
3762        //
3763        // Error handling:
3764        // This FSM analyzes the VCI error code and signals directly the
3765        // Write Bus Error.
3766        // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error
3767        // flip_flop and the error is signaled by the DCACHE FSM. 
3768        // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
3769        // flip_flop and the error is signaled by the DCACHE FSM. 
3770        // In case of Cleanup Error, the simulation stops with an error message...
3771        //////////////////////////////////////////////////////////////////////////
3772
3773      switch (r_vci_rsp_fsm) {
3774
3775      case RSP_IDLE:
3776
3777        if( p_vci_ini_rw.rspval.read() )
3778          {
3779            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());
3780
3781            ASSERT(p_vci_ini_rw.rpktid.read() <= (1<<vci_param::P),
3782                   "invalid pktid in a cleanup response");
3783
3784            r_vci_rsp_cpt = 0;
3785
3786            if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 )
3787              {
3788                r_vci_rsp_fsm = RSP_DATA_WRITE;
3789
3790#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3791                if (generate_log_transaction_file_cmd)
3792                  {
3793                    log_transaction_file_cmd
3794                      << "[" << m_cpt_total_cycles << "] "
3795                      << "RSP DATA WRITE "
3796                      << "(" << p_vci_ini_rw.rpktid.read() << ") "
3797                      << "{" << (p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1))) << "}"
3798                      << std::endl;
3799                  }
3800#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3801              }
3802            else
3803              {
3804                switch (p_vci_ini_rw.rtrdid.read())
3805                  {
3806                  case TYPE_INS_MISS     :
3807                    {
3808                      r_vci_rsp_fsm = RSP_INS_MISS;
3809
3810#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3811                      if (generate_log_transaction_file_cmd)
3812                        {
3813                          log_transaction_file_cmd
3814                            << "[" << m_cpt_total_cycles << "] "
3815                            << "RSP INS  MISS  "
3816                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
3817                            << std::endl;
3818                        }
3819#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3820
3821                      break;
3822                    }
3823                  case TYPE_INS_UNC      :
3824                    {
3825                      r_vci_rsp_fsm = RSP_INS_UNC;
3826
3827#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3828                      if (generate_log_transaction_file_cmd)
3829                        {
3830                          log_transaction_file_cmd
3831                            << "[" << m_cpt_total_cycles << "] "
3832                            << "RSP INS  UNC   "
3833                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
3834                            << std::endl;
3835                        }
3836#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3837
3838                      break;
3839                    }
3840                  case TYPE_DATA_MISS    :
3841                    {
3842                      r_vci_rsp_fsm = RSP_DATA_MISS;
3843
3844#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3845                      if (generate_log_transaction_file_cmd)
3846                        {
3847                          log_transaction_file_cmd
3848                            << "[" << m_cpt_total_cycles << "] "
3849                            << "RSP DATA MISS  "
3850                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
3851                            << std::endl;
3852                        }
3853#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3854
3855                      break;
3856                    }
3857                  case TYPE_DATA_UNC     :
3858                    {
3859                      r_vci_rsp_fsm = RSP_DATA_UNC;
3860
3861#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3862                      if (generate_log_transaction_file_cmd)
3863                        {
3864                          log_transaction_file_cmd
3865                            << "[" << m_cpt_total_cycles << "] "
3866                            << "RSP DATA UNC   "
3867                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
3868                            << std::endl;
3869                        }
3870#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3871
3872                      break;
3873                    }
3874                  case TYPE_DATA_SC      :
3875                    {
3876                      r_vci_rsp_fsm = RSP_DATA_SC;
3877
3878#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3879                      if (generate_log_transaction_file_cmd)
3880                        {
3881                          log_transaction_file_cmd
3882                            << "[" << m_cpt_total_cycles << "] "
3883                            << "RSP DATA SC    "
3884                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
3885                            << std::endl;
3886                        }
3887#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
3888
3889                      break;
3890                    }
3891                  default :
3892                    {
3893                      ASSERT(false, "Unexpected response");
3894                    }
3895                  }
3896              }
3897
3898            r_vci_rsp_num_cache = p_vci_ini_rw.rpktid.read();
3899          }
3900        break;
3901
3902      case RSP_INS_MISS:
3903
3904        m_cost_imiss_transaction++;
3905        PRINTF("      * <RSP> rspval : %d\n",(uint32_t)p_vci_ini_rw.rspval.read());
3906
3907        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok())
3908          {
3909            PRINTF("      * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words);
3910            PRINTF("      * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read());
3911
3912            ASSERT( (r_vci_rsp_cpt.read() < m_icache_words),
3913                    "The VCI response packet for instruction miss is too long" );
3914            r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1;
3915            vci_rsp_fifo_icache_put       = true,
3916            vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache;
3917            vci_rsp_fifo_icache_data      = p_vci_ini_rw.rdata.read();
3918
3919            if ( p_vci_ini_rw.reop.read() )
3920              {
3921                PRINTF("      * <RSP> have reop\n");
3922
3923                ASSERT( ((r_vci_rsp_cpt.read() == m_icache_words - 1) or
3924                         (p_vci_ini_rw.rerror.read()&1) or
3925                         (r_vci_rsp_ins_error[r_vci_rsp_num_cache].read()&0x1)),
3926                        "The VCI response packet for instruction miss is too short");
3927                r_vci_rsp_cpt    = 0;
3928                r_vci_rsp_fsm    = RSP_IDLE;
3929
3930              }
3931            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
3932          }
3933        break;
3934
3935      case RSP_INS_UNC:
3936
3937        m_cost_imiss_transaction++;
3938        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok())
3939          {
3940            ASSERT(p_vci_ini_rw.reop.read(),
3941                   "illegal VCI response packet for uncached instruction");
3942
3943            vci_rsp_fifo_icache_put       = true,
3944            vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache;
3945            vci_rsp_fifo_icache_data      = p_vci_ini_rw.rdata.read();
3946
3947            r_vci_rsp_fsm = RSP_IDLE;
3948
3949            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
3950          }
3951        break;
3952
3953      case RSP_DATA_MISS:
3954
3955        m_cost_dmiss_transaction++;
3956        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
3957          {
3958            PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
3959
3960            ASSERT(r_vci_rsp_cpt.read() < m_dcache_words,
3961                   "illegal VCI response packet for data read miss");
3962            r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1;
3963
3964            vci_rsp_fifo_dcache_put       = true,
3965            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
3966            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
3967
3968            if ( p_vci_ini_rw.reop.read() ) {
3969              ASSERT( ((r_vci_rsp_cpt.read() == m_dcache_words - 1)
3970                       or (p_vci_ini_rw.rerror.read()&0x1)
3971                       or r_vci_rsp_data_error[r_vci_rsp_num_cache].read()),
3972                      "illegal VCI response packet for data read miss");
3973              r_vci_rsp_cpt     = 0;
3974              r_vci_rsp_fsm     = RSP_IDLE;
3975            }
3976            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
3977          }
3978        break;
3979
3980      case RSP_DATA_WRITE:
3981        m_cost_write_transaction++;
3982        if (p_vci_ini_rw.rspval.read())
3983          {
3984            PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
3985
3986            ASSERT(p_vci_ini_rw.reop.read(),
3987                   "A VCI response packet must contain one flit for a write transaction");
3988            r_vci_rsp_fsm = RSP_IDLE;
3989            uint32_t wbuf_index = p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1));
3990            size_t cpu_id = r_wbuf[r_vci_rsp_num_cache]->getCpuId (wbuf_index);
3991            bool   cached = r_wbuf[r_vci_rsp_num_cache]->completed(wbuf_index);
3992            PRINTF("      * <RSP> cached : %d\n",cached);
3993
3994            if (not cached)
3995              r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
3996
3997            if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL)
3998              m_iss[cpu_id]->setWriteBerr();
3999
4000#if MWBUF_VHDL_TESTBENCH
4001            vhdl_mwbuf_port_completed_val    [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
4002            vhdl_mwbuf_port_completed_index  [r_vci_rsp_num_cache] = (vhdl_tb_t)wbuf_index;
4003            vhdl_mwbuf_test_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
4004            vhdl_mwbuf_port_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)cached;
4005            vhdl_mwbuf_test_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
4006            vhdl_mwbuf_port_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)cpu_id;
4007#endif
4008          }
4009        break;
4010
4011      case RSP_DATA_UNC:
4012        m_cost_unc_transaction++;
4013        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
4014          {
4015            ASSERT(p_vci_ini_rw.reop.read(),
4016                   "illegal VCI response packet for data read uncached");
4017
4018            vci_rsp_fifo_dcache_put       = true,
4019            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
4020            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
4021
4022            r_vci_rsp_fsm = RSP_IDLE;
4023            r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
4024
4025            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
4026          }
4027        break;
4028
4029      case RSP_DATA_SC:
4030        m_cost_unc_transaction++;
4031        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
4032          {
4033            ASSERT(p_vci_ini_rw.reop.read(),
4034                   "illegal VCI response packet for data SC");
4035
4036            vci_rsp_fifo_dcache_put       = true,
4037            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
4038            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
4039
4040            r_vci_rsp_fsm = RSP_IDLE;
4041            r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
4042
4043            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
4044          }
4045        break;
4046
4047      } // end switch r_vci_rsp_fsm
4048
4049        //////////////////////////////////////////////////////////////////////////
4050        // FIFO_RSP
4051        //////////////////////////////////////////////////////////////////////////
4052
4053      r_vci_rsp_fifo_icache_data     .update(vci_rsp_fifo_icache_get,
4054                                             vci_rsp_fifo_icache_put,
4055                                             vci_rsp_fifo_icache_data);
4056      r_vci_rsp_fifo_icache_num_cache.update(vci_rsp_fifo_icache_get,
4057                                             vci_rsp_fifo_icache_put,
4058                                             vci_rsp_fifo_icache_num_cache);
4059     
4060      r_vci_rsp_fifo_dcache_data     .update(vci_rsp_fifo_dcache_get,
4061                                             vci_rsp_fifo_dcache_put,
4062                                             vci_rsp_fifo_dcache_data);
4063      r_vci_rsp_fifo_dcache_num_cache.update(vci_rsp_fifo_dcache_get,
4064                                             vci_rsp_fifo_dcache_put,
4065                                             vci_rsp_fifo_dcache_num_cache);
4066     
4067#if MWBUF_VHDL_TESTBENCH
4068      for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
4069        {
4070          vhdl_mwbuf_test_empty            [num_dcache] = (vhdl_tb_t)1;
4071          vhdl_mwbuf_port_empty            [num_dcache] = (vhdl_tb_t)r_wbuf[num_dcache]->empty();
4072
4073          vhdl_testbench_mwbuf [num_dcache]
4074            << std::hex
4075            << vhdl_mwbuf_test_empty            [num_dcache] << " "
4076            << vhdl_mwbuf_port_empty            [num_dcache] << " "
4077            << vhdl_mwbuf_port_flush            [num_dcache] << " "
4078            << vhdl_mwbuf_port_write_val        [num_dcache] << " "
4079            << vhdl_mwbuf_test_write_ack        [num_dcache] << " "
4080            << vhdl_mwbuf_port_write_ack        [num_dcache] << " "
4081            << vhdl_mwbuf_port_write_addr       [num_dcache] << " "
4082            << vhdl_mwbuf_port_write_data       [num_dcache] << " "
4083            << vhdl_mwbuf_port_write_be         [num_dcache] << " "
4084            << vhdl_mwbuf_port_write_cached     [num_dcache] << " "
4085            << vhdl_mwbuf_port_write_cpu_id     [num_dcache] << " "
4086            << vhdl_mwbuf_test_sent_val         [num_dcache] << " "
4087            << vhdl_mwbuf_port_sent_val         [num_dcache] << " "
4088            << vhdl_mwbuf_port_sent_ack         [num_dcache] << " "
4089            << vhdl_mwbuf_test_sent_word_min    [num_dcache] << " "
4090            << vhdl_mwbuf_port_sent_word_min    [num_dcache] << " "
4091            << vhdl_mwbuf_test_sent_word_max    [num_dcache] << " "
4092            << vhdl_mwbuf_port_sent_word_max    [num_dcache] << " "
4093            << vhdl_mwbuf_port_sent_word        [num_dcache] << " "
4094            << vhdl_mwbuf_test_sent_addr        [num_dcache] << " "
4095            << vhdl_mwbuf_port_sent_addr        [num_dcache] << " "
4096            << vhdl_mwbuf_test_sent_data        [num_dcache] << " "
4097            << vhdl_mwbuf_port_sent_data        [num_dcache] << " "
4098            << vhdl_mwbuf_test_sent_be          [num_dcache] << " "
4099            << vhdl_mwbuf_port_sent_be          [num_dcache] << " "
4100            << vhdl_mwbuf_test_sent_index       [num_dcache] << " "
4101            << vhdl_mwbuf_port_sent_index       [num_dcache] << " "
4102            << vhdl_mwbuf_port_raw_test         [num_dcache] << " "
4103            << vhdl_mwbuf_port_raw_addr         [num_dcache] << " "
4104            << vhdl_mwbuf_test_raw_miss         [num_dcache] << " "
4105            << vhdl_mwbuf_port_raw_miss         [num_dcache] << " "
4106            << vhdl_mwbuf_port_completed_val    [num_dcache] << " "
4107            << vhdl_mwbuf_port_completed_index  [num_dcache] << " "
4108            << vhdl_mwbuf_test_completed_cached [num_dcache] << " "
4109            << vhdl_mwbuf_port_completed_cached [num_dcache] << " "
4110            << vhdl_mwbuf_test_completed_cpu_id [num_dcache] << " "
4111            << vhdl_mwbuf_port_completed_cpu_id [num_dcache]
4112            << std::dec
4113            << std::endl;
4114        }
4115#endif
4116    } // end transition()
4117
4118    //////////////////////////////////////////////////////////////////////////////////
4119    tmpl(void)::genMoore()
4120    //////////////////////////////////////////////////////////////////////////////////
4121    {
4122      PRINTF("--------------------------------------------\n");
4123      PRINTF("  * CC_XCACHE_WRAPPER \"%s\" genMoore - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
4124
4125      // VCI initiator response
4126      switch ( r_cleanup_fsm.read() ) {
4127      case CLEANUP_IDLE:
4128        p_vci_ini_c.rspack  = false;
4129        p_vci_ini_c.cmdval  = false;
4130        p_vci_ini_c.address = 0;
4131        p_vci_ini_c.wdata   = 0;
4132        p_vci_ini_c.be      = 0;
4133        p_vci_ini_c.plen    = 0;
4134        p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
4135        p_vci_ini_c.trdid   = 0;
4136        p_vci_ini_c.pktid   = 0;
4137        p_vci_ini_c.srcid   = 0;
4138        p_vci_ini_c.cons    = false;
4139        p_vci_ini_c.wrap    = false;
4140        p_vci_ini_c.contig  = false;
4141        p_vci_ini_c.clen    = 0;
4142        p_vci_ini_c.cfixed  = false;
4143        p_vci_ini_c.eop     = false;
4144        break;
4145
4146      case CLEANUP_REQ:
4147        {
4148          addr_40 addr;
4149          if (r_cleanup_icache)
4150            {
4151              addr = r_icache_cleanup_line[r_cleanup_num_cache].read()<<m_icache_words_shift;
4152              set_num_icache(addr,r_cleanup_num_cache);
4153
4154              PRINTF("      * <CLEANUP> icache             : %llx\n",(blob_t)addr);
4155            }
4156          else
4157            {
4158              addr = r_dcache_cleanup_line[r_cleanup_num_cache].read()<<m_dcache_words_shift;
4159              set_num_dcache(addr,r_cleanup_num_cache);
4160
4161              PRINTF("      * <CLEANUP> dcache             : %llx\n",(blob_t)addr);
4162            }
4163
4164          p_vci_ini_c.rspack  = false;
4165          p_vci_ini_c.cmdval  = true;
4166          p_vci_ini_c.address = addr;
4167          p_vci_ini_c.wdata   = 0;
4168          p_vci_ini_c.be      = 0xF;
4169          p_vci_ini_c.plen    = 4;
4170          p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
4171          p_vci_ini_c.trdid   = (r_cleanup_icache)?TYPE_INS_CLEANUP:TYPE_DATA_CLEANUP;
4172          p_vci_ini_c.pktid   = (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache;
4173          p_vci_ini_c.srcid   = m_srcid_c;
4174          p_vci_ini_c.cons    = false;
4175          p_vci_ini_c.wrap    = false;
4176          p_vci_ini_c.contig  = false;
4177          p_vci_ini_c.clen    = 0;
4178          p_vci_ini_c.cfixed  = false;
4179          p_vci_ini_c.eop     = true;
4180
4181          break;
4182        }
4183
4184      case CLEANUP_RSP_DCACHE:
4185        p_vci_ini_c.rspack  = true;
4186        p_vci_ini_c.cmdval  = false;
4187        p_vci_ini_c.address = 0;
4188        p_vci_ini_c.wdata  = 0;
4189        p_vci_ini_c.be     = 0;
4190        p_vci_ini_c.plen   = 0;
4191        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
4192        p_vci_ini_c.trdid  = 0;
4193        p_vci_ini_c.pktid  = 0;
4194        p_vci_ini_c.srcid  = 0;
4195        p_vci_ini_c.cons   = false;
4196        p_vci_ini_c.wrap   = false;
4197        p_vci_ini_c.contig = false;
4198        p_vci_ini_c.clen   = 0;
4199        p_vci_ini_c.cfixed = false;
4200        p_vci_ini_c.eop = false;
4201        break;
4202
4203      case CLEANUP_RSP_ICACHE:
4204        p_vci_ini_c.rspack  = true;
4205        p_vci_ini_c.cmdval  = false;
4206        p_vci_ini_c.address = 0;
4207        p_vci_ini_c.wdata  = 0;
4208        p_vci_ini_c.be     = 0;
4209        p_vci_ini_c.plen   = 0;
4210        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
4211        p_vci_ini_c.trdid  = 0;
4212        p_vci_ini_c.pktid  = 0;
4213        p_vci_ini_c.srcid  = 0;
4214        p_vci_ini_c.cons   = false;
4215        p_vci_ini_c.wrap   = false;
4216        p_vci_ini_c.contig = false;
4217        p_vci_ini_c.clen   = 0;
4218        p_vci_ini_c.cfixed = false;
4219        p_vci_ini_c.eop = false;
4220        break;
4221      } // end switch r_cleanup_fsm
4222
4223        // VCI initiator command
4224
4225      switch (r_vci_cmd_fsm.read() ) {
4226      case CMD_IDLE:
4227        {
4228          p_vci_ini_rw.cmdval  = false;
4229          p_vci_ini_rw.address = 0;
4230          p_vci_ini_rw.wdata   = 0;
4231          p_vci_ini_rw.be      = 0;
4232          p_vci_ini_rw.plen    = 0;
4233          p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
4234          p_vci_ini_rw.trdid   = 0;
4235          p_vci_ini_rw.pktid   = 0;
4236          p_vci_ini_rw.srcid   = 0;
4237          p_vci_ini_rw.cons    = false;
4238          p_vci_ini_rw.wrap    = false;
4239          p_vci_ini_rw.contig  = false;
4240          p_vci_ini_rw.clen    = 0;
4241          p_vci_ini_rw.cfixed  = false;
4242          p_vci_ini_rw.eop     = false;
4243
4244          break;
4245        }
4246      case CMD_DATA_UNC:
4247        {
4248          p_vci_ini_rw.cmdval = true;
4249
4250          addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
4251          set_num_dcache(addr,r_vci_cmd_num_cache);
4252
4253          PRINTF("      * <CMD> DATA_UNC   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4254
4255          p_vci_ini_rw.address = addr;
4256          switch( r_dcache_type_save[r_vci_cmd_num_cache] ) {
4257          case iss_t::DATA_READ:
4258            p_vci_ini_rw.wdata = 0;
4259            p_vci_ini_rw.be  = r_dcache_be_save[r_vci_cmd_num_cache].read();
4260            p_vci_ini_rw.cmd = vci_param::CMD_READ;
4261            break;
4262          case iss_t::DATA_LL:
4263            p_vci_ini_rw.wdata = 0;
4264            p_vci_ini_rw.be  = 0xF;
4265            p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ;
4266            break;
4267          default:
4268            ASSERT(false,"this should not happen");
4269          }
4270          p_vci_ini_rw.plen = 4;
4271          p_vci_ini_rw.trdid  = TYPE_DATA_UNC;   // data cache uncached read
4272          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4273          p_vci_ini_rw.srcid  = m_srcid_rw;
4274          p_vci_ini_rw.cons   = false;
4275          p_vci_ini_rw.wrap   = false;
4276          p_vci_ini_rw.contig = true;
4277          p_vci_ini_rw.clen   = 0;
4278          p_vci_ini_rw.cfixed = false;
4279          p_vci_ini_rw.eop    = true;
4280
4281          break;
4282        }
4283      case CMD_DATA_SC:
4284        {
4285          p_vci_ini_rw.cmdval = true;
4286
4287          addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
4288          set_num_dcache(addr,r_vci_cmd_num_cache);
4289
4290          PRINTF("      * <CMD> DATA_SC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4291
4292          p_vci_ini_rw.address = addr;
4293          if(r_vci_cmd_max.read() == 3){
4294            ASSERT(false, "Not handled yet");
4295          } else { // r_vci_cmd_cpt == 1
4296            switch(r_vci_cmd_cpt.read()){
4297            case 0:
4298              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);
4299              break;
4300            case 1:
4301              p_vci_ini_rw.wdata = r_dcache_wdata_save[r_vci_cmd_num_cache].read();
4302              break;
4303            }
4304          }
4305          p_vci_ini_rw.be     = 0xF;
4306          p_vci_ini_rw.cmd    = vci_param::CMD_STORE_COND;
4307          p_vci_ini_rw.plen   = 4*(r_vci_cmd_max.read()+1);
4308          p_vci_ini_rw.trdid  = TYPE_DATA_SC;   // data cache uncached read
4309          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4310          p_vci_ini_rw.srcid  = m_srcid_rw;
4311          p_vci_ini_rw.cons   = true;
4312          p_vci_ini_rw.wrap   = false;
4313          p_vci_ini_rw.contig = false;
4314          p_vci_ini_rw.clen   = 0;
4315          p_vci_ini_rw.cfixed = false;
4316          p_vci_ini_rw.eop    = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
4317
4318          break;
4319        }
4320      case CMD_DATA_WRITE:
4321        {
4322          p_vci_ini_rw.cmdval  = true;
4323
4324          addr_40 addr       = (addr_40) r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt)&~0x3;
4325
4326          PRINTF("      * <CMD> DATA_WRITE : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4327
4328          p_vci_ini_rw.address = addr;
4329          p_vci_ini_rw.wdata   = r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt);
4330          p_vci_ini_rw.be      = r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt);
4331          p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
4332          p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
4333          p_vci_ini_rw.trdid   = r_wbuf[r_vci_cmd_num_cache]->getIndex() + (1<<(vci_param::T-1));
4334          p_vci_ini_rw.pktid   = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4335          p_vci_ini_rw.srcid   = m_srcid_rw;
4336          p_vci_ini_rw.cons    = false;
4337          p_vci_ini_rw.wrap    = false;
4338          p_vci_ini_rw.contig  = true;
4339          p_vci_ini_rw.clen    = 0;
4340          p_vci_ini_rw.cfixed  = false;
4341          p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
4342
4343          break;
4344        }
4345      case CMD_DATA_MISS:
4346        {
4347          p_vci_ini_rw.cmdval = true;
4348
4349          addr_40 addr = r_dcache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_dcache_yzmask;
4350          set_num_dcache(addr,r_vci_cmd_num_cache);
4351
4352          PRINTF("      * <CMD> DATA_MISS  : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4353
4354          p_vci_ini_rw.address = addr;
4355          p_vci_ini_rw.be     = 0xF;
4356          p_vci_ini_rw.plen   = m_dcache_words << 2;
4357          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
4358          p_vci_ini_rw.trdid  = TYPE_DATA_MISS;   // data cache cached read
4359          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4360          p_vci_ini_rw.srcid  = m_srcid_rw;
4361          p_vci_ini_rw.cons   = false;
4362          p_vci_ini_rw.wrap   = false;
4363          p_vci_ini_rw.contig = true;
4364          p_vci_ini_rw.clen   = 0;
4365          p_vci_ini_rw.cfixed = false;
4366          p_vci_ini_rw.eop = true;
4367
4368          break;
4369        }
4370      case CMD_INS_MISS:
4371        {
4372          p_vci_ini_rw.cmdval = true;
4373
4374          addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_icache_yzmask;
4375          set_num_icache(addr,r_vci_cmd_num_cache);
4376
4377          PRINTF("      * <CMD> INS_MISS   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4378
4379          p_vci_ini_rw.address = addr;
4380          p_vci_ini_rw.be     = 0xF;
4381          p_vci_ini_rw.plen   = m_icache_words << 2;
4382          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
4383          p_vci_ini_rw.trdid  = TYPE_INS_MISS;   // ins cache cached read
4384          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4385          p_vci_ini_rw.srcid  = m_srcid_rw;
4386          p_vci_ini_rw.cons   = false;
4387          p_vci_ini_rw.wrap   = false;
4388          p_vci_ini_rw.contig = true;
4389          p_vci_ini_rw.clen   = 0;
4390          p_vci_ini_rw.cfixed = false;
4391          p_vci_ini_rw.eop = true;
4392
4393          break;
4394        }
4395      case CMD_INS_UNC:
4396        {
4397          p_vci_ini_rw.cmdval = true;
4398
4399          addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
4400          set_num_icache(addr,r_vci_cmd_num_cache);
4401
4402          PRINTF("      * <CMD> INS_UNC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
4403
4404          p_vci_ini_rw.address = addr;
4405          p_vci_ini_rw.be     = 0xF;
4406          p_vci_ini_rw.plen   = 4;
4407          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
4408          p_vci_ini_rw.trdid  = TYPE_INS_UNC;   // ins cache uncached read
4409          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
4410          p_vci_ini_rw.srcid  = m_srcid_rw;
4411          p_vci_ini_rw.cons   = false;
4412          p_vci_ini_rw.wrap   = false;
4413          p_vci_ini_rw.contig = true;
4414          p_vci_ini_rw.clen   = 0;
4415          p_vci_ini_rw.cfixed = false;
4416          p_vci_ini_rw.eop = true;
4417
4418          break;
4419        }
4420      } // end switch r_vci_cmd_fsm
4421
4422      switch (r_vci_rsp_fsm.read() ) {
4423      case RSP_DATA_WRITE : p_vci_ini_rw.rspack = true; break;
4424      case RSP_INS_MISS   :
4425      case RSP_INS_UNC    : p_vci_ini_rw.rspack = r_vci_rsp_fifo_icache_data.wok(); break;
4426      case RSP_DATA_MISS  :
4427      case RSP_DATA_UNC   :
4428      case RSP_DATA_SC    : p_vci_ini_rw.rspack = r_vci_rsp_fifo_dcache_data.wok(); break;
4429      case RSP_IDLE       :
4430      default             : p_vci_ini_rw.rspack = false; break;
4431      } // end switch r_vci_rsp_fsm
4432
4433      // VCI_TGT
4434
4435      // PRINTF("      * <TGT> srcid : %d\n", r_tgt_srcid.read());
4436
4437      switch ( r_vci_tgt_fsm.read() ) {
4438
4439      case TGT_IDLE:
4440      case TGT_UPDT_WORD:
4441      case TGT_UPDT_DATA:
4442        p_vci_tgt.cmdack  = true;
4443        p_vci_tgt.rspval  = false;
4444        break;
4445
4446      case TGT_RSP_BROADCAST:
4447        {
4448          bool tgt_icache_req;
4449          bool tgt_icache_rsp;
4450
4451#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
4452          tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
4453          tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
4454#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
4455          tgt_icache_req = false;
4456          tgt_icache_rsp = false;
4457          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
4458            {
4459              tgt_icache_req |= r_tgt_icache_req[num_cache].read();
4460              tgt_icache_rsp |= r_tgt_icache_rsp[num_cache].read();
4461            }
4462#endif
4463
4464          bool rspval = ((not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
4465                         and (tgt_icache_rsp | r_tgt_dcache_rsp[r_tgt_num_cache]));
4466
4467          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());
4468                   
4469          p_vci_tgt.cmdack  = false;
4470          p_vci_tgt.rspval  = rspval;
4471          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4472          p_vci_tgt.rpktid  = r_tgt_pktid.read();
4473          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4474          p_vci_tgt.rdata   = 0;
4475          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4476          p_vci_tgt.reop    = true;
4477          break;
4478        }
4479      case TGT_RSP_ICACHE:
4480        {
4481          bool rspval = not r_tgt_icache_req[r_tgt_num_cache].read() and r_tgt_icache_rsp[r_tgt_num_cache].read();
4482
4483          PRINTF("      * <TGT> RSP_ICACHE : rspval : %d\n",rspval);
4484
4485          p_vci_tgt.cmdack  = false;
4486          p_vci_tgt.rspval  = rspval;
4487          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4488          p_vci_tgt.rpktid  = r_tgt_pktid.read();
4489          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4490          p_vci_tgt.rdata   = 0;
4491          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4492          p_vci_tgt.reop    = true;
4493          break;
4494        }
4495      case TGT_RSP_DCACHE:
4496        {
4497          bool rspval = not r_tgt_dcache_req[r_tgt_num_cache].read() and r_tgt_dcache_rsp[r_tgt_num_cache].read();
4498
4499          PRINTF("      * <TGT> RSP_DCACHE : rspval : %d\n",rspval);
4500                   
4501          p_vci_tgt.cmdack  = false;
4502          p_vci_tgt.rspval  = rspval;
4503          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
4504          p_vci_tgt.rpktid  = r_tgt_pktid.read();
4505          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
4506          p_vci_tgt.rdata   = 0;
4507          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
4508          p_vci_tgt.reop    = true;
4509          break;
4510        }
4511      case TGT_REQ_BROADCAST:
4512      case TGT_REQ_ICACHE:
4513      case TGT_REQ_DCACHE:
4514        p_vci_tgt.cmdack  = false;
4515        p_vci_tgt.rspval  = false;
4516        break;
4517
4518      } // end switch TGT_FSM
4519    } // end genMoore()
4520 
4521    //////////////////////////////////////////////////////////////////////////////////
4522    tmpl(void)::stop_simulation (uint32_t nb_frz_cycles)
4523    //////////////////////////////////////////////////////////////////////////////////
4524    {
4525#if CC_XCACHE_WRAPPER_STOP_SIMULATION
4526      if (nb_frz_cycles == 0)
4527        {
4528          PRINTF("CC_XCACHE_WRAPPER \"%s\" : don't stop the simulation.\n",name().c_str());
4529          m_stop_simulation = false;
4530        }
4531      else
4532        {
4533          PRINTF("CC_XCACHE_WRAPPER \"%s\" : stop the simulation after %d cycles.\n",name().c_str(),nb_frz_cycles);
4534          m_stop_simulation = true;
4535          m_stop_simulation_nb_frz_cycles_max = nb_frz_cycles;
4536        }
4537#else
4538      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_STOP_SIMULATION is unset, you can't use stop_simulation." << std::endl;
4539#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
4540       
4541    }
4542
4543    //////////////////////////////////////////////////////////////////////////////////
4544    tmpl(void)::log_transaction ( bool generate_file_icache
4545                                  ,bool generate_file_dcache
4546                                  ,bool generate_file_cmd
4547                                  ,bool generate_file_tgt
4548                                  ,bool generate_file_cleanup)
4549    //////////////////////////////////////////////////////////////////////////////////
4550    {
4551#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
4552      generate_log_transaction_file_icache  = generate_file_icache ;
4553      generate_log_transaction_file_dcache  = generate_file_dcache ;
4554      generate_log_transaction_file_cmd     = generate_file_cmd    ;
4555      generate_log_transaction_file_tgt     = generate_file_tgt    ;
4556      generate_log_transaction_file_cleanup = generate_file_cleanup;
4557#else
4558      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION is unset, you can't use log_transaction." << std::endl;
4559#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
4560       
4561    }
4562
4563    //////////////////////////////////////////////////////////////////////////////////
4564    tmpl(void)::vhdl_testbench (bool generate_file_mwbuf)
4565    //////////////////////////////////////////////////////////////////////////////////
4566    {
4567#if MWBUF_VHDL_TESTBENCH
4568      if (simulation_started)
4569        std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : Simulation is starting, you can't use vhdl_testbench." << std::endl;
4570      else
4571        generate_vhdl_testbench_mwbuf = generate_file_mwbuf;
4572#else
4573      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag MWBUF_VHDL_TESTBENCH is unset, you can't use vhdl_testbench." << std::endl;
4574#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
4575    }
4576
4577    //////////////////////////////////////////////////////////////////////////////////
4578    tmpl(uint32_t)::get_num_cache(addr_40 & addr)
4579    //////////////////////////////////////////////////////////////////////////////////
4580    {
4581      uint32_t num_cache = get_num_cache_only(addr);
4582
4583      addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
4584              ((addr>>m_num_cache_MSB)<<m_num_cache_LSB)); // set MSB
4585
4586      return num_cache;
4587    }
4588
4589    //////////////////////////////////////////////////////////////////////////////////
4590    tmpl(uint32_t)::get_num_cache_only(addr_40 addr)
4591    //////////////////////////////////////////////////////////////////////////////////
4592    {
4593      return (addr>>m_num_cache_LSB)&m_num_cache_mask;
4594    }
4595
4596    //////////////////////////////////////////////////////////////////////////////////
4597    tmpl(void)::set_num_cache(addr_40 & addr, uint32_t num_cache)
4598    //////////////////////////////////////////////////////////////////////////////////
4599    {
4600      addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
4601              ((addr_40)num_cache << m_num_cache_LSB) |
4602              ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
4603    }
4604
4605    //////////////////////////////////////////////////////////////////////////////////
4606    // FIXME : mettre le type addr_40
4607    tmpl(sc_dt::sc_uint<40>)::set_num_cache_only(addr_40 addr, uint32_t num_cache)
4608    //////////////////////////////////////////////////////////////////////////////////
4609    {
4610      return ((addr&m_num_cache_LSB_mask) | // keep LSB
4611              ((addr_40)num_cache << m_num_cache_LSB) |
4612              ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
4613    }
4614
4615
4616  }} // end namespace
4617
4618// Local Variables:
4619// tab-width: 4
4620// c-basic-offset: 4
4621// c-file-offsets:((innamespace . 0)(inline-open . 0))
4622// indent-tabs-mode: nil
4623// End:
4624
4625// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.