Changeset 165


Ignore:
Timestamp:
May 11, 2011, 1:36:38 PM (14 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

Location:
trunk
Files:
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_cc_xcache_wrapper_v4/caba/metadata/vci_cc_xcache_wrapper_v4.sd

    r134 r165  
    2222                Uses('common:iss2'),
    2323                Uses('caba:multi_write_buffer'),
     24                Uses('caba:generic_fifo'),
    2425                Uses('caba:generic_cache', addr_t = 'uint32_t'),
    2526                ],
  • trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/include/vci_cc_xcache_wrapper_v4.h

    r147 r165  
    3131
    3232#include <inttypes.h>
     33#include <fstream>
    3334#include <systemc>
    3435#include <queue>
     
    3637#include "multi_write_buffer.h"
    3738#include "generic_cache.h"
     39#include "generic_fifo.h"
    3840#include "vci_initiator.h"
    3941#include "vci_target.h"
     
    4244
    4345/*
    44  * CC_XCACHE_WRAPPER_SELECT_VICTIM :
    45  *   The selection and the update of cache (after a read miss)
    46  *   are separated in two step
    47  *   Also, the cleanup can be send in parallel at the read miss.
    48  *
    49  * CC_XCACHE_WRAPPER_FIFO_RSP
    50  *   Two simple fifo (each 2x32 depth) receive the cache line from
    51  *   RAM. Instead of two buffers (m_icache_words and m_dcache_words)
    52  *   
    53  * CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
    54  *   Update cache in "2*cache_words" cycles (read+mask, write)
    55  *   
    56  * CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
    57  *   Update cache with only modified data (be != 0)
    58  *   
    59  * CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME
    60  *   Write buffer scheme for update step :
    61  *     1    - multi_scan
    62  *     2    - round_robin_scan
    63  *     3    - one_scan
    64  *     else - default scheme
    65  *
    66  * CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY
    67  *   Write buffer access is conditionnal with dcache_miss_req and icache_miss_req
    68  *     1    - two access authorized
    69  *     2    - one access with static priority (dcache prior)
    70  *     3    - one access with static priority (icache prior)
    71  *     4    - one access with round robin priority
    72  *
    73  * CC_XCACHE_WRAPPER_STOP_SIMULATION :
     46 * ----------------------------------------------------------
     47 * Implementation
     48 * ----------------------------------------------------------
     49 *
     50 * CC_XCACHE_WRAPPER_MULTI_CACHE
     51 *     1    - icache static partitionnement
     52 *     2    - icache dedicated
     53 *
     54 * ----------------------------------------------------------
     55 * Debug
     56 * ----------------------------------------------------------
     57 *
     58 * CC_XCACHE_WRAPPER_STOP_SIMULATION
    7459 *   stop simulation if processor is stall after a long time
    7560 *   (configurable with "stop_simulation" function)
    7661 *
    77  * CC_XCACHE_WRAPPER_DEBUG :
     62 * CC_XCACHE_WRAPPER_DEBUG
    7863 *   Add log to help the debugging
    7964 *
    80  * CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN :
     65 * CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN
    8166 *   Number of cycle before to prinf debug message
    8267 *
    83  * CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
    84  *   Print transaction between the cpu and the cache
     68 * CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
     69 *   Print transaction between :
     70 *     - the cpu and the cache (icache and dcache)
     71 *     - vci
     72 *     - cleanup
     73 *     - coherency
     74 *
     75 * MWBUF_VHDL_TESTBENCH
     76 *   generate a vhdl testbench for multi write buffer
    8577 */
    8678
    8779// implementation
    88 #ifndef CC_XCACHE_WRAPPER_SELECT_VICTIM
    89 #define CC_XCACHE_WRAPPER_SELECT_VICTIM             0
    90 #endif
    91 #ifndef CC_XCACHE_WRAPPER_FIFO_RSP
    92 #define CC_XCACHE_WRAPPER_FIFO_RSP                  0
    93 #endif
    94 #ifndef CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
    95 #define CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE     1
    96 #endif
    97 #ifndef CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT
    98 #define CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE_OPT 1
    99 #endif
    100 #ifndef CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME
    101 #define CC_XCACHE_WRAPPER_WBUF_UPDATE_SCHEME        0
    102 #endif
    103 #ifndef CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY
    104 #define CC_XCACHE_WRAPPER_VCI_CMD_PRIORITY          2
    105 #endif 
    106 // debugging
     80#ifndef CC_XCACHE_WRAPPER_MULTI_CACHE
     81#define CC_XCACHE_WRAPPER_MULTI_CACHE                 2
     82// if multi_cache :
     83// <tsar toplevel>/modules/vci_mem_cache_v4/caba/source/include/mem_cache_directory_v4.h : L1_MULTI_CACHE 1
     84#endif
     85 
     86// debug
    10787#ifndef CC_XCACHE_WRAPPER_STOP_SIMULATION
    108 #define CC_XCACHE_WRAPPER_STOP_SIMULATION           1
     88#define CC_XCACHE_WRAPPER_STOP_SIMULATION             1
    10989#endif
    11090#ifndef CC_XCACHE_WRAPPER_DEBUG
    111 #define CC_XCACHE_WRAPPER_DEBUG                     0
     91#define CC_XCACHE_WRAPPER_DEBUG                       0
    11292#endif
    11393#ifndef CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN
    114 #define CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN           200000
    115 #endif
    116 #ifndef CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
    117 #define CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION  0
     94#define CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN             4725000
     95#endif
     96#ifndef CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
     97#define CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION      0
     98#define CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH "log"
     99#endif
     100#ifndef MWBUF_VHDL_TESTBENCH
     101#define MWBUF_VHDL_TESTBENCH                          0
    118102#endif
    119103
     
    129113    : public soclib::caba::BaseModule
    130114{
     115    typedef uint64_t            vhdl_tb_t;
    131116    typedef sc_dt::sc_uint<40>  addr_40;
    132     typedef sc_dt::sc_uint<64>  data_64;
    133117    typedef uint32_t            data_t;
    134118    typedef uint32_t            tag_t;
    135119    typedef uint32_t            be_t;
    136120    typedef typename vci_param::fast_addr_t vci_addr_t;
    137 
     121    typedef  enum
     122        {
     123            WRITE_THROUGH,
     124            RELEASE_WRITE_THROUGH
     125        } write_policy_t;
     126   
    138127    enum dcache_fsm_state_e {
    139128        DCACHE_IDLE,
    140129        DCACHE_WRITE_UPDT,
    141 #if CC_XCACHE_WRAPPER_SELECT_VICTIM
    142130        DCACHE_MISS_VICTIM,
    143 #endif
    144131        DCACHE_MISS_WAIT,
    145132        DCACHE_MISS_UPDT,
     
    157144    enum icache_fsm_state_e {
    158145        ICACHE_IDLE,
    159 #if CC_XCACHE_WRAPPER_SELECT_VICTIM
    160146        ICACHE_MISS_VICTIM,
    161 #endif
    162147        ICACHE_MISS_WAIT,
    163148        ICACHE_MISS_UPDT,
     
    204189    enum cleanup_fsm_state_e {
    205190        CLEANUP_IDLE,
    206         CLEANUP_DCACHE,
    207         CLEANUP_ICACHE,
     191        CLEANUP_REQ,
     192        CLEANUP_RSP_DCACHE,
     193        CLEANUP_RSP_ICACHE,
    208194    };
    209195
     
    231217    sc_in<bool>                             p_clk;
    232218    sc_in<bool>                             p_resetn;
    233     sc_in<bool>                             p_irq[iss_t::n_irq];
     219    sc_in<bool>                          ** p_irq;//[m_nb_cpu][iss_t::n_irq];
    234220    soclib::caba::VciInitiator<vci_param>   p_vci_ini_rw;
    235221    soclib::caba::VciInitiator<vci_param>   p_vci_ini_c;
     
    241227    const soclib::common::AddressDecodingTable<vci_addr_t, bool>    m_cacheability_table;
    242228    const soclib::common::Segment                                   m_segment;
    243     iss_t               m_iss;
     229    iss_t            ** m_iss; //[m_nb_cpu]
    244230    const uint32_t      m_srcid_rw;   
    245231    const uint32_t      m_srcid_c;   
    246232   
    247     const size_t        m_dcache_ways;
    248     const size_t        m_dcache_words;
    249     const uint32_t      m_dcache_words_shift;
    250     const size_t        m_dcache_yzmask;
    251     const size_t        m_icache_ways;
    252     const size_t        m_icache_words;
    253     const uint32_t      m_icache_words_shift;
    254     const size_t        m_icache_yzmask;
    255     const size_t        m_cache_words; // max between m_dcache_words and m_icache_words
     233    const size_t         m_nb_cpu;
     234    const size_t         m_nb_icache;
     235    const size_t         m_nb_dcache;
     236    const size_t         m_nb_cache;
     237    const size_t         m_dcache_ways;
     238    const size_t         m_dcache_words;
     239    const uint32_t       m_dcache_words_shift;
     240    const size_t         m_dcache_yzmask;
     241    const size_t         m_icache_ways;
     242    const size_t         m_icache_words;
     243    const uint32_t       m_icache_words_shift;
     244    const size_t         m_icache_yzmask;
     245    const write_policy_t m_write_policy;
     246    const size_t         m_cache_words; // max between m_dcache_words and m_icache_words
    256247
    257248#if CC_XCACHE_WRAPPER_STOP_SIMULATION
    258249    bool                m_stop_simulation;
    259250    uint32_t            m_stop_simulation_nb_frz_cycles_max;
    260     uint32_t            m_stop_simulation_nb_frz_cycles;
     251    uint32_t          * m_stop_simulation_nb_frz_cycles; //[m_nb_cpu]
    261252#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
    262253
    263254    // REGISTERS
    264     sc_signal<int>          r_dcache_fsm;
    265     sc_signal<int>          r_dcache_fsm_save;
    266     sc_signal<addr_40>      r_dcache_addr_save;
    267     sc_signal<data_t>       r_dcache_wdata_save;
    268     sc_signal<data_t>       r_dcache_rdata_save;
    269     sc_signal<int>          r_dcache_type_save;
    270     sc_signal<be_t>         r_dcache_be_save;
    271     sc_signal<bool>         r_dcache_cached_save;
    272     sc_signal<bool>         r_dcache_cleanup_req;
    273     sc_signal<addr_40>      r_dcache_cleanup_line;
    274     sc_signal<bool>         r_dcache_miss_req;
    275     sc_signal<size_t>       r_dcache_miss_way;
    276     sc_signal<size_t>       r_dcache_miss_set;
    277     sc_signal<bool>         r_dcache_unc_req;
    278     sc_signal<bool>         r_dcache_sc_req;
    279     sc_signal<bool>         r_dcache_inval_rsp;
    280     sc_signal<size_t>       r_dcache_update_addr;
    281     sc_signal<data_64>      r_dcache_ll_data;
    282     sc_signal<addr_40>      r_dcache_ll_addr;
    283     sc_signal<bool>         r_dcache_ll_valid;
    284     sc_signal<bool>         r_dcache_previous_unc;
    285 
    286     sc_signal<int>          r_icache_fsm;
    287     sc_signal<int>          r_icache_fsm_save;
    288     sc_signal<addr_40>      r_icache_addr_save;
    289     sc_signal<bool>         r_icache_miss_req;
    290     sc_signal<size_t>       r_icache_miss_way;
    291     sc_signal<size_t>       r_icache_miss_set;
    292     sc_signal<bool>         r_icache_unc_req;
    293     sc_signal<bool>         r_icache_cleanup_req;
    294     sc_signal<addr_40>      r_icache_cleanup_line;
    295     sc_signal<bool>         r_icache_inval_rsp;
    296     sc_signal<size_t>       r_icache_update_addr;
     255    sc_signal<uint32_t>     r_cpu_prior;
     256    sc_signal<uint32_t>   * r_icache_lock;//[m_nb_icache]
     257    sc_signal<uint32_t>   * r_dcache_lock;//[m_nb_dcache]
     258    sc_signal<bool>       * r_dcache_sync;//[m_nb_dcache]
     259
     260    sc_signal<int>        * r_dcache_fsm;          //[m_nb_dcache]
     261    sc_signal<int>        * r_dcache_fsm_save;     //[m_nb_dcache]
     262    sc_signal<addr_40>    * r_dcache_addr_save;    //[m_nb_dcache]
     263    sc_signal<data_t>     * r_dcache_wdata_save;   //[m_nb_dcache]
     264    sc_signal<data_t>     * r_dcache_rdata_save;   //[m_nb_dcache]
     265    sc_signal<int>        * r_dcache_type_save;    //[m_nb_dcache]
     266    sc_signal<be_t>       * r_dcache_be_save;      //[m_nb_dcache]
     267    sc_signal<bool>       * r_dcache_cached_save;  //[m_nb_dcache]
     268    sc_signal<uint32_t>   * r_dcache_num_cpu_save; //[m_nb_dcache]
     269    sc_signal<bool>       * r_dcache_cleanup_req;  //[m_nb_dcache]
     270    sc_signal<addr_40>    * r_dcache_cleanup_line; //[m_nb_dcache]
     271    sc_signal<bool>       * r_dcache_miss_req;     //[m_nb_dcache]
     272    sc_signal<size_t>     * r_dcache_miss_way;     //[m_nb_dcache]
     273    sc_signal<size_t>     * r_dcache_miss_set;     //[m_nb_dcache]
     274    sc_signal<bool>       * r_dcache_unc_req;      //[m_nb_dcache]
     275    sc_signal<bool>       * r_dcache_sc_req;       //[m_nb_dcache]
     276    sc_signal<bool>       * r_dcache_inval_rsp;    //[m_nb_dcache]
     277    sc_signal<size_t>     * r_dcache_update_addr;  //[m_nb_dcache]
     278    sc_signal<data_t>    ** r_dcache_ll_data;      //[m_nb_dcache][m_nb_cpu]
     279    sc_signal<addr_40>   ** r_dcache_ll_addr;      //[m_nb_dcache][m_nb_cpu]
     280    sc_signal<bool>      ** r_dcache_ll_valid;     //[m_nb_dcache][m_nb_cpu]
     281    sc_signal<bool>       * r_dcache_previous_unc; //[m_nb_dcache]
     282                                                   
     283    sc_signal<int>        * r_icache_fsm;          //[m_nb_icache]
     284    sc_signal<int>        * r_icache_fsm_save;     //[m_nb_icache]
     285    sc_signal<addr_40>    * r_icache_addr_save;    //[m_nb_icache]
     286    sc_signal<bool>       * r_icache_miss_req;     //[m_nb_icache]
     287    sc_signal<size_t>     * r_icache_miss_way;     //[m_nb_icache]
     288    sc_signal<size_t>     * r_icache_miss_set;     //[m_nb_icache]
     289    sc_signal<bool>       * r_icache_unc_req;      //[m_nb_icache]
     290    sc_signal<bool>       * r_icache_cleanup_req;  //[m_nb_icache]
     291    sc_signal<addr_40>    * r_icache_cleanup_line; //[m_nb_icache]
     292    sc_signal<bool>       * r_icache_inval_rsp;    //[m_nb_icache]
     293    sc_signal<size_t>     * r_icache_update_addr;  //[m_nb_icache]
     294    sc_signal<bool>       * r_icache_buf_unc_valid;//[m_nb_icache]
    297295
    298296    sc_signal<int>          r_vci_cmd_fsm;
     
    301299    sc_signal<size_t>       r_vci_cmd_cpt;       
    302300    sc_signal<bool>         r_vci_cmd_dcache_prior;
    303      
     301    sc_signal<uint32_t>     r_vci_cmd_num_icache_prior;
     302    sc_signal<uint32_t>     r_vci_cmd_num_dcache_prior;
     303    sc_signal<uint32_t>     r_vci_cmd_num_cache;
     304
    304305    sc_signal<int>          r_vci_rsp_fsm;
    305     sc_signal<bool>         r_vci_rsp_ins_error;   
    306     sc_signal<bool>         r_vci_rsp_data_error;   
    307306    sc_signal<size_t>       r_vci_rsp_cpt; 
    308     sc_signal<bool>         r_vci_rsp_ack;
    309 
    310 #if CC_XCACHE_WRAPPER_FIFO_RSP
    311     std::queue<data_t>      r_icache_miss_buf;
    312     std::queue<data_t>      r_dcache_miss_buf;
    313 #else
    314     bool                   *r_icache_miss_val;    //[m_icache_words]
    315     data_t                 *r_icache_miss_buf;    //[m_icache_words]
    316     bool                   *r_dcache_miss_val;    //[m_dcache_words]
    317     data_t                 *r_dcache_miss_buf;    //[m_dcache_words]
    318 #endif
    319     sc_signal<bool>         r_icache_buf_unc_valid;
    320 
    321     data_t                 *r_tgt_buf;            //[m_cache_words]
    322     be_t                   *r_tgt_be;             //[m_cache_words]
    323 #if CC_XCACHE_WRAPPER_CC_UPDATE_MULTI_CYCLE
     307    sc_signal<uint32_t>     r_vci_rsp_num_cache;
     308    sc_signal<bool>       * r_vci_rsp_ins_error;  //[m_nb_icache]
     309    sc_signal<bool>       * r_vci_rsp_data_error; //[m_nb_dcache]
     310
     311    GenericFifo<data_t>     r_vci_rsp_fifo_icache_data;
     312    GenericFifo<uint32_t>   r_vci_rsp_fifo_icache_num_cache;
     313    GenericFifo<data_t>     r_vci_rsp_fifo_dcache_data;
     314    GenericFifo<uint32_t>   r_vci_rsp_fifo_dcache_num_cache;
     315
     316    data_t                * r_tgt_buf;            //[m_cache_words]
     317    be_t                  * r_tgt_be;             //[m_cache_words]
    324318    sc_signal<uint32_t>     r_cache_word;
    325 #endif
    326319
    327320    sc_signal<int>          r_vci_tgt_fsm;
    328     sc_signal<addr_40>      r_tgt_addr;
     321    sc_signal<addr_40>      r_tgt_iaddr;
     322    sc_signal<addr_40>      r_tgt_daddr;
    329323    sc_signal<size_t>       r_tgt_word;
    330324    sc_signal<bool>         r_tgt_update;
     
    335329    sc_signal<size_t>       r_tgt_trdid;
    336330  //sc_signal<size_t>       r_tgt_plen;
    337     sc_signal<bool>         r_tgt_icache_req;
    338     sc_signal<bool>         r_tgt_dcache_req;
    339     sc_signal<bool>         r_tgt_icache_rsp;
    340     sc_signal<bool>         r_tgt_dcache_rsp;
     331    sc_signal<uint32_t>     r_tgt_num_cache;
     332    sc_signal<bool>       * r_tgt_icache_req; //[m_nb_icache]
     333    sc_signal<bool>       * r_tgt_icache_rsp; //[m_nb_icache]
     334    sc_signal<bool>       * r_tgt_dcache_req; //[m_nb_dcache]
     335    sc_signal<bool>       * r_tgt_dcache_rsp; //[m_nb_dcache]
    341336
    342337    sc_signal<int>          r_cleanup_fsm;              // controls initiator port of the coherence network
    343 
    344     MultiWriteBuffer<addr_40>   r_wbuf;
    345     GenericCache<vci_addr_t>    r_icache;
    346     GenericCache<vci_addr_t>    r_dcache;
    347 
    348 #if CC_XCACHE_WRAPPER_DEBUG_DCACHE_TRANSACTION
    349     std::ofstream               log_dcache_transaction_file;
     338    sc_signal<uint32_t>     r_cleanup_num_cache;
     339    sc_signal<bool>         r_cleanup_icache;
     340
     341    MultiWriteBuffer<addr_40>** r_wbuf;
     342    GenericCache<vci_addr_t> ** r_icache;
     343    GenericCache<vci_addr_t> ** r_dcache;
     344
     345#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
     346    bool                        generate_log_transaction_file_icache;
     347    bool                        generate_log_transaction_file_dcache;
     348    bool                        generate_log_transaction_file_cmd;
     349    bool                        generate_log_transaction_file_tgt;
     350    bool                        generate_log_transaction_file_cleanup;
     351
     352    std::ofstream             * log_transaction_file_icache; //[m_nb_cpu]
     353    std::ofstream             * log_transaction_file_dcache; //[m_nb_cpu]
     354    std::ofstream               log_transaction_file_cmd;
     355    std::ofstream               log_transaction_file_tgt;
     356    std::ofstream               log_transaction_file_cleanup;
     357#endif
     358
     359#if MWBUF_VHDL_TESTBENCH
     360    bool                        simulation_started;
     361    bool                        generate_vhdl_testbench_mwbuf;
     362    std::ofstream             * vhdl_testbench_mwbuf; //[m_nb_dcache]
    350363#endif
    351364
    352365    // Activity counters
    353     uint32_t m_cpt_dcache_data_read;             // * DCACHE DATA READ
    354     uint32_t m_cpt_dcache_data_write;            // * DCACHE DATA WRITE
    355     uint32_t m_cpt_dcache_dir_read;              // * DCACHE DIR READ
    356     uint32_t m_cpt_dcache_dir_write;             // * DCACHE DIR WRITE
    357                                                  
    358     uint32_t m_cpt_icache_data_read;             // * ICACHE DATA READ
    359     uint32_t m_cpt_icache_data_write;            // * ICACHE DATA WRITE
    360     uint32_t m_cpt_icache_dir_read;              // * ICACHE DIR READ
    361     uint32_t m_cpt_icache_dir_write;             // * ICACHE DIR WRITE
    362 
    363     uint32_t m_cpt_cc_update_icache;             // number of coherence update packets (for icache)
    364     uint32_t m_cpt_cc_update_dcache;             // number of coherence update packets (for dcache)
    365     uint32_t m_cpt_cc_inval_broadcast;           // number of coherence inval packets
    366     uint32_t m_cpt_cc_inval_icache;              // number of coherence inval packets
    367     uint32_t m_cpt_cc_inval_dcache;              // number of coherence inval packets
    368     uint32_t m_cpt_cc_update_icache_word_useful; // number of valid word in coherence update packets
    369     uint32_t m_cpt_cc_update_dcache_word_useful; // number of valid word in coherence update packets
    370 
    371     uint32_t m_cpt_frz_cycles;                   // * number of cycles where the cpu is frozen
    372     uint32_t m_cpt_total_cycles;                     // total number of cycles
    373 
    374     uint32_t m_cpt_data_read;                    //   number of data read
    375     uint32_t m_cpt_data_read_miss;               //   number of data read miss
    376     uint32_t m_cpt_data_read_uncached;           //   number of data read uncached
    377     uint32_t m_cpt_data_write;                   //   number of data write
    378     uint32_t m_cpt_data_write_miss;              //   number of data write miss
    379     uint32_t m_cpt_data_write_uncached;          //   number of data write uncached
    380     uint32_t m_cpt_ins_miss;                     // * number of instruction miss
    381 
    382     uint32_t m_cost_write_frz;                   // * number of frozen cycles related to write buffer         
    383     uint32_t m_cost_data_miss_frz;               // * number of frozen cycles related to data miss
    384     uint32_t m_cost_unc_read_frz;                // * number of frozen cycles related to uncached read
    385     uint32_t m_cost_ins_miss_frz;                // * number of frozen cycles related to ins miss
    386 
    387     uint32_t m_cpt_imiss_transaction;            // * number of VCI instruction miss transactions
    388     uint32_t m_cpt_dmiss_transaction;            // * number of VCI data miss transactions
    389     uint32_t m_cpt_unc_transaction;              // * number of VCI uncached read transactions
    390     uint32_t m_cpt_data_write_transaction;       // * number of VCI write transactions
    391 
    392     uint32_t m_cost_imiss_transaction;           // * cumulated duration for VCI IMISS transactions
    393     uint32_t m_cost_dmiss_transaction;           // * cumulated duration for VCI DMISS transactions
    394     uint32_t m_cost_unc_transaction;             // * cumulated duration for VCI UNC transactions
    395     uint32_t m_cost_write_transaction;           // * cumulated duration for VCI WRITE transactions
    396     uint32_t m_length_write_transaction;         // * cumulated length for VCI WRITE transactions
     366    uint32_t   m_cpt_dcache_data_read;             // * DCACHE DATA READ
     367    uint32_t   m_cpt_dcache_data_write;            // * DCACHE DATA WRITE
     368    uint32_t   m_cpt_dcache_dir_read;              // * DCACHE DIR READ
     369    uint32_t   m_cpt_dcache_dir_write;             // * DCACHE DIR WRITE
     370                                                   
     371    uint32_t   m_cpt_icache_data_read;             // * ICACHE DATA READ
     372    uint32_t   m_cpt_icache_data_write;            // * ICACHE DATA WRITE
     373    uint32_t   m_cpt_icache_dir_read;              // * ICACHE DIR READ
     374    uint32_t   m_cpt_icache_dir_write;             // * ICACHE DIR WRITE
     375               
     376    uint32_t   m_cpt_cc_update_icache;             // number of coherence update packets (for icache)
     377    uint32_t   m_cpt_cc_update_dcache;             // number of coherence update packets (for dcache)
     378    uint32_t   m_cpt_cc_inval_broadcast;           // number of coherence inval packets
     379    uint32_t   m_cpt_cc_inval_icache;              // number of coherence inval packets
     380    uint32_t   m_cpt_cc_inval_dcache;              // number of coherence inval packets
     381    uint32_t   m_cpt_cc_update_icache_word_useful; // number of valid word in coherence update packets
     382    uint32_t   m_cpt_cc_update_dcache_word_useful; // number of valid word in coherence update packets
     383               
     384    uint32_t * m_cpt_frz_cycles;                       // * number of cycles where the cpu is frozen
     385    uint32_t   m_cpt_total_cycles;                     // total number of cycles
     386               
     387    uint32_t   m_cpt_data_read;                    //   number of data read
     388    uint32_t   m_cpt_data_read_miss;               //   number of data read miss
     389    uint32_t   m_cpt_data_read_uncached;           //   number of data read uncached
     390    uint32_t   m_cpt_data_write;                   //   number of data write
     391    uint32_t   m_cpt_data_write_miss;              //   number of data write miss
     392    uint32_t   m_cpt_data_write_uncached;          //   number of data write uncached
     393    uint32_t   m_cpt_ins_miss;                     // * number of instruction miss
     394               
     395    uint32_t   m_cost_write_frz;                   // * number of frozen cycles related to write buffer         
     396    uint32_t   m_cost_data_miss_frz;               // * number of frozen cycles related to data miss
     397    uint32_t   m_cost_unc_read_frz;                // * number of frozen cycles related to uncached read
     398    uint32_t   m_cost_ins_miss_frz;                // * number of frozen cycles related to ins miss
     399               
     400    uint32_t   m_cpt_imiss_transaction;            // * number of VCI instruction miss transactions
     401    uint32_t   m_cpt_dmiss_transaction;            // * number of VCI data miss transactions
     402    uint32_t   m_cpt_unc_transaction;              // * number of VCI uncached read transactions
     403    uint32_t   m_cpt_data_write_transaction;       // * number of VCI write transactions
     404               
     405    uint32_t   m_cost_imiss_transaction;           // * cumulated duration for VCI IMISS transactions
     406    uint32_t   m_cost_dmiss_transaction;           // * cumulated duration for VCI DMISS transactions
     407    uint32_t   m_cost_unc_transaction;             // * cumulated duration for VCI UNC transactions
     408    uint32_t   m_cost_write_transaction;           // * cumulated duration for VCI WRITE transactions
     409    uint32_t   m_length_write_transaction;         // * cumulated length for VCI WRITE transactions
     410
     411    uint32_t * m_cpt_icache_access; //[m_nb_icache]
     412    uint32_t * m_cpt_dcache_access; //[m_nb_dcache]
     413    uint32_t * m_cpt_dcache_hit_after_miss_read;  //[m_nb_dcache]
     414    uint32_t * m_cpt_dcache_hit_after_miss_write; //[m_nb_dcache]
     415    uint32_t * m_cpt_dcache_store_after_store; //[m_nb_dcache]
     416    uint32_t * m_cpt_icache_miss_victim_wait; //[m_nb_icache]
     417    uint32_t * m_cpt_dcache_miss_victim_wait; //[m_nb_dcache]
     418
     419    uint32_t ** m_cpt_fsm_dcache;  //[m_nb_dcache]
     420    uint32_t ** m_cpt_fsm_icache;  //[m_nb_icache]
     421    uint32_t  * m_cpt_fsm_cmd;
     422    uint32_t  * m_cpt_fsm_rsp;
     423    uint32_t  * m_cpt_fsm_tgt;
     424    uint32_t  * m_cpt_fsm_cleanup;
     425
     426    // Non blocking multi-cache
     427    typename iss_t::InstructionRequest  * ireq        ; //[m_nb_icache]
     428    typename iss_t::InstructionResponse * irsp        ; //[m_nb_icache]
     429    bool                                * ireq_cached ; //[m_nb_icache]
     430    uint32_t                            * ireq_num_cpu; //[m_nb_dcache]
     431    typename iss_t::DataRequest         * dreq        ; //[m_nb_dcache]
     432    typename iss_t::DataResponse        * drsp        ; //[m_nb_dcache]
     433    bool                                * dreq_cached ; //[m_nb_dcache]
     434    uint32_t                            * dreq_num_cpu; //[m_nb_dcache]
     435
     436    const uint32_t m_num_cache_LSB;
     437    const uint32_t m_num_cache_MSB;
     438          addr_40  m_num_cache_LSB_mask;
     439          addr_40  m_num_cache_mask;
    397440
    398441protected:
     
    409452                       const soclib::common::IntTab &initiator_index_c,
    410453                       const soclib::common::IntTab &target_index,
     454                       size_t nb_cpu,
     455                       size_t nb_dcache,
    411456                       size_t icache_ways,
    412457                       size_t icache_sets,
     
    417462                       size_t wbuf_nwords,
    418463                       size_t wbuf_nlines,
    419                        size_t wbuf_timeout
     464                       size_t wbuf_timeout,
     465                       write_policy_t write_policy=WRITE_THROUGH
    420466                         );
    421467
    422468    ~VciCcXCacheWrapperV4();
    423469
    424     void print_trace(size_t mode = 0);
    425     void print_cpi();
    426     void print_stats();
    427 
    428 // #if CC_XCACHE_WRAPPER_STOP_SIMULATION
    429     void stop_simulation (uint32_t);
    430 // #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
     470  void print_trace(size_t mode = 0);
     471  void print_cpi();
     472  void print_stats(bool print_wbuf=true, bool print_fsm=true);
     473
     474  void stop_simulation (uint32_t);
     475  void log_transaction ( bool generate_file_icache
     476                        ,bool generate_file_dcache
     477                        ,bool generate_file_cmd
     478                        ,bool generate_file_tgt
     479                        ,bool generate_file_cleanup);
     480
     481  void vhdl_testbench (bool generate_file_mwbuf);
    431482
    432483private:
     
    435486    void genMoore();
    436487
    437     soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
     488    uint32_t get_num_cache     (addr_40 & addr);
     489    uint32_t get_num_cache_only(addr_40   addr);
     490    void     set_num_cache     (addr_40 & addr, uint32_t num_cache);
     491    addr_40  set_num_cache_only(addr_40   addr, uint32_t num_cache);
     492
     493    soclib_static_assert((int)iss_t::SC_ATOMIC     == (int)vci_param::STORE_COND_ATOMIC);
    438494    soclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
    439495};
  • 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_sav