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

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

delete all timeout reference (multi write buffer)

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