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

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

vci_cc_xcache_wrapper_v4 : suppress one state (CC_UPDATE)

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