Ignore:
Timestamp:
May 11, 2011, 1:36:38 PM (13 years ago)
Author:
kane
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp

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