Changeset 188


Ignore:
Timestamp:
Jan 8, 2012, 2:36:49 PM (12 years ago)
Author:
alain
Message:

A maitainable version removing the multi-caches feature.

Location:
trunk/modules/vci_cc_xcache_wrapper_v4/caba
Files:
3 edited

Legend:

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

    r165 r188  
    2323                Uses('caba:multi_write_buffer'),
    2424                Uses('caba:generic_fifo'),
     25                Uses('caba:generic_cam'),
    2526                Uses('caba:generic_cache', addr_t = 'uint32_t'),
    2627                ],
    2728        ports = [
    28                 Port('caba:vci_initiator', 'p_vci_ini_rw'),
     29                Port('caba:vci_initiator', 'p_vci_ini_d'),
    2930                Port('caba:vci_initiator', 'p_vci_ini_c'),
    30                 Port('caba:vci_target', 'p_vci_tgt'),
     31                Port('caba:vci_target', 'p_vci_tgt_c'),
    3132                Port('caba:bit_in', 'p_irq', parameter.Constant('n_irq')),
    3233                Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
     
    3536        instance_parameters = [
    3637                parameter.Int('proc_id'),
    37                 parameter.Module('mtp', 'common:mapping_table'),
     38                parameter.Module('mtd', 'common:mapping_table'),
    3839                parameter.Module('mtc', 'common:mapping_table'),
    39                 parameter.IntTab('initiator_rw_index'),
    40                 parameter.IntTab('initiator_c_index'),
    41                 parameter.IntTab('target_index'),
     40                parameter.IntTab('initiator_index_d'),
     41                parameter.IntTab('initiator_index_c'),
     42                parameter.IntTab('target_index_c'),
    4243                parameter.Int('icache_ways'),
    4344                parameter.Int('icache_sets'),
     
    4647                parameter.Int('dcache_sets'),
    4748                parameter.Int('dcache_words'),
    48                 parameter.Int('ram_width_access'),
    4949                parameter.Int('wbuf_nwords'),
    5050                parameter.Int('wbuf_nlines'),
    51                 parameter.Int('wbuf_timeout'),
     51                parameter.Int('max_frozen_cycles'),
    5252                ],
    5353        extensions = [
    5454                'dsx:get_ident='
    55                 'initiator_rw_index:p_vci_ini_rw:mt,'
    56                 'initiator_c_index:p_vci_ini_c:mc,'
    57                 'target_index:p_vci_tgt:mc',
     55                'initiator_index_d:p_vci_ini_d:mtd,'
     56                'initiator_index_c:p_vci_ini_c:mtc'
     57                'target_index_c:p_vci_tgt_c:mtc',
    5858                'dsx:cpu=wrapper:iss_t',
    59                 'dsx:addressable=target_index',
    60                 'dsx:on_segment=mc:add_index:initiator_rw_index',
     59                'dsx:addressable=target_index_c',
     60                'dsx:on_segment=mtc:add_index:initiator_index_d',
    6161                'dsx:mapping_type=processor:proc_id',
    6262                ],
  • trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/include/vci_cc_xcache_wrapper_v4.h

    r175 r188  
    11/* -*- c++ -*-
     2 * File : vci_cc_xcache_wrapper_v4.h
     3 * Copyright (c) UPMC, Lip6, SoC
     4 * Authors : Alain GREINER
     5 * Date : 27/11/2011
    26 *
    37 * SOCLIB_LGPL_HEADER_BEGIN
     
    2024 *
    2125 * SOCLIB_LGPL_HEADER_END
    22  *
    23  * Copyright (c) UPMC, Lip6, SoC
    24  *         Alain Greiner <alain.greiner@lip6.fr>, 2008
    25  *
    26  * Maintainers: alain
    2726 */
    2827 
     
    3837#include "generic_cache.h"
    3938#include "generic_fifo.h"
     39#include "generic_cam.h"
    4040#include "vci_initiator.h"
    4141#include "vci_target.h"
    4242#include "mapping_table.h"
    4343#include "static_assert.h"
    44 
    45 /*
    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
    59  *   stop simulation if processor is stall after a long time
    60  *   (configurable with "stop_simulation" function)
    61  *
    62  * CC_XCACHE_WRAPPER_DEBUG
    63  *   Add log to help the debugging
    64  *
    65  * CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN
    66  *   Number of cycle before to prinf debug message
    67  *
    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
    77  */
    78 
    79 // implementation
    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
    87 #ifndef CC_XCACHE_WRAPPER_STOP_SIMULATION
    88 #define CC_XCACHE_WRAPPER_STOP_SIMULATION             1
    89 #endif
    90 #ifndef CC_XCACHE_WRAPPER_DEBUG
    91 #define CC_XCACHE_WRAPPER_DEBUG                       0
    92 #endif
    93 #ifndef CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN
    94 #define CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN             1013300
    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
    102 #endif
     44#include "iss2.h"
    10345
    10446namespace soclib {
     
    11355    : public soclib::caba::BaseModule
    11456{
    115     typedef uint64_t            vhdl_tb_t;
    116     typedef sc_dt::sc_uint<40>  addr_40;
    117     typedef uint32_t            data_t;
    118     typedef uint32_t            tag_t;
    119     typedef uint32_t            be_t;
    120     typedef typename vci_param::fast_addr_t vci_addr_t;
     57    typedef uint32_t                                        data_t;
     58    typedef uint32_t                                        tag_t;
     59    typedef uint32_t                                        be_t;
     60    typedef typename vci_param::fast_addr_t     vci_addr_t;
    12161   
    122     enum dcache_fsm_state_e {
     62    enum dcache_fsm_state_e
     63    {
    12364        DCACHE_IDLE,
    12465        DCACHE_WRITE_UPDT,
     
    12768        DCACHE_MISS_UPDT,
    12869        DCACHE_UNC_WAIT,
    129         DCACHE_SC_WAIT,
    13070        DCACHE_INVAL,
     71        DCACHE_INVAL_GO,
    13172        DCACHE_SYNC,
    13273        DCACHE_ERROR,
    13374        DCACHE_CC_CHECK,
    13475        DCACHE_CC_INVAL,
    135         DCACHE_CC_CLEANUP,
    136     };
    137 
    138     enum icache_fsm_state_e {
     76        DCACHE_CC_UPDT,
     77    };
     78
     79    enum icache_fsm_state_e
     80    {
    13981        ICACHE_IDLE,
    14082        ICACHE_MISS_VICTIM,
     
    14385        ICACHE_UNC_WAIT,
    14486        ICACHE_ERROR,
    145         ICACHE_CC_CLEANUP,
    14687        ICACHE_CC_CHECK,
    14788        ICACHE_CC_INVAL,
    148     };
    149 
    150     enum cmd_fsm_state_e {
     89        ICACHE_CC_UPDT,
     90    };
     91
     92    enum cmd_fsm_state_e
     93    {
    15194        CMD_IDLE,
    15295        CMD_INS_MISS,
     
    158101    };
    159102
    160     enum rsp_fsm_state_e {
     103    enum rsp_fsm_state_e
     104    {
    161105        RSP_IDLE,
    162106        RSP_INS_MISS,
     
    168112    };
    169113
    170     enum tgt_fsm_state_e {
     114    enum tgt_fsm_state_e
     115    {
    171116        TGT_IDLE,
    172117        TGT_UPDT_WORD,
     
    180125    };
    181126
    182     enum cleanup_fsm_state_e {
    183         CLEANUP_IDLE,
    184         CLEANUP_REQ,
    185         CLEANUP_RSP_DCACHE,
    186         CLEANUP_RSP_ICACHE,
    187     };
    188 
    189     enum transaction_type_c_e {
    190         // convention with memcache
    191         TYPE_DATA_CLEANUP = 0x0,
    192         TYPE_INS_CLEANUP  = 0x1
    193     };
    194 
    195     enum transaction_type_rw_e {
     127    enum cleanup_cmd_fsm_state_e
     128    {
     129        CLEANUP_DATA_IDLE,
     130        CLEANUP_INS_IDLE,
     131        CLEANUP_DATA_GO,
     132        CLEANUP_INS_GO,
     133    };
     134
     135    enum transaction_type_d_e
     136    {
    196137        // convention with memcache
    197138        // b0 : 1 if cached
     
    202143        TYPE_INS_UNC      = 0x2,
    203144        TYPE_INS_MISS     = 0x3,
    204         TYPE_DATA_SC      = 0x4, // sc is data and no cached
    205145    };
    206146
     
    210150    sc_in<bool>                             p_clk;
    211151    sc_in<bool>                             p_resetn;
    212     sc_in<bool>                          ** p_irq;//[m_nb_cpu][iss_t::n_irq];
    213     soclib::caba::VciInitiator<vci_param>   p_vci_ini_rw;
     152    sc_in<bool>                           * p_irq;              // [iss_t::n_irq];
     153    soclib::caba::VciInitiator<vci_param>   p_vci_ini_d;
    214154    soclib::caba::VciInitiator<vci_param>   p_vci_ini_c;
    215     soclib::caba::VciTarget<vci_param>      p_vci_tgt;
     155    soclib::caba::VciTarget<vci_param>      p_vci_tgt_c;
    216156
    217157private:
    218158
    219159    // STRUCTURAL PARAMETERS
    220     const soclib::common::AddressDecodingTable<vci_addr_t, bool>    m_cacheability_table;
    221     const soclib::common::Segment                                   m_segment;
    222     iss_t            ** m_iss; //[m_nb_cpu]
    223     const uint32_t      m_srcid_rw;   
    224     const uint32_t      m_srcid_c;   
     160    const soclib::common::AddressDecodingTable<vci_addr_t, bool>        m_cacheability_table;
     161    const soclib::common::Segment                                       m_segment;
     162
     163    const uint32_t                                                      m_srcid_d;   
     164    const uint32_t                                                      m_srcid_c;   
    225165   
    226     const size_t         m_nb_cpu;
    227     const size_t         m_nb_icache;
    228     const size_t         m_nb_dcache;
    229     const size_t         m_nb_cache;
    230     const size_t         m_dcache_ways;
    231     const size_t         m_dcache_words;
    232     const uint32_t       m_dcache_words_shift;
    233     const size_t         m_dcache_yzmask;
    234     const size_t         m_icache_ways;
    235     const size_t         m_icache_words;
    236     const uint32_t       m_icache_words_shift;
    237     const size_t         m_icache_yzmask;
    238     const size_t         m_cache_words; // max between m_dcache_words and m_icache_words
    239 
    240 #if CC_XCACHE_WRAPPER_STOP_SIMULATION
    241     bool                m_stop_simulation;
    242     uint32_t            m_stop_simulation_nb_frz_cycles_max;
    243     uint32_t          * m_stop_simulation_nb_frz_cycles; //[m_nb_cpu]
    244 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
    245 
    246     // REGISTERS
    247     sc_signal<uint32_t>     r_cpu_prior;
    248     sc_signal<uint32_t>   * r_icache_lock;//[m_nb_icache]
    249     sc_signal<uint32_t>   * r_dcache_lock;//[m_nb_dcache]
    250     sc_signal<bool>       * r_dcache_sync;//[m_nb_dcache]
    251 
    252     sc_signal<int>        * r_dcache_fsm;          //[m_nb_dcache]
    253     sc_signal<int>        * r_dcache_fsm_save;     //[m_nb_dcache]
    254     sc_signal<addr_40>    * r_dcache_addr_save;    //[m_nb_dcache]
    255     sc_signal<data_t>     * r_dcache_wdata_save;   //[m_nb_dcache]
    256     sc_signal<data_t>     * r_dcache_rdata_save;   //[m_nb_dcache]
    257     sc_signal<int>        * r_dcache_type_save;    //[m_nb_dcache]
    258     sc_signal<be_t>       * r_dcache_be_save;      //[m_nb_dcache]
    259     sc_signal<bool>       * r_dcache_cached_save;  //[m_nb_dcache]
    260     sc_signal<uint32_t>   * r_dcache_num_cpu_save; //[m_nb_dcache]
    261     sc_signal<bool>       * r_dcache_cleanup_req;  //[m_nb_dcache]
    262     sc_signal<addr_40>    * r_dcache_cleanup_line; //[m_nb_dcache]
    263     sc_signal<bool>       * r_dcache_miss_req;     //[m_nb_dcache]
    264     sc_signal<size_t>     * r_dcache_miss_way;     //[m_nb_dcache]
    265     sc_signal<size_t>     * r_dcache_miss_set;     //[m_nb_dcache]
    266     sc_signal<bool>       * r_dcache_unc_req;      //[m_nb_dcache]
    267     sc_signal<bool>       * r_dcache_sc_req;       //[m_nb_dcache]
    268     sc_signal<bool>       * r_dcache_inval_rsp;    //[m_nb_dcache]
    269     sc_signal<size_t>     * r_dcache_update_addr;  //[m_nb_dcache]
    270     sc_signal<data_t>    ** r_dcache_ll_data;      //[m_nb_dcache][m_nb_cpu]
    271     sc_signal<addr_40>   ** r_dcache_ll_addr;      //[m_nb_dcache][m_nb_cpu]
    272     sc_signal<bool>      ** r_dcache_ll_valid;     //[m_nb_dcache][m_nb_cpu]
    273     sc_signal<bool>       * r_dcache_previous_unc; //[m_nb_dcache]
     166    const size_t                                                        m_dcache_ways;
     167    const size_t                                                        m_icache_ways;
     168
     169    const size_t                                                        m_cache_words;
     170    const size_t                                                        m_cache_words_shift;
     171    const vci_addr_t                                                    m_cache_yzmask;
     172
     173    const uint32_t                                                          m_max_frozen_cycles;
     174
     175    iss_t                                   * r_iss;
     176    MultiWriteBuffer<vci_addr_t>        * r_wbuf;
     177    GenericCache<vci_addr_t>            * r_icache;
     178    GenericCache<vci_addr_t>            * r_dcache;
     179
     180    sc_signal<int>          r_icache_fsm;
     181    sc_signal<int>          r_icache_fsm_save;          // return state for coherence request
     182    sc_signal<vci_addr_t>   r_icache_addr_save;         // address requested by proc
     183    sc_signal<bool>         r_icache_miss_req;          // set by icache_fsm / reset by cmd_fsm
     184    sc_signal<bool>         r_icache_unc_req;           // set by icache_fsm / reset by cmd_fsm
     185    sc_signal<bool>         r_icache_cleanup_req;       // a victim line must be evicted   
     186    sc_signal<vci_addr_t>   r_icache_cleanup_line;      // address of the selected victim line
     187    sc_signal<size_t>       r_icache_cleanup_way;       // way of the selected victim line
     188    sc_signal<size_t>       r_icache_cleanup_set;       // set of the selected victim line
     189    sc_signal<bool>         r_icache_miss_inval;        // cancellation request for pending miss
     190    sc_signal<size_t>       r_icache_update_word;       // word index for update (intern/extern)
     191    sc_signal<data_t>       r_icache_unc_buf;       // Non cacheable read buffer (one word)
     192    sc_signal<bool>             r_icache_unc_valid;     // Non cacheable read buffer valid
     193    sc_signal<size_t>       r_icache_cc_way;        // way index for coherence request
     194    sc_signal<size_t>       r_icache_cc_set;        // set index for coherence request
     195
     196    sc_signal<int>          r_dcache_fsm;
     197    sc_signal<int>          r_dcache_fsm_save;          // return state when coherence request
     198    sc_signal<vci_addr_t>   r_dcache_addr_save;         // address requested by proc
     199    sc_signal<data_t>       r_dcache_wdata_save;        // data written (for dcache update)
     200    sc_signal<be_t>         r_dcache_be_save;           // byte enable (for dcache update)
     201    sc_signal<be_t>         r_dcache_way_save;          // selected way (in case of hit)
     202    sc_signal<be_t>         r_dcache_set_save;          // selected set (in case of hit)
     203    sc_signal<be_t>         r_dcache_word_save;         // selected word (in case of hit)
     204    sc_signal<bool>         r_dcache_cleanup_req;       // a victim line must be evicted
     205    sc_signal<vci_addr_t>   r_dcache_cleanup_line;      // address of the selected victim line
     206    sc_signal<size_t>       r_dcache_cleanup_way;       // way of the selected victim line
     207    sc_signal<size_t>       r_dcache_cleanup_set;       // set of the selected victim line
     208    sc_signal<bool>         r_dcache_miss_req;          // set by dcache_fsm / reset by cmd_fsm
     209    sc_signal<bool>         r_dcache_unc_req;           // set by dcache_fsm / reset by cmd_fsm
     210    sc_signal<bool>         r_dcache_sc_req;            // set by dcache_fsm / reset by cmd_fsm
     211    sc_signal<bool>         r_dcache_miss_inval;        // cancellation of a pending miss     
     212    sc_signal<size_t>       r_dcache_update_word;       // word index for update (intern/extern)
     213    sc_signal<data_t>       r_dcache_ll_data;           // LL reservation data
     214    sc_signal<vci_addr_t>   r_dcache_ll_addr;           // ll reservation address
     215    sc_signal<bool>         r_dcache_ll_valid;          // ll reservation valid
     216    sc_signal<bool>             r_dcache_pending_unc_write; // Non cacheable write pending
     217    sc_signal<data_t>       r_dcache_unc_buf;       // Non cacheable read buffer (one word)
     218    sc_signal<bool>             r_dcache_unc_valid;     // Non cacheable read buffer valid
     219    sc_signal<size_t>       r_dcache_cc_way;        // way index for coherence request
     220    sc_signal<size_t>       r_dcache_cc_set;        // set index for coherence request
    274221                                                   
    275     sc_signal<int>        * r_icache_fsm;          //[m_nb_icache]
    276     sc_signal<int>        * r_icache_fsm_save;     //[m_nb_icache]
    277     sc_signal<addr_40>    * r_icache_addr_save;    //[m_nb_icache]
    278     sc_signal<bool>       * r_icache_miss_req;     //[m_nb_icache]
    279     sc_signal<size_t>     * r_icache_miss_way;     //[m_nb_icache]
    280     sc_signal<size_t>     * r_icache_miss_set;     //[m_nb_icache]
    281     sc_signal<bool>       * r_icache_unc_req;      //[m_nb_icache]
    282     sc_signal<bool>       * r_icache_cleanup_req;  //[m_nb_icache]
    283     sc_signal<addr_40>    * r_icache_cleanup_line; //[m_nb_icache]
    284     sc_signal<bool>       * r_icache_inval_rsp;    //[m_nb_icache]
    285     sc_signal<size_t>     * r_icache_update_addr;  //[m_nb_icache]
    286     sc_signal<bool>       * r_icache_buf_unc_valid;//[m_nb_icache]
    287 
    288222    sc_signal<int>          r_vci_cmd_fsm;
    289     sc_signal<size_t>       r_vci_cmd_min;       
    290     sc_signal<size_t>       r_vci_cmd_max;       
     223    sc_signal<size_t>       r_vci_cmd_min;              // min word index for a write burst
     224    sc_signal<size_t>       r_vci_cmd_max;              // max word index for a write burst
    291225    sc_signal<size_t>       r_vci_cmd_cpt;       
    292     sc_signal<bool>         r_vci_cmd_dcache_prior;
    293     sc_signal<uint32_t>     r_vci_cmd_num_icache_prior;
    294     sc_signal<uint32_t>     r_vci_cmd_num_dcache_prior;
    295     sc_signal<uint32_t>     r_vci_cmd_num_cache;
     226    sc_signal<bool>         r_vci_cmd_imiss_prio;       // round-robin flip-flop to access wbuf
    296227
    297228    sc_signal<int>          r_vci_rsp_fsm;
    298229    sc_signal<size_t>       r_vci_rsp_cpt; 
    299     sc_signal<uint32_t>     r_vci_rsp_num_cache;
    300     sc_signal<bool>       * r_vci_rsp_ins_error;  //[m_nb_icache]
    301     sc_signal<bool>       * r_vci_rsp_data_error; //[m_nb_dcache]
    302 
    303     GenericFifo<data_t>     r_vci_rsp_fifo_icache_data;
    304     GenericFifo<uint32_t>   r_vci_rsp_fifo_icache_num_cache;
    305     GenericFifo<data_t>     r_vci_rsp_fifo_dcache_data;
    306     GenericFifo<uint32_t>   r_vci_rsp_fifo_dcache_num_cache;
    307 
    308     data_t                * r_tgt_buf;            //[m_cache_words]
    309     be_t                  * r_tgt_be;             //[m_cache_words]
    310     sc_signal<uint32_t>     r_cache_word;
    311 
    312     sc_signal<int>          r_vci_tgt_fsm;
    313     sc_signal<addr_40>      r_tgt_iaddr;
    314     sc_signal<addr_40>      r_tgt_daddr;
    315     sc_signal<size_t>       r_tgt_word;
    316     sc_signal<bool>         r_tgt_update;
    317     sc_signal<bool>         r_tgt_update_data;
    318   //sc_signal<bool>         r_tgt_brdcast;
     230    sc_signal<bool>         r_vci_rsp_ins_error;        // set by rsp_fsm / reset by icache_fsm
     231    sc_signal<bool>         r_vci_rsp_data_error;       // set by rsp_fsm / reset by dcache_fsm
     232    GenericFifo<data_t>     r_vci_rsp_fifo_icache;      // response fifo to ICACHE FSM
     233    GenericFifo<data_t>     r_vci_rsp_fifo_dcache;      // response FIFO to DCACHE FSM
     234
     235    sc_signal<int>          r_tgt_fsm;                      // target port on coherence network
     236    sc_signal<bool>         r_tgt_icache_rsp;           // VCI response required when true
     237    sc_signal<bool>         r_tgt_dcache_rsp;           // VCI response required when true
     238    sc_signal<vci_addr_t>   r_tgt_addr;                     // address of the target line
     239    sc_signal<size_t>       r_tgt_word_min;                 // index of the first word to be updated
     240    sc_signal<size_t>       r_tgt_word_max;                 // index of the last word to be updated
     241    sc_signal<size_t>       r_tgt_word_count;           // word counter to fill the tgt_buf
     242    sc_signal<bool>         r_tgt_update;                   // update request when true
     243    sc_signal<bool>         r_tgt_update_data;          // update_data request when true
    319244    sc_signal<size_t>       r_tgt_srcid;
    320245    sc_signal<size_t>       r_tgt_pktid;
    321246    sc_signal<size_t>       r_tgt_trdid;
    322   //sc_signal<size_t>       r_tgt_plen;
    323     sc_signal<uint32_t>     r_tgt_num_cache;
    324     sc_signal<bool>       * r_tgt_icache_req; //[m_nb_icache]
    325     sc_signal<bool>       * r_tgt_icache_rsp; //[m_nb_icache]
    326     sc_signal<bool>       * r_tgt_dcache_req; //[m_nb_dcache]
    327     sc_signal<bool>       * r_tgt_dcache_rsp; //[m_nb_dcache]
    328 
    329     sc_signal<int>          r_cleanup_fsm;              // controls initiator port of the coherence network
    330     sc_signal<uint32_t>     r_cleanup_num_cache;
    331     sc_signal<bool>         r_cleanup_icache;
    332 
    333     MultiWriteBuffer<addr_40>** r_wbuf;
    334     GenericCache<vci_addr_t> ** r_icache;
    335     GenericCache<vci_addr_t> ** r_dcache;
    336 
    337 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    338     bool                        generate_log_transaction_file_icache;
    339     bool                        generate_log_transaction_file_dcache;
    340     bool                        generate_log_transaction_file_cmd;
    341     bool                        generate_log_transaction_file_tgt;
    342     bool                        generate_log_transaction_file_cleanup;
    343 
    344     std::ofstream             * log_transaction_file_icache; //[m_nb_cpu]
    345     std::ofstream             * log_transaction_file_dcache; //[m_nb_cpu]
    346     std::ofstream               log_transaction_file_cmd;
    347     std::ofstream               log_transaction_file_tgt;
    348     std::ofstream               log_transaction_file_cleanup;
    349 #endif
    350 
    351 #if MWBUF_VHDL_TESTBENCH
    352     bool                        simulation_started;
    353     bool                        generate_vhdl_testbench_mwbuf;
    354     std::ofstream             * vhdl_testbench_mwbuf; //[m_nb_dcache]
    355 #endif
    356 
    357     // Activity counters
    358     uint32_t   m_cpt_dcache_data_read;             // * DCACHE DATA READ
    359     uint32_t   m_cpt_dcache_data_write;            // * DCACHE DATA WRITE
    360     uint32_t   m_cpt_dcache_dir_read;              // * DCACHE DIR READ
    361     uint32_t   m_cpt_dcache_dir_write;             // * DCACHE DIR WRITE
    362                                                    
    363     uint32_t   m_cpt_icache_data_read;             // * ICACHE DATA READ
    364     uint32_t   m_cpt_icache_data_write;            // * ICACHE DATA WRITE
    365     uint32_t   m_cpt_icache_dir_read;              // * ICACHE DIR READ
    366     uint32_t   m_cpt_icache_dir_write;             // * ICACHE DIR WRITE
    367                
    368     uint32_t   m_cpt_cc_update_icache;             // number of coherence update packets (for icache)
    369     uint32_t   m_cpt_cc_update_dcache;             // number of coherence update packets (for dcache)
    370     uint32_t   m_cpt_cc_inval_broadcast;           // number of coherence inval packets
    371     uint32_t   m_cpt_cc_inval_icache;              // number of coherence inval packets
    372     uint32_t   m_cpt_cc_inval_dcache;              // number of coherence inval packets
    373     uint32_t   m_cpt_cc_update_icache_word_useful; // number of valid word in coherence update packets
    374     uint32_t   m_cpt_cc_update_dcache_word_useful; // number of valid word in coherence update packets
    375                
    376     uint32_t * m_cpt_frz_cycles;                       // * number of cycles where the cpu is frozen
    377     uint32_t   m_cpt_total_cycles;                     // total number of cycles
    378                
    379     uint32_t   m_cpt_data_read;                    //   number of data read
    380     uint32_t   m_cpt_data_read_miss;               //   number of data read miss
    381     uint32_t   m_cpt_data_read_uncached;           //   number of data read uncached
    382     uint32_t   m_cpt_data_write;                   //   number of data write
    383     uint32_t   m_cpt_data_write_miss;              //   number of data write miss
    384     uint32_t   m_cpt_data_write_uncached;          //   number of data write uncached
    385     uint32_t   m_cpt_ins_miss;                     // * number of instruction miss
    386                
    387     uint32_t   m_cost_write_frz;                   // * number of frozen cycles related to write buffer         
    388     uint32_t   m_cost_data_miss_frz;               // * number of frozen cycles related to data miss
    389     uint32_t   m_cost_unc_read_frz;                // * number of frozen cycles related to uncached read
    390     uint32_t   m_cost_ins_miss_frz;                // * number of frozen cycles related to ins miss
    391                
    392     uint32_t   m_cpt_imiss_transaction;            // * number of VCI instruction miss transactions
    393     uint32_t   m_cpt_dmiss_transaction;            // * number of VCI data miss transactions
    394     uint32_t   m_cpt_unc_transaction;              // * number of VCI uncached read transactions
    395     uint32_t   m_cpt_data_write_transaction;       // * number of VCI write transactions
    396                
    397     uint32_t   m_cost_imiss_transaction;           // * cumulated duration for VCI IMISS transactions
    398     uint32_t   m_cost_dmiss_transaction;           // * cumulated duration for VCI DMISS transactions
    399     uint32_t   m_cost_unc_transaction;             // * cumulated duration for VCI UNC transactions
    400     uint32_t   m_cost_write_transaction;           // * cumulated duration for VCI WRITE transactions
    401     uint32_t   m_length_write_transaction;         // * cumulated length for VCI WRITE transactions
    402 
    403     uint32_t * m_cpt_icache_access; //[m_nb_icache]
    404     uint32_t * m_cpt_dcache_access; //[m_nb_dcache]
    405     uint32_t * m_cpt_dcache_hit_after_miss_read;  //[m_nb_dcache]
    406     uint32_t * m_cpt_dcache_hit_after_miss_write; //[m_nb_dcache]
    407     uint32_t * m_cpt_dcache_store_after_store; //[m_nb_dcache]
    408     uint32_t * m_cpt_icache_miss_victim_wait; //[m_nb_icache]
    409     uint32_t * m_cpt_dcache_miss_victim_wait; //[m_nb_dcache]
    410 
    411     uint32_t ** m_cpt_fsm_dcache;  //[m_nb_dcache]
    412     uint32_t ** m_cpt_fsm_icache;  //[m_nb_icache]
    413     uint32_t  * m_cpt_fsm_cmd;
    414     uint32_t  * m_cpt_fsm_rsp;
    415     uint32_t  * m_cpt_fsm_tgt;
    416     uint32_t  * m_cpt_fsm_cleanup;
    417 
    418     // Non blocking multi-cache
    419     typename iss_t::InstructionRequest  * ireq        ; //[m_nb_icache]
    420     typename iss_t::InstructionResponse * irsp        ; //[m_nb_icache]
    421     bool                                * ireq_cached ; //[m_nb_icache]
    422     uint32_t                            * ireq_num_cpu; //[m_nb_dcache]
    423     typename iss_t::DataRequest         * dreq        ; //[m_nb_dcache]
    424     typename iss_t::DataResponse        * drsp        ; //[m_nb_dcache]
    425     bool                                * dreq_cached ; //[m_nb_dcache]
    426     uint32_t                            * dreq_num_cpu; //[m_nb_dcache]
    427 
    428     const uint32_t m_num_cache_LSB;
    429     const uint32_t m_num_cache_MSB;
    430           addr_40  m_num_cache_LSB_mask;
    431           addr_40  m_num_cache_mask;
     247    sc_signal<bool>         r_tgt_icache_req;           // coherence request to ICACHE
     248    sc_signal<bool>         r_tgt_dcache_req;           // coherence request to DCACHE
     249    sc_signal<data_t>     * r_tgt_buf;                  // [m_cache_words]
     250    sc_signal<be_t>       * r_tgt_be;                   // [m_cache_words]
     251
     252    sc_signal<int>          r_cleanup_fsm;              // send cleanup commands
     253    sc_signal<size_t>       r_cleanup_trdid;        // index for trdid
     254    GenericCam<vci_addr_t>  r_cleanup_buffer;       // registration buffer for cleanups
     255
     256    // ISS interface variables (used for communication
     257    // between transition() and print_trace() functions
     258    bool                                                        m_ireq_valid;
     259    uint32_t                                            m_ireq_addr;
     260    soclib::common::Iss2::ExecMode                  m_ireq_mode;
     261       
     262    bool                                                        m_irsp_valid;
     263    uint32_t                                            m_irsp_instruction;
     264    bool                                                        m_irsp_error;
     265       
     266    bool                                                        m_dreq_valid;
     267    uint32_t                                            m_dreq_addr;
     268    soclib::common::Iss2::ExecMode                  m_dreq_mode;
     269    soclib::common::Iss2::DataOperationType     m_dreq_type;
     270    uint32_t                                                m_dreq_wdata;
     271    uint8_t                                                     m_dreq_be;
     272
     273    bool                                                        m_drsp_valid;
     274    uint32_t                                                m_drsp_rdata;
     275    bool                                                        m_drsp_error;
     276
     277    // Activity counters (for power consumption evaluation)
     278    uint32_t   m_conso_dcache_data_read;           // DCACHE DATA READ activity
     279    uint32_t   m_conso_dcache_data_write;          // DCACHE DATA WRITE activity
     280    uint32_t   m_conso_dcache_dir_read;            // DCACHE DIR READ activity
     281    uint32_t   m_conso_dcache_dir_write;           // DCACHE DIR WRITE activity
     282                                                 
     283    uint32_t   m_conso_icache_data_read;           // ICACHE DATA READ activity
     284    uint32_t   m_conso_icache_data_write;          // ICACHE DATA WRITE activity
     285    uint32_t   m_conso_icache_dir_read;            // ICACHE DIR READ activity
     286    uint32_t   m_conso_icache_dir_write;           // ICACHE DIR WRITE activity
     287               
     288    uint32_t   m_conso_wbuf_read;                          // WBUF READ activity
     289    uint32_t   m_conso_wbuf_write;                         // WBUF WRITE activity
     290
     291    uint32_t   m_cpt_cc_update_icache;             // number of coherence update packets for icache
     292    uint32_t   m_cpt_cc_update_dcache;             // number of coherence update packets for dcache
     293    uint32_t   m_cpt_cc_inval_icache;              // number of coherence inval packets for icache
     294    uint32_t   m_cpt_cc_inval_dcache;              // number of coherence inval packets for dcache
     295    uint32_t   m_cpt_cc_inval_broadcast;           // number of coherence broadcast packets
     296               
     297    uint32_t   m_cpt_frz_cycles;                       // total number of cpu frozen cycles
     298    uint32_t   m_cpt_total_cycles;                     // total number of cycles from reset
     299    uint32_t   m_cpt_stop_simulation;                  // consecutive frozen cycles counter
     300               
     301    uint32_t   m_cpt_ins_cacheable;                // number of cacheable instructions
     302    uint32_t   m_cpt_ins_uncacheable;              // number of non cacheable instructions
     303    uint32_t   m_cpt_ins_miss;                     // number of cacheable instruction miss
     304               
     305    uint32_t   m_cpt_data_read_cacheable;          // number of cacheable data read
     306    uint32_t   m_cpt_data_read_miss;               // number of cacheable data read miss
     307    uint32_t   m_cpt_data_read_uncacheable;        // number of non cacheable data read
     308    uint32_t   m_cpt_data_write_cacheable;         // number of cacheable write
     309    uint32_t   m_cpt_data_write_uncacheable;       // number of non cacheable write
     310    uint32_t   m_cpt_data_write_hit;               // number of cacheable write making hit
     311    uint32_t   m_cpt_data_ll;                              // number of LL requests
     312    uint32_t   m_cpt_data_sc;                              // number of SC requests
     313
     314    uint32_t   m_cpt_xtn_dcache_inval;                 // dcache line invalidation request
     315    uint32_t   m_cpt_xtn_sync;                         // write buffer flush request
     316
     317    uint32_t   m_cost_write_frz;                   // number of frozen cycles related to write buffer
     318    uint32_t   m_cost_data_miss_frz;               // number of frozen cycles related to data miss
     319    uint32_t   m_cost_ins_miss_frz;                // number of frozen cycles related to ins miss
     320               
     321    uint32_t   m_cpt_imiss_transaction;            // number of VCI inst read miss transactions
     322    uint32_t   m_cpt_dmiss_transaction;            // number of VCI data read miss transactions
     323    uint32_t   m_cpt_iunc_transaction;             // number of VCI uncacheable inst read transactions
     324    uint32_t   m_cpt_dunc_transaction;             // number of VCI uncacheable data read transactions
     325    uint32_t   m_cpt_write_transaction;            // number of VCI write transactions
     326    uint32_t   m_cpt_sc_transaction;               // number of VCI sc transactions
     327               
     328    uint32_t   m_cost_imiss_transaction;           // cumulated duration for VCI IMISS transactions
     329    uint32_t   m_cost_dmiss_transaction;           // cumulated duration for VCI DMISS transactions
     330    uint32_t   m_cost_unc_transaction;             // cumulated duration for VCI UNC transactions
     331    uint32_t   m_cost_write_transaction;           // cumulated duration for VCI WRITE transactions
     332    uint32_t   m_length_write_transaction;         // cumulated length for VCI WRITE transactions
     333
     334
     335    uint32_t * m_cpt_fsm_dcache;                   // array of number of cycles per state
     336    uint32_t * m_cpt_fsm_icache;                   // array of number of cycles per state
     337    uint32_t * m_cpt_fsm_cmd;                      // array of number of cycles per state
     338    uint32_t * m_cpt_fsm_rsp;                      // array of number of cycles per state
     339    uint32_t * m_cpt_fsm_tgt;                      // array of number of cycles per state
     340    uint32_t * m_cpt_fsm_cleanup;                  // array of number of cycles per state
    432341
    433342protected:
     
    437346
    438347    VciCcXCacheWrapperV4(
    439                        sc_module_name insname,
    440                        int proc_id,
    441                        const soclib::common::MappingTable &mtp,
    442                        const soclib::common::MappingTable &mtc,
    443                        const soclib::common::IntTab &initiator_index_rw,
    444                        const soclib::common::IntTab &initiator_index_c,
    445                        const soclib::common::IntTab &target_index,
    446                        size_t nb_cpu,
    447                        size_t nb_dcache,
    448                        size_t icache_ways,
    449                        size_t icache_sets,
    450                        size_t icache_words,
    451                        size_t dcache_ways,
    452                        size_t dcache_sets,
    453                        size_t dcache_words,
    454                        size_t wbuf_nwords,
    455                        size_t wbuf_nlines
    456                          );
     348                       sc_module_name                           insname,
     349                       int                                      proc_id,
     350                       const soclib::common::MappingTable       &mtd,
     351                       const soclib::common::MappingTable       &mtc,
     352                       const soclib::common::IntTab             &initiator_index_d,
     353                       const soclib::common::IntTab             &initiator_index_c,
     354                       const soclib::common::IntTab             &target_index_c,
     355                       size_t                                   icache_ways,
     356                       size_t                                   icache_sets,
     357                       size_t                                   icache_words,
     358                       size_t                                   dcache_ways,
     359                       size_t                                   dcache_sets,
     360                       size_t                                   dcache_words,
     361                       size_t                                   wbuf_nwords,
     362                       size_t                                   wbuf_nlines,
     363                       uint32_t                                 max_frozen_cycles = 1000);
    457364
    458365    ~VciCcXCacheWrapperV4();
    459366
    460   void print_trace(size_t mode = 0);
    461   void print_cpi();
    462   void print_stats(bool print_wbuf=true, bool print_fsm=true);
    463 
    464   void stop_simulation (uint32_t);
    465   void log_transaction ( bool generate_file_icache
    466                         ,bool generate_file_dcache
    467                         ,bool generate_file_cmd
    468                         ,bool generate_file_tgt
    469                         ,bool generate_file_cleanup);
    470 
    471   void vhdl_testbench (bool generate_file_mwbuf);
     367    void print_trace(size_t mode = 0);
     368    void print_cpi();
     369    void print_stats(bool print_wbuf=true, bool print_fsm=true);
    472370
    473371private:
     
    475373    void transition();
    476374    void genMoore();
    477 
    478     uint32_t get_num_cache     (addr_40 & addr);
    479     uint32_t get_num_cache_only(addr_40   addr);
    480     void     set_num_cache     (addr_40 & addr, uint32_t num_cache);
    481     addr_40  set_num_cache_only(addr_40   addr, uint32_t num_cache);
    482375
    483376    soclib_static_assert((int)iss_t::SC_ATOMIC     == (int)vci_param::STORE_COND_ATOMIC);
     
    487380}}
    488381
    489 #endif /* SOCLIB_CABA_VCI_CC_XCACHE_WRAPPER_V4_H */
     382#endif /* SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER_V4_H */
    490383
    491384// Local Variables:
  • trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp

    r175 r188  
    11/* -*- c++ -*-
     2 * File         : vci_cc_xcache_wrapper_v4.cpp
     3 * Date         : 26/11/2011
     4 * Copyright    : UPMC / LIP6
     5 * Authors      : Alain Greiner
    26 *
    37 * SOCLIB_LGPL_HEADER_BEGIN
     
    2125 * SOCLIB_LGPL_HEADER_END
    2226 *
    23  * Copyright (c) UPMC, Lip6, SoC
    24  *         Alain Greiner <alain.greiner@lip6.fr>, 2008
     27 * Copyright (c) UPMC, Lip6
     28 *         Alain Greiner <alain.greiner@lip6.fr>, 2011
    2529 *
    26  * Maintainers: alain eric.guthmuller@polytechnique.edu nipo
     30 * Maintainers: alain
    2731 */
    2832
    29 /////////////////////////////////////////////////////////////////////////////
    30 // History
    31 // - 25/04/2008
    32 //   The existing vci_xcache component has been extended to include
    33 //   a VCI target port to support a directory based coherence protocol.
    34 //   Two types of packets can be send by the L2 cache to the L1 cache
    35 //   * INVALIDATE packets : length = 1
    36 //   * UPDATE packets : length = n + 2   
    37 //   The CLEANUP packets are sent by the L1 cache to the L2 cache,
    38 //   to signal a replaced cache line.
    39 // - 12/08/2008
    40 //   The vci_cc_xcache_wrapper component instanciates directly the processsor
    41 //   iss, in order to supress the processor/cache interface.
    42 //   According to the VCI advanced specification, this component uses one
    43 //   word VCI CMD packets for MISS transactions, and accept one word VCI RSP
    44 //   packets for Write burst  transactions.
    45 //   The write buffer has been modified to use the WriteBuffer object.
    46 //   A VCI write burst is constructed when two conditions are satisfied :
    47 //   The processor make strictly successive write requests, and they are
    48 //   in the same cache line. The write buffer performs re-ordering, to
    49 //   respect the contiguous addresses VCI constraint. In case of several
    50 //   WRITE_WORD requests in the same word, only the last request is conserved.
    51 //   In case of several WRITE_HALF or WRITE_WORD requests in the same word,
    52 //   the requests are merged in the same word. In case of uncached write
    53 //   requests, each request is transmited as a single VCI transaction.
    54 //   Both the data & instruction caches can be flushed in one single cycle.
    55 ///////////////////////////////////////////////////////////////////////////////
    56 
    57 #include <iomanip>
    58 #include "arithmetics.h"
    59 #include "size.h"
    6033#include "../include/vci_cc_xcache_wrapper_v4.h"
    61 namespace soclib {
    62   namespace caba {
     34
     35#define DEBUG_GLOBAL            0
     36#define DEBUG_DCACHE            0
     37#define DEBUG_ICACHE            0
     38
     39#define DEBUG_START_CYCLE       0
     40#define DEBUG_ID                    0
     41
     42namespace soclib { namespace caba {
     43
    6344    namespace {
    64 
    65 // =====[ DEBUG ]====================================
    66 
    67 #define ASSERT_VERBOSE
    68 #define ASSERT_NCYCLES m_cpt_total_cycles
    69 
    70 #include "debug.h"
    71 
    72 #if CC_XCACHE_WRAPPER_DEBUG
    73 # define PRINTF(msg...) PRINTF_COND(m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN,msg)
    74 #else
    75 # define PRINTF(msg...)
    76 #endif
    77 
    78 /////////////////////////////////////////////////////////////////////
    79 // Management of address stocked in icache/dcache/mwbuf in case
    80 // of multiple bank implementation
    81 /////////////////////////////////////////////////////////////////////
    82 
    83 // =====[ MULTI_CACHE ]==============================
    84 
    85 #if (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    86 # define get_num_icache(     addr,num_cpu)   get_num_cache     (addr)         
    87 # define get_num_icache_only(addr,num_cpu)   get_num_cache_only(addr)         
    88 # define set_num_icache(     addr,num_cache) set_num_cache     (addr,num_cache)
    89 # define set_num_icache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
    90 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    91 # define get_num_icache(     addr,num_cpu)   num_cpu
    92 # define get_num_icache_only(addr,num_cpu)   num_cpu
    93 # define set_num_icache(     addr,num_cache) do  {} while (0)
    94 # define set_num_icache_only(addr,num_cache) addr
    95 #else
    96 #error "Invalid value to CC_XCACHE_WRAPPER_MULTI_CACHE"
    97 #endif
    98 # define get_num_dcache(     addr)           get_num_cache     (addr)         
    99 # define get_num_dcache_only(addr)           get_num_cache_only(addr)         
    100 # define set_num_dcache(     addr,num_cache) set_num_cache     (addr,num_cache)
    101 # define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
    102 
    103       const char *dcache_fsm_state_str[] = {
     45      const char *dcache_fsm_state_str[] =
     46      {
    10447        "DCACHE_IDLE",
    10548        "DCACHE_WRITE_UPDT",
     
    10851        "DCACHE_MISS_UPDT",
    10952        "DCACHE_UNC_WAIT",
    110         "DCACHE_SC_WAIT",
    11153        "DCACHE_INVAL",
     54        "DCACHE_INVAL_GO",
    11255        "DCACHE_SYNC",
    11356        "DCACHE_ERROR",
    11457        "DCACHE_CC_CHECK",
    11558        "DCACHE_CC_INVAL",
    116         "DCACHE_CC_CLEANUP",
     59        "DCACHE_CC_UPDT",
    11760      };
    118       const char *icache_fsm_state_str[] = {
     61      const char *icache_fsm_state_str[] =
     62      {
    11963        "ICACHE_IDLE",
    12064        "ICACHE_MISS_VICTIM",
     
    12367        "ICACHE_UNC_WAIT",
    12468        "ICACHE_ERROR",
    125         "ICACHE_CC_CLEANUP",
    12669        "ICACHE_CC_CHECK",
    12770        "ICACHE_CC_INVAL",
     71        "ICACHE_CC_UPDT",
    12872      };
    129       const char *cmd_fsm_state_str[] = {
     73      const char *cmd_fsm_state_str[] =
     74      {
    13075        "CMD_IDLE",
    13176        "CMD_INS_MISS",
     
    13681        "CMD_DATA_SC",
    13782      };
    138       const char *rsp_fsm_state_str[] = {
     83      const char *rsp_fsm_state_str[] =
     84      {
    13985        "RSP_IDLE",
    14086        "RSP_INS_MISS",
     
    14591        "RSP_DATA_SC",
    14692      };
    147       const char *tgt_fsm_state_str[] = {
     93      const char *tgt_fsm_state_str[] =
     94      {
    14895        "TGT_IDLE",
    14996        "TGT_UPDT_WORD",
     
    157104      };
    158105
    159       const char *cleanup_fsm_state_str[] = {
    160         "CLEANUP_IDLE",
    161         "CLEANUP_REQ",
    162         "CLEANUP_RSP_DCACHE",
    163         "CLEANUP_RSP_ICACHE",
     106      const char *cleanup_fsm_state_str[] =
     107      {
     108        "CLEANUP_DATA_IDLE",
     109        "CLEANUP_DATA_GO",
     110        "CLEANUP_INS_IDLE",
     111        "CLEANUP_INS_GO",
    164112      };
    165113    }
    166114
    167     typedef long long unsigned int blob_t;
    168 
    169 #define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
    170 
    171     using soclib::common::uint32_log2;
    172 
    173     /////////////////////////////////
    174     tmpl(/**/)::VciCcXCacheWrapperV4(
    175                                      /////////////////////////////////
    176                                      sc_module_name name,
    177                                      int proc_id,
    178                                      const soclib::common::MappingTable &mtp,
    179                                      const soclib::common::MappingTable &mtc,
    180                                      const soclib::common::IntTab &initiator_index_rw,
    181                                      const soclib::common::IntTab &initiator_index_c,
    182                                      const soclib::common::IntTab &target_index,
    183                                      size_t nb_cpu,
    184                                      size_t nb_dcache,
    185                                      size_t icache_ways,
    186                                      size_t icache_sets,
    187                                      size_t icache_words,
    188                                      size_t dcache_ways,
    189                                      size_t dcache_sets,
    190                                      size_t dcache_words,
    191                                      size_t wbuf_nwords,
    192                                      size_t wbuf_nlines
    193                                      )
    194                :
    195                soclib::caba::BaseModule(name),
    196 
    197                p_clk       ("clk"),
    198                p_resetn    ("resetn"),
    199                p_vci_ini_rw("vci_ini_rw"),
    200                p_vci_ini_c ("vci_ini_c"),
    201                p_vci_tgt   ("vci_tgt"),
    202 
    203                m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
    204                m_segment(mtc.getSegment(target_index)),
    205                m_srcid_rw(mtp.indexForId(initiator_index_rw)),
    206                m_srcid_c(mtc.indexForId(initiator_index_c)),
    207 
    208                m_nb_cpu(nb_cpu),
    209 #if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    210                m_nb_icache(nb_dcache),
    211 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    212                m_nb_icache(m_nb_cpu),
     115#define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
     116
     117using soclib::common::uint32_log2;
     118
     119/////////////////////////////////
     120tmpl(/**/)::VciCcXCacheWrapperV4(
     121    sc_module_name                      name,
     122    int                                 proc_id,
     123    const soclib::common::MappingTable  &mtp,
     124    const soclib::common::MappingTable  &mtc,
     125    const soclib::common::IntTab        &initiator_index_d,
     126    const soclib::common::IntTab        &initiator_index_c,
     127    const soclib::common::IntTab        &target_index_c,
     128    size_t                              icache_ways,
     129    size_t                              icache_sets,
     130    size_t                              icache_words,
     131    size_t                              dcache_ways,
     132    size_t                              dcache_sets,
     133    size_t                              dcache_words,
     134    size_t                              wbuf_nwords,
     135    size_t                              wbuf_nlines,
     136    uint32_t                                        max_frozen_cycles)
     137     :
     138     soclib::caba::BaseModule(name),
     139
     140     p_clk       ("clk"),
     141     p_resetn    ("resetn"),
     142     p_vci_ini_d ("vci_ini_d"),
     143     p_vci_ini_c ("vci_ini_c"),
     144     p_vci_tgt_c ("vci_tgt_c"),
     145
     146     m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
     147     m_segment(mtc.getSegment(target_index_c)),
     148     m_srcid_d(mtp.indexForId(initiator_index_d)),
     149     m_srcid_c(mtc.indexForId(initiator_index_c)),
     150
     151     m_dcache_ways(dcache_ways),
     152     m_icache_ways(icache_ways),
     153
     154     m_cache_words(icache_words),
     155     m_cache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))),
     156     m_cache_yzmask((~0)<<m_cache_words_shift),
     157
     158     m_max_frozen_cycles(max_frozen_cycles),
     159
     160     r_icache_fsm("r_icache_fsm"),
     161     r_icache_fsm_save("r_icache_fsm_save"),
     162     r_icache_addr_save("r_icache_addr_save"),
     163     r_icache_miss_req("r_icache_miss_req"),
     164     r_icache_unc_req("r_icache_unc_req"),
     165     r_icache_cleanup_req("r_icache_cleanup_req"),
     166     r_icache_cleanup_line("r_icache_cleanup_line"),
     167     r_icache_cleanup_way("r_icache_cleanup_way"),
     168     r_icache_cleanup_set("r_icache_cleanup_set"),
     169     r_icache_miss_inval("r_icache_miss_inval"),
     170     r_icache_update_word("r_icache_update_word"),
     171
     172     r_dcache_fsm("r_dcache_fsm"),
     173     r_dcache_fsm_save("r_dcache_fsm_save"),
     174     r_dcache_addr_save("r_dcache_addr_save"),
     175     r_dcache_wdata_save("r_dcache_wdata_save"),
     176     r_dcache_be_save("r_dcache_be_save"),
     177     r_dcache_way_save("r_dcache_way_save"),
     178     r_dcache_set_save("r_dcache_set_save"),
     179     r_dcache_word_save("r_dcache_word_save"),
     180     r_dcache_cleanup_req("r_dcache_cleanup_req"),
     181     r_dcache_cleanup_line("r_dcache_cleanup_line"),
     182     r_dcache_cleanup_way("r_dcache_cleanup_way"),
     183     r_dcache_cleanup_set("r_dcache_cleanup_set"),
     184     r_dcache_miss_req("r_dcache_miss_req"),
     185     r_dcache_unc_req("r_dcache_unc_req"),
     186     r_dcache_sc_req("r_dcache_sc_req"),
     187     r_dcache_miss_inval("r_dcache_miss_inval"),
     188     r_dcache_update_word("r_dcache_update_word"),
     189     r_dcache_ll_data("r_dcache_ll_data"),
     190     r_dcache_ll_addr("r_dcache_ll_addr"),
     191     r_dcache_ll_valid("r_dcache_ll_valid"),
     192
     193     r_vci_cmd_fsm("r_vci_cmd_fsm"),
     194     r_vci_cmd_min("r_vci_cmd_min"),
     195     r_vci_cmd_max("r_vci_cmd_max"),
     196     r_vci_cmd_cpt("r_vci_cmd_cpt"),
     197     r_vci_cmd_imiss_prio("r_vci_cmd_imiss_prio"),
     198
     199     r_vci_rsp_fsm("r_vci_rsp_fsm"),
     200     r_vci_rsp_cpt("r_vci_rsp_cpt"),
     201     r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
     202     r_vci_rsp_data_error("r_vci_rsp_data_error"),
     203     r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache" ,2),     // two words depth
     204     r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache" ,2),     // two words depth
     205
     206     r_tgt_fsm("r_tgt_fsm"),
     207     r_tgt_icache_rsp("r_tgt_icache_rsp"),
     208     r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
     209     r_tgt_addr("r_tgt_daddr"),
     210     r_tgt_word_min("r_tgt_word_min"),
     211     r_tgt_word_max("r_tgt_word_max"),
     212     r_tgt_word_count("r_tgt_word_count"),
     213     r_tgt_update("r_tgt_update"),
     214     r_tgt_update_data("r_tgt_update_data"),
     215     r_tgt_srcid("r_tgt_srcid"),
     216     r_tgt_pktid("r_tgt_pktid"),
     217     r_tgt_trdid("r_tgt_trdid"),
     218     r_tgt_icache_req("r_tgt_icache_req"),
     219     r_tgt_dcache_req("r_tgt_dcache_req"),
     220
     221     r_cleanup_fsm("r_cleanup_fsm"),
     222     r_cleanup_trdid("r_cleanup_trdid"),
     223     r_cleanup_buffer(16)                   // up to 16 simultaneous cleanup transactions
     224{
     225    assert( ((icache_words*vci_param::B) < (1<<vci_param::K)) and
     226             "Need more PLEN bits.");
     227
     228    assert( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines)) and
     229             "Need more TRDID bits.");
     230
     231    assert( (icache_words == dcache_words) and
     232             "icache_words must be equal at dcache_words.");
     233
     234    p_irq  = new sc_in<bool> [iss_t::n_irq];
     235
     236    r_iss     = new iss_t (this->name() , proc_id);
     237    r_icache  = new GenericCache<vci_addr_t>("icache", icache_ways, icache_sets, icache_words);
     238    r_dcache  = new GenericCache<vci_addr_t>("dcache", dcache_ways, dcache_sets, dcache_words);
     239    r_wbuf    = new MultiWriteBuffer<vci_addr_t>("wbuf", wbuf_nwords, wbuf_nlines, dcache_words);
     240               
     241    r_tgt_buf = new sc_signal<data_t> [m_cache_words];
     242    r_tgt_be  = new sc_signal<be_t>   [m_cache_words];
     243
     244    m_cpt_fsm_dcache  = new uint32_t [32];
     245    m_cpt_fsm_icache  = new uint32_t [32];
     246    m_cpt_fsm_cmd     = new uint32_t [32];
     247    m_cpt_fsm_rsp     = new uint32_t [32];
     248    m_cpt_fsm_tgt     = new uint32_t [32];
     249    m_cpt_fsm_cleanup = new uint32_t [32];
     250
     251    SC_METHOD(transition);
     252    dont_initialize();
     253    sensitive << p_clk.pos();
     254
     255    SC_METHOD(genMoore);
     256    dont_initialize();
     257    sensitive << p_clk.neg();
     258
     259    typename iss_t::CacheInfo cache_info;
     260    cache_info.has_mmu          = false;
     261    cache_info.icache_line_size = icache_words*sizeof(data_t);
     262    cache_info.icache_assoc     = icache_ways;
     263    cache_info.icache_n_lines   = icache_sets;
     264    cache_info.dcache_line_size = dcache_words*sizeof(data_t);
     265    cache_info.dcache_assoc     = dcache_ways;
     266    cache_info.dcache_n_lines   = dcache_sets;
     267
     268    r_iss->setCacheInfo(cache_info);
     269   
     270} // end constructor
     271
     272///////////////////////////////////
     273tmpl(/**/)::~VciCcXCacheWrapperV4()
     274{
     275    delete r_icache ;
     276    delete r_wbuf   ;
     277    delete r_dcache ;
     278    delete r_iss;
     279    delete [] p_irq;
     280    delete [] r_tgt_buf;
     281    delete [] r_tgt_be;
     282}
     283
     284////////////////////////
     285tmpl(void)::print_cpi()
     286{
     287    std::cout << "CPU " << m_srcid_d << " : CPI = "
     288              << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles)
     289              << std::endl ;
     290}
     291
     292/*
     293
     294////////////////////////////////////////////////////////
     295tmpl(void)::print_stats(bool print_wbuf, bool print_fsm)
     296{
     297    std::cout << "------------------------------------" << std:: dec << std::endl;
     298    std::cout << "CPU " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl;
     299
     300    float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
     301
     302    std::cout << "- CPI                            : "
     303              << (float)m_cpt_total_cycles/run_cycles << std::endl ;
     304
     305    std::cout << "- CACHABLE INSTRUCTIONS          : "
     306              << m_cpt_ins_cacheable << std::endl ;
     307
     308    std::cout << "- INSTRUCTION CACHE MISS RATE    : "
     309              << (float)m_cpt_ins_miss*100.0/(float)m_cpt_ins_cacheable
     310              << " %" << std::endl ;
     311
     312    std::cout << "- NON CACHABLE INSTRUCTIONS      : "
     313              << m_cpt_ins_uncacheable << std::endl ;
     314
     315    std::cout << "- CACHABLE DATA READ             : "
     316              << m_cpt_data_read_cacheable << std::endl;
     317
     318    std::cout << "- DATA CACHE MISS RATE           : "
     319              << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cacheable
     320              << " %" << std::endl;
     321
     322    std::cout << "- CACHABLE DATA WRITE            : "
     323              << m_cpt_data_write_cacheable << std::endl ;
     324
     325    std::cout << "- CACHED WRITE RATE              : "
     326              << (float)m_cpt_data_write_hit*100.0/(float)m_cpt_data_write_cacheable
     327              << " %" << std::endl;
     328
     329    std::cout << "- NON CACHABLE DATA READ         : "
     330              << m_cpt_data_read_uncacheable << std::endl;
     331
     332    std::cout << "- NON CACHABLE DATA WRITE        : "
     333              << m_cpt_data_write_uncacheable << std::endl;
     334
     335    std::cout << "- WRITE RATE                     : "
     336              << (float)m_cpt_data_write_cacheable*100.0/(float)m_cpt_ins_cacheable
     337              << " %" << std::endl;
     338
     339    std::cout << "- READ RATE                      : "
     340              << (float)m_cpt_data_read_cacheable*100.0/(float)m_cpt_ins_cacheable
     341              << " %" << std::endl;
     342
     343    std::cout << "- AVERAGE INSTRUCTION MISS COST  : "
     344              << (float)m_cost_ins_miss_frz/(float)m_cpt_ins_miss << std::endl;
     345
     346    std::cout << "- AVERAGE DATA MISS COST         : "
     347              << (float)m_cost_data_miss_frz/m_cpt_data_read_miss << std::endl;
     348
     349    std::cout << "- AVERAGE WRITE COST             : "
     350              << (float)m_cost_write_frz/m_cpt_data_write_cacheable << std::endl;
     351
     352    std::cout << "- CC_UPDATE_ICACHE               : "
     353              << m_cpt_cc_update_icache  << std::endl;
     354
     355    std::cout << "- CC_UPDATE_DCACHE               : "
     356              << m_cpt_cc_update_dcache  << std::endl;
     357
     358    std::cout << "- CC_INVAL_ICACHE                : "
     359              << m_cpt_cc_inval_icache << std::endl;
     360
     361    std::cout << "- CC_INVAL_ICACHE                : "
     362              << m_cpt_cc_inval_icache << std::endl;
     363
     364    std::cout << "-CC_BROADCAST                    : "
     365              << m_cpt_cc_inval_broadcast << std::endl;
     366
     367//  this part is removed because soclib::common::size() not found ...
     368
     369    if (print_fsm)
     370    {
     371        std::cout << "- DCACHE FSM" << std::endl;
     372        for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
     373            std::cout << "  + "  << dcache_fsm_state_str[i] << " : "
     374                      << m_cpt_fsm_dcache [i] << std::endl;
     375
     376        std::cout << "- ICACHE FSM" << std::endl;
     377        for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
     378            std::cout << "  + "  << icache_fsm_state_str[i] << " : "
     379                      << m_cpt_fsm_icache [i] << std::endl;
     380
     381        std::cout << "- CMD FSM" << std::endl;
     382        for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i)
     383            std::cout << "  + " << cmd_fsm_state_str[i] << " : "
     384                      << m_cpt_fsm_cmd [i] << std::endl;
     385
     386        std::cout << "- RSP FSM" << std::endl;
     387        for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i)
     388            std::cout << "  + " << rsp_fsm_state_str[i] << " : "
     389                      << m_cpt_fsm_rsp [i] << std::endl;
     390
     391        std::cout << "- TGT FSM" << std::endl;
     392        for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i)
     393            std::cout << "  + "  << tgt_fsm_state_str[i] << " : "
     394                      << m_cpt_fsm_tgt [i] << std::endl;
     395
     396        std::cout << "- CLEANUP FSM" << std::endl;
     397        for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i)
     398            std::cout << "  + "  << cleanup_fsm_state_str[i] << " : "
     399                      << m_cpt_fsm_cleanup [i] << std::endl;
     400    }
     401
     402    if (print_wbuf) r_wbuf->printStatistics();
     403}
     404
     405*/
     406////////////////////////////////////
     407tmpl(void)::print_trace(size_t mode)
     408{
     409    // b0 : write buffer print trace
     410    // b1 : write buffer verbose
     411    // b2 : dcache print trace
     412    // b3 : icache print trace
     413
     414    typename iss_t::InstructionRequest  ireq;
     415    typename iss_t::InstructionResponse irsp;
     416    typename iss_t::DataRequest         dreq;
     417    typename iss_t::DataResponse        drsp;
     418
     419    ireq.valid       = m_ireq_valid;
     420    ireq.addr        = m_ireq_addr;
     421    ireq.mode        = m_ireq_mode;
     422
     423    irsp.valid       = m_irsp_valid;
     424    irsp.instruction = m_irsp_instruction;
     425    irsp.error       = m_irsp_error;
     426
     427    dreq.valid       = m_dreq_valid;
     428    dreq.addr        = m_dreq_addr;
     429    dreq.mode        = m_dreq_mode;
     430    dreq.type        = m_dreq_type;
     431    dreq.wdata       = m_dreq_wdata;
     432    dreq.be          = m_dreq_be;
     433
     434    drsp.valid       = m_drsp_valid;
     435    drsp.rdata       = m_drsp_rdata;
     436    drsp.error       = m_drsp_error;
     437
     438    std::cout << std::dec << "Proc " << name() << std::endl;
     439
     440    std::cout << "  " << ireq << std::endl;
     441    std::cout << "  " << irsp << std::endl;
     442    std::cout << "  " << dreq << std::endl;
     443    std::cout << "  " << drsp << std::endl;
     444 
     445    std::cout << "  " << icache_fsm_state_str[r_icache_fsm.read()]
     446              << " | " << dcache_fsm_state_str[r_dcache_fsm.read()]
     447              << " | " << cmd_fsm_state_str[r_vci_cmd_fsm.read()]
     448              << " | " << rsp_fsm_state_str[r_vci_rsp_fsm.read()]
     449              << " | " << tgt_fsm_state_str[r_tgt_fsm.read()]
     450              << " | " << cleanup_fsm_state_str[r_cleanup_fsm.read()] << std::endl;
     451
     452    if(mode & 0x1)
     453    {
     454        std::cout << "  Write Buffer" << std::endl;
     455        r_wbuf->printTrace((mode>>1)&1);
     456    }
     457    if(mode & 0x4)
     458    {
     459        std::cout << "  Data cache" << std::endl;
     460        r_dcache->printTrace();
     461    }
     462    if(mode & 0x8)
     463    {
     464        std::cout << "  Instruction cache" << std::endl;
     465        r_icache->printTrace();
     466    }
     467}
     468
     469//////////////////////////
     470tmpl(void)::transition()
     471//////////////////////////
     472{
     473    // Reset
     474    if ( not p_resetn.read() )
     475    {
     476        // iss, write buffer & caches
     477        r_iss->reset();
     478        r_wbuf->reset();
     479        r_dcache->reset();
     480        r_icache->reset();
     481        r_cleanup_buffer.reset();
     482
     483        // FSM states
     484        r_icache_fsm                = ICACHE_IDLE;
     485        r_dcache_fsm                = DCACHE_IDLE;
     486        r_vci_cmd_fsm               = CMD_IDLE;
     487        r_vci_rsp_fsm               = RSP_IDLE;
     488        r_tgt_fsm                   = TGT_IDLE;
     489        r_cleanup_fsm               = CLEANUP_DATA_IDLE;
     490
     491        // synchronisation flip-flops between TGT FSM and ICACHE/DCACHE FSMs
     492        r_tgt_icache_req            = false;
     493        r_tgt_dcache_req            = false;
     494
     495        // synchronisation flip-flops between ICACHE/DCACHE FSMs and CLEANUP FSM
     496        r_icache_cleanup_req        = false;
     497        r_dcache_cleanup_req        = false;
     498
     499        // synchronisation flip-flops between ICACHE FSMs and VCI FSMs
     500        r_icache_miss_req           = false;
     501        r_icache_unc_req            = false;
     502        r_icache_miss_inval         = false;
     503        r_vci_rsp_ins_error         = false;
     504
     505        // synchronisation flip-flops between DCACHE FSMs and VCI FSMs
     506        r_dcache_miss_req           = false;
     507        r_dcache_unc_req            = false;
     508        r_dcache_sc_req             = false;
     509        r_dcache_miss_inval         = false;
     510        r_vci_rsp_data_error        = false;
     511
     512        // pending non cacheable write
     513        r_dcache_pending_unc_write  = false;
     514
     515        // linked load reservation flip-flop
     516        r_dcache_ll_valid           = false;
     517
     518        // uncacheable read buffers
     519        r_icache_unc_valid          = false;
     520        r_dcache_unc_valid          = false;
     521
     522        // response FIFOs
     523        r_vci_rsp_fifo_icache.init();
     524        r_vci_rsp_fifo_dcache.init();
     525     
     526        // activity counters (consommation)
     527        m_conso_dcache_data_read     = 0;
     528        m_conso_dcache_data_write    = 0;
     529        m_conso_dcache_dir_read      = 0;
     530        m_conso_dcache_dir_write     = 0;
     531
     532        m_conso_icache_data_read     = 0;
     533        m_conso_icache_data_write    = 0;
     534        m_conso_icache_dir_read      = 0;
     535        m_conso_icache_dir_write     = 0;
     536
     537        m_conso_wbuf_read            = 0;
     538        m_conso_wbuf_write           = 0;
     539
     540        // coherence request counters
     541        m_cpt_cc_update_icache       = 0;
     542        m_cpt_cc_update_dcache       = 0;
     543        m_cpt_cc_inval_icache        = 0;
     544        m_cpt_cc_inval_dcache        = 0;
     545        m_cpt_cc_inval_broadcast     = 0;
     546
     547        // CPI computation
     548        m_cpt_frz_cycles             = 0;
     549        m_cpt_total_cycles           = 0;
     550        m_cpt_stop_simulation        = 0;
     551
     552        // number of executed instructions
     553        m_cpt_ins_cacheable          = 0;
     554        m_cpt_ins_uncacheable        = 0;
     555        m_cpt_ins_miss               = 0;
     556
     557        // number of data requests
     558        m_cpt_data_read_cacheable    = 0;
     559        m_cpt_data_read_miss         = 0;
     560        m_cpt_data_read_uncacheable  = 0;
     561        m_cpt_data_write_cacheable   = 0;
     562        m_cpt_data_write_uncacheable = 0;
     563        m_cpt_data_write_hit         = 0;
     564        m_cpt_data_ll                = 0;
     565        m_cpt_data_sc                = 0;
     566
     567        // number of external register requests
     568        m_cpt_xtn_dcache_inval       = 0;
     569        m_cpt_xtn_sync               = 0;
     570
     571        // cumulated cost (frozen cycles) for write and miss
     572        m_cost_write_frz             = 0;
     573        m_cost_data_miss_frz         = 0;
     574        m_cost_ins_miss_frz          = 0;
     575
     576        m_cpt_imiss_transaction      = 0;
     577        m_cpt_dmiss_transaction      = 0;
     578        m_cpt_iunc_transaction       = 0;
     579        m_cpt_dunc_transaction       = 0;
     580        m_cpt_write_transaction      = 0;
     581        m_cpt_sc_transaction         = 0;
     582
     583        m_cost_imiss_transaction    = 0;
     584        m_cost_dmiss_transaction    = 0;
     585        m_cost_unc_transaction      = 0;
     586        m_cost_write_transaction    = 0;
     587        m_length_write_transaction  = 0;
     588
     589        for (uint32_t i=0; i<32 ; ++i)
     590            m_cpt_fsm_icache  [i]   = 0;
     591        for (uint32_t i=0; i<32 ; ++i)
     592            m_cpt_fsm_dcache  [i]   = 0;
     593        for (uint32_t i=0; i<32 ; ++i)
     594            m_cpt_fsm_cmd     [i]   = 0;
     595        for (uint32_t i=0; i<32 ; ++i)
     596            m_cpt_fsm_rsp     [i]   = 0;
     597        for (uint32_t i=0; i<32 ; ++i)
     598            m_cpt_fsm_tgt     [i]   = 0;
     599        for (uint32_t i=0; i<32 ; ++i)
     600            m_cpt_fsm_cleanup [i]   = 0;
     601
     602        return;
     603    }
     604
     605    // Response FIFOs default values
     606    bool     vci_rsp_fifo_icache_get       = false;
     607    bool     vci_rsp_fifo_icache_put       = false;
     608    data_t   vci_rsp_fifo_icache_data      = 0;
     609
     610    bool     vci_rsp_fifo_dcache_get       = false;
     611    bool     vci_rsp_fifo_dcache_put       = false;
     612    data_t   vci_rsp_fifo_dcache_data      = 0;
     613
     614    // FSMs activity
     615    m_cpt_fsm_dcache  [r_dcache_fsm.read() ] ++;
     616    m_cpt_fsm_icache  [r_icache_fsm.read() ] ++;
     617    m_cpt_fsm_cmd     [r_vci_cmd_fsm.read()] ++;
     618    m_cpt_fsm_rsp     [r_vci_rsp_fsm.read()] ++;
     619    m_cpt_fsm_tgt     [r_tgt_fsm.read()    ] ++;
     620    m_cpt_fsm_cleanup [r_cleanup_fsm.read()] ++;
     621
     622    m_cpt_total_cycles++;
     623
     624    //////////////////////////////////////////////////////////////////////////////
     625    // The TGT_FSM receives the coherence requests.
     626    // It controls the following ressources:
     627    // - r_tgt_fsm
     628    // - r_tgt_buf[nwords]
     629    // - r_tgt_be[nwords]
     630    // - r_tgt_update
     631    // - r_tgt_word_min
     632    // - r_tgt_word_max
     633    // - r_tgt_word_count
     634    // - r_tgt_addr
     635    // - r_tgt_srcid
     636    // - r_tgt_trdid
     637    // - r_tgt_pktid
     638    // - r_tgt_icache_req (set)
     639    // - r_tgt_dcache_req (set)
     640    //
     641    // All VCI commands must be CMD_WRITE.
     642    // - If the 2 LSB bits of the VCI address are 11, it is a broadcast request.
     643    //   It is a multicast request otherwise.
     644    // - For multicast requests, the ADDRESS[2] bit distinguishes DATA/INS
     645    //   (0 for data / 1 for instruction), and the ADDRESS[3] bit distinguishes
     646    //   INVAL/UPDATE (0 for invalidate / 1 for UPDATE).
     647    //
     648    // For all types of coherence resqests, the line index (i.e. the Z & Y fields)
     649    // is coded on 34 bits, and is contained in the WDATA and BE fields
     650    // of the first VCI flit.
     651    // -  for a multicast invalidate or for a broadcast invalidate request
     652    //    the VCI packet length is 1 word.
     653    // -  for an update request the VCI packet length is (n+2) words.
     654    //    The WDATA field of the second VCI word contains the word index.
     655    //    The WDATA field of the n following words contains the values.
     656    // -  for all transaction types, the VCI response is one single word.
     657    // In case of errors in the VCI command packet, the simulation
     658    // is stopped with an error message.
     659    //
     660    // This FSM is NOT pipelined : It consumes a new request on the VCI port
     661    // only when the previous request is completed.
     662    //
     663    // The VCI_TGT FSM stores the external request arguments in the
     664    // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
     665    // and/or the r_tgt_dcache_req flip-flops to signal the coherence request
     666    // to the ICACHE & DCACHE FSMs in the REQ_ICACHE, REQ_DCACHE & REQ_BROADCAST
     667    // states. It waits the completion of the coherence request  by polling the
     668    // r_tgt_*cache_req flip-flops in the RSP_ICACHE, RSP_DCACHE & RSP_BROADCAST
     669    // states. These flip-flops are reset by the ICACHE_FSM and/or DCACHE_FSM.
     670    // These two FSMs signal if a VCI answer must be send by setting
     671    // the r_tgt_icache_rsp and/or the r_tgt_dcache_rsp flip_flops.
     672    ///////////////////////////////////////////////////////////////////////////////
     673
     674    switch( r_tgt_fsm.read() )
     675    {
     676        //////////////
     677        case TGT_IDLE:
     678        {
     679            vci_addr_t tgt_addr;
     680           
     681            if ( p_vci_tgt_c.cmdval.read() )
     682            {
     683                vci_addr_t address = p_vci_tgt_c.address.read();
     684
     685                if ( p_vci_tgt_c.cmd.read() != vci_param::CMD_WRITE)
     686                {
     687                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     688                              << name() << std::endl;
     689                    std::cout << "coherence request is not a write"
     690                              << std::endl;
     691                    exit(0);
     692                }
     693
     694                // address checking for multi-update or multi-invalidate
     695                if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) )
     696                {
     697                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     698                              << name() << std::endl;
     699                    std::cout << "out of segment coherence request"
     700                              << std::endl;
     701                    exit(0);
     702                }
     703           
     704                // address of the target cache line = nline * m_cache_words * 4
     705                tgt_addr  = (vci_addr_t)(((((uint64_t)p_vci_tgt_c.be.read() & 0x3) << 32) |
     706                                  (uint64_t)p_vci_tgt_c.wdata.read() ) << m_cache_words_shift);
     707
     708                r_tgt_srcid     = p_vci_tgt_c.srcid.read();
     709                r_tgt_trdid     = p_vci_tgt_c.trdid.read();
     710                r_tgt_pktid     = p_vci_tgt_c.pktid.read();
     711                r_tgt_addr      = tgt_addr;             // target line (for *CACHE FSMs)
     712                   
     713                if ( (address&0x3) == 0x3 )   // broadcast invalidate
     714                {
     715                    if ( not p_vci_tgt_c.eop.read() )
     716                    {
     717                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     718                                  << name() << std::endl;
     719                        std::cout << "the BROADCAST INVALIDATE command length must be one word"
     720                                  << std::endl;
     721                        exit(0);
     722                    }
     723                    r_tgt_update = false;
     724                    r_tgt_fsm = TGT_REQ_BROADCAST;
     725
     726                    m_cpt_cc_inval_broadcast++ ;
     727                }
     728                else                    // multi-update or multi-invalidate
     729                {
     730                    uint32_t cell = address - m_segment.baseAddress();
     731                    if (cell == 0)                           // invalidate data
     732                    {
     733                        if ( not p_vci_tgt_c.eop.read() )
     734                        {
     735                            std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     736                                      << name() << std::endl;
     737                            std::cout << "the MULTI-INVALIDATE command length must be one word"
     738                                      << std::endl;
     739                            exit(0);
     740                        }
     741                        r_tgt_update            = false;
     742                        r_tgt_fsm               = TGT_REQ_DCACHE;
     743
     744                        m_cpt_cc_inval_dcache++ ;
     745                    }
     746                    else if (cell == 4)                     // invalidate instruction
     747                    {                         
     748                        if ( not p_vci_tgt_c.eop.read() )
     749                        {
     750                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER "
     751                                      << name() << std::endl;
     752                            std::cout << "the MULTI-INVALIDATE command length must be one word"
     753                                      << std::endl;
     754                            exit(0);
     755                        }
     756                        r_tgt_update            = false;
     757                        r_tgt_fsm               = TGT_REQ_ICACHE;
     758
     759                        m_cpt_cc_inval_icache++ ;
     760                    }
     761                    else if (cell == 8)                         // update data
     762                    {                               
     763                        if ( p_vci_tgt_c.eop.read() )
     764                        {
     765                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER "
     766                                      << name() << std::endl;
     767                            std::cout << "the MULTI-UPDATE command length must be N+2 words"
     768                                      << std::endl;
     769                            exit(0);
     770                        }
     771                        r_tgt_update            = true;
     772                        r_tgt_update_data       = true;
     773                        r_tgt_fsm               = TGT_UPDT_WORD;
     774
     775                        m_cpt_cc_update_dcache++;
     776                    }
     777                    else                                        // update instruction
     778                    {
     779
     780
     781                        if ( p_vci_tgt_c.eop.read() )
     782                        {
     783                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER "
     784                                      << name() << std::endl;
     785                            std::cout << "the MULTI-UPDATE command length must be N+2 words"
     786                                      << std::endl;
     787                            exit(0);
     788                        }
     789                        r_tgt_update            = true;
     790                        r_tgt_update_data       = false;
     791                        r_tgt_fsm               = TGT_UPDT_WORD;
     792
     793                        m_cpt_cc_update_icache++;
     794                    }
     795                } // end if multi
     796            } // end if cmdval
     797            break;
     798        }
     799        //////////////////
     800        case TGT_UPDT_WORD:      // first word index acquisition fo update requests
     801
     802        {
     803            if (p_vci_tgt_c.cmdval.read())
     804            {
     805                if ( p_vci_tgt_c.eop.read() )
     806                {
     807                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     808                              << name() << std::endl;
     809                    std::cout << "the MULTI-UPDATE command length must be N+2 words"
     810                              << std::endl;
     811                    exit(0);
     812                }
     813
     814                for ( size_t i=0 ; i<m_cache_words ; i++ ) r_tgt_be[i] = 0;
     815
     816                r_tgt_word_min   = p_vci_tgt_c.wdata.read();  // first modified word
     817                r_tgt_word_count = p_vci_tgt_c.wdata.read();  // initializes the word counter
     818                r_tgt_fsm   = TGT_UPDT_DATA;
     819            }
     820            break;
     821        }
     822        ///////////////////
     823        case TGT_UPDT_DATA:  // data acquisition for update requests
     824        {
     825            if (p_vci_tgt_c.cmdval.read())
     826            {
     827                size_t word = r_tgt_word_count.read();
     828                if ( word >= m_cache_words )
     829                {
     830                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
     831                              << name() << std::endl;
     832                    std::cout << "the reveived MULTI-UPDATE command length is wrong"
     833                              << std::endl;
     834                    exit(0);
     835                }
     836
     837                r_tgt_buf[word] = p_vci_tgt_c.wdata.read();
     838                r_tgt_be [word] = p_vci_tgt_c.be.read();
     839
     840                r_tgt_word_count = word + 1;
     841                if (p_vci_tgt_c.eop.read())  // last word
     842                {
     843                    r_tgt_word_max = word;          // last modified word
     844                    if(r_tgt_update_data.read())        r_tgt_fsm = TGT_REQ_DCACHE;
     845                    else                                r_tgt_fsm = TGT_REQ_ICACHE;
     846                }
     847            }
     848            break;
     849        }
     850        ///////////////////////
     851        case TGT_REQ_BROADCAST: // set the requests (if no previous request pending)
     852        {
     853            if (not r_tgt_icache_req.read() and not r_tgt_dcache_req.read())
     854            {
     855                r_tgt_fsm = TGT_RSP_BROADCAST;
     856                r_tgt_icache_req = true;
     857                r_tgt_dcache_req = true;
     858            }
     859            break;
     860        }
     861        ////////////////////
     862        case TGT_REQ_ICACHE: // set the request (if no previous request pending)
     863        {
     864            if ( not r_tgt_icache_req.read() )
     865            {
     866                r_tgt_fsm = TGT_RSP_ICACHE;
     867                r_tgt_icache_req = true;
     868            }
     869            break;
     870        }
     871        ////////////////////
     872        case TGT_REQ_DCACHE: // set the request (if no previous request pending)
     873        {
     874            if ( not r_tgt_dcache_req.read() )
     875            {
     876                r_tgt_fsm = TGT_RSP_DCACHE;
     877                r_tgt_dcache_req = true;
     878            }
     879            break;
     880        }
     881        ///////////////////////
     882        case TGT_RSP_BROADCAST:  // waiting acknowlege from both dcache fsm and icache fsm
     883                                 // no VCI response when the r_tgt_*cache_rsp flip_flop is false
     884        {
     885            if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() )
     886            {
     887                if ( r_tgt_icache_rsp.read() or r_tgt_dcache_rsp.read() )  // at least one response
     888                {
     889                    if ( p_vci_tgt_c.rspack.read())
     890                    {
     891                        // reset dcache first if activated
     892                        if (r_tgt_dcache_rsp)   r_tgt_dcache_rsp = false;
     893                        else                    r_tgt_icache_rsp = false;
     894                    }
     895                }
     896                else
     897                {
     898                    r_tgt_fsm = TGT_IDLE;
     899                }
     900            }
     901            break;
     902        }
     903        ////////////////////
     904        case TGT_RSP_ICACHE:  // waiting acknowledge from the icache fsm
     905        {
     906            // no VCI response when the r_tgt_icache_rsp flip_flop is false
     907            if ( not r_tgt_icache_req.read() and p_vci_tgt_c.rspack.read() )
     908            {
     909                r_tgt_fsm = TGT_IDLE;
     910                r_tgt_icache_rsp = false;
     911            }
     912            break;
     913        }
     914        ////////////////////
     915        case TGT_RSP_DCACHE:  // waiting acknowledge from the dcache fsm
     916        {
     917            // no VCI response when the r_tgt_dcache_rsp flip_flop is false
     918            if ( not r_tgt_dcache_req.read() and p_vci_tgt_c.rspack.read() )
     919            {
     920                r_tgt_fsm = TGT_IDLE;
     921                r_tgt_dcache_rsp = false;
     922            }
     923            break;
     924        }
     925    } // end switch TGT_FSM
     926
     927    /////////////////////////////////////////////////////////////////////
     928    // Get data and instruction requests from processor
     929    ///////////////////////////////////////////////////////////////////////
     930
     931    typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
     932    typename iss_t::DataRequest         dreq = ISS_DREQ_INITIALIZER;
     933
     934    r_iss->getRequests(ireq, dreq);
     935
     936    ///////////////////////////////////////////////////////////////////////////////
     937    // The ICACHE FSM controls the following ressources:
     938    // - r_icache_fsm
     939    // - r_icache_fsm_save
     940    // - r_icache_addr_save
     941    // - r_icache_miss_req (set)
     942    // - r_icache_unc_req (set)
     943    // - r_icache_cleanup_req (set)
     944    // - r_icache_cleanup_line
     945    // - r_icache_cleanup_set
     946    // - r_icache_cleanup_way
     947    // - r_icache_miss_inval
     948    // - r_icache (instruction cache access)
     949    // - r_vci_rsp_ins_error (reset)
     950    // - r_tgt_icache_req (reset)
     951    // - r_tgt_icache_rsp
     952    // - ireq & irsp structures for communication with the processor
     953    //
     954    // 1/ Coherence requests (update or invalidate) have highest priority.
     955    //    They are taken into account in IDLE, UNC_WAIT, and MISS_WAIT states.
     956    //    In case of coherence request the ICACHE FSM goes to the CC_CHECK
     957    //    state to test the cache hit, and then to the CC_INVAL or
     958    //    CC_UPDATE states to execute the request. It reset the r_tgt_icache_req
     959    //    flip_flop to signal completion, writes in the r_tgt_icache_rsp
     960    //    to allow the VCI response, and returns in the pre-empted state.
     961    //   
     962    // 2/ Processor requests are taken into account only in the IDLE state.
     963    //    In case of miss, or in case of uncached instruction, the FSM
     964    //    writes the missing address line in the r_icache_addr_save register
     965    //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
     966    //    These request flip-flops are reset by the VCI_RSP FSM
     967    //    when the VCI transaction is completed.
     968    //
     969    // 3/ In case of uncacheable instruction, the VCI_RSP FSM writes the
     970    //    requested instruction in the r_icache_unc_buf register, and
     971    //    sets the r_icache_unc_valid flip_flop. This flip_flop is reset
     972    //    by the ICACHE FSM.
     973    //
     974    // 4/ In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
     975    //    flip-flop, and does not write any data in the response FIFO.
     976    //    The r_vci_rsp_ins_error flip-flop is reset by the ICACHE FSM.
     977    ////////////////////////////////////////////////////////////////////////////////
     978       
     979    // The default value for irsp.valid is false
     980    typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
     981
     982    switch( r_icache_fsm.read() )
     983    {
     984        /////////////////
     985        case ICACHE_IDLE:
     986        {
     987            if ( r_tgt_icache_req.read() )    // coherence request
     988            {
     989                r_icache_fsm = ICACHE_CC_CHECK;
     990                r_icache_fsm_save = r_icache_fsm.read();
     991                break;
     992            }
     993            if ( ireq.valid )  // processor request
     994            {
     995                bool     cacheable = m_cacheability_table[ireq.addr];
     996                vci_addr_t addr     = (vci_addr_t)ireq.addr;
     997
     998                if ( cacheable )         // cacheable
     999                {
     1000                    data_t   inst;
     1001                    bool     hit = r_icache->read(addr, &inst);
     1002                    m_conso_icache_dir_read++;
     1003                    m_conso_icache_data_read++;
     1004                    if ( !hit )     // cacheable miss
     1005                    {
     1006                        // in order to avoid a dead-lock with the mem_cache
     1007                        // (in case of simultaneous broadcast for example),
     1008                        // we check that the previous cleanup request is completed
     1009                        // and the ICACHE FSM is blocked in IDLE state until completion
     1010                        if ( not r_icache_cleanup_req.read() )
     1011                        {
     1012                            r_icache_fsm       = ICACHE_MISS_VICTIM;
     1013                            r_icache_miss_req  = true;
     1014                            r_icache_addr_save = addr;
     1015                            m_cpt_ins_miss++;
     1016                            m_cost_ins_miss_frz++;
     1017                        }
     1018                    }
     1019                    else            // cacheable hit
     1020                    {
     1021                        irsp.valid          = true;
     1022                        irsp.instruction    = inst;
     1023                        m_cpt_ins_cacheable++;
     1024                    }
     1025                }
     1026                else                // non cacheable
     1027                {
     1028                    if ( r_icache_unc_valid.read() and (addr == r_icache_addr_save.read()) )
     1029                    {
     1030                        r_icache_unc_valid  = false;
     1031                        irsp.valid          = true;
     1032                        irsp.instruction    = r_icache_unc_buf.read();
     1033                        m_cpt_ins_uncacheable++;
     1034                    }
     1035                    else
     1036                    {
     1037                        r_icache_unc_valid  = false;
     1038                        r_icache_fsm       = ICACHE_UNC_WAIT;
     1039                        r_icache_unc_req   = true;
     1040                        r_icache_addr_save = addr;
     1041                    }
     1042                }
     1043            }
     1044            break;
     1045        }
     1046        ////////////////////////
     1047        case ICACHE_MISS_VICTIM:           // Selects (and invalidates) a victim line
     1048        {                                  // Set the r_icache_cleanup_req flip-flop
     1049                                           // when the selected slot is not empty
     1050            m_cost_ins_miss_frz++;
     1051
     1052            size_t       way;
     1053            size_t       set;
     1054            vci_addr_t   victim;
     1055                       
     1056            r_icache_cleanup_req  = r_icache->victim_select( r_icache_addr_save.read(),
     1057                                                             &victim,
     1058                                                             &way,
     1059                                                             &set );
     1060            r_icache_cleanup_line = victim;
     1061            r_icache_cleanup_way  = way;
     1062            r_icache_cleanup_set  = set;
     1063            r_icache_fsm = ICACHE_MISS_WAIT;
     1064            break;
     1065        }
     1066        //////////////////////
     1067        case ICACHE_MISS_WAIT:            // waiting the response to a miss request
     1068        {                                 // to test a bus error
     1069            m_cost_ins_miss_frz++;
     1070
     1071            if ( r_tgt_icache_req.read() )    // coherence request
     1072            {
     1073                r_icache_fsm      = ICACHE_CC_CHECK;
     1074                r_icache_fsm_save = r_icache_fsm.read();
     1075                break;
     1076            }
     1077
     1078            if ( r_vci_rsp_ins_error.read() )
     1079            {
     1080                r_icache_fsm = ICACHE_ERROR;
     1081            }
     1082            else if ( r_vci_rsp_fifo_icache.rok() )
     1083            {
     1084                r_icache_update_word = 0;
     1085                r_icache_fsm = ICACHE_MISS_UPDT;
     1086            }
     1087            break;
     1088        }
     1089        //////////////////////
     1090        case ICACHE_MISS_UPDT:          // Update the cache (one word per cycle)
     1091        {
     1092            m_cost_ins_miss_frz++;
     1093            if ( r_vci_rsp_fifo_icache.rok() )
     1094            {
     1095                size_t      word = r_icache_update_word.read();
     1096                vci_addr_t  addr = r_icache_addr_save.read();
     1097                size_t      way  = r_icache_cleanup_way.read();
     1098                size_t      set  = r_icache_cleanup_set.read();
     1099
     1100                m_conso_icache_data_write++;
     1101                // if the pending miss is cancelled by a matching coherence request
     1102                // we pop the FIFO, but we don't update the cache
     1103                if ( not r_icache_miss_inval.read() )
     1104                      r_icache->write( way,
     1105                                       set,
     1106                                       word,
     1107                                       r_vci_rsp_fifo_icache.read() );
     1108
     1109                vci_rsp_fifo_icache_get = true;
     1110                r_icache_update_word = word+1;
     1111
     1112                // if last word, finish the update
     1113                if ( word == m_cache_words-1 )
     1114                {
     1115                    if ( not r_icache_miss_inval.read() )
     1116                    {
     1117                        m_conso_icache_dir_write++;
     1118                        r_icache->victim_update_tag(addr, way, set);
     1119                    }
     1120                    r_icache_miss_inval = false;
     1121                    r_icache_fsm = ICACHE_IDLE;
     1122                }
     1123            }
     1124            break;
     1125        }
     1126        /////////////////////
     1127        case ICACHE_UNC_WAIT:           // waiting the response to an uncached request
     1128        {
     1129            if ( r_tgt_icache_req.read() )   // coherence request
     1130            {
     1131                r_icache_fsm      = ICACHE_CC_CHECK;
     1132                r_icache_fsm_save = r_icache_fsm.read();
     1133                break;
     1134            }
     1135            if ( r_vci_rsp_ins_error ) 
     1136            {
     1137                r_icache_fsm = ICACHE_ERROR;
     1138            }
     1139            else if ( r_vci_rsp_fifo_icache.rok() )
     1140            {
     1141                vci_rsp_fifo_icache_get = true;
     1142                r_icache_unc_buf        = r_vci_rsp_fifo_icache.read();
     1143                r_icache_unc_valid      = true;               
     1144                r_icache_fsm            = ICACHE_IDLE;
     1145            }
     1146            break;
     1147        }
     1148        //////////////////
     1149        case ICACHE_ERROR:
     1150        {
     1151            irsp.error          = true;
     1152            irsp.valid          = true;
     1153            r_icache_fsm        = ICACHE_IDLE;
     1154            r_vci_rsp_ins_error = false;
     1155            break;
     1156        }
     1157        /////////////////////
     1158        case ICACHE_CC_CHECK:   // check directory in case of coherence request
     1159        {
     1160            vci_addr_t  addr = r_tgt_addr.read();
     1161            vci_addr_t  mask = ~((m_cache_words<<2)-1);
     1162
     1163            if( (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) and
     1164                ((r_icache_addr_save.read() & mask) == (addr & mask)))
     1165                // The coherence request matches a pending miss
     1166            {
     1167                r_icache_miss_inval = true;
     1168                r_tgt_icache_req    = false;
     1169                r_tgt_icache_rsp    = r_tgt_update.read();
     1170                r_icache_fsm        = r_icache_fsm_save.read(); 
     1171            }
     1172            else  // no match for a pending miss
     1173            {
     1174                size_t way;
     1175                size_t set;
     1176                size_t word;
     1177                bool   hit = r_icache->hit(addr,
     1178                                           &way,
     1179                                           &set,
     1180                                           &word);
     1181                r_icache_cc_way = way;
     1182                r_icache_cc_set = set;
     1183
     1184                m_conso_icache_dir_read++;
     1185
     1186                if ( hit and r_tgt_update.read() )           // hit update
     1187                {
     1188                      r_icache_fsm         = ICACHE_CC_UPDT;
     1189                      r_icache_update_word = r_tgt_word_min.read();
     1190                }
     1191                else if ( hit and not r_tgt_update.read() )  // hit inval
     1192                {
     1193                    r_icache_fsm = ICACHE_CC_INVAL;
     1194                }
     1195                else                                                    // miss can happen
     1196                {
     1197                    r_tgt_icache_req = false;
     1198                    r_tgt_icache_rsp = r_tgt_update.read();
     1199                    r_icache_fsm     = r_icache_fsm_save.read();
     1200                }
     1201            }
     1202            break;
     1203        }
     1204        /////////////////////
     1205        case ICACHE_CC_INVAL: 
     1206        {                     
     1207              vci_addr_t nline;
     1208              r_icache->inval( r_icache_cc_way.read(),
     1209                               r_icache_cc_way.read(),
     1210                               &nline );
     1211              r_tgt_icache_req = false;
     1212              r_tgt_icache_rsp = true;
     1213              r_icache_fsm     = r_icache_fsm_save.read();
     1214              break;
     1215        }   
     1216        /////////////////////
     1217        case ICACHE_CC_UPDT:
     1218        {                       
     1219            size_t  word = r_icache_update_word.read();
     1220            r_icache->write( r_icache_cc_way.read(),
     1221                             r_icache_cc_set.read(),
     1222                             word,
     1223                             r_tgt_buf[word].read(),
     1224                             r_tgt_be[word].read() );
     1225            r_icache_update_word = word+1;
     1226
     1227            if ( word == r_tgt_word_max.read() )  // last word
     1228            {
     1229                r_tgt_icache_req = false;
     1230                r_tgt_icache_rsp = true;
     1231                r_icache_fsm     = r_icache_fsm_save.read();
     1232            }
     1233            break;
     1234        }   
     1235    } // end switch r_icache_fsm
     1236
     1237    // save the IREQ and IRSP fields for the print_trace() function
     1238    m_ireq_valid        = ireq.valid;
     1239    m_ireq_addr         = ireq.addr;
     1240    m_ireq_mode         = ireq.mode;
     1241   
     1242    m_irsp_valid        = irsp.valid;
     1243    m_irsp_instruction  = irsp.instruction;
     1244    m_irsp_error        = irsp.error;
     1245
     1246    //////////////////////////////////////////////////////////////////////://///////////
     1247    // The DCACHE FSM controls the following ressources:
     1248    // - r_dcache_fsm
     1249    // - r_dcache_fsm_save
     1250    // - r_dcache (data cache access)
     1251    // - r_dcache_addr_save
     1252    // - r_dcache_wdata_save
     1253    // - r_dcache_be_save
     1254    // - r_dcache_way_save
     1255    // - r_dcache_set_save
     1256    // - r_dcache_word_save
     1257    // - r_dcache_miss_req (set)
     1258    // - r_dcache_unc_req (set)
     1259    // - r_dcache_sc_req (set)
     1260    // - r_dcache_cleanup_req (set)
     1261    // - r_vci_rsp_data_error (reset)
     1262    // - r_tgt_dcache_req (reset)
     1263    // - r_wbuf write
     1264    // - drsp structure
     1265    //
     1266    // 1/ Coherence requests :
     1267    //    There is a coherence request when the tgt_dcache_req flip-flop is set,
     1268    //    requesting a line invalidation or a line update.
     1269    //    Coherence requests are taken into account in IDLE, UNC_WAIT, MISS_WAIT states,
     1270    //    and have the highest priority.
     1271    //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
     1272    //    goes to the CC_CHECK state to execute the requested action, and returns to the
     1273    //    pre-empted state.
     1274    //
     1275    // 2/ processor requests :
     1276    //    Processor READ requests are taken into account in IDLE state only.
     1277    //    In order to support WRITE bursts, write requests are taken into account
     1278    //    in the WRITE_UPDT state as well as in the IDLE state.
     1279    //    - The processor read requests cannot be satisfied if
     1280    //    there is a cached read miss, or an uncached read.
     1281    //    - The processor write requests cannot be satisfied when the write buffer is full.
     1282    //
     1283    // 3/ Atomic instructions LL/SC
     1284    //    The reservation registers (r_dcache_ll_valid, r_dcache_ll_addr and
     1285    //    r_dcache_ll_data are stored in the L1 cache controller, and not in the
     1286    //    memory controller.
     1287    //    - LL requests from the processor and are transmitted as standard
     1288    //      VCI read transactions (one word / one line, depending on the cacheability).
     1289    //    - SC requests from the processor are systematically transmitted to the
     1290    //      memory cache as compare&swap requests (both the data value stored in the
     1291    //      r_dcache_ll_data register and the new value).
     1292    //    The LL/SC address can be cacheable or not cacheable.
     1293    //
     1294    // 4/ Non cacheable access
     1295    //    This component implement a strong order between non cacheable access
     1296    //    (read or write) : A new non cacheable VCI transaction starts only when
     1297    //    the previous non cacheable transaction is completed. Both cacheable and
     1298    //    non cacheable transactions use the write buffer, but the DCACHE FSM registers
     1299    //    a non cacheable write transaction posted in the write buffer by setting the
     1300    //    r_dcache_pending_unc_write flip_flop. All other non cacheable requests
     1301    //    are stalled until this flip-flop is reset by the VCI_RSP_FSM (when the
     1302    //    pending non cacheable write transaction completes).
     1303    //
     1304    // 5/ Error handling :  Read Bus Errors are synchronous events, but
     1305    //    Write Bus Errors are asynchronous events (processor is not frozen).
     1306    //    - If a Read Bus Error is detected, the VCI_RSP FSM sets the
     1307    //      r_vci_rsp_data_error flip-flop, without writing any data in the
     1308    //      r_vci_rsp_fifo_dcache FIFO, and the synchronous error is signaled
     1309    //      by the DCACHE FSM.
     1310    //    - If a Write Bus Error is detected, the VCI_RSP FSM  signals
     1311    //      the asynchronous error using the setWriteBerr() method.
     1312    ///////////////////////////////////////////////////////////////////////////////////
     1313
     1314    // The default value for drsp.valid is false
     1315    typename iss_t::DataResponse  drsp = ISS_DRSP_INITIALIZER;
     1316
     1317    switch ( r_dcache_fsm.read() )
     1318    {
     1319        /////////////////
     1320        case DCACHE_IDLE:       // waiting requests from processor
     1321        {
     1322            if ( r_tgt_dcache_req.read() )  // coherence request
     1323            {
     1324                r_dcache_fsm      = DCACHE_CC_CHECK;
     1325                r_dcache_fsm_save = r_dcache_fsm.read();
     1326                break;
     1327            }
     1328            if ( dreq.valid )  // processor request
     1329            {
     1330                bool            cacheable      = m_cacheability_table[dreq.addr];
     1331                vci_addr_t      addr          = (vci_addr_t)dreq.addr;
     1332
     1333                switch( dreq.type )
     1334                {
     1335                    case iss_t::DATA_LL:
     1336                    case iss_t::DATA_READ:
     1337                    {
     1338                        if ( cacheable )        // cacheable read   
     1339                        {
     1340                            data_t   rdata;
     1341                            bool     hit = r_dcache->read(addr, &rdata);
     1342                            m_conso_dcache_dir_read++;
     1343                            m_conso_dcache_data_read++;
     1344                            if ( !hit )         // cacheable read miss
     1345                            {
     1346                                // in order to avoid a dead-lock with the mem_cache
     1347                                // (in case of simultaneous broadcast for example),
     1348                                // we check that the previous cleanup request is completed
     1349                                // if not the DCACHE_FSM is blocked in IDLE state until completion
     1350                                if ( not r_dcache_cleanup_req.read() )
     1351                                {
     1352                                    r_dcache_fsm       = DCACHE_MISS_VICTIM;
     1353                                    r_dcache_miss_req  = true;
     1354                                    r_dcache_addr_save = addr;
     1355                                    m_cpt_data_read_miss++;
     1356                                    m_cost_data_miss_frz++;
     1357                                }
     1358                            }
     1359                            else                // cacheable read hit
     1360                            {
     1361                                m_cpt_data_read_cacheable++;
     1362                                drsp.valid   = true;
     1363                                drsp.rdata   = rdata;
     1364
     1365                                // makes reservation in case of LL
     1366                                if( dreq.type == iss_t::DATA_LL )
     1367                                {
     1368                                    m_cpt_data_ll++;
     1369                                    r_dcache_ll_valid = true;
     1370                                    r_dcache_ll_data  = rdata;
     1371                                    r_dcache_ll_addr  = addr;
     1372                                }
     1373                            }
     1374                        }
     1375                        else            // non cacheable read   
     1376                        {
     1377                            // non cacheable accesses must be strongly ordered
     1378                            // A non cacheable read must be delayed if there is
     1379                            // a pending uncacheable write in the write buffer
     1380                            if ( not r_dcache_pending_unc_write.read() )
     1381                            {
     1382                                if ( r_dcache_unc_valid.read() and                      // hit
     1383                                           (addr == r_dcache_addr_save.read()) )
     1384                                {
     1385                                    r_dcache_unc_valid = false;
     1386                                    drsp.valid         = true;
     1387                                    drsp.rdata         = r_dcache_unc_buf.read();
     1388                                    m_cpt_data_read_uncacheable++;
     1389
     1390                                    // makes reservation in case of uncacheable LL
     1391                                    if( dreq.type == iss_t::DATA_LL )
     1392                                    {
     1393                                        m_cpt_data_ll++;
     1394                                        r_dcache_ll_valid = true;
     1395                                        r_dcache_ll_data  = r_dcache_unc_buf.read();
     1396                                        r_dcache_ll_addr  = addr;
     1397                                    }
     1398                                }
     1399                                else                                                    // miss
     1400                                {
     1401                                    r_dcache_unc_valid = false;
     1402                                    r_dcache_unc_req   = true;
     1403                                    r_dcache_fsm       = DCACHE_UNC_WAIT;
     1404                                    r_dcache_addr_save = addr;
     1405                                }
     1406                            } // end if pending_unc_write
     1407                        }                       
     1408                        break;
     1409                    }
     1410                    case iss_t::DATA_SC:
     1411                    {
     1412                        // - if a previous LL (with the same address) is registered,
     1413                        // we makes a SC transaction, that will store the response
     1414                        // in the r_dcache_unc_buf register (0 if success).
     1415                        // As for the non cacheable read, we must test the
     1416                        // r_dcache_unc_valid flip-flop to detect the SC completion,
     1417                        // return the value stored in r_dcache_unc_buf, and invalidate
     1418                        // the LL reservation.
     1419                        // - if there is no registerd LL, we just stay in IDLE state
     1420                        // and return 1 (atomic access failed)
     1421
     1422                        if( r_dcache_ll_valid.read() and (r_dcache_ll_addr.read() == addr))
     1423                        {
     1424                            if ( r_dcache_unc_valid.read() and          // SC done
     1425                                    (addr == r_dcache_addr_save.read()) )
     1426                            {
     1427                                r_dcache_ll_valid  = false;
     1428                                r_dcache_unc_valid = false;
     1429                                drsp.valid         = true;
     1430                                drsp.rdata         = r_dcache_unc_buf.read();
     1431                                m_cpt_data_sc++;
     1432                            }
     1433                            else                                        // SC to be done
     1434                            {
     1435                                r_dcache_sc_req     = true;
     1436                                r_dcache_fsm        = DCACHE_UNC_WAIT;
     1437                                r_dcache_addr_save  = addr;
     1438                                r_dcache_wdata_save = dreq.wdata;
     1439                            }
     1440                        }
     1441                        else                                    // no registered LL
     1442                        {
     1443                            drsp.valid = true;
     1444                            drsp.rdata = 1;
     1445                            r_dcache_ll_valid = false;
     1446                        }
     1447                        break;
     1448                    }
     1449                    case iss_t::XTN_READ:
     1450                    case iss_t::XTN_WRITE:
     1451                    {
     1452                        // only DCACHE INVALIDATE and SYNC requests are supported
     1453                        if ( dreq.addr>>2 == iss_t::XTN_DCACHE_INVAL )
     1454                        {
     1455                            m_cpt_xtn_dcache_inval++;
     1456                            r_dcache_fsm        = DCACHE_INVAL;
     1457                            r_dcache_wdata_save = dreq.wdata;
     1458                        }
     1459                        else if ( dreq.addr>>2 == iss_t::XTN_SYNC )
     1460                        {
     1461                            m_cpt_xtn_sync++;
     1462                            // Test if write buffer is already empty
     1463                            if ( r_wbuf->empty() )
     1464                            {
     1465                                drsp.valid = true;
     1466                                r_dcache_fsm  = DCACHE_IDLE;
     1467                            }
     1468                            else
     1469                            {
     1470                                r_dcache_fsm  = DCACHE_SYNC;
     1471                            }
     1472                        }
     1473                        else
     1474                        {
     1475                            std::cout << "Warning in VCI_CC_XCACHE_WRAPPER "
     1476                                      << name() << std::endl;
     1477                            std::cout << "Unsupported  external access : "
     1478                                      << (dreq.addr>>2) << std::endl;
     1479                            drsp.valid = true;
     1480                            r_dcache_fsm  = DCACHE_IDLE;
     1481                        }
     1482                        break;
     1483                    }
     1484                    case iss_t::DATA_WRITE:
     1485                    {
     1486                        if ( cacheable )     // cacheable write
     1487                        {
     1488                            bool    hit;
     1489                            size_t  way         = 0;
     1490                            size_t  set         = 0;
     1491                            size_t  word        = 0;
     1492
     1493                            m_conso_dcache_dir_read++;
     1494                            hit = r_dcache->hit(addr, &way, &set, &word);
     1495                            m_conso_wbuf_write++;
     1496                            bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
     1497                            if ( wok )
     1498                            {
     1499                                m_cpt_data_write_cacheable++;
     1500                                drsp.valid = true;
     1501                                if (hit)    // cached write
     1502                                {
     1503                                    m_cpt_data_write_hit++;
     1504                                    r_dcache_fsm          = DCACHE_WRITE_UPDT;
     1505                                    r_dcache_addr_save    = addr;
     1506                                    r_dcache_wdata_save   = dreq.wdata;
     1507                                    r_dcache_be_save      = dreq.be;
     1508                                    r_dcache_way_save     = way;
     1509                                    r_dcache_set_save     = set;
     1510                                    r_dcache_word_save    = word;
     1511                                }
     1512                                else      // non cached
     1513                                {
     1514                                    r_dcache_fsm = DCACHE_IDLE;
     1515                                }
     1516                            }
     1517                            else  // write miss into write buffer
     1518                            {
     1519                                r_dcache_fsm = DCACHE_IDLE;
     1520                                m_cost_write_frz++;
     1521                            }
     1522                        }
     1523                        else                // non cacheable write
     1524                        {
     1525                            // non cacheable accesses must be strongly ordered
     1526                            // A non cacahble write must be delayed if there is
     1527                            // a pending uncacheable write in the write buffer
     1528                            if ( not r_dcache_pending_unc_write.read() )
     1529                            {
     1530                                m_conso_wbuf_write++;
     1531                                bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
     1532                                if ( wok )
     1533                                {
     1534                                    m_cpt_data_write_uncacheable++;
     1535                                    drsp.valid = true;
     1536                                }
     1537                            }
     1538                            r_dcache_fsm = DCACHE_IDLE;
     1539                        }
     1540
     1541                        break;
     1542                    }
     1543                }   // end switch dreq.type
     1544            }   // end if dreq.valid
     1545            break;
     1546        }
     1547        ///////////////////////
     1548        case DCACHE_WRITE_UPDT:
     1549        {
     1550            // cache update (address, data & be from the previous cycle)
     1551            m_conso_dcache_data_write++;
     1552            r_dcache->write( r_dcache_way_save.read(),         
     1553                             r_dcache_set_save.read(),       
     1554                             r_dcache_word_save.read(),
     1555                             r_dcache_wdata_save.read(), 
     1556                             r_dcache_be_save.read() ); 
     1557
     1558#if DEBUG_DCACHE
     1559if ( (m_cpt_total_cycles > DEBUG_START_CYCLE) and (m_srcid_d == DEBUG_ID) )
     1560{
     1561    std::cout << "  <PROC.DCACHE_WRITE_UPDT> Writing one word :" << std::hex
     1562              << " data = " << r_dcache_wdata_save.read()
     1563              << " / be = " << r_dcache_be_save.read()
     1564              << " / way = " << r_dcache_way_save.read()
     1565              << " / set = " << r_dcache_set_save.read()
     1566              << " / word = " << r_dcache_word_save.read() << std::endl;
     1567}
    2131568#endif
    214                m_nb_dcache(nb_dcache),
    215                m_nb_cache((m_nb_dcache>m_nb_icache)?m_nb_dcache:m_nb_icache),
    216                m_dcache_ways(dcache_ways),
    217                m_dcache_words(dcache_words),
    218                m_dcache_words_shift(uint32_log2(dcache_words)+uint32_log2(sizeof(data_t))),
    219                m_dcache_yzmask((~0)<<m_dcache_words_shift),
    220                m_icache_ways(icache_ways),
    221                m_icache_words(icache_words),
    222                m_icache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))),
    223                m_icache_yzmask((~0)<<m_icache_words_shift),
    224                m_cache_words((dcache_words)?dcache_words:icache_words),
    225 
    226                r_cpu_prior("r_cpu_prior"),
    227 
    228                r_vci_cmd_fsm("r_vci_cmd_fsm"),
    229                r_vci_cmd_min("r_vci_cmd_min"),
    230                r_vci_cmd_max("r_vci_cmd_max"),
    231                r_vci_cmd_cpt("r_vci_cmd_cpt"),
    232                r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"),
    233                r_vci_cmd_num_icache_prior("r_vci_cmd_num_icache_prior"),
    234                r_vci_cmd_num_dcache_prior("r_vci_cmd_num_dcache_prior"),
    235                r_vci_cmd_num_cache("r_vci_cmd_num_cache"),
    236 
    237                r_vci_rsp_fsm("r_vci_rsp_fsm"),
    238                r_vci_rsp_cpt("r_vci_rsp_cpt"),
    239                r_vci_rsp_num_cache("r_vci_rsp_num_cache"),
    240 
    241                r_vci_rsp_fifo_icache_data      ("r_vci_rsp_fifo_icache_data"     ,2),
    242                r_vci_rsp_fifo_icache_num_cache ("r_vci_rsp_fifo_icache_num_cache",2),
    243                r_vci_rsp_fifo_dcache_data      ("r_vci_rsp_fifo_dcache_data"     ,2),
    244                r_vci_rsp_fifo_dcache_num_cache ("r_vci_rsp_fifo_dcache_num_cache",2),
    245 
    246                r_cache_word("r_cache_word"),
    247 
    248                r_vci_tgt_fsm("r_vci_tgt_fsm"),
    249                r_tgt_iaddr("r_tgt_iaddr"),
    250                r_tgt_daddr("r_tgt_daddr"),
    251                r_tgt_word("r_tgt_word"),
    252                r_tgt_update("r_tgt_update"),
    253                r_tgt_update_data("r_tgt_update_data"),
    254                // r_tgt_brdcast("r_tgt_brdcast"),
    255                r_tgt_srcid("r_tgt_srcid"),
    256                r_tgt_pktid("r_tgt_pktid"),
    257                r_tgt_trdid("r_tgt_trdid"),
    258                // r_tgt_plen("r_tgt_plen"),
    259                r_tgt_num_cache("r_tgt_num_cache"),
    260 
    261                r_cleanup_fsm("r_cleanup_fsm"),
    262                r_cleanup_num_cache("r_cleanup_num_cache"),
    263                r_cleanup_icache("r_cleanup_icache"),
    264 
    265                m_num_cache_LSB(uint32_log2(icache_words) + uint32_log2(sizeof(data_t))),
    266                m_num_cache_MSB(uint32_log2(nb_dcache) + m_num_cache_LSB)
     1569
     1570            // possible write after write
     1571            if ( dreq.valid and (dreq.type == iss_t::DATA_WRITE) )
     1572            {
     1573                bool     cacheable = m_cacheability_table[dreq.addr];
     1574                vci_addr_t addr     = (vci_addr_t)dreq.addr;
     1575
     1576                if ( cacheable ) // cacheable write
     1577                {
     1578                    bool    hit;
     1579                    size_t  way  = 0;
     1580                    size_t  set  = 0;
     1581                    size_t  word = 0;
     1582
     1583                    m_conso_dcache_dir_read++;
     1584                    hit = r_dcache->hit(addr, &way, &set, &word);
     1585                    m_conso_wbuf_write++;
     1586                    bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
     1587                    if (wok)   
     1588                    {
     1589                        m_cpt_data_write_cacheable++;
     1590                        drsp.valid = true;
     1591                        if (hit)        // cached write
     1592                        {
     1593                            m_cpt_data_write_hit++;
     1594                            r_dcache_fsm          = DCACHE_WRITE_UPDT;
     1595                            r_dcache_addr_save    = addr;
     1596                            r_dcache_wdata_save   = dreq.wdata;
     1597                            r_dcache_be_save      = dreq.be;
     1598                            r_dcache_way_save     = way;
     1599                            r_dcache_set_save     = set;
     1600                            r_dcache_word_save    = word;
     1601                        }
     1602                        else   // uncached write
     1603                        {
     1604                            r_dcache_fsm = DCACHE_IDLE;
     1605                        }
     1606                    }
     1607                    else   // write miss into write buffer
     1608                    {
     1609                        m_cost_write_frz++;
     1610                        r_dcache_fsm = DCACHE_IDLE;
     1611                    }
     1612                }
     1613                else  // non cacheable write
     1614                {
     1615                    // non cacheable accesses must be strongly ordered
     1616                    // A non cacahble write must be delayed if there is
     1617                    // a pending uncacheable write in the write buffer
     1618                    if ( not r_dcache_pending_unc_write.read() )
     1619                    {
     1620                        m_conso_wbuf_write++;
     1621                        bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
     1622                        if ( wok )
     1623                        {
     1624                            m_cpt_data_write_uncacheable++;
     1625                            drsp.valid = true;
     1626                        }
     1627                    }
     1628                    r_dcache_fsm = DCACHE_IDLE;
     1629                }
     1630            }
     1631            else    // no valid write request
     1632            {
     1633                r_dcache_fsm = DCACHE_IDLE;
     1634            }
     1635            break;
     1636        }
     1637        ////////////////////////
     1638        case DCACHE_MISS_VICTIM:           // Selects (and invalidates) a victim line
     1639        {                                  // Set the r_dcache_cleanup_req flip-flop
     1640                                           // when the selected slot is not empty
     1641            m_cost_data_miss_frz++;
     1642
     1643            size_t     way;
     1644            size_t     set;
     1645            vci_addr_t   addr = r_dcache_addr_save.read();
     1646            vci_addr_t   victim;
     1647                       
     1648            bool cleanup_requested = r_dcache->victim_select( addr, &victim, &way, &set );
     1649
     1650            r_dcache_cleanup_line = victim;
     1651            r_dcache_cleanup_way  = way;
     1652            r_dcache_cleanup_set  = set;
     1653            r_dcache_cleanup_req  = cleanup_requested;
     1654            r_dcache_fsm = DCACHE_MISS_WAIT;
     1655            break;
     1656        }
     1657        //////////////////////
     1658        case DCACHE_MISS_WAIT:          // Waiting the response to a miss request
     1659        {                               // to test a bus error
     1660            m_cost_data_miss_frz++;
     1661
     1662            if ( r_tgt_dcache_req.read() )    // coherence request
     1663            {
     1664                r_dcache_fsm      = DCACHE_CC_CHECK;
     1665                r_dcache_fsm_save = r_dcache_fsm.read();
     1666                break;
     1667            }
     1668
     1669            if ( r_vci_rsp_data_error.read() )
     1670            {
     1671                r_dcache_fsm = DCACHE_ERROR;
     1672            }
     1673            else if ( r_vci_rsp_fifo_dcache.rok() )
     1674            {
     1675                r_dcache_update_word = 0;
     1676                r_dcache_fsm = DCACHE_MISS_UPDT;
     1677            }
     1678            break;
     1679        }
     1680        //////////////////////
     1681        case DCACHE_MISS_UPDT:      // Update the cache (one word per cycle)
     1682        {
     1683            m_cost_data_miss_frz++;
     1684
     1685            size_t       word = r_dcache_update_word.read();
     1686            vci_addr_t   addr = r_dcache_addr_save.read();
     1687            size_t       way  = r_dcache_cleanup_way.read();
     1688            size_t       set  = r_dcache_cleanup_set.read();
     1689                   
     1690            if ( r_vci_rsp_fifo_dcache.rok() )
     1691            {
     1692                if ( not r_dcache_miss_inval.read() )  // no matching coherence request
     1693                {
     1694                    m_conso_dcache_data_write++;
     1695                    r_dcache->write( way,
     1696                                     set,
     1697                                     word,
     1698                                     r_vci_rsp_fifo_dcache.read() );
     1699
     1700                    if ( word == m_cache_words-1 )      // last word
     1701                    {
     1702                        m_conso_dcache_dir_write++;
     1703                        r_dcache->victim_update_tag(addr, way, set);
     1704                        r_dcache_fsm = DCACHE_IDLE;
     1705                    }
     1706                    vci_rsp_fifo_dcache_get = true;
     1707                    r_dcache_update_word = word+1;
     1708                }
     1709                else    // if there is a matching coherence request :
     1710                        // we pop the response FIFO, but we don't update the cache
     1711                        // when we receive the last word, we send a cleanup for the
     1712                        // missing line and return to the IDLE state
     1713                {
     1714                    if ( word < m_cache_words-1 )
     1715                    {
     1716                        vci_rsp_fifo_dcache_get = true;
     1717                        r_dcache_update_word = word+1;
     1718                    }
     1719                    else        // last word
     1720                    {
     1721                        if ( not r_dcache_cleanup_req )
     1722                        {
     1723                            vci_rsp_fifo_dcache_get = true;
     1724                            r_dcache_cleanup_req  = true;
     1725                            r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_cache_words_shift;
     1726                            r_dcache_miss_inval    = false;
     1727                            r_dcache_fsm          = DCACHE_IDLE;
     1728                        }
     1729                    }
     1730                }
     1731
     1732#if DEBUG_DCACHE
     1733if ( (m_cpt_total_cycles > DEBUG_START_CYCLE) and (m_srcid_d == DEBUG_ID) )
     1734{
     1735    if ( r_dcache_miss_inval.read() )
    2671736    {
    268       // Size of word is 32 bits
    269       ASSERT((icache_words*vci_param::B) < (1<<vci_param::K),
    270              "Need more PLEN bits.");
    271 
    272       ASSERT((vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines/m_nb_dcache)),
    273              "Need more TRDID bits.");
    274 
    275       ASSERT(uint32_log2(nb_dcache) <= (1<<vci_param::P),
    276              "Need more PKTID bits.");
    277                
    278       ASSERT(IS_POW_OF_2(m_nb_dcache),
    279              "nb_dcache must be a power of 2.");
    280 
    281       ASSERT(IS_POW_OF_2(m_nb_cpu) and (m_nb_cpu <= m_nb_dcache) and (m_nb_cpu > 0),
    282              "nb cpu must be a multiple of nb cache.");
    283 
    284       ASSERT(IS_POW_OF_2(m_icache_ways) and (m_nb_icache <= m_icache_ways),
    285              "nb icache ways must be a multiple of nb cache.");
    286 
    287       ASSERT(IS_POW_OF_2(m_dcache_ways) and (m_nb_dcache <= m_dcache_ways),
    288              "nb dcache ways must be a multiple of nb cache.");
    289 
    290       ASSERT(icache_words == dcache_words,
    291              "icache_words must be equal at dcache_words.");
    292 
    293       ASSERT(IS_POW_OF_2(wbuf_nlines) and (m_nb_dcache <= wbuf_nlines),
    294              "wbuf_nlines must be a multiple of nb cache.");
    295 
    296       // FIXME : s'adapter à la taille des requêtes XTN_READ/XTN_WRITE, car le type est fournit dans le champs l'adresse
    297       ASSERT((m_nb_dcache == 1) or (dcache_words >= 16),
    298              "When multi cache is activated, need 4 bits (16 word) to the cache set .");
    299 
    300       if (m_nb_cpu > 1)
    301         ASSERT(CC_XCACHE_MULTI_CPU!=0,
    302                "Macro CC_XCACHE_MULTI_CPU in wbuf must be set at 1.");
    303 
    304       p_irq = new sc_in<bool> * [m_nb_cpu];
    305       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    306         p_irq [num_cpu] = new sc_in<bool> [iss_t::n_irq];
    307 
    308       m_iss = new iss_t * [m_nb_cpu];
    309       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    310         {
    311           std::ostringstream iss_name("");
    312           iss_name << this->name() << "_" << num_cpu;
    313 
    314           m_iss[num_cpu] = new iss_t (iss_name.str().c_str(), proc_id+num_cpu);
    315         }
    316                
    317       r_icache_lock          = new sc_signal<uint32_t>[m_nb_icache];
    318       r_dcache_lock          = new sc_signal<uint32_t>[m_nb_dcache];
    319       r_dcache_sync          = new sc_signal<bool>    [m_nb_dcache];
    320 
    321       r_icache_fsm           = new sc_signal<int>     [m_nb_icache];
    322       r_icache_fsm_save      = new sc_signal<int>     [m_nb_icache];
    323       r_icache_addr_save     = new sc_signal<addr_40> [m_nb_icache];
    324       r_icache_miss_req      = new sc_signal<bool>    [m_nb_icache];
    325       r_icache_miss_way      = new sc_signal<size_t>  [m_nb_icache];
    326       r_icache_miss_set      = new sc_signal<size_t>  [m_nb_icache];
    327       r_icache_unc_req       = new sc_signal<bool>    [m_nb_icache];
    328       r_icache_cleanup_req   = new sc_signal<bool>    [m_nb_icache];
    329       r_icache_cleanup_line  = new sc_signal<addr_40> [m_nb_icache];
    330       r_icache_inval_rsp     = new sc_signal<bool>    [m_nb_icache];
    331       r_icache_update_addr   = new sc_signal<size_t>  [m_nb_icache];
    332       r_icache_buf_unc_valid = new sc_signal<bool>    [m_nb_icache];
    333 
    334       r_dcache_fsm           = new sc_signal<int>     [m_nb_dcache];
    335       r_dcache_fsm_save      = new sc_signal<int>     [m_nb_dcache];
    336       r_dcache_addr_save     = new sc_signal<addr_40> [m_nb_dcache];
    337       r_dcache_wdata_save    = new sc_signal<data_t>  [m_nb_dcache];
    338       r_dcache_rdata_save    = new sc_signal<data_t>  [m_nb_dcache];
    339       r_dcache_type_save     = new sc_signal<int>     [m_nb_dcache];
    340       r_dcache_be_save       = new sc_signal<be_t>    [m_nb_dcache];
    341       r_dcache_cached_save   = new sc_signal<bool>    [m_nb_dcache];
    342       r_dcache_num_cpu_save  = new sc_signal<uint32_t>[m_nb_dcache];
    343       r_dcache_cleanup_req   = new sc_signal<bool>    [m_nb_dcache];
    344       r_dcache_cleanup_line  = new sc_signal<addr_40> [m_nb_dcache];
    345       r_dcache_miss_req      = new sc_signal<bool>    [m_nb_dcache];
    346       r_dcache_miss_way      = new sc_signal<size_t>  [m_nb_dcache];
    347       r_dcache_miss_set      = new sc_signal<size_t>  [m_nb_dcache];
    348       r_dcache_unc_req       = new sc_signal<bool>    [m_nb_dcache];
    349       r_dcache_sc_req        = new sc_signal<bool>    [m_nb_dcache];
    350       r_dcache_inval_rsp     = new sc_signal<bool>    [m_nb_dcache];
    351       r_dcache_update_addr   = new sc_signal<size_t>  [m_nb_dcache];
    352       r_dcache_previous_unc  = new sc_signal<bool>    [m_nb_dcache];
    353 
    354       r_dcache_ll_data       = new sc_signal<data_t>   * [m_nb_dcache];
    355       r_dcache_ll_addr       = new sc_signal<addr_40>  * [m_nb_dcache];
    356       r_dcache_ll_valid      = new sc_signal<bool>     * [m_nb_dcache];
    357       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    358         {
    359           r_dcache_ll_data    [num_cache] = new sc_signal<data_t>   [m_nb_cpu];
    360           r_dcache_ll_addr    [num_cache] = new sc_signal<addr_40>  [m_nb_cpu];
    361           r_dcache_ll_valid   [num_cache] = new sc_signal<bool>     [m_nb_cpu];
    362         }
    363 
    364       r_tgt_icache_req       = new sc_signal<bool>    [m_nb_icache];
    365       r_tgt_icache_rsp       = new sc_signal<bool>    [m_nb_icache];
    366       r_tgt_dcache_req       = new sc_signal<bool>    [m_nb_dcache];
    367       r_tgt_dcache_rsp       = new sc_signal<bool>    [m_nb_dcache];
    368 
    369       r_tgt_buf              = new data_t             [m_cache_words];
    370       r_tgt_be               = new be_t               [m_cache_words];
    371 
    372       r_vci_rsp_ins_error    = new sc_signal<bool>    [m_nb_icache];
    373       r_vci_rsp_data_error   = new sc_signal<bool>    [m_nb_dcache];
    374 
    375       ireq                   = new typename iss_t::InstructionRequest  [m_nb_icache];
    376       irsp                   = new typename iss_t::InstructionResponse [m_nb_icache];
    377       ireq_cached            = new bool                                [m_nb_icache];
    378       ireq_num_cpu           = new uint32_t                            [m_nb_dcache];
    379 
    380       dreq                   = new typename iss_t::DataRequest         [m_nb_dcache];
    381       drsp                   = new typename iss_t::DataResponse        [m_nb_dcache];
    382       dreq_cached            = new bool                                [m_nb_dcache];
    383       dreq_num_cpu           = new uint32_t                            [m_nb_dcache];
    384 
    385       m_cpt_icache_access         = new uint32_t [m_nb_icache];
    386       m_cpt_dcache_access         = new uint32_t [m_nb_dcache];
    387       m_cpt_icache_miss_victim_wait = new uint32_t [m_nb_icache];
    388       m_cpt_dcache_miss_victim_wait = new uint32_t [m_nb_dcache];
    389 
    390       m_cpt_dcache_store_after_store    = new uint32_t [m_nb_dcache];
    391       m_cpt_dcache_hit_after_miss_read  = new uint32_t [m_nb_dcache];
    392       m_cpt_dcache_hit_after_miss_write = new uint32_t [m_nb_dcache];
    393                
    394       m_cpt_fsm_dcache  = new uint32_t * [m_nb_dcache];
    395       m_cpt_fsm_icache  = new uint32_t * [m_nb_icache];
    396       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    397         m_cpt_fsm_dcache[num_cache]  = new uint32_t [soclib::common::size(dcache_fsm_state_str )];
    398       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    399         m_cpt_fsm_icache[num_cache]  = new uint32_t [soclib::common::size(icache_fsm_state_str )];
    400       m_cpt_fsm_cmd     = new uint32_t [soclib::common::size(cmd_fsm_state_str    )];
    401       m_cpt_fsm_rsp     = new uint32_t [soclib::common::size(rsp_fsm_state_str    )];
    402       m_cpt_fsm_tgt     = new uint32_t [soclib::common::size(tgt_fsm_state_str    )];
    403       m_cpt_fsm_cleanup = new uint32_t [soclib::common::size(cleanup_fsm_state_str)];
    404 
    405       m_cpt_frz_cycles  = new uint32_t [m_nb_cpu];
    406       // r_icache_fsm("r_icache_fsm"),
    407       // r_icache_fsm_save("r_icache_fsm_save"),
    408       // r_icache_addr_save("r_icache_addr_save"),
    409       // r_icache_miss_req("r_icache_miss_req"),
    410       // r_icache_miss_way("r_icache_miss_way"),
    411       // r_icache_miss_set("r_icache_miss_set"),
    412       // r_icache_unc_req("r_icache_unc_req"),
    413       // r_icache_cleanup_req("r_icache_cleanup_req"),
    414       // r_icache_cleanup_line("r_icache_cleanup_line"),
    415       // r_icache_inval_rsp("r_icache_inval_rsp"),
    416       // r_icache_update_addr("r_icache_update_addr"),
    417       // r_icache_buf_unc_valid("r_icache_buf_unc_valid"),
    418 
    419       // r_dcache_fsm("r_dcache_fsm"),
    420       // r_dcache_fsm_save("r_dcache_fsm_save"),
    421       // r_dcache_addr_save("r_dcache_addr_save"),
    422       // r_dcache_wdata_save("r_dcache_wdata_save"),
    423       // r_dcache_rdata_save("r_dcache_rdata_save"),
    424       // r_dcache_type_save("r_dcache_type_save"),
    425       // r_dcache_be_save("r_dcache_be_save"),
    426       // r_dcache_cached_save("r_dcache_cached_save"),
    427       // r_dcache_cleanup_req("r_dcache_cleanup_req"),
    428       // r_dcache_cleanup_line("r_dcache_cleanup_line"),
    429       // r_dcache_miss_req("r_dcache_miss_req"),
    430       // r_dcache_miss_way("r_dcache_miss_way"),
    431       // r_dcache_miss_set("r_dcache_miss_set"),
    432       // r_dcache_unc_req("r_dcache_unc_req"),
    433       // r_dcache_sc_req("r_dcache_sc_req"),
    434       // r_dcache_inval_rsp("r_dcache_inval_rsp"),
    435       // r_dcache_update_addr("r_dcache_update_addr"),
    436       // r_dcache_ll_data("r_dcache_ll_data"),
    437       // r_dcache_ll_addr("r_dcache_ll_addr"),
    438       // r_dcache_ll_valid("r_dcache_ll_valid"),
    439       // r_dcache_previous_unc("r_dcache_previous_unc"),
    440 
    441       // r_tgt_icache_req("r_tgt_icache_req"),
    442       // r_tgt_icache_rsp("r_tgt_icache_rsp"),
    443 
    444       // r_tgt_dcache_req("r_tgt_dcache_req"),
    445       // r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
    446 
    447       // r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
    448       // r_vci_rsp_data_error("r_vci_rsp_data_error"),
    449 
    450       size_t _icache_ways  = icache_ways /m_nb_icache;
    451       size_t _icache_sets  = icache_sets ;
    452       size_t _dcache_ways  = dcache_ways /m_nb_dcache;
    453       size_t _dcache_sets  = dcache_sets ;
    454       size_t _icache_words = icache_words;
    455       size_t _dcache_words = dcache_words;
    456 
    457       size_t _wbuf_nwords  = wbuf_nwords ;
    458       size_t _wbuf_nlines  = wbuf_nlines /m_nb_dcache;
    459 
    460       r_icache = new GenericCache<vci_addr_t>  * [m_nb_icache];
    461       r_dcache = new GenericCache<vci_addr_t>  * [m_nb_dcache];
    462       r_wbuf   = new MultiWriteBuffer<addr_40> * [m_nb_dcache];
    463 
    464       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    465         {
    466           r_icache [num_cache] = new GenericCache<vci_addr_t>  ("icache", _icache_ways, _icache_sets, _icache_words);
    467         }
    468       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    469         {
    470           r_dcache [num_cache] = new GenericCache<vci_addr_t>  ("dcache", _dcache_ways, _dcache_sets, _dcache_words);
    471           r_wbuf   [num_cache] = new MultiWriteBuffer<addr_40> ("r_wbuf", _wbuf_nwords, _wbuf_nlines, _dcache_words);
    472         }
    473 
    474       m_num_cache_LSB_mask = 0;
    475       for (uint32_t i=0; i<m_num_cache_LSB; ++i)
    476         {
    477           m_num_cache_LSB_mask <<= 1;
    478           m_num_cache_LSB_mask  |= 1;
    479         }
    480       m_num_cache_mask = 0;
    481       for (uint32_t i=0; i<(m_num_cache_MSB-m_num_cache_LSB); ++i)
    482         {
    483           m_num_cache_mask <<= 1;
    484           m_num_cache_mask  |= 1;
    485         }
    486 
    487       SC_METHOD(transition);
    488       dont_initialize();
    489       sensitive << p_clk.pos();
    490 
    491       SC_METHOD(genMoore);
    492       dont_initialize();
    493       sensitive << p_clk.neg();
    494 
    495       typename iss_t::CacheInfo cache_info;
    496       cache_info.has_mmu          = false;
    497       cache_info.icache_line_size = icache_words*sizeof(data_t);
    498       cache_info.icache_assoc     = icache_ways;
    499       cache_info.icache_n_lines   = icache_sets;
    500       cache_info.dcache_line_size = dcache_words*sizeof(data_t);
    501       cache_info.dcache_assoc     = dcache_ways;
    502       cache_info.dcache_n_lines   = dcache_sets;
    503 
    504       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    505         m_iss[num_cpu]->setCacheInfo(cache_info);
    506                
    507 #if CC_XCACHE_WRAPPER_STOP_SIMULATION
    508       m_stop_simulation               = false;
    509       m_stop_simulation_nb_frz_cycles = new uint32_t [m_nb_cpu];
    510       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    511         m_stop_simulation_nb_frz_cycles [num_cpu] = 0;
    512 #endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
    513 
    514 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    515       generate_log_transaction_file_icache  = true;
    516       generate_log_transaction_file_dcache  = true;
    517       generate_log_transaction_file_cmd     = true;
    518       generate_log_transaction_file_tgt     = true;
    519       generate_log_transaction_file_cleanup = true;
    520 
    521       log_transaction_file_icache = new std::ofstream [m_nb_cpu];
    522       log_transaction_file_dcache = new std::ofstream [m_nb_cpu];
    523       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    524         {
    525           {
    526             std::ostringstream filename("");
    527             filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_icache-" << proc_id << "_" << num_cpu << ".log";
    528             log_transaction_file_icache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    529           }
    530           {
    531             std::ostringstream filename("");
    532             filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_dcache-" << proc_id << "_" << num_cpu << ".log";
    533             log_transaction_file_dcache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    534           }
    535         }
    536 
    537       {
    538         std::ostringstream filename("");
    539         filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cmd-" << proc_id << ".log";
    540         log_transaction_file_cmd.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    541       }
    542       {
    543         std::ostringstream filename("");
    544         filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_tgt-" << proc_id << ".log";
    545         log_transaction_file_tgt.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    546       }
    547       {
    548         std::ostringstream filename("");
    549         filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cleanup-" << proc_id << ".log";
    550         log_transaction_file_cleanup.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    551       }
     1737        if ( word < m_cache_words-1 )
     1738        {
     1739            std::cout << "  <PROC.DCACHE_MISS_UPDT> Matching coherence request:"
     1740                      << "  pop the FIFO, don't update the cache" << std::endl;
     1741        }
     1742        else
     1743        {
     1744            std::cout << "  <PROC.DCACHE_MISS_UPDT> Matching coherence request:"
     1745                      << " last word : send a cleanup request " << std::endl;
     1746        }
     1747    }
     1748    else
     1749    {
     1750        std::cout << "  <PROC.DCACHE_MISS_UPDT> Write one word:"
     1751                  << " address = " << addr
     1752                  << " / data = " << r_vci_rsp_fifo_dcache.read()
     1753                  << " / way = " << way
     1754                  << " / set = " << set
     1755                  << " / word = " << word << std::endl;
     1756    }
     1757}
    5521758#endif
    553 
    554 #if MWBUF_VHDL_TESTBENCH
    555       simulation_started = false;
    556 
    557       vhdl_testbench_mwbuf = new std::ofstream [m_nb_dcache];
    558       for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
    559         {
    560           std::ostringstream filename("");
    561           filename << "VHDL_testbench_mwbuf-" << proc_id << "_" << num_dcache << ".txt";
    562           vhdl_testbench_mwbuf[num_dcache].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
    563 
    564           vhdl_testbench_mwbuf[num_dcache]
    565             << _wbuf_nlines  << " "        // nb_lines     
    566             << _wbuf_nwords  << " "        // nb_words     
    567             << m_nb_cpu      << " "        // nb_cpu       
    568             << 32            << " "        // size_data     
    569             << 40            << " "        // size_addr     
    570             << _dcache_words << std::endl; // cache_nb_words
    571         }
    572 #endif
    573     } // end constructor
    574 
    575     ///////////////////////////////////
    576     tmpl(/**/)::~VciCcXCacheWrapperV4()
    577                ///////////////////////////////////
    578     {
    579 #if MWBUF_VHDL_TESTBENCH
    580       for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
    581         vhdl_testbench_mwbuf[num_dcache].close();
    582       delete [] vhdl_testbench_mwbuf;
    583 #endif
    584 
    585 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    586       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    587         {
    588           log_transaction_file_dcache[num_cpu].close();
    589           log_transaction_file_icache[num_cpu].close();
    590         }
    591       delete [] log_transaction_file_dcache;
    592       delete [] log_transaction_file_icache;
    593 
    594       log_transaction_file_cmd    .close();
    595       log_transaction_file_tgt    .close();
    596       log_transaction_file_cleanup.close();
    597 #endif
    598 
    599       delete [] m_stop_simulation_nb_frz_cycles;
    600 
    601 
    602       delete [] r_icache_lock         ;
    603       delete [] r_dcache_lock         ;
    604       delete [] r_dcache_sync         ;
    605 
    606       delete [] r_icache_fsm          ;
    607       delete [] r_icache_fsm_save     ;
    608       delete [] r_icache_addr_save    ;
    609       delete [] r_icache_miss_req     ;
    610       delete [] r_icache_miss_way     ;
    611       delete [] r_icache_miss_set     ;
    612       delete [] r_icache_unc_req      ;
    613       delete [] r_icache_cleanup_req  ;
    614       delete [] r_icache_cleanup_line ;
    615       delete [] r_icache_inval_rsp    ;
    616       delete [] r_icache_update_addr  ;
    617       delete [] r_icache_buf_unc_valid;
    618 
    619       delete [] r_dcache_fsm          ;
    620       delete [] r_dcache_fsm_save     ;
    621       delete [] r_dcache_addr_save    ;
    622       delete [] r_dcache_wdata_save   ;
    623       delete [] r_dcache_rdata_save   ;
    624       delete [] r_dcache_type_save    ;
    625       delete [] r_dcache_be_save      ;
    626       delete [] r_dcache_cached_save  ;
    627       delete [] r_dcache_cleanup_req  ;
    628       delete [] r_dcache_cleanup_line ;
    629       delete [] r_dcache_miss_req     ;
    630       delete [] r_dcache_miss_way     ;
    631       delete [] r_dcache_miss_set     ;
    632       delete [] r_dcache_unc_req      ;
    633       delete [] r_dcache_sc_req       ;
    634       delete [] r_dcache_inval_rsp    ;
    635       delete [] r_dcache_update_addr  ;
    636       delete [] r_dcache_previous_unc ;
    637 
    638       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    639         {
    640           delete [] r_dcache_ll_data    [num_cache];
    641           delete [] r_dcache_ll_addr    [num_cache];
    642           delete [] r_dcache_ll_valid   [num_cache];
    643         }
    644       delete [] r_dcache_num_cpu_save ;
    645       delete [] r_dcache_ll_data      ;
    646       delete [] r_dcache_ll_addr      ;
    647       delete [] r_dcache_ll_valid     ;
    648 
    649       delete [] r_tgt_icache_req      ;
    650       delete [] r_tgt_icache_rsp      ;
    651       delete [] r_tgt_dcache_req      ;
    652       delete [] r_tgt_dcache_rsp      ;
    653 
    654       delete [] r_tgt_be ;
    655       delete [] r_tgt_buf;
    656 
    657       delete [] r_vci_rsp_ins_error   ;
    658       delete [] r_vci_rsp_data_error  ;
    659 
    660       delete [] ireq           ;
    661       delete [] irsp           ;
    662       delete [] ireq_cached    ;
    663       delete [] ireq_num_cpu   ;
    664       delete [] dreq           ;
    665       delete [] drsp           ;
    666       delete [] dreq_cached    ;
    667       delete [] dreq_num_cpu   ;
    668 
    669       delete [] m_cpt_frz_cycles;
    670 
    671       delete [] m_cpt_icache_access   ;
    672       delete [] m_cpt_dcache_access   ;
    673       delete [] m_cpt_icache_miss_victim_wait;
    674       delete [] m_cpt_dcache_miss_victim_wait;
    675       delete [] m_cpt_dcache_store_after_store;
    676       delete [] m_cpt_dcache_hit_after_miss_read;
    677       delete [] m_cpt_dcache_hit_after_miss_write;
    678       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    679         delete [] m_cpt_fsm_dcache [num_cache];
    680       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    681         delete [] m_cpt_fsm_icache [num_cache];
    682        
    683       delete [] m_cpt_fsm_dcache ;
    684       delete [] m_cpt_fsm_icache ;
    685       delete [] m_cpt_fsm_cmd    ;
    686       delete [] m_cpt_fsm_rsp    ;
    687       delete [] m_cpt_fsm_tgt    ;
    688       delete [] m_cpt_fsm_cleanup;
    689 
    690       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    691         {
    692           delete r_icache [num_cache];
    693         }
    694       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    695         {
    696           delete r_wbuf   [num_cache];
    697           delete r_dcache [num_cache];
    698         }
    699       delete [] r_wbuf;
    700       delete [] r_icache;
    701       delete [] r_dcache;
    702 
    703       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    704         {
    705           delete    m_iss [num_cpu];
    706           delete [] p_irq [num_cpu];
    707         }
    708       delete [] m_iss;
    709       delete [] p_irq;
    710     }
    711 
    712     ////////////////////////
    713     tmpl(void)::print_cpi()
    714     ////////////////////////
    715     {
    716       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    717         std::cout << "CPU " << m_srcid_rw << " : CPI = "
    718                   << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]) << std::endl ;
    719     }
    720     ////////////////////////
    721     tmpl(void)::print_stats(bool print_wbuf, bool print_fsm)
    722                ////////////////////////
    723     {
    724       uint32_t m_cpt_data_read_cached  = m_cpt_data_read-m_cpt_data_read_uncached;
    725       uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached;
    726       std::cout << "------------------------------------" << std:: dec << std::endl;
    727       std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
    728       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    729         {
    730           float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]);
    731 
    732           std::cout << "- CPI                            : [" << num_cpu << "] "<< (float)m_cpt_total_cycles/run_cycles << std::endl ;
    733           std::cout << "- IPC                            : [" << num_cpu << "] "<< (float)run_cycles/m_cpt_total_cycles << std::endl ;
    734         }
    735       std::cout << "- DATA READ *                    : " << m_cpt_data_read << std::endl ;
    736       std::cout << "  + Uncached                     : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ;
    737       std::cout << "  + Cached and miss              : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl;
    738       std::cout << "- DATA WRITE *                   : " << m_cpt_data_write << std::endl ;
    739       std::cout << "  + Uncached                     : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ;
    740       std::cout << "  + Cached and miss              : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl;
    741       // std::cout << "- WRITE RATE                     : " << (float)m_cpt_data_write/run_cycles << std::endl;
    742       // std::cout << "- UNCACHED READ RATE             : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ;
    743       // std::cout << "- CACHED WRITE RATE              : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ;
    744       // std::cout << "- IMISS_RATE                     : " << (float)m_cpt_ins_miss/run_cycles << std::endl;
    745       // std::cout << "- DMISS RATE                     : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ;
    746       // std::cout << "- INS MISS COST                  : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
    747       // std::cout << "- IMISS TRANSACTION              : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
    748       // std::cout << "- DMISS COST                     : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
    749       // std::cout << "- DMISS TRANSACTION              : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
    750       // std::cout << "- UNC COST                       : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl;
    751       // std::cout << "- UNC TRANSACTION                : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
    752       // std::cout << "- WRITE COST                     : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl;
    753       // std::cout << "- WRITE TRANSACTION              : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl;
    754       // std::cout << "- WRITE LENGTH                   : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl;
    755 
    756       std::cout << "- CC_UPDATE_ICACHE               : " << m_cpt_cc_update_icache  << std::endl;
    757       std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl;
    758       std::cout << "- CC_UPDATE_DCACHE               : " << m_cpt_cc_update_dcache  << std::endl;
    759       std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl;
    760       uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache;
    761       std::cout << "- CC_INVALID                     : " << m_cpt_cc_inval << std::endl;
    762       std::cout << "  + ICACHE Only                  : " << (float)m_cpt_cc_inval_icache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
    763       std::cout << "  + DCACHE Only                  : " << (float)m_cpt_cc_inval_dcache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
    764       std::cout << "  + BROADCAST                    : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl;
    765 
    766       uint32_t m_cpt_icache_access_all = 0;
    767       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    768         m_cpt_icache_access_all += m_cpt_icache_access [num_cache];
    769 
    770       std::cout << "- ICACHE ACCESS                  : " << m_cpt_icache_access_all << std::endl;
    771       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    772         std::cout << "  + [" << num_cache << "] : " << m_cpt_icache_access [num_cache] << " (" << (float)m_cpt_icache_access [num_cache]*100.0/(float)m_cpt_icache_access_all << "%)" << std::endl;
    773 
    774       uint32_t m_cpt_dcache_access_all = 0;
    775       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    776         m_cpt_dcache_access_all += m_cpt_dcache_access [num_cache];
    777 
    778       std::cout << "- DCACHE ACCESS                  : " << m_cpt_dcache_access_all << std::endl;
    779       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    780         {
    781           std::cout << "  + [" << num_cache << "] : " << m_cpt_dcache_access [num_cache] << " (" << (float)m_cpt_dcache_access [num_cache]*100.0/(float)m_cpt_dcache_access_all << "%)";
    782 
    783           std::cout << " - store after store : " << m_cpt_dcache_store_after_store [num_cache];
    784           std::cout << " - Hit after Miss : Read " << m_cpt_dcache_hit_after_miss_read [num_cache] << ", Write " << m_cpt_dcache_hit_after_miss_write [num_cache];
    785           std::cout << std::endl;
    786         }
    787 
    788       uint32_t m_cpt_icache_miss_victim_wait_all = 0;
    789       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    790         m_cpt_icache_miss_victim_wait_all += m_cpt_icache_miss_victim_wait [num_cache];
    791       std::cout << "- ICACHE MISS VICTIM WAIT        : " << m_cpt_icache_miss_victim_wait_all << std::endl;
    792       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    793         std::cout << "  + [" << num_cache << "] : " << m_cpt_icache_miss_victim_wait [num_cache] << std::endl;
    794 
    795       uint32_t m_cpt_dcache_miss_victim_wait_all = 0;
    796       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    797         m_cpt_dcache_miss_victim_wait_all += m_cpt_dcache_miss_victim_wait [num_cache];
    798       std::cout << "- DCACHE MISS VICTIM WAIT        : " << m_cpt_dcache_miss_victim_wait_all << std::endl;
    799       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    800         std::cout << "  + [" << num_cache << "] : " << m_cpt_dcache_miss_victim_wait [num_cache] << std::endl;
    801 
    802       if (print_fsm)
    803         {
    804           std::cout << "- DCACHE FSM" << std::endl;
    805           for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
    806             {
    807               std::cout << "  + "  << dcache_fsm_state_str[i] << " :\t ";
    808               for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    809                 std::cout << m_cpt_fsm_dcache [num_cache][i] << ", ";
    810               std::cout << std::endl;
    811             }
    812           std::cout << "- ICACHE FSM" << std::endl;
    813           for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
    814             {
    815               std::cout << "  + "  << icache_fsm_state_str[i] << " :\t ";
    816               for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    817                 std::cout << m_cpt_fsm_icache [num_cache][i] << ", ";
    818               std::cout << std::endl;
    819             }
    820           std::cout << "- CMD FSM" << std::endl;
    821           for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i)
    822             std::cout << "  + " << cmd_fsm_state_str[i] << " :\t " << m_cpt_fsm_cmd [i] << std::endl;
    823           std::cout << "- RSP FSM" << std::endl;
    824           for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i)
    825             std::cout << "  + " << rsp_fsm_state_str[i] << " :\t " << m_cpt_fsm_rsp [i] << std::endl;
    826           std::cout << "- TGT FSM" << std::endl;
    827           for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i)
    828             std::cout << "  + "  << tgt_fsm_state_str[i] << " :\t " << m_cpt_fsm_tgt [i] << std::endl;
    829           std::cout << "- CLEANUP FSM" << std::endl;
    830           for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i)
    831             std::cout << "  + "  << cleanup_fsm_state_str[i] << " :\t " << m_cpt_fsm_cleanup [i] << std::endl;
    832         }
    833 
    834       std::cout << "* : accepted or not by the cache" << std::endl ;
    835 
    836       if (print_wbuf)
    837         for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    838           r_wbuf[num_cache]->printStatistics();
    839     }
    840 
    841     ////////////////////////////////////
    842     tmpl(void)::print_trace(size_t mode)
    843                ////////////////////////////////////
    844     {
    845       // b0 : write buffer print trace
    846       // b1 : write buffer verbose
    847       // b2 : dcache print trace
    848       // b3 : icache print trace
    849 
    850       typename iss_t::InstructionRequest  ireq;
    851       typename iss_t::DataRequest         dreq;
    852 
    853       std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl;
    854 
    855       for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    856         {
    857           m_iss[num_cpu]->getRequests( ireq, dreq );
    858           std::cout << ireq << std::endl;
    859           std::cout << dreq << std::endl;
    860         }
    861       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    862         std::cout << "  " << icache_fsm_state_str[r_icache_fsm[num_cache]] << std::endl;
    863       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    864         std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm[num_cache]] << std::endl;
    865            
    866       std::cout << "  " << cmd_fsm_state_str[r_vci_cmd_fsm]
    867                 << "  " << rsp_fsm_state_str[r_vci_rsp_fsm]
    868                 << "  " << tgt_fsm_state_str[r_vci_tgt_fsm]
    869                 << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
    870 
    871       if(mode & 0x1)
    872         {
    873           for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    874             r_wbuf[num_cache]->printTrace((mode>>1)&1);
    875         }
    876       if(mode & 0x4)
    877         {
    878           std::cout << "  Data cache" << std::endl;
    879           for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    880             r_dcache[num_cache]->printTrace();
    881         }
    882       if(mode & 0x8)
    883         {
    884           std::cout << "  Instruction cache" << std::endl;
    885           for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    886             r_icache[num_cache]->printTrace();
    887         }
    888     }
    889 
    890     //////////////////////////
    891     tmpl(void)::transition()
    892     //////////////////////////
    893     {
    894 
    895       /////////////////////////////////////////////////////////////////////
    896       // Reset
    897       /////////////////////////////////////////////////////////////////////
    898 
    899       if ( not p_resetn.read() ) {
    900 
    901         r_cpu_prior = 0;
    902 
    903         for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    904           m_iss[num_cpu]->reset();
    905 
    906         // FSM states
    907         for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    908           {
    909             r_icache_fsm [num_cache] = ICACHE_IDLE;
    910 
    911             r_icache_lock[num_cache] = m_nb_cpu;
    912           }
    913         for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    914           {
    915             r_dcache_fsm [num_cache] = DCACHE_IDLE;
    916 
    917             r_dcache_lock[num_cache] = m_nb_cpu;
    918             r_dcache_sync[num_cache] = false;
    919           }
    920 
    921         r_vci_cmd_fsm = CMD_IDLE;
    922         r_vci_rsp_fsm = RSP_IDLE;
    923         r_vci_tgt_fsm = TGT_IDLE;
    924         r_cleanup_fsm = CLEANUP_IDLE;
    925 
    926         for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    927           {
    928             // write buffer & caches
    929             r_icache[num_cache]->reset();
    930 
    931             // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
    932             r_icache_miss_req    [num_cache] = false;
    933             r_icache_unc_req     [num_cache] = false;
    934             r_icache_cleanup_req [num_cache] = false;
    935 
    936             // internal messages in DCACHE et ICACHE FSMs
    937             r_icache_inval_rsp   [num_cache] = false;
    938 
    939             // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
    940             r_icache_buf_unc_valid [num_cache] = false;
    941 
    942             // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
    943             r_tgt_icache_req     [num_cache] = false;
    944             r_tgt_icache_rsp     [num_cache] = false;
    945 
    946             r_vci_rsp_ins_error  [num_cache] = false;
    947           }// end for num_cache
    948 
    949         for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    950           {
    951             // write buffer & caches
    952             r_wbuf  [num_cache]->reset();
    953             r_dcache[num_cache]->reset();
    954 
    955             // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
    956             r_dcache_miss_req    [num_cache] = false;
    957             r_dcache_unc_req     [num_cache] = false;
    958             r_dcache_sc_req      [num_cache] = false;
    959             r_dcache_cleanup_req [num_cache] = false;
    960             r_dcache_previous_unc[num_cache] = false;
    961 
    962             // internal messages in DCACHE et ICACHE FSMs
    963             r_dcache_inval_rsp   [num_cache] = false;
    964 
    965             // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
    966             for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    967               r_dcache_ll_valid      [num_cache][num_cpu] = false;
    968 
    969             // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
    970             r_tgt_dcache_req     [num_cache] = false;
    971             r_tgt_dcache_rsp     [num_cache] = false;
    972 
    973             r_vci_rsp_data_error [num_cache] = false;
    974           }// end for num_cache
    975 
    976         r_cache_word         = 0;
    977 
    978         r_vci_cmd_dcache_prior     = false;
    979         r_vci_cmd_num_icache_prior = 0;
    980         r_vci_cmd_num_dcache_prior = 0;
    981 
    982         r_vci_rsp_fifo_icache_data      .init();
    983         r_vci_rsp_fifo_icache_num_cache .init();
    984         r_vci_rsp_fifo_dcache_data      .init();
    985         r_vci_rsp_fifo_dcache_num_cache .init();
    986        
    987         // activity counters
    988         m_cpt_dcache_data_read  = 0;
    989         m_cpt_dcache_data_write = 0;
    990         m_cpt_dcache_dir_read   = 0;
    991         m_cpt_dcache_dir_write  = 0;
    992         m_cpt_icache_data_read  = 0;
    993         m_cpt_icache_data_write = 0;
    994         m_cpt_icache_dir_read   = 0;
    995         m_cpt_icache_dir_write  = 0;
    996 
    997         m_cpt_cc_update_icache             = 0;
    998         m_cpt_cc_update_dcache             = 0;
    999         m_cpt_cc_inval_broadcast           = 0;
    1000         m_cpt_cc_inval_icache              = 0;
    1001         m_cpt_cc_inval_dcache              = 0;
    1002         m_cpt_cc_update_icache_word_useful = 0;
    1003         m_cpt_cc_update_dcache_word_useful = 0;
    1004 
    1005         for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    1006           m_cpt_frz_cycles [num_cpu]  = 0;
    1007         m_cpt_total_cycles = 0;
    1008 
    1009         m_cpt_data_read            = 0;
    1010         m_cpt_data_read_miss       = 0;
    1011         m_cpt_data_read_uncached   = 0;
    1012         m_cpt_data_write           = 0;
    1013         m_cpt_data_write_miss      = 0;
    1014         m_cpt_data_write_uncached  = 0;
    1015 
    1016         m_cpt_ins_miss     = 0;
    1017 
    1018         m_cost_write_frz = 0;
    1019         m_cost_data_miss_frz = 0;
    1020         m_cost_unc_read_frz = 0;
    1021         m_cost_ins_miss_frz = 0;
    1022 
    1023         m_cpt_imiss_transaction = 0;
    1024         m_cpt_dmiss_transaction = 0;
    1025         m_cpt_unc_transaction = 0;
    1026         m_cpt_data_write_transaction = 0;
    1027 
    1028         m_cost_imiss_transaction = 0;
    1029         m_cost_dmiss_transaction = 0;
    1030         m_cost_unc_transaction = 0;
    1031         m_cost_write_transaction = 0;
    1032         m_length_write_transaction = 0;
    1033 
    1034         for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1035           {
    1036             m_cpt_icache_access           [num_cache] = 0;
    1037             m_cpt_icache_miss_victim_wait [num_cache] = 0;
    1038 
    1039             for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
    1040               m_cpt_fsm_icache  [num_cache][i] = 0;
    1041           }
    1042         for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    1043           {
    1044             m_cpt_dcache_access               [num_cache] = 0;
    1045             m_cpt_dcache_miss_victim_wait     [num_cache] = 0;
    1046             m_cpt_dcache_store_after_store    [num_cache] = 0;
    1047             m_cpt_dcache_hit_after_miss_read  [num_cache] = 0;
    1048             m_cpt_dcache_hit_after_miss_write [num_cache] = 0;
    1049             for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
    1050               m_cpt_fsm_dcache  [num_cache][i] = 0;
    1051           }
    1052 
    1053         for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str    ); ++i)
    1054           m_cpt_fsm_cmd     [i] = 0;
    1055         for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str    ); ++i)
    1056           m_cpt_fsm_rsp     [i] = 0;
    1057         for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str    ); ++i)
    1058           m_cpt_fsm_tgt     [i] = 0;
    1059         for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str); ++i)
    1060           m_cpt_fsm_cleanup [i] = 0;
    1061 
    1062         return; // reset is finish, quit the transition fonction
    1063       }
    1064 
    1065       bool     vci_rsp_fifo_icache_get       = false;
    1066       bool     vci_rsp_fifo_icache_put       = false;
    1067       data_t   vci_rsp_fifo_icache_data      = 0;
    1068       uint32_t vci_rsp_fifo_icache_num_cache = 0;
    1069 
    1070       bool     vci_rsp_fifo_dcache_get       = false;
    1071       bool     vci_rsp_fifo_dcache_put       = false;
    1072       data_t   vci_rsp_fifo_dcache_data      = 0;
    1073       uint32_t vci_rsp_fifo_dcache_num_cache = 0;
    1074 
    1075       /////////////////////////////////////////////////////////////////////
    1076       // VHDL TESTBENCH
    1077       // Create and initialize variable
    1078       /////////////////////////////////////////////////////////////////////
    1079 
    1080 #if MWBUF_VHDL_TESTBENCH
    1081       simulation_started = true;
    1082 
    1083       vhdl_tb_t vhdl_mwbuf_test_empty            [m_nb_dcache];
    1084       vhdl_tb_t vhdl_mwbuf_port_empty            [m_nb_dcache];
    1085       vhdl_tb_t vhdl_mwbuf_port_flush            [m_nb_dcache];
    1086       vhdl_tb_t vhdl_mwbuf_port_write_val        [m_nb_dcache];
    1087       vhdl_tb_t vhdl_mwbuf_test_write_ack        [m_nb_dcache];
    1088       vhdl_tb_t vhdl_mwbuf_port_write_ack        [m_nb_dcache];
    1089       vhdl_tb_t vhdl_mwbuf_port_write_addr       [m_nb_dcache];
    1090       vhdl_tb_t vhdl_mwbuf_port_write_data       [m_nb_dcache];
    1091       vhdl_tb_t vhdl_mwbuf_port_write_be         [m_nb_dcache];
    1092       vhdl_tb_t vhdl_mwbuf_port_write_cached     [m_nb_dcache];
    1093       vhdl_tb_t vhdl_mwbuf_port_write_cpu_id     [m_nb_dcache];
    1094       vhdl_tb_t vhdl_mwbuf_test_sent_val         [m_nb_dcache];
    1095       vhdl_tb_t vhdl_mwbuf_port_sent_val         [m_nb_dcache];
    1096       vhdl_tb_t vhdl_mwbuf_port_sent_ack         [m_nb_dcache];
    1097       vhdl_tb_t vhdl_mwbuf_test_sent_word_min    [m_nb_dcache];
    1098       vhdl_tb_t vhdl_mwbuf_port_sent_word_min    [m_nb_dcache];
    1099       vhdl_tb_t vhdl_mwbuf_test_sent_word_max    [m_nb_dcache];
    1100       vhdl_tb_t vhdl_mwbuf_port_sent_word_max    [m_nb_dcache];
    1101       vhdl_tb_t vhdl_mwbuf_port_sent_word        [m_nb_dcache];
    1102       vhdl_tb_t vhdl_mwbuf_test_sent_addr        [m_nb_dcache];
    1103       vhdl_tb_t vhdl_mwbuf_port_sent_addr        [m_nb_dcache];
    1104       vhdl_tb_t vhdl_mwbuf_test_sent_data        [m_nb_dcache];
    1105       vhdl_tb_t vhdl_mwbuf_port_sent_data        [m_nb_dcache];
    1106       vhdl_tb_t vhdl_mwbuf_test_sent_be          [m_nb_dcache];
    1107       vhdl_tb_t vhdl_mwbuf_port_sent_be          [m_nb_dcache];
    1108       vhdl_tb_t vhdl_mwbuf_test_sent_index       [m_nb_dcache];
    1109       vhdl_tb_t vhdl_mwbuf_port_sent_index       [m_nb_dcache];
    1110       vhdl_tb_t vhdl_mwbuf_port_raw_test         [m_nb_dcache];
    1111       vhdl_tb_t vhdl_mwbuf_port_raw_addr         [m_nb_dcache];
    1112       vhdl_tb_t vhdl_mwbuf_test_raw_miss         [m_nb_dcache];
    1113       vhdl_tb_t vhdl_mwbuf_port_raw_miss         [m_nb_dcache];
    1114       vhdl_tb_t vhdl_mwbuf_port_completed_val    [m_nb_dcache];
    1115       vhdl_tb_t vhdl_mwbuf_port_completed_index  [m_nb_dcache];
    1116       vhdl_tb_t vhdl_mwbuf_test_completed_cached [m_nb_dcache];
    1117       vhdl_tb_t vhdl_mwbuf_port_completed_cached [m_nb_dcache];
    1118       vhdl_tb_t vhdl_mwbuf_test_completed_cpu_id [m_nb_dcache];
    1119       vhdl_tb_t vhdl_mwbuf_port_completed_cpu_id [m_nb_dcache];
    1120 
    1121       for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
    1122         {
    1123           vhdl_mwbuf_test_empty            [num_dcache] = 0;
    1124           vhdl_mwbuf_port_empty            [num_dcache] = 0;
    1125           vhdl_mwbuf_port_flush            [num_dcache] = 0;
    1126           vhdl_mwbuf_port_write_val        [num_dcache] = 0;
    1127           vhdl_mwbuf_test_write_ack        [num_dcache] = 0;
    1128           vhdl_mwbuf_port_write_ack        [num_dcache] = 0;
    1129           vhdl_mwbuf_port_write_addr       [num_dcache] = 0;
    1130           vhdl_mwbuf_port_write_data       [num_dcache] = 0;
    1131           vhdl_mwbuf_port_write_be         [num_dcache] = 0;
    1132           vhdl_mwbuf_port_write_cached     [num_dcache] = 0;
    1133           vhdl_mwbuf_port_write_cpu_id     [num_dcache] = 0;
    1134           vhdl_mwbuf_test_sent_val         [num_dcache] = 0;
    1135           vhdl_mwbuf_port_sent_val         [num_dcache] = 0;
    1136           vhdl_mwbuf_port_sent_ack         [num_dcache] = 0;
    1137           vhdl_mwbuf_test_sent_word_min    [num_dcache] = 0;
    1138           vhdl_mwbuf_port_sent_word_min    [num_dcache] = 0;
    1139           vhdl_mwbuf_test_sent_word_max    [num_dcache] = 0;
    1140           vhdl_mwbuf_port_sent_word_max    [num_dcache] = 0;
    1141           vhdl_mwbuf_port_sent_word        [num_dcache] = 0;
    1142           vhdl_mwbuf_test_sent_addr        [num_dcache] = 0;
    1143           vhdl_mwbuf_port_sent_addr        [num_dcache] = 0;
    1144           vhdl_mwbuf_test_sent_data        [num_dcache] = 0;
    1145           vhdl_mwbuf_port_sent_data        [num_dcache] = 0;
    1146           vhdl_mwbuf_test_sent_be          [num_dcache] = 0;
    1147           vhdl_mwbuf_port_sent_be          [num_dcache] = 0;
    1148           vhdl_mwbuf_test_sent_index       [num_dcache] = 0;
    1149           vhdl_mwbuf_port_sent_index       [num_dcache] = 0;
    1150           vhdl_mwbuf_port_raw_test         [num_dcache] = 0;
    1151           vhdl_mwbuf_port_raw_addr         [num_dcache] = 0;
    1152           vhdl_mwbuf_test_raw_miss         [num_dcache] = 0;
    1153           vhdl_mwbuf_port_raw_miss         [num_dcache] = 0;
    1154           vhdl_mwbuf_port_completed_val    [num_dcache] = 0;
    1155           vhdl_mwbuf_port_completed_index  [num_dcache] = 0;
    1156           vhdl_mwbuf_test_completed_cached [num_dcache] = 0;
    1157           vhdl_mwbuf_port_completed_cached [num_dcache] = 0;
    1158           vhdl_mwbuf_test_completed_cpu_id [num_dcache] = 0;
    1159           vhdl_mwbuf_port_completed_cpu_id [num_dcache] = 0;
    1160         }
    1161 #endif
    1162 
    1163       /////////////////////////////////////////////////////////////////////
    1164       // DEBUG :
    1165       // print state of all fsm and main register
    1166       /////////////////////////////////////////////////////////////////////
    1167 
    1168       // printf("%d\n",(uint32_t)m_cpt_total_cycles);
    1169 
    1170       PRINTF("--------------------------------------------\n");
    1171       PRINTF("  * CC_XCACHE_WRAPPER \"%s\" Transition - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
    1172       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    1173       PRINTF("    * fsm dcache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,dcache_fsm_state_str[r_dcache_fsm[num_cache]],r_dcache_lock[num_cache].read(),(blob_t)r_dcache_addr_save[num_cache].read(),(blob_t)set_num_dcache_only(r_dcache_addr_save[num_cache].read(),num_cache));
    1174       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1175         PRINTF("    * fsm icache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,icache_fsm_state_str[r_icache_fsm[num_cache]],r_icache_lock[num_cache].read(),(blob_t)r_icache_addr_save[num_cache].read(),(blob_t)set_num_icache_only(r_icache_addr_save[num_cache].read(),num_cache));
    1176       PRINTF("    * fsm cmd                 = (%.2d) %s\n",r_vci_cmd_num_cache.read(), cmd_fsm_state_str[r_vci_cmd_fsm]);
    1177       PRINTF("    * fsm rsp                 = (%.2d) %s\n",r_vci_rsp_num_cache.read(), rsp_fsm_state_str[r_vci_rsp_fsm]);
    1178       PRINTF("    * fsm tgt                 = (%.2d) %s - i %llx d %llx\n",r_tgt_num_cache.read(), tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_iaddr.read(),(blob_t)r_tgt_daddr.read());
    1179     //PRINTF("    * fsm tgt                 =      %s - %llx\n",tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_addr.read());
    1180       PRINTF("    * fsm cleanup             = (%.2d) %s\n",r_cleanup_num_cache.read(), cleanup_fsm_state_str[r_cleanup_fsm]);
    1181       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    1182         {
    1183           for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
    1184             PRINTF("    * ll info                 : [%.2d][%.2d] %d %llx (%llx) %llx\n"
    1185                    ,num_cache
    1186                    ,num_cpu
    1187                    ,          r_dcache_ll_valid [num_cache][num_cpu].read()
    1188                    ,(blob_t)r_dcache_ll_addr  [num_cache][num_cpu].read()
    1189                    ,(blob_t)set_num_dcache_only(r_dcache_ll_addr [num_cache][num_cpu].read(),num_cache)
    1190                    ,(blob_t)r_dcache_ll_data [num_cache][num_cpu].read());
    1191 
    1192           PRINTF("    * dcache_previous_unc     : [%.2d] %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
    1193 
    1194 #if CC_XCACHE_WRAPPER_DEBUG
    1195           if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
    1196             r_wbuf[num_cache]->printTrace(1);
    1197 #endif
    1198 
    1199           // VHDL debug
    1200 // #if MWBUF_VHDL_TESTBENCH
    1201 //           printf("\nMWBUF[%d] - Time = %d\n\n",num_cache,(uint32_t)m_cpt_total_cycles);
    1202 //           r_wbuf[num_cache]->printTrace(1);
    1203 // #endif
    1204         }
    1205 #if CC_XCACHE_WRAPPER_DEBUG
    1206       if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
    1207       {
    1208           PRINTF("    * rsp_fifo_icache %s\n",name().c_str());
    1209           r_vci_rsp_fifo_icache_data     .print();
    1210           r_vci_rsp_fifo_icache_num_cache.print();
    1211           PRINTF("    * rsp_fifo_dcache %s\n",name().c_str());
    1212           r_vci_rsp_fifo_dcache_data     .print();
    1213           r_vci_rsp_fifo_dcache_num_cache.print();
    1214       }
    1215 #endif
    1216 
    1217       /////////////////////////////////////////////////////////////////////
    1218       // Statistics
    1219       // Count state fsm activity
    1220       /////////////////////////////////////////////////////////////////////
    1221 
    1222 
    1223       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    1224         m_cpt_fsm_dcache  [num_cache][r_dcache_fsm[num_cache]] ++;
    1225       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1226         m_cpt_fsm_icache  [num_cache][r_icache_fsm[num_cache]] ++;
    1227       m_cpt_fsm_cmd     [r_vci_cmd_fsm] ++;
    1228       m_cpt_fsm_rsp     [r_vci_rsp_fsm] ++;
    1229       m_cpt_fsm_tgt     [r_vci_tgt_fsm] ++;
    1230       m_cpt_fsm_cleanup [r_cleanup_fsm] ++;
    1231 
    1232       m_cpt_total_cycles++;
    1233 
    1234       /////////////////////////////////////////////////////////////////////
    1235       // The TGT_FSM controls the following ressources:
    1236       // - r_vci_tgt_fsm
    1237       // - r_tgt_buf[nwords]
    1238       // - r_tgt_be[nwords]
    1239       // - r_tgt_update
    1240       // - r_tgt_word
    1241       // - r_tgt_addr
    1242       // - r_tgt_srcid
    1243       // - r_tgt_trdid
    1244       // - r_tgt_pktid
    1245       // All VCI commands must be CMD_WRITE.
    1246       // If the VCI address offset is null, the command is an invalidate
    1247       // request. It is an update request otherwise.
    1248       // The VCI_TGT FSM stores the external request arguments in the
    1249       // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req
    1250       // & r_tgt_dcache_req flip-flops to signal the external request to
    1251       // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
    1252       // of the update or invalidate request in the RSP state.
    1253       // -  for an invalidate request the VCI packet length is 1 word.
    1254       // The WDATA field contains the line index (i.e. the Z & Y fields).
    1255       // -  for an update request the VCI packet length is (n+2) words.
    1256       // The WDATA field of the first VCI word contains the line number.
    1257       // The WDATA field of the second VCI word contains the word index.
    1258       // The WDATA field of the n following words contains the values.
    1259       // -  for both invalidate & update requests, the VCI response
    1260       // is one single word.
    1261       // In case of errors in the VCI command packet, the simulation
    1262       // is stopped with an error message.
    1263       /////////////////////////////////////////////////////////////////////
    1264 
    1265       switch(r_vci_tgt_fsm) {
    1266 
    1267       case TGT_IDLE:
    1268         if ( p_vci_tgt.cmdval.read() )
    1269           {
    1270             PRINTF("    * <TGT> Request\n");
    1271 
    1272             addr_40 address = p_vci_tgt.address.read();
    1273 
    1274             if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE)
     1759            }
     1760            break;
     1761        }
     1762        /////////////////////
     1763        case DCACHE_UNC_WAIT:       // Waiting the response to an uncached request
     1764        {
     1765            if ( r_tgt_dcache_req )    // coherence request
     1766            {
     1767                r_dcache_fsm      = DCACHE_CC_CHECK;
     1768                r_dcache_fsm_save = r_dcache_fsm;
     1769                break;
     1770            }
     1771
     1772            if ( r_vci_rsp_data_error )
     1773            {
     1774                r_dcache_fsm = DCACHE_ERROR;
     1775            }
     1776            else if ( r_vci_rsp_fifo_dcache.rok() )
     1777            {
     1778                vci_rsp_fifo_dcache_get = true;
     1779                r_dcache_unc_valid      = true;
     1780                r_dcache_unc_buf        = r_vci_rsp_fifo_dcache.read();
     1781                r_dcache_fsm            = DCACHE_IDLE;
     1782            }
     1783            break;
     1784        }
     1785        //////////////////
     1786        case DCACHE_ERROR:      // signal a read bus error to the processor
     1787        {
     1788            r_dcache_fsm         = DCACHE_IDLE;
     1789            r_vci_rsp_data_error = false;
     1790            drsp.error           = true;
     1791            drsp.valid           = true;
     1792            break;
     1793        }
     1794        //////////////////   
     1795        case DCACHE_INVAL:      // XTN inval is done in two cycles
     1796                                // In this state we test the cache hit
     1797        {                   
     1798            uint32_t    data;   // unused
     1799            size_t      word;   // unused
     1800            size_t      way;
     1801            size_t      set;
     1802            bool        hit = r_dcache->read( r_dcache_wdata_save.read(),
     1803                                              &data,
     1804                                              &way,
     1805                                              &set,
     1806                                              &word );
     1807            if ( hit )  // inval to be done
     1808            {
     1809                r_dcache_way_save = way;
     1810                r_dcache_set_save = set;
     1811                r_dcache_fsm      = DCACHE_INVAL_GO;
     1812            }
     1813            else        // nothing to do
     1814            {
     1815                drsp.valid        = true;
     1816                r_dcache_fsm      = DCACHE_IDLE;
     1817            }
     1818            break;
     1819        }
     1820        /////////////////////   
     1821        case DCACHE_INVAL_GO:   // XTN inval is done in two cycles
     1822                                // In this state we wait to post a cleanup request
     1823                                // and make the inval when cleanup is possible
     1824        {
     1825
     1826            if ( r_tgt_dcache_req )  // coherence request
     1827            {   
     1828                r_dcache_fsm      = DCACHE_CC_CHECK;
     1829                r_dcache_fsm_save = r_dcache_fsm;
     1830                break;
     1831            }
     1832
     1833            if ( not r_dcache_cleanup_req .read() )
     1834            {
     1835                vci_addr_t  nline;
     1836                r_dcache_cleanup_req  = r_dcache->inval( r_dcache_way_save.read(),
     1837                                                         r_dcache_set_save.read(),
     1838                                                         &nline );
     1839
     1840                r_dcache_cleanup_line = r_dcache_wdata_save.read() >> m_cache_words_shift;
     1841                r_dcache_fsm          = DCACHE_IDLE;
     1842                drsp.valid            = true;     
     1843            }
     1844            break;
     1845        }
     1846        /////////////////
     1847        case DCACHE_SYNC:       // waiting until the write buffer is empty
     1848        {
     1849            if ( r_tgt_dcache_req )  // coherence request
     1850            {   
     1851                r_dcache_fsm      = DCACHE_CC_CHECK;
     1852                r_dcache_fsm_save = r_dcache_fsm;
     1853                break;
     1854            }
     1855
     1856            if ( r_wbuf->empty() );
     1857            {
     1858                drsp.valid    = true;     
     1859                r_dcache_fsm  = DCACHE_IDLE;
     1860            }
     1861            break;
     1862        }
     1863        /////////////////////
     1864        case DCACHE_CC_CHECK:   // read directory in case of coherence request
     1865        {
     1866            vci_addr_t  addr  = r_tgt_addr.read();
     1867            vci_addr_t  mask  = ~((m_cache_words<<2)-1);
     1868
     1869            if( (r_dcache_fsm_save.read() == DCACHE_MISS_WAIT) and
     1870                 ((r_dcache_addr_save.read() & mask) == (addr & mask)) )
     1871                 // The coherence request matches a pending miss
     1872            {
     1873                r_dcache_miss_inval = true;
     1874                r_tgt_dcache_req    = false;
     1875                r_tgt_dcache_rsp    = r_tgt_update.read();
     1876                r_dcache_fsm        = r_dcache_fsm_save.read();
     1877            }
     1878            else    // no match for a pending miss
     1879            {
     1880                size_t  way;
     1881                size_t  set;
     1882                size_t  word;
     1883                bool    hit   = r_dcache->hit( addr,
     1884                                               &way,
     1885                                               &set,
     1886                                               &word );
     1887                r_dcache_cc_way = way;
     1888                r_dcache_cc_set = set;
     1889
     1890                m_conso_dcache_dir_read++;
     1891
     1892                if ( hit and r_tgt_update.read() )          // hit update
     1893                {
     1894                    r_dcache_fsm         = DCACHE_CC_UPDT;
     1895                    r_dcache_update_word = r_tgt_word_min.read();
     1896                }
     1897                else if (hit and not r_tgt_update.read() )  // hit inval
     1898                {
     1899                    r_dcache_fsm         = DCACHE_CC_INVAL;
     1900                }
     1901                else                                        // miss can happen
     1902                {
     1903                    r_tgt_dcache_req = false;
     1904                    r_tgt_dcache_rsp = r_tgt_update.read();
     1905                    r_dcache_fsm     = r_dcache_fsm_save.read();
     1906                }
     1907            }
     1908            break;
     1909        }
     1910        /////////////////////
     1911        case DCACHE_CC_INVAL: 
     1912        {
     1913            vci_addr_t  nline;
     1914            r_dcache->inval( r_dcache_cc_way.read(),
     1915                             r_dcache_cc_set.read(),
     1916                             &nline );
     1917            r_tgt_dcache_req = false;
     1918            r_tgt_dcache_rsp = true;
     1919            r_dcache_fsm     = r_dcache_fsm_save.read();
     1920            break;
     1921        }
     1922        ////////////////////
     1923        case DCACHE_CC_UPDT:   
     1924        {
     1925              size_t word = r_dcache_update_word.read();
     1926              r_dcache->write( r_dcache_cc_way.read(),
     1927                               r_dcache_cc_set.read(),
     1928                               word,
     1929                               r_tgt_buf[ word].read(),
     1930                               r_tgt_be[word].read() );
     1931
     1932              r_dcache_update_word = word+1;
     1933              if ( word == r_tgt_word_max.read() )      // last word
    12751934              {
    1276                 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1277                 std::cout << "coherence request is not a write" << std::endl;
    1278                 std::cout << "address = " << std::hex << address << std::dec << std::endl;
    1279                 std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
    1280                 exit(0);
    1281               }
    1282 
    1283             // multi-update or multi-invalidate for data type
    1284             if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) )
    1285               {
    1286                 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1287                 std::cout << "out of segment coherence request" << std::endl;
    1288                 std::cout << "address = " << std::hex << address << std::dec << std::endl;
    1289                 std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
    1290                 exit(0);
    1291               }
    1292 
    1293             addr_40 tgt_addr  = ((((addr_40)p_vci_tgt.be.read() & 0x3) << 32) | ((addr_40) p_vci_tgt.wdata.read())) << (addr_40)m_dcache_words_shift;
    1294             // * m_dcache_words * 4;
    1295 
    1296             addr_40 tgt_iaddr = tgt_addr;
    1297             addr_40 tgt_daddr = tgt_addr;
    1298 
    1299             PRINTF("    * <TGT> srcid            : %d\n",(uint32_t)p_vci_tgt.srcid.read());
    1300             PRINTF("    * <TGT> trdid            : %d\n",(uint32_t)p_vci_tgt.trdid.read());
    1301             PRINTF("    * <TGT> pktid            : %d\n",(uint32_t)p_vci_tgt.pktid.read());
    1302             PRINTF("    * <TGT> address (before) : %llx\n",(blob_t)tgt_iaddr);
    1303 
    1304             r_tgt_srcid     = p_vci_tgt.srcid.read();
    1305             r_tgt_trdid     = p_vci_tgt.trdid.read();
    1306             r_tgt_pktid     = p_vci_tgt.pktid.read();
    1307             // r_tgt_plen      = p_vci_tgt.plen.read();
    1308                    
    1309             // BROADCAST
    1310             if ( (address&0x3) == 0x3 )   // broadcast invalidate for data or instruction type
    1311               {
    1312                 if ( not p_vci_tgt.eop.read() )
    1313                   {
    1314                     std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1315                     std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
    1316                     exit(0);
    1317                   }
    1318                 r_tgt_update = false;
    1319                 // r_tgt_brdcast= true;
    1320                 r_vci_tgt_fsm = TGT_REQ_BROADCAST;
    1321                 uint32_t tgt_num_cache;
    1322                 tgt_num_cache = get_num_icache(tgt_iaddr,0); // none effect (else CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    1323                 tgt_num_cache = get_num_dcache(tgt_daddr);
    1324                 r_tgt_num_cache = tgt_num_cache;
    1325 
    1326                 PRINTF("    * <TGT> REQ_BROADCAST\n");
    1327                 PRINTF("    * <TGT> num_cache (data) : %d\n",tgt_num_cache);
    1328 
    1329                 m_cpt_cc_inval_broadcast++ ;
    1330 
    1331 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1332                 if (generate_log_transaction_file_tgt)
    1333                   {
    1334                     log_transaction_file_tgt
    1335                       << "[" << m_cpt_total_cycles << "] "
    1336                       << "BROADCAST  "
    1337                       << std::hex
    1338                       << " L " << std::setw(10) << (blob_t)tgt_addr
    1339                       << std::dec
    1340                       << " - " << tgt_num_cache
    1341                       << std::endl;
    1342                   }
    1343 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1344 
    1345               }
    1346             else                    // multi-update or multi-invalidate for data type
    1347               {
    1348                 uint32_t cell = address - m_segment.baseAddress(); // addr_40
    1349                 // r_tgt_brdcast = false;
    1350 
    1351                 if (cell == 0)
    1352                   {                                       // invalidate data
    1353                     if ( not p_vci_tgt.eop.read() )
    1354                       {
    1355                         std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1356                         std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
    1357                         exit(0);
    1358                       }
    1359                     r_tgt_update = false;
    1360                     r_vci_tgt_fsm = TGT_REQ_DCACHE;
    1361                     uint32_t tgt_num_cache = get_num_dcache(tgt_daddr); // static partionnement
    1362                     r_tgt_num_cache = tgt_num_cache;
    1363                            
    1364                     PRINTF("    * <TGT> REQ_DCACHE\n");
    1365                     PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
    1366 
    1367                     m_cpt_cc_inval_dcache++ ;
    1368 
    1369 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1370                     if (generate_log_transaction_file_tgt)
    1371                       {
    1372                         log_transaction_file_tgt
    1373                           << "[" << m_cpt_total_cycles << "] "
    1374                           << "INVAL DATA "
    1375                           << std::hex
    1376                           << " L " << std::setw(10) << (blob_t)tgt_addr
    1377                           << std::dec
    1378                           << " - " << tgt_num_cache
    1379                           << std::endl;
    1380                       }
    1381 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1382 
    1383                   }
    1384                 else if (cell == 4)                     // invalidate instruction
    1385                   {                         
    1386                     if ( not p_vci_tgt.eop.read() )
    1387                       {
    1388                         std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
    1389                         std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
    1390                         exit(0);
    1391                       }
    1392                     r_tgt_update = false;
    1393                     r_vci_tgt_fsm = TGT_REQ_ICACHE;
    1394                     uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
    1395                     uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
    1396                     r_tgt_num_cache = tgt_num_cache;
    1397                            
    1398                     PRINTF("    * <TGT> REQ_ICACHE\n");
    1399                     PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
    1400 
    1401                     m_cpt_cc_inval_icache++ ;
    1402 
    1403 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1404                     if (generate_log_transaction_file_tgt)
    1405                       {
    1406                         log_transaction_file_tgt
    1407                           << "[" << m_cpt_total_cycles << "] "
    1408                           << "INVAL INS  "
    1409                           << std::hex
    1410                           << " L " << std::setw(10) << (blob_t)tgt_addr
    1411                           << std::dec
    1412                           << " - " << tgt_num_cache
    1413                           << std::endl;
    1414                       }
    1415 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1416 
    1417                   }
    1418                 else if ( (cell == 8) or (cell==12) )    // update data or instruction
    1419                   {                               
    1420                     if ( p_vci_tgt.eop.read() )
    1421                       {
    1422                         std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
    1423                         std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
    1424                         exit(0);
    1425                       }
    1426                     if(cell == 8)
    1427                       {
    1428                         m_cpt_cc_update_dcache++;
    1429                         r_tgt_update_data = true;
    1430 
    1431                         uint32_t tgt_num_cache = get_num_dcache(tgt_daddr);
    1432                         r_tgt_num_cache = tgt_num_cache;
    1433                                
    1434                         PRINTF("    * <TGT> UPDT_WORD DATA\n");
    1435                         PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
    1436 
    1437 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1438                         if (generate_log_transaction_file_tgt)
    1439                           {
    1440                             log_transaction_file_tgt
    1441                               << "[" << m_cpt_total_cycles << "] "
    1442                               << "UPT DATA   "
    1443                               << std::hex
    1444                               << " L " << std::setw(10) << (blob_t)tgt_addr
    1445                               << std::dec
    1446                               << " - " << tgt_num_cache
    1447                               << std::endl;
    1448                           }
    1449 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1450                       }
    1451                     else
    1452                       {
    1453                         m_cpt_cc_update_icache++;
    1454                         r_tgt_update_data = false;
    1455 
    1456                         uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
    1457                         uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
    1458                         r_tgt_num_cache = tgt_num_cache;
    1459                                
    1460                         PRINTF("    * <TGT> UPDT_WORD INSTRUCTION\n");
    1461                         PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
    1462 
    1463 #if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1464                         if (generate_log_transaction_file_tgt)
    1465                           {
    1466                             log_transaction_file_tgt
    1467                               << "[" << m_cpt_total_cycles << "] "
    1468                               << "UPT INS    "
    1469                               << std::hex
    1470                               << " L " << std::setw(10) << (blob_t)tgt_addr
    1471                               << std::dec
    1472                               << " - " << tgt_num_cache
    1473                               << std::endl;
    1474                           }
    1475 #endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
    1476                       }
    1477                     r_tgt_update = true;
    1478                     r_vci_tgt_fsm = TGT_UPDT_WORD;
    1479                   }
    1480 
    1481               } // end if address
    1482                    
    1483             r_tgt_iaddr      = tgt_iaddr;
    1484             r_tgt_daddr      = tgt_daddr;
    1485             PRINTF("    * <TGT> address (after)  : i %llx, d %llx\n",(blob_t)tgt_iaddr,(blob_t)tgt_daddr);
    1486 
    1487           } // end if cmdval
    1488         break;
    1489 
    1490       case TGT_UPDT_WORD:
    1491         if (p_vci_tgt.cmdval.read())
    1492           {
    1493             if ( p_vci_tgt.eop.read() )
    1494               {
    1495                 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1496                 std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
    1497                 exit(0);
    1498               }
    1499             for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0;
    1500             r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
    1501             r_vci_tgt_fsm = TGT_UPDT_DATA;
    1502           }
    1503         break;
    1504 
    1505       case TGT_UPDT_DATA:
    1506         if (p_vci_tgt.cmdval.read())
    1507           {
    1508             size_t word = r_tgt_word.read();
    1509             if ( word >= m_cache_words )
    1510               {
    1511                 std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
    1512                 std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
    1513                 exit(0);
    1514               }
    1515 
    1516             r_tgt_buf[word] = p_vci_tgt.wdata.read();
    1517             r_tgt_be [word] = p_vci_tgt.be.read();
    1518 
    1519             if (p_vci_tgt.be.read())
    1520               {
    1521                 if(r_tgt_update_data.read())
    1522                   m_cpt_cc_update_dcache_word_useful++ ;
    1523                 else
    1524                   m_cpt_cc_update_icache_word_useful++ ;
    1525               }
    1526 
    1527             r_tgt_word = word + 1;
    1528             if (p_vci_tgt.eop.read()){
    1529 
    1530               uint32_t word=0;
    1531               for (; word<m_cache_words; ++word)
    1532                 if (r_tgt_be[word] != 0)
    1533                   break;
    1534               r_cache_word = word;
    1535 
    1536               if(r_tgt_update_data.read()){
    1537                 r_vci_tgt_fsm = TGT_REQ_DCACHE;
    1538               } else {
    1539                 r_vci_tgt_fsm = TGT_REQ_ICACHE;
    1540               }
    1541             }
    1542           }
    1543         break;
    1544 
    1545       case TGT_REQ_BROADCAST:
    1546         {
    1547           bool tgt_icache_req;
    1548 
    1549 #if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    1550           tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
    1551 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    1552           tgt_icache_req = false;
    1553           for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1554             tgt_icache_req |= r_tgt_icache_req[num_cache].read();
    1555 #endif
    1556           if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
    1557             {
    1558               r_vci_tgt_fsm = TGT_RSP_BROADCAST;
    1559 
    1560 #if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    1561               r_tgt_icache_req[r_tgt_num_cache] = true;
    1562 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    1563               for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1564                 r_tgt_icache_req[      num_cache] = true;
    1565 #endif
    1566 
    1567               r_tgt_dcache_req[r_tgt_num_cache] = true;
    1568             }
    1569         }
    1570         break;
    1571         ////////////////////
    1572       case TGT_REQ_ICACHE:
    1573         {
    1574           // Request treated by the icache
    1575           if ( not r_tgt_icache_req[r_tgt_num_cache].read() )
    1576             {
    1577               r_vci_tgt_fsm = TGT_RSP_ICACHE;
    1578               r_tgt_icache_req[r_tgt_num_cache] = true;
    1579             }
    1580           break;
    1581         }
    1582 
    1583       case TGT_REQ_DCACHE:
    1584         {
    1585           // Request treated by the dcache
    1586 
    1587           if ( not r_tgt_dcache_req[r_tgt_num_cache].read() )
    1588             {
    1589               r_vci_tgt_fsm = TGT_RSP_DCACHE;
    1590               r_tgt_dcache_req[r_tgt_num_cache] = true;
    1591             }
    1592           break;
    1593         }
    1594       case TGT_RSP_BROADCAST:
    1595         {
    1596           PRINTF("      * <TGT> dcache[%d] : %d - %d\n",(uint32_t)r_tgt_num_cache, (uint32_t)r_tgt_dcache_req[r_tgt_num_cache].read(),(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
    1597           for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1598             PRINTF("      * <TGT> icache[%d] : %d - %d\n",(uint32_t)num_cache, (uint32_t)r_tgt_icache_req[num_cache].read(),(uint32_t)r_tgt_icache_rsp[num_cache].read());
    1599 
    1600           bool tgt_icache_req;
    1601                    
    1602 #if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    1603           tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
    1604 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    1605           tgt_icache_req = false;
    1606           for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1607             tgt_icache_req |= r_tgt_icache_req[num_cache].read();
    1608 #endif
    1609           if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read())
    1610             {
    1611               bool     tgt_icache_rsp;
    1612               uint32_t tgt_icache_rsp_num_cache;
    1613                        
    1614 #if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
    1615               tgt_icache_rsp_num_cache = r_tgt_num_cache;
    1616               tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
    1617 #elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
    1618               tgt_icache_rsp_num_cache = 0;
    1619               for (;tgt_icache_rsp_num_cache<m_nb_icache; ++tgt_icache_rsp_num_cache)
    1620                 {
    1621                   PRINTF("      * <TGT> icache[%d] : %d\n",(uint32_t)tgt_icache_rsp_num_cache, (uint32_t)r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read());
    1622                            
    1623                   if (r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read())
    1624                     break;
    1625                 }
    1626 
    1627               tgt_icache_rsp = (tgt_icache_rsp_num_cache<m_nb_icache);
    1628 #endif
    1629 
    1630               PRINTF("      * <TGT> icache_rsp [%d] : %d\n",tgt_icache_rsp_num_cache,(uint32_t) tgt_icache_rsp);
    1631               PRINTF("      * <TGT> dcache_rsp [%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t) r_tgt_dcache_rsp[r_tgt_num_cache]);
    1632 
    1633               if (tgt_icache_rsp or r_tgt_dcache_rsp[r_tgt_num_cache])
    1634                 {
    1635                   // Have send one response
    1636                   if ( p_vci_tgt.rspack.read())
    1637                     {
    1638                       // reset dcache if activated
    1639                       if (r_tgt_dcache_rsp[r_tgt_num_cache])
    1640                         r_tgt_dcache_rsp[r_tgt_num_cache] = false;
    1641                       else
    1642                         // reset one icache
    1643                         r_tgt_icache_rsp[tgt_icache_rsp_num_cache] = false;
    1644                     }
    1645                 }
    1646 
    1647               // // one response
    1648               // if ( not r_tgt_icache_rsp[r_tgt_num_cache] or not r_tgt_dcache_rsp[r_tgt_num_cache] )
    1649               // {
    1650               //     if ( p_vci_tgt.rspack.read() )
    1651               //     {
    1652               //         r_vci_tgt_fsm = TGT_IDLE;
    1653               //         r_tgt_icache_rsp[r_tgt_num_cache] = false;
    1654               //         r_tgt_dcache_rsp[r_tgt_num_cache] = false;
    1655               //     }
    1656               // }
    1657                        
    1658               // // if data and instruction have the inval line, need two responses 
    1659               // if ( r_tgt_icache_rsp[r_tgt_num_cache] and r_tgt_dcache_rsp[r_tgt_num_cache] )
    1660               // {
    1661               //     if ( p_vci_tgt.rspack.read() )
    1662               //     {
    1663               //         r_tgt_icache_rsp[r_tgt_num_cache] = false; // only reset one for respond the second time
    1664               //     }
    1665               // }
    1666 
    1667               PRINTF("      * <TGT> icache_rsp    : %d\n",(uint32_t) r_tgt_icache_rsp[r_tgt_num_cache]);
    1668               PRINTF("      * <TGT> dcache_rsp[%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
    1669               // if there is no need for a response
    1670               if (not tgt_icache_rsp and not r_tgt_dcache_rsp[r_tgt_num_cache] )
    1671                 {
    1672                   r_vci_tgt_fsm = TGT_IDLE;
    1673                 }
    1674                        
    1675             }
    1676           break;
    1677         }
    1678         ////////////////////
    1679       case TGT_RSP_ICACHE:
    1680         {
    1681           bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp[r_tgt_num_cache].read()) and not r_tgt_icache_req[r_tgt_num_cache].read();
    1682 
    1683           PRINTF("      * <TGT> RSP_ICACHE : transaction : %d ((%d or not %d) and not %d)\n",transaction_rsp
    1684                  ,(int)p_vci_tgt.rspack.read()
    1685                  ,(int)r_tgt_icache_rsp[r_tgt_num_cache].read()
    1686                  ,(int)r_tgt_icache_req[r_tgt_num_cache].read()
    1687                  );
    1688 
    1689           if (transaction_rsp)
    1690             {
    1691               r_vci_tgt_fsm = TGT_IDLE;
    1692               r_tgt_icache_rsp[r_tgt_num_cache] = false;
    1693             }
    1694           break;
    1695         }
    1696 
    1697       case TGT_RSP_DCACHE:
    1698         {
    1699           bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp[r_tgt_num_cache].read()) and not r_tgt_dcache_req[r_tgt_num_cache].read();
    1700 
    1701           PRINTF("      * <TGT> RSP_DCACHE : transaction : %d\n",transaction_rsp);
    1702 
    1703           if (transaction_rsp)
    1704             {
    1705               r_vci_tgt_fsm = TGT_IDLE;
    1706               r_tgt_dcache_rsp[r_tgt_num_cache] = false;
    1707             }
    1708           break;
    1709         }
    1710       } // end switch TGT_FSM
    1711 
    1712         /////////////////////////////////////////////////////////////////////
    1713         // Interface between CPU and CACHE FSM
    1714         ///////////////////////////////////////////////////////////////////////
    1715 
    1716       uint32_t ireq_num_cache [m_nb_cpu];
    1717       uint32_t dreq_num_cache [m_nb_cpu];
    1718       bool     have_sync = false;
    1719 
    1720       {
    1721         typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
    1722         typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
    1723 
    1724         for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1725           {
    1726             ireq [num_cache] = _ireq;
    1727             //irsp [num_cache] = _irsp;
    1728           }
    1729         for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    1730           {
    1731             dreq [num_cache] = _dreq;
    1732             //drsp [num_cache] = _drsp;
    1733                
    1734             have_sync |= r_dcache_sync [num_cache];
    1735           }
    1736       }
    1737 
    1738       for (uint32_t _num_cpu=0; _num_cpu<m_nb_cpu; ++_num_cpu)
    1739         {
    1740           // round robin priority
    1741           uint32_t num_cpu = (r_cpu_prior+_num_cpu)%m_nb_cpu;
    1742 
    1743           typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
    1744           typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
    1745            
    1746           m_iss[num_cpu]->getRequests(_ireq, _dreq);
    1747 
    1748           addr_40  addr;
    1749           uint32_t num_cache;
    1750 
    1751           addr      = (addr_40)_ireq.addr;
    1752           num_cache = get_num_icache(addr,num_cpu);
    1753 
    1754           bool icache_req_valid = ((not ireq[num_cache].valid and               // no previous request in this cycle
    1755                                     (r_icache_lock [num_cache] == m_nb_cpu)) or // no previous request in previous cycle
    1756                                    (r_icache_lock [num_cache] == num_cpu));     // previous request in previous cycle by this cpu
    1757 
    1758           if (icache_req_valid)
    1759             {
    1760               bool valid = _ireq.valid;
    1761 
    1762               if (valid)
    1763                 {
    1764                   PRINTF("    * <CPU2CACHE> ICACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
    1765                   ireq_num_cache [num_cpu  ] = num_cache;
    1766                   r_icache_lock [num_cache] = num_cpu;
    1767                 }
    1768               else
    1769                 {
    1770                   PRINTF("    * <CPU2CACHE> ICACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
    1771                   ireq_num_cache [num_cpu] = m_nb_icache;
    1772                 }
    1773 
    1774               ireq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_ireq.addr];
    1775               ireq_num_cpu   [num_cache] = num_cpu;
    1776               ireq           [num_cache] = _ireq;
    1777               ireq           [num_cache].addr = addr;
    1778             }
    1779           else
    1780             {
    1781               PRINTF("    * <CPU2CACHE> ICACHE : No transaction (cpu %d)\n",num_cpu);
    1782 
    1783               ireq_num_cache [num_cpu] = m_nb_icache;
    1784             }
    1785 
    1786           addr      = (addr_40)_dreq.addr;
    1787           num_cache = get_num_dcache(addr);
    1788            
    1789 
    1790           bool dcache_no_lock      = (r_dcache_lock [num_cache] == m_nb_cpu);
    1791           bool dcache_lock_owner   = (r_dcache_lock [num_cache] == num_cpu);
    1792           bool dcache_lock_no_owner= not dcache_no_lock and not dcache_lock_owner;
    1793           bool dcache_req_valid;
    1794 
    1795           // multi cache : hit after miss)
    1796           if (m_nb_dcache > 0)
    1797           {
    1798               bool dcache_wait         = ((r_dcache_fsm[num_cache] == DCACHE_MISS_WAIT)//  or
    1799                                           // (r_dcache_fsm[num_cache] == DCACHE_UNC_WAIT) or
    1800                                           // (r_dcache_fsm[num_cache] == DCACHE_SC_WAIT)
    1801                                           );
    1802 
    1803               dcache_req_valid = ((not dreq[num_cache].valid and               // no previous request in this cycle
    1804                                    not have_sync and                           // no sync instruction
    1805                                    (dcache_no_lock or
    1806                                     (dcache_lock_no_owner and dcache_wait))) or // no previous request in previous cycle
    1807                                   (dcache_lock_owner and not dcache_wait));     // previous request in previous cycle by this cpu
    1808           }
    1809           else
    1810           {
    1811               dcache_req_valid = ((not dreq[num_cache].valid and // no previous request in this cycle
    1812                                    not have_sync and             // no sync instruction
    1813                                    dcache_no_lock) or            // no previous request in previous cycle
    1814                                   dcache_lock_owner);            // previous request in previous cycle by this cpu
    1815           }
    1816 
    1817           // test if already used
    1818           if (dcache_req_valid)
    1819             {
    1820               bool valid = _dreq.valid;
    1821 
    1822               if (valid)
    1823                 {
    1824                   PRINTF("    * <CPU2CACHE> DCACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
    1825                   dreq_num_cache [num_cpu  ] = num_cache;
    1826                  
    1827                   // always lock if no multi cache
    1828                   if ((m_nb_dcache == 1) or (not dcache_lock_no_owner))
    1829                     r_dcache_lock [num_cache] = num_cpu;
    1830                 }
    1831               else
    1832                 {
    1833                   PRINTF("    * <CPU2CACHE> DCACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
    1834                   dreq_num_cache [num_cpu] = m_nb_dcache;
    1835                 }
    1836 
    1837               dreq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_dreq.addr];
    1838               dreq_num_cpu   [num_cache] = num_cpu;
    1839               dreq           [num_cache] = _dreq;
    1840               dreq           [num_cache].addr = addr;
    1841             }
    1842           else
    1843             {
    1844               PRINTF("    * <CPU2CACHE> DCACHE : No transaction (cpu %d)\n",num_cpu);
    1845 
    1846               dreq_num_cache [num_cpu] = m_nb_dcache;
    1847             }
    1848 
    1849 
    1850 #if CC_XCACHE_WRAPPER_DEBUG
    1851           if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
    1852             {
    1853               std::cout << "    * <CPU2CACHE> Instruction Request   : " << ireq_num_cache[num_cpu] << " - " << _ireq << std::endl
    1854                         << "    * <CPU2CACHE> Data        Request   : " << dreq_num_cache[num_cpu] << " - " << _dreq << std::endl;
    1855             }
    1856 #endif
    1857         }
    1858 
    1859       // round robin priority
    1860       r_cpu_prior = (r_cpu_prior+1)%m_nb_cpu;
    1861 
    1862       /////////////////////////////////////////////////////////////////////
    1863       // The ICACHE FSM controls the following ressources:
    1864       // - r_icache_fsm
    1865       // - r_icache_fsm_save
    1866       // - r_icache instruction cache access
    1867       // - r_icache_addr_save
    1868       // - r_icache_miss_req set
    1869       // - r_icache_unc_req set
    1870       // - r_icache_buf_unc_valid set
    1871       // - r_vci_rsp_icache_miss_ok reset
    1872       // - r_vci_rsp_ins_error reset
    1873       // - r_tgt_icache_req reset
    1874       // - ireq & irsp structures for communication with the processor
    1875       //
    1876       // 1/ External requests (update or invalidate) have highest priority.
    1877       //    They are taken into account in the IDLE and WAIT states.
    1878       //    As external hit should be extremly rare on the ICACHE,
    1879       //    all external requests are handled as invalidate...
    1880       //    In case of external request the ICACHE FSM goes to the CC_CHECK
    1881       //    state to test the external hit, and returns in the
    1882       //    pre-empted state after completion.
    1883       // 2/ Processor requests are taken into account only in the IDLE state.
    1884       //    In case of MISS, or in case of uncached instruction, the FSM
    1885       //    writes the missing address line in the  r_icache_addr_save register
    1886       //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
    1887       //    These request flip-flops are reset by the VCI_RSP FSM
    1888       //    when the VCI transaction is completed and the r_icache_buf_unc_valid
    1889       //    is set in case of uncached access.
    1890       //    In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
    1891       //    flip-flop. It is reset by the ICACHE FSM.
    1892       ///////////////////////////////////////////////////////////////////////
    1893        
    1894       for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
    1895         {
    1896           typename iss_t::InstructionRequest  _ireq = ireq [num_cache];
    1897           typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER;
    1898 
    1899           switch(r_icache_fsm[num_cache]) {
    1900             /////////////////
    1901           case ICACHE_IDLE:
    1902             {
    1903               if ( r_tgt_icache_req[num_cache] ) {   // external request
    1904                 // if ( _ireq.valid ) m_cost_ins_miss_frz++;
    1905                 r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
    1906                 r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache];
    1907                 break;
    1908               }
    1909               if ( _ireq.valid ) {
    1910                 data_t   icache_ins         = 0;
    1911                 bool     icache_hit         = false;
    1912                 bool     icache_cached      = ireq_cached  [num_cache];
    1913                 // uint32_t icache_num_cpu     = ireq_num_cpu [num_cache];
    1914                 bool     icache_cleanup_hit = r_icache_cleanup_req[num_cache] and (((addr_40)_ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line[num_cache].read());
    1915 
    1916                 // icache_hit & icache_ins evaluation
    1917                 if ( icache_cached ) {
    1918                   icache_hit = r_icache[num_cache]->read((vci_addr_t) _ireq.addr, &icache_ins);
    1919                 } else {
    1920                   // if uncache, again in the vci_rsp_fifo_icache
    1921                   icache_hit = (r_icache_buf_unc_valid[num_cache] and
    1922                                 ((addr_40) _ireq.addr == (addr_40)r_icache_addr_save[num_cache]));
    1923                  
    1924                   // Test if top of fifo_rsp is for this cache is in ICACHE_UNC_WAIT
    1925                   icache_ins = r_vci_rsp_fifo_icache_data.read();
    1926 
    1927                   if (icache_hit)
    1928                       vci_rsp_fifo_icache_get = true;
    1929                 }
    1930 
    1931                 PRINTF("    * <ICACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache, icache_hit, icache_cached, icache_cleanup_hit);
    1932 
    1933                 if (icache_hit and icache_cleanup_hit)
    1934                   {
    1935                     PRINTF("    * <ICACHE [%d]> Warning : icache hit and icache_cleanup_hit\n",num_cache);
    1936                     icache_hit = false;
    1937                   }
    1938                 else
    1939                   {
    1940                     if ( not icache_hit and not icache_cleanup_hit)
    1941                       {
    1942                              
    1943                         m_cpt_ins_miss++;
    1944                         m_cost_ins_miss_frz++;
    1945                                
    1946                         r_icache_addr_save[num_cache] = (addr_40) _ireq.addr;
    1947 
    1948                         if ( icache_cached )
    1949                           {
    1950                             // to prevent deadlock, miss victim don't be block
    1951                             if (not r_icache_cleanup_req[num_cache])
    1952                               {
    1953                                 r_icache_fsm     [num_cache] = ICACHE_MISS_VICTIM;
    1954                                 r_icache_miss_req[num_cache] = true;
    1955                               }
    1956                             else
    1957                               m_cpt_icache_miss_victim_wait [num_cache] ++;
    1958                           }
    1959                         else
    1960                           {
    1961                             r_icache_addr_save[num_cache] = (addr_40) _ireq.addr;
    1962 
    1963                             r_icache_fsm    [num_cache] = ICACHE_UNC_WAIT;
    1964                             r_icache_unc_req[num_cache] = true;
    1965                           }
    1966                       }
    1967                     else
    1968                       {
    1969                         //     icache_hit and not icache_cleanup_hit
    1970                         // not icache_hit and     icache_cleanup_hit
    1971 
    1972                         // request accepted, inval the buf unc
    1973 
    1974                         r_icache_buf_unc_valid[num_cache] = false;
    1975                       }
    1976                     m_cpt_icache_dir_read += m_icache_ways;
    1977                     m_cpt_icache_data_read += m_icache_ways;
    1978                   }
    1979 
    1980                 _irsp.valid          = icache_hit;
    1981                 _irsp.instruction    = icache_ins;
     1935                  r_tgt_dcache_req = false;
     1936                  r_tgt_dcache_rsp = true;
     1937                  r_dcache_fsm     = r_dcache_fsm_save.read();
    19821938              }
    19831939              break;
    1984             }
    1985             //////////////////////
    1986           case ICACHE_MISS_VICTIM:
    1987             {
    1988               // if (not r_icache_cleanup_req[num_cache])
    1989               {
    1990                 size_t     way;
    1991                 size_t     set;
    1992                 vci_addr_t addr = (vci_addr_t) r_icache_addr_save[num_cache].read();
    1993                 vci_addr_t victim;
    1994                        
    1995                 r_icache_cleanup_req [num_cache] = r_icache[num_cache]->victim_select(addr, &victim, &way, &set );
    1996                 r_icache_cleanup_line[num_cache] = (addr_40) victim;
    1997                 r_icache_miss_way    [num_cache] = way;
    1998                 r_icache_miss_set    [num_cache] = set;
    1999                        
    2000                 r_icache_fsm         [num_cache] = ICACHE_MISS_WAIT;
    2001               }
    2002               break;
    2003             }
    2004             //////////////////////
    2005           case ICACHE_MISS_WAIT:
    2006             {
    2007               m_cost_ins_miss_frz++;
    2008               if ( r_tgt_icache_req[num_cache] ) {   // external request
    2009                 r_icache_fsm      [num_cache] = ICACHE_CC_CHECK;
    2010                 r_icache_fsm_save [num_cache] = r_icache_fsm[num_cache].read();
    2011                 break;
    2012               }
    2013 
    2014               bool val = (r_vci_rsp_fifo_icache_data.rok() and
    2015                           (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
    2016 
    2017               PRINTF("    * <ICACHE [%d]> val                  : %d\n",num_cache,val);
    2018 
    2019               if (val)
    2020                 {
    2021                   PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp   : %d\n",num_cache,(int) r_icache_inval_rsp  [num_cache]);
    2022                   PRINTF("    * <ICACHE [%d]> r_vci_rsp_ins_error  : %d\n",num_cache,(int) r_vci_rsp_ins_error [num_cache]);
    2023                   PRINTF("    * <ICACHE [%d]> r_icache_cleanup_req : %d\n",num_cache,(int) r_icache_cleanup_req[num_cache]);
    2024 
    2025                   // Miss read response and no invalidation
    2026                   if ( r_vci_rsp_ins_error [num_cache]) {
    2027                     r_icache_fsm[num_cache] = ICACHE_ERROR;
    2028                   } else {
    2029                     r_icache_update_addr[num_cache] = 0;
    2030                     r_icache_fsm        [num_cache] = ICACHE_MISS_UPDT;
    2031                   }
    2032                 }
    2033               break;
    2034             }
    2035             /////////////////////
    2036           case ICACHE_UNC_WAIT:
    2037             {
    2038               m_cost_ins_miss_frz++;
    2039               if ( r_tgt_icache_req[num_cache] ) {   // external request
    2040                 r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
    2041                 r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache].read();
    2042                 break;
    2043               }
    2044 
    2045               bool ok = (r_vci_rsp_fifo_icache_data.rok() and
    2046                          (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
    2047 
    2048               PRINTF("    * <ICACHE [%d]> ok                   : %d\n",num_cache,ok);
    2049               PRINTF("    * <ICACHE [%d]> error                : %d\n",num_cache,(uint32_t)r_vci_rsp_ins_error [num_cache]);
    2050 
    2051               if (ok)
    2052                 {
    2053                   if ( r_vci_rsp_ins_error [num_cache]) {
    2054                     r_icache_fsm[num_cache] = ICACHE_ERROR;
    2055                   } else {
    2056                     r_icache_fsm [num_cache] = ICACHE_IDLE;
    2057                     r_icache_buf_unc_valid[num_cache] = true;
    2058                   }
    2059                 }
    2060               break;
    2061             }
    2062             //////////////////
    2063           case ICACHE_ERROR:
    2064             {
    2065               if ( (addr_40)_ireq.addr == (addr_40)r_icache_addr_save[num_cache] ) {
    2066                 _irsp.error          = true;
    2067                 _irsp.valid          = true;
    2068               }
    2069               r_icache_fsm        [num_cache] = ICACHE_IDLE;
    2070               r_vci_rsp_ins_error [num_cache] = false;
    2071               break;
    2072             }
    2073             //////////////////////
    2074           case ICACHE_MISS_UPDT:
    2075             {
    2076               size_t     word =              r_icache_update_addr[num_cache].read();
    2077               vci_addr_t addr = (vci_addr_t) r_icache_addr_save  [num_cache].read();
    2078               size_t     way  = r_icache_miss_way[num_cache].read();
    2079               size_t     set  = r_icache_miss_set[num_cache].read();
    2080 
    2081               bool val = (r_vci_rsp_fifo_icache_data.rok() and
    2082                           (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
    2083 
    2084               if (val)
    2085                 {
    2086                   PRINTF("    * <ICACHE [%d]> rsp_val            : %d/%d\n",num_cache,(int)r_icache_update_addr[num_cache],(int)m_icache_words);
    2087                   PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp : %d\n"   ,num_cache,(int)r_icache_inval_rsp[num_cache]);
    2088                   PRINTF("    * <ICACHE [%d]> ins                : %x\n"   ,num_cache,(int)r_vci_rsp_fifo_icache_data.read());
    2089                   // m_cpt_icache_dir_write++;
    2090                   // m_cpt_icache_data_write++;
    2091                   // if ( _ireq.valid ) m_cost_ins_miss_frz++;
    2092 
    2093                   // if need invalid rsp, don't modify the cache, but pop the buf_rsp
    2094                   if (not r_icache_inval_rsp[num_cache])
    2095                       r_icache[num_cache]->write(way, set, word, r_vci_rsp_fifo_icache_data.read());
    2096 
    2097                   vci_rsp_fifo_icache_get = true;
    2098 
    2099                   r_icache_update_addr[num_cache] = ++word;
    2100                            
    2101                   // if last word, finish the update
    2102                   if (word >= m_icache_words)
     1940          }
     1941    } // end switch r_dcache_fsm
     1942       
     1943    // save the DREQ and DRSP fields for the print_trace() function
     1944    m_dreq_valid = dreq.valid;
     1945    m_dreq_addr  = dreq.addr;
     1946    m_dreq_mode  = dreq.mode;
     1947    m_dreq_type  = dreq.type;
     1948    m_dreq_wdata = dreq.wdata;
     1949    m_dreq_be    = dreq.be;
     1950   
     1951    m_drsp_valid = drsp.valid;
     1952    m_drsp_rdata = drsp.rdata;
     1953    m_drsp_error = drsp.error;
     1954
     1955    ////////// write buffer state update  ////////////////////////////////////////////
     1956    // The update() method must be called at each cycle to update the internal state.
     1957
     1958    r_wbuf->update ();
     1959
     1960    /////////// test processor frozen /////////////////////////////////////////////
     1961    // The simulation exit if the number of consecutive frozen cycles
     1962    // is larger than the m_max_frozen_cycles (constructor parameter)
     1963    if ( (ireq.valid and not irsp.valid) or (dreq.valid and not drsp.valid) )       
     1964    {
     1965        m_cpt_frz_cycles++;         // used for instrumentation
     1966        m_cpt_stop_simulation++;    // used for processor stop if frozen
     1967        if ( m_cpt_stop_simulation > m_max_frozen_cycles )
     1968        {
     1969            std::cout << std::dec << "ERROR in CC_XCACHE_WRAPPER " << name()
     1970                      << " frozen since cycle " << m_cpt_total_cycles - m_max_frozen_cycles
     1971                      << std::endl;
     1972            exit(1);
     1973        }
     1974    }
     1975    else
     1976    {
     1977        m_cpt_stop_simulation = 0;
     1978    }
     1979
     1980    /////////// execute one iss cycle /////////////////////////////////////////////
     1981
     1982    uint32_t it = 0;
     1983    for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if ( p_irq[i].read() ) it |= (1<<i);
     1984               
     1985    r_iss->executeNCycles(1, irsp, drsp, it);
     1986
     1987    ////////////////////////////////////////////////////////////////////////////////
     1988    // The CLEANUP FSM send the cleanup commands on the coherence network,
     1989    // and supports simultaneous cleanup transactions, but two simultaneous
     1990    // transactions mut address different cache lines.
     1991    // Therefore, the line number is registered in an associative
     1992    // registration buffer (Content Adressable Memory) by the CLEANUP FSM,
     1993    // and the corresponding slot (identified by the VCI TRDID field) is cleared
     1994    // when the cleanup transaction response is received.
     1995    // It handles cleanup requests from both the DCACHE FSM & ICACHE FSM
     1996    // with a round robin priority, and can support up to 16 simultaneous
     1997    // cleanup transactions (16 slots in the registration buffer).
     1998    // The r_dcache_cleanup_req (or r_icache_cleanup_req) flip-flops are reset
     1999    // when the command has been sent.
     2000    // The VCI TRDID field is used to distinguish data/instruction cleanups:
     2001    // - if data cleanup        : TRDID = 2*index + 0
     2002    // - if instruction cleanup : TRDID = 2*index + 1
     2003    ////////////////////////////////////////////////////////////////////////////
     2004
     2005    switch ( r_cleanup_fsm.read() )
     2006    {
     2007        ///////////////////////
     2008        case CLEANUP_DATA_IDLE:     // dcache has highest priority
     2009        {
     2010            size_t  index = 0;
     2011            bool    ok;
     2012            if ( r_dcache_cleanup_req.read() )      // dcache request
     2013            {
     2014                ok = r_cleanup_buffer.register_value( r_dcache_cleanup_line.read(),
     2015                                                      &index );   
     2016                if ( ok )   // successful registration
     2017                {
     2018                    r_cleanup_fsm   = CLEANUP_DATA_GO;
     2019                    r_cleanup_trdid = index<<1;
     2020                }
     2021            }
     2022            else if ( r_icache_cleanup_req.read() ) // icache request
     2023            {
     2024                ok = r_cleanup_buffer.register_value( r_icache_cleanup_line.read(),
     2025                                                      &index );   
     2026                if ( ok )   // successful registration
     2027                {
     2028                    r_cleanup_fsm   = CLEANUP_INS_GO;
     2029                    r_cleanup_trdid = index<<1 + 1;
     2030                }
     2031            }
     2032            break;
     2033        }
     2034        //////////////////////
     2035        case CLEANUP_INS_IDLE:     // icache has highest priority
     2036        {
     2037            size_t  index = 0;
     2038            bool    ok;
     2039            if ( r_icache_cleanup_req.read() )      // icache request
     2040            {
     2041                ok = r_cleanup_buffer.register_value( r_icache_cleanup_line.read(),
     2042                                                      &index );   
     2043                if ( ok )   // successful registration
     2044                {
     2045                    r_cleanup_fsm   = CLEANUP_INS_GO;
     2046                    r_cleanup_trdid = index<<1 + 1;
     2047                }
     2048            }
     2049            else if ( r_dcache_cleanup_req.read() ) // dcache request
     2050            {
     2051                ok = r_cleanup_buffer.register_value( r_dcache_cleanup_line.read(),
     2052                                                      &index );   
     2053                if ( ok )   // successful registration
     2054                {
     2055                    r_cleanup_fsm   = CLEANUP_DATA_GO;
     2056                    r_cleanup_trdid = index<<1;
     2057                }
     2058            }
     2059            break;
     2060        }
     2061        /////////////////////
     2062        case CLEANUP_DATA_GO:
     2063        {
     2064            if ( p_vci_ini_c.cmdack.read() )
     2065            {
     2066                r_dcache_cleanup_req = false;
     2067                r_cleanup_fsm    = CLEANUP_INS_IDLE;
     2068            }
     2069        }
     2070        ////////////////////////
     2071        case CLEANUP_INS_GO:
     2072        {
     2073            if ( p_vci_ini_c.cmdack.read() )
     2074            {
     2075                r_icache_cleanup_req = false;
     2076                r_cleanup_fsm    = CLEANUP_DATA_IDLE;
     2077            }
     2078        }
     2079    } // end switch CLEANUP FSM
     2080
     2081    //////////////// Handling  cleanup responses //////////////////
     2082    if ( p_vci_ini_c.rspval.read() )    // valid response
     2083    {
     2084        r_cleanup_buffer.cancel_index( p_vci_ini_c.rtrdid.read() >> 1);
     2085    }
     2086
     2087    ////////////////////////////////////////////////////////////////////////////
     2088    // The VCI_CMD FSM controls the following ressources:
     2089    // - r_vci_cmd_fsm
     2090    // - r_vci_cmd_min
     2091    // - r_vci_cmd_max
     2092    // - r_vci_cmd_cpt
     2093    // - r_vci_cmd_imiss_prio
     2094    // - wbuf (reset)
     2095    // - r_icache_miss_req (reset)
     2096    // - r_icache_unc_req (reset)
     2097    // - r_dcache_miss_req (reset)
     2098    // - r_dcache_unc_req (reset)
     2099    // - r_dcache_sc_req (reset)
     2100    //
     2101    // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
     2102    // There is 6 request types, with the following priorities :
     2103    // 1 - Data Read Miss         : r_dcache_miss_req and miss in the write buffer
     2104    // 2 - Data Read Uncacheable   : r_dcache_unc_req 
     2105    // 3 - Instruction Miss       : r_icache_miss_req and miss in the write buffer
     2106    // 4 - Instruction Uncacheable : r_icache_unc_req
     2107    // 5 - Data Write             : r_wbuf.rok()     
     2108    // 6 - Data Store Conditionnal: r_dcache_sc_req
     2109    //
     2110    // As we want to support several simultaneous VCI transactions, the VCI_CMD_FSM
     2111    // and the VCI_RSP_FSM are fully desynchronized.
     2112    //
     2113    // VCI formats:
     2114    // According to the VCI advanced specification, all read requests packets
     2115    // (data Uncached, Miss data, instruction Uncached, Miss instruction)
     2116    // are one word packets.
     2117    // For write burst packets, all words are in the same cache line,
     2118    // and addresses must be contiguous (the BE field is 0 in case of "holes").
     2119    // The sc command packet implements actually a compare-and-swap mechanism
     2120    // and the packet contains two flits.
     2121    //////////////////////////////////////////////////////////////////////////////
     2122
     2123    switch ( r_vci_cmd_fsm.read() )
     2124    {
     2125        //////////////
     2126        case CMD_IDLE:
     2127        {
     2128            // r_dcache_miss_req and r_icache_miss_req require both a write_buffer access
     2129            // to check a possible pending write on the same cache line.
     2130            // As there is only one possible access per cycle to write buffer, we implement
     2131            // a round-robin priority for this access, using the r_vci_cmd_imiss_prio flip-flop.
     2132
     2133            size_t      wbuf_min;
     2134            size_t      wbuf_max;
     2135
     2136            bool dcache_miss_req = r_dcache_miss_req.read()
     2137                 and ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read() );
     2138            bool icache_miss_req = r_icache_miss_req.read()
     2139                 and ( not r_dcache_miss_req.read() or r_vci_cmd_imiss_prio.read() );
     2140
     2141            // 1 - Data Read Miss
     2142            if ( dcache_miss_req and r_wbuf->miss(r_dcache_addr_save.read()) )
     2143            {
     2144                r_vci_cmd_fsm        = CMD_DATA_MISS;
     2145                r_dcache_miss_req    = false;
     2146                r_vci_cmd_imiss_prio = true;
     2147                m_cpt_dmiss_transaction++;
     2148            }
     2149            // 2 - Data Read Uncacheable
     2150            else if ( r_dcache_unc_req.read() )
     2151            {
     2152                r_vci_cmd_fsm    = CMD_DATA_UNC;
     2153                r_dcache_unc_req = false;
     2154                m_cpt_dunc_transaction++;
     2155            }
     2156            // 3 - Instruction Miss
     2157            else if ( icache_miss_req and r_wbuf->miss(r_icache_addr_save.read()) )
     2158            {
     2159                r_vci_cmd_fsm        = CMD_INS_MISS;
     2160                r_icache_miss_req    = false;
     2161                r_vci_cmd_imiss_prio = false;
     2162                m_cpt_imiss_transaction++;
     2163            }
     2164            // 4 - Instruction Uncacheable
     2165            else if ( r_icache_unc_req.read() )
     2166            {
     2167                r_vci_cmd_fsm    = CMD_INS_UNC;
     2168                r_icache_unc_req = false;
     2169                m_cpt_iunc_transaction++;
     2170            }
     2171            // 5 - Data Write
     2172            else if ( r_wbuf->rok(&wbuf_min, &wbuf_max) )
     2173            {
     2174                r_vci_cmd_fsm       = CMD_DATA_WRITE;
     2175                r_vci_cmd_cpt       = wbuf_min;
     2176                r_vci_cmd_min       = wbuf_min;
     2177                r_vci_cmd_max       = wbuf_max;
     2178                m_cpt_write_transaction++;
     2179                m_length_write_transaction += (wbuf_max-wbuf_min+1);
     2180            }
     2181            // 6 - Data Store Conditionnal
     2182            else if ( r_dcache_sc_req.read() )
     2183            {
     2184                r_vci_cmd_fsm       = CMD_DATA_SC;
     2185                r_dcache_sc_req = false;
     2186                r_vci_cmd_cpt       = 0;
     2187                m_cpt_sc_transaction++;
     2188            }
     2189            break;
     2190        }
     2191        ////////////////////
     2192        case CMD_DATA_WRITE:
     2193        {
     2194            if ( p_vci_ini_d.cmdack.read() )
     2195            {
     2196                m_conso_wbuf_read++;
     2197                r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
     2198                if (r_vci_cmd_cpt == r_vci_cmd_max) // last flit sent
     2199                {
     2200                    r_vci_cmd_fsm = CMD_IDLE ;
     2201                    r_wbuf->sent() ;
     2202                }
     2203            }
     2204            break;
     2205        }
     2206        /////////////////
     2207        case CMD_DATA_SC:
     2208        {
     2209            // The SC VCI command contains two flits
     2210            if ( p_vci_ini_d.cmdack.read() )
     2211            {
     2212               r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
     2213               if (r_vci_cmd_cpt == 1) r_vci_cmd_fsm = CMD_IDLE ;
     2214            }
     2215            break;
     2216        }
     2217        //////////////////
     2218        case CMD_INS_MISS:
     2219        case CMD_INS_UNC:
     2220        case CMD_DATA_MISS:
     2221        case CMD_DATA_UNC:
     2222        {
     2223            // all read VCI commands contain one single flit
     2224            if ( p_vci_ini_d.cmdack.read() )  r_vci_cmd_fsm = CMD_IDLE;
     2225            break;
     2226        }
     2227
     2228    } // end  switch r_vci_cmd_fsm
     2229
     2230    ///////////////////////////////////////////////////////////////////////////////
     2231    // The VCI_RSP FSM controls the following ressources:
     2232    // - r_vci_rsp_fsm:
     2233    // - r_vci_rsp_fifo_icache (push)
     2234    // - r_vci_rsp_fifo_dcache (push)
     2235    // - r_vci_rsp_data_error (set)
     2236    // - r_vci_rsp_ins_error (set)
     2237    // - r_vci_rsp_cpt
     2238    //
     2239    // As we support several simultaneous transactions, this FSM uses
     2240    // the VCI TRDID field to identify the transactions.
     2241    //
     2242    // VCI vormat:
     2243    // This component Rcheks the response packet length and accepts only
     2244    // single word packets for write response packets.
     2245    //
     2246    // Error handling:
     2247    // This FSM analyzes the VCI error code and signals directly the Write Bus Error.
     2248    // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error
     2249    // flip_flop and the error is signaled by the DCACHE FSM. 
     2250    // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error
     2251    // flip_flop and the error is signaled by the DCACHE FSM. 
     2252    // In case of Cleanup Error, the simulation stops with an error message...
     2253    /////////////////////////////////////////////////////////////////////////////////
     2254
     2255    switch ( r_vci_rsp_fsm.read() )
     2256    {
     2257        //////////////
     2258        case RSP_IDLE:
     2259        {
     2260            if( p_vci_ini_d.rspval.read() )
     2261            {
     2262                r_vci_rsp_cpt = 0;
     2263
     2264                if ( (p_vci_ini_d.rtrdid.read()>>(vci_param::T-1)) != 0 )
     2265                {
     2266                    r_vci_rsp_fsm = RSP_DATA_WRITE;
     2267                }
     2268                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS )
     2269                {
     2270                    r_vci_rsp_fsm = RSP_INS_MISS;
     2271                }
     2272                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC )
     2273                {
     2274                    r_vci_rsp_fsm = RSP_INS_UNC;
     2275                }
     2276                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS )
     2277                {
     2278                    r_vci_rsp_fsm = RSP_DATA_MISS;
     2279                }
     2280                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC )
     2281                {
     2282                    r_vci_rsp_fsm = RSP_DATA_UNC;
     2283                }
     2284                else
     2285                {
     2286                    assert(false and "Unexpected response");
     2287                }
     2288            }
     2289            break;
     2290        }
     2291        //////////////////
     2292        case RSP_INS_MISS:
     2293        {       
     2294            if ( p_vci_ini_d.rspval.read() )
     2295            {
     2296                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
     2297                {
     2298                    r_vci_rsp_ins_error = true;
     2299                    if ( p_vci_ini_d.reop.read() ) r_vci_rsp_fsm = RSP_IDLE;
     2300                }
     2301                else                                        // no error reported
     2302                {
     2303                    if ( r_vci_rsp_fifo_icache.wok() )
    21032304                    {
    2104                       // in all case (inval_rsp or not), update the victim tag
    2105                       r_icache[num_cache]->victim_update_tag(addr, way, set);
    2106 
    2107                       // Last word : if previous invalid_rsp, can cleanup, else update the TAG
    2108                       if (r_icache_inval_rsp[num_cache])
     2305                        assert( (r_vci_rsp_cpt.read() < m_cache_words) and
     2306                        "The VCI response packet for instruction miss is too long" );
     2307
     2308                        r_vci_rsp_cpt                 = r_vci_rsp_cpt.read() + 1;
     2309                        vci_rsp_fifo_icache_put       = true,
     2310                        vci_rsp_fifo_icache_data      = p_vci_ini_d.rdata.read();
     2311                        if ( p_vci_ini_d.reop.read() )
    21092312                        {
    2110                           r_icache_inval_rsp[num_cache] = false;
    2111                           r_icache_fsm      [num_cache] = ICACHE_CC_CLEANUP;
    2112                         }
    2113                       else
    2114                         {
    2115                           r_icache_fsm [num_cache] = ICACHE_IDLE;
     2313                            assert( (r_vci_rsp_cpt.read() == m_cache_words - 1) and
     2314                            "The VCI response packet for instruction miss is too short");
     2315
     2316                            r_vci_rsp_fsm    = RSP_IDLE;
    21162317                        }
    21172318                    }
    21182319                }
    2119 
    2120               break;
    2121             }
    2122             ////////////////////
    2123           case ICACHE_CC_CLEANUP:
    2124             {
    2125               // cleanup
    2126               if(not r_icache_cleanup_req[num_cache]){
    2127                 r_icache_cleanup_req [num_cache] = true;
    2128                 r_icache_cleanup_line[num_cache] = r_icache_addr_save[num_cache].read() >> m_icache_words_shift;
    2129                 r_icache_fsm         [num_cache] = ICACHE_IDLE;
    2130 
    2131                 m_cpt_icache_dir_read += m_icache_ways;
    2132                 r_icache[num_cache]->inval((addr_40)r_icache_addr_save[num_cache]);
    2133               }
    2134               break;
    2135             }
    2136             /////////////////////
    2137           case ICACHE_CC_CHECK:   // read directory in case of invalidate or update request
    2138             {
    2139 
    2140               m_cpt_icache_dir_read  += m_icache_ways;
    2141               m_cpt_icache_data_read += m_icache_ways;
    2142               addr_40 ad = r_tgt_iaddr;
    2143 
    2144               PRINTF("    * <ICACHE [%d]> CC_CHECK\n",num_cache);
    2145 
    2146               if((r_icache_fsm_save[num_cache] == ICACHE_MISS_WAIT) and
    2147                  ((r_icache_addr_save[num_cache].read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) {
    2148                 PRINTF("    * <ICACHE [%d]> have request, need inval rsp\n",num_cache);
    2149 
    2150                 r_icache_inval_rsp[num_cache] = true;
    2151                 r_tgt_icache_req  [num_cache] = false;
    2152                 if(r_tgt_update){    // Also send a cleanup and answer
    2153                   PRINTF("    * <ICACHE [%d]> send a cleanup and answer\n",num_cache);
    2154                   r_tgt_icache_rsp[num_cache] = true;
    2155                 } else {            // Also send a cleanup but don't answer
    2156                   PRINTF("    * <ICACHE [%d]> send a cleanup and but don't answer\n",num_cache);
    2157                   r_tgt_icache_rsp[num_cache] = false;
    2158                 }
    2159                 r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
    2160               } else {
    2161                 uint32_t word       = r_cache_word;
    2162                 data_t   mask       = vci_param::be2mask(r_tgt_be[word]);
    2163                 data_t   rdata      = 0;
    2164                 bool     icache_hit = r_icache[num_cache]->read(ad+word*4,&rdata);
    2165 
    2166                 PRINTF("    * <ICACHE [%d]> have no request, hit cache : %d\n",num_cache,icache_hit);
    2167 
    2168                 if ( icache_hit and r_tgt_update)
    2169                   {
    2170                     // Assumption : We have RAM for icache with write enable on byte.
    2171                     // Consequence : icache_read is only consultation of directory
    2172 
    2173                     //if(r_tgt_be[word])
    2174                     r_icache[num_cache]->write(ad+word*4, (mask & r_tgt_buf[word]) | (~mask & rdata));
    2175                            
    2176                     word ++;
    2177                    
    2178                     // Find next valid word
    2179                     for (; word<m_icache_words; ++word)
    2180                       if (r_tgt_be[word] != 0)
    2181                         break;
    2182 
    2183                     if (word==m_icache_words)
    2184                       {
    2185                           r_tgt_icache_req[num_cache] = false;
    2186                           r_tgt_icache_rsp[num_cache] = true;
    2187                           r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache].read();
    2188                           word = 0;
    2189                       }
    2190                     r_cache_word = word;
    2191 
    2192                   } else if ( icache_hit and not r_tgt_update) {
    2193                   r_icache_fsm[num_cache] = ICACHE_CC_INVAL;
    2194                 } else { // instruction not found (can happen)
    2195                   r_tgt_icache_req[num_cache] = false;
    2196                   if(r_tgt_update){
    2197                     r_tgt_icache_rsp[num_cache] = true;
    2198                   } else {
    2199                     r_tgt_icache_rsp[num_cache] = false;
    2200                   }
    2201                   r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
    2202                 }
    2203               }
    2204               break;
    2205             }
    2206             /////////////////////
    2207           case ICACHE_CC_INVAL: 
    2208             {                       
    2209               addr_40 ad  = r_tgt_iaddr;
    2210               // if ( _ireq.valid ) m_cost_ins_miss_frz++;
    2211               m_cpt_icache_dir_read += m_icache_ways;
    2212               r_tgt_icache_rsp[num_cache] = true;
    2213               r_icache[num_cache]->inval(ad);
    2214               r_tgt_icache_req[num_cache] = false;
    2215               r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache];
    2216               break;
    2217             }   
    2218           }// end switch r_icache_fsm
    2219 
    2220           irsp [num_cache] = _irsp;
    2221           if (_ireq.valid and _irsp.valid)
    2222             {
    2223               PRINTF("    * <CPU2CACHE> Transaction between cpu %d and Icache %d (unlock)\n",r_icache_lock [num_cache].read(),num_cache);
    2224 
    2225               r_icache_lock       [num_cache] = m_nb_cpu;
    2226               m_cpt_icache_access [num_cache] ++;
    2227             }
    2228 
    2229         }// end for num_cache
    2230 
    2231       //////////////////////////////////////////////////////////////////////://///////////
    2232       // The DCACHE FSM controls the following ressources:
    2233       // - r_dcache_fsm
    2234       // - r_dcache_fsm_save
    2235       // - r_dcache (data cache access)
    2236       // - r_dcache_addr_save
    2237       // - r_dcache_wdata_save
    2238       // - r_dcache_rdata_save
    2239       // - r_dcache_type_save
    2240       // - r_dcache_be_save
    2241       // - r_dcache_cached_save
    2242       // - r_dcache_miss_req set
    2243       // - r_dcache_unc_req set
    2244       // - r_dcache_cleanup_req set
    2245       // - r_vci_rsp_data_error reset
    2246       // - r_tgt_dcache_req reset
    2247       // - r_wbuf write
    2248       // - dreq & drsp structures for communication with the processor
    2249       //
    2250       // 1/ EXTERNAL REQUEST :
    2251       //    There is an external request when the tgt_dcache req flip-flop is set,
    2252       //    requesting a line invalidation or a line update.
    2253       //    External requests are taken into account in the states  IDLE, WRITE_REQ, 
    2254       //    UNC_WAIT, MISS_WAIT, and have the highest priority :
    2255       //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
    2256       //    goes to the CC_CHECK state to execute the requested action, and returns to the
    2257       //    pre-empted state.
    2258       //  2/ PROCESSOR REQUEST :
    2259       //   In order to support VCI write burst, the processor requests are taken into account
    2260       //   in the WRITE_REQ state as well as in the IDLE state.
    2261       //   - In the IDLE state, the processor request cannot be satisfied if
    2262       //   there is a cached read miss, or an uncached read.
    2263       //   - In the WRITE_REQ state, the request cannot be satisfied if
    2264       //   there is a cached read miss, or an uncached read,
    2265       //   or when the write buffer is full.
    2266       //   - In all other states, the processor request is not satisfied.
    2267       //
    2268       //   The cache access takes into account the cacheability_table.
    2269       //   In case of processor request, there is five conditions to exit the IDLE state:
    2270       //   - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal),
    2271       //     then to the MISS_UPDT state, and finally to the IDLE state.
    2272       //   - UNCACHED READ  => to the UNC_WAIT state (waiting the r_miss_ok signal),
    2273       //     and to the IDLE state.
    2274       //   - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state.
    2275       //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
    2276       //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
    2277       //
    2278       // Error handling :  Read Bus Errors are synchronous events, but
    2279       // Write Bus Errors are asynchronous events (processor is not frozen).
    2280       // - If a Read Bus Error is detected, the VCI_RSP FSM sets the
    2281       //   r_vci_rsp_data_error flip-flop, and the synchronous error is signaled
    2282       //   by the DCACHE FSM.
    2283       // - If a Write Bus Error is detected, the VCI_RSP FSM  signals
    2284       //   the asynchronous error using the setWriteBerr() method.
    2285       ///////////////////////////////////////////////////////////////////////////////////
    2286 
    2287       for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
    2288         {
    2289           typename iss_t::DataRequest  _dreq = dreq [num_cache];
    2290           typename iss_t::DataResponse _drsp = ISS_DRSP_INITIALIZER;
    2291 
    2292           switch ( r_dcache_fsm[num_cache]) {
    2293 
    2294             /////////////////
    2295           case DCACHE_IDLE:
    2296             {
    2297               if ( r_tgt_dcache_req[num_cache]) {   // external request
    2298                 r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
    2299                 r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
    2300                 break;
    2301               }
    2302 
    2303               if ( _dreq.valid ) {
    2304                 PRINTF("    * <DCACHE [%d]> Have dreq\n",num_cache);
    2305 
    2306                 data_t      dcache_rdata       = 0;
    2307                 // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE}
    2308                 bool        dcache_cached      = dreq_cached  [num_cache];
    2309                 uint32_t    dcache_num_cpu     = dreq_num_cpu [num_cache];
    2310                 bool        dcache_hit         = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
    2311                 bool        dcache_cleanup_hit = r_dcache_cleanup_req[num_cache] and (((addr_40)_dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line[num_cache].read());
    2312 
    2313                 PRINTF("    * <DCACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache,dcache_hit, dcache_cached, dcache_cleanup_hit);
    2314                        
    2315                 m_cpt_dcache_data_read += m_dcache_ways;
    2316                 m_cpt_dcache_dir_read  += m_dcache_ways;
    2317 
    2318                 switch( _dreq.type ) {
    2319                 case iss_t::DATA_READ:
    2320                 case iss_t::DATA_LL:
    2321                   {
    2322                     m_cpt_data_read++; // new dcache read
    2323 
    2324                     if (dcache_hit) // no special test for uncached read, because it's always miss
    2325                       {
    2326                         // address is in the cache : return the word
    2327                         r_dcache_fsm [num_cache] = DCACHE_IDLE;
    2328 
    2329                         _drsp.valid   = true;
    2330                         _drsp.rdata   = dcache_rdata; // return read data (cf dcache_hit)
    2331                                            
    2332                         // if the request is a Load Linked instruction, save request information
    2333                         if(_dreq.type == iss_t::DATA_LL)
    2334                           {
    2335                             PRINTF("    * <DCACHE [%d]> ll_valid = true\n",num_cache);
    2336 
    2337                             r_dcache_ll_valid  [num_cache][dcache_num_cpu] = true;
    2338                             r_dcache_ll_data   [num_cache][dcache_num_cpu] = dcache_rdata;
    2339                             r_dcache_ll_addr   [num_cache][dcache_num_cpu] = (vci_addr_t) _dreq.addr;
    2340                           }
    2341                       }
    2342                     else
    2343                       {
    2344                         if (not dcache_cleanup_hit)
    2345                           {
    2346                                                
    2347                             // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req)
    2348                             if ( dcache_cached ) {
    2349                               // to prevent deadlock, miss victim don't be block
    2350                               if (not r_dcache_cleanup_req[num_cache].read())
    2351                                 {
    2352                                   m_cpt_data_read_miss++;
    2353                                   m_cost_data_miss_frz++;
    2354                                   r_dcache_miss_req [num_cache] = true;
    2355                                   r_dcache_fsm [num_cache] = DCACHE_MISS_VICTIM;
    2356                                 }
    2357                               else
    2358                                 m_cpt_icache_miss_victim_wait [num_cache] ++;
    2359                             } else {
    2360                               if (not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
    2361                                 {
    2362                                   r_dcache_previous_unc[num_cache] = true;
    2363                                                        
    2364                                   m_cpt_data_read_uncached++;
    2365                                   m_cost_unc_read_frz++;
    2366                                   r_dcache_unc_req[num_cache] = true;
    2367                                   r_dcache_fsm    [num_cache] = DCACHE_UNC_WAIT;
    2368                                 }
    2369                             }
    2370                           }
    2371                       }
    2372                   }
    2373                   break;
    2374                 case iss_t::DATA_SC:
    2375                   {
    2376                     PRINTF("    * <DCACHE [%d]> DATA_SC - ll_valid = %d, num_cpu = %d\n",num_cache,r_dcache_ll_valid[num_cache][dcache_num_cpu].read(),dcache_num_cpu);
    2377 
    2378                     if (not r_dcache_previous_unc[num_cache].read() and not dcache_cleanup_hit) // strongly order to the uncached access
    2379                       {
    2380                         //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode
    2381                         m_cost_unc_read_frz++;
    2382                                    
    2383                         // if previous load linked (with the same address), make a transaction
    2384                         // else, keep in IDLE state and return 1 (no OK)