Ignore:
Timestamp:
Oct 4, 2013, 4:31:55 PM (11 years ago)
Author:
haoliu
Message:

RWT - VCI_MEM_CACHE cosmetic

Location:
branches/RWT/modules/vci_mem_cache/caba/source
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/RWT/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h

    r542 r545  
    8080      {
    8181        TGT_CMD_IDLE,
    82         TGT_CMD_ERROR,
    8382        TGT_CMD_READ,
    8483        TGT_CMD_WRITE,
    8584        TGT_CMD_CAS,
     85        TGT_CMD_ERROR,
    8686        TGT_CMD_CONFIG
    8787      };
     
    9090      enum tgt_rsp_fsm_state_e
    9191      {
    92         TGT_RSP_CONFIG_IDLE,
    93         TGT_RSP_TGT_CMD_IDLE,
    9492        TGT_RSP_READ_IDLE,
    9593        TGT_RSP_WRITE_IDLE,
     
    9896        TGT_RSP_MULTI_ACK_IDLE,
    9997        TGT_RSP_CLEANUP_IDLE,
    100         TGT_RSP_CONFIG,
    101         TGT_RSP_TGT_CMD,
     98        TGT_RSP_CONFIG_IDLE,
     99        TGT_RSP_TGT_CMD_IDLE,
    102100        TGT_RSP_READ,
    103101        TGT_RSP_WRITE,
     
    105103        TGT_RSP_XRAM,
    106104        TGT_RSP_MULTI_ACK,
    107         TGT_RSP_CLEANUP
     105        TGT_RSP_CLEANUP,
     106        TGT_RSP_CONFIG,
     107        TGT_RSP_TGT_CMD
    108108      };
    109109
     
    120120      enum cc_send_fsm_state_e
    121121      {
    122         CC_SEND_CONFIG_IDLE,
    123122        CC_SEND_XRAM_RSP_IDLE,
    124123        CC_SEND_WRITE_IDLE,
    125124        CC_SEND_CAS_IDLE,
    126         CC_SEND_CONFIG_INVAL_HEADER,
    127         CC_SEND_CONFIG_INVAL_NLINE,
    128         CC_SEND_CONFIG_BRDCAST_HEADER,
    129         CC_SEND_CONFIG_BRDCAST_NLINE,
     125        CC_SEND_CONFIG_IDLE,
    130126        CC_SEND_XRAM_RSP_BRDCAST_HEADER,
    131127        CC_SEND_XRAM_RSP_BRDCAST_NLINE,
     
    146142        CC_SEND_CAS_UPDT_NLINE,
    147143        CC_SEND_CAS_UPDT_DATA,
    148         CC_SEND_CAS_UPDT_DATA_HIGH
     144        CC_SEND_CAS_UPDT_DATA_HIGH,
     145        CC_SEND_CONFIG_INVAL_HEADER,
     146        CC_SEND_CONFIG_INVAL_NLINE,
     147        CC_SEND_CONFIG_BRDCAST_HEADER,
     148        CC_SEND_CONFIG_BRDCAST_NLINE
    149149      };
    150150
     
    335335      {
    336336        ALLOC_DIR_RESET,
    337         ALLOC_DIR_CONFIG,
    338337        ALLOC_DIR_READ,
    339338        ALLOC_DIR_WRITE,
    340339        ALLOC_DIR_CAS,
    341340        ALLOC_DIR_CLEANUP,
    342         ALLOC_DIR_XRAM_RSP
     341        ALLOC_DIR_XRAM_RSP,
     342        ALLOC_DIR_CONFIG
    343343      };
    344344
     
    426426      uint32_t     m_cpt_cycles;        // Counter of cycles
    427427
    428       uint32_t     m_cpt_read;          // Number of READ transactions
     428      // Counters accessible in software (not yet but eventually)
     429      uint32_t     m_cpt_read_local;     // Number of local READ transactions
    429430      uint32_t     m_cpt_read_remote;   // number of remote READ transactions
    430       uint32_t     m_cpt_read_flits;    // number of flits for READs
    431431      uint32_t     m_cpt_read_cost;     // Number of (flits * distance) for READs
    432432
    433       uint32_t     m_cpt_read_miss;     // Number of MISS READ
    434 
    435       uint32_t     m_cpt_write;         // Number of WRITE transactions
     433      uint32_t     m_cpt_write_local;    // Number of local WRITE transactions
    436434      uint32_t     m_cpt_write_remote;  // number of remote WRITE transactions
    437       uint32_t     m_cpt_write_flits;   // number of flits for WRITEs
     435      uint32_t     m_cpt_write_flits_local;  // number of flits for local WRITEs
     436      uint32_t     m_cpt_write_flits_remote; // number of flits for remote WRITEs
    438437      uint32_t     m_cpt_write_cost;    // Number of (flits * distance) for WRITEs
    439438
     439      uint32_t     m_cpt_ll_local;       // Number of local LL transactions
     440      uint32_t     m_cpt_ll_remote;      // number of remote LL transactions
     441      uint32_t     m_cpt_ll_cost;        // Number of (flits * distance) for LLs
     442
     443      uint32_t     m_cpt_sc_local;       // Number of local SC transactions
     444      uint32_t     m_cpt_sc_remote;      // number of remote SC transactions
     445      uint32_t     m_cpt_sc_cost;        // Number of (flits * distance) for SCs
     446
     447      uint32_t     m_cpt_cas_local;      // Number of local SC transactions
     448      uint32_t     m_cpt_cas_remote;     // number of remote SC transactions
     449      uint32_t     m_cpt_cas_cost;       // Number of (flits * distance) for SCs
     450
     451      uint32_t     m_cpt_update;         // Number of requests causing an UPDATE
     452      uint32_t     m_cpt_update_local;   // Number of local UPDATE transactions
     453      uint32_t     m_cpt_update_remote;  // Number of remote UPDATE transactions
     454      uint32_t     m_cpt_update_cost;    // Number of (flits * distance) for UPDT
     455
     456      uint32_t     m_cpt_m_inval;        // Number of requests causing M_INV
     457      uint32_t     m_cpt_m_inval_local;  // Number of local M_INV transactions
     458      uint32_t     m_cpt_m_inval_remote; // Number of remote M_INV transactions
     459      uint32_t     m_cpt_m_inval_cost;   // Number of (flits * distance) for M_INV
     460
     461      uint32_t     m_cpt_br_inval;       // Number of BROADCAST INVAL
     462
     463      uint32_t     m_cpt_cleanup_local;  // Number of local CLEANUP transactions
     464      uint32_t     m_cpt_cleanup_remote; // Number of remote CLEANUP transactions
     465      uint32_t     m_cpt_cleanup_cost;   // Number of (flits * distance) for CLEANUPs
     466
     467      // Counters not accessible by software
     468      uint32_t     m_cpt_read_miss;      // Number of MISS READ
    440469      uint32_t     m_cpt_write_miss;    // Number of MISS WRITE
    441       uint32_t     m_cpt_write_cells;   // Cumulated length for WRITE transactions
    442470      uint32_t     m_cpt_write_dirty;   // Cumulated length for WRITE transactions
    443       uint32_t     m_cpt_update;        // Number of UPDATE transactions
     471      uint32_t     m_cpt_write_broadcast;// Number of BROADCAST INVAL because write
     472
    444473      uint32_t     m_cpt_trt_rb;        // Read blocked by a hit in trt
    445474      uint32_t     m_cpt_trt_full;      // Transaction blocked due to a full trt
    446       uint32_t     m_cpt_update_mult;   // Number of targets for UPDATE
    447       uint32_t     m_cpt_inval;         // Number of INVAL  transactions
    448       uint32_t     m_cpt_inval_mult;    // Number of targets for INVAL
    449       uint32_t     m_cpt_inval_brdcast; // Number of BROADCAST INVAL
    450       uint32_t     m_cpt_cleanup;       // Number of CLEANUP transactions
    451       uint32_t     m_cpt_ll;            // Number of LL transactions
    452       uint32_t     m_cpt_sc;            // Number of SC transactions
    453       uint32_t     m_cpt_cas;           // Number of CAS transactions
    454475     
    455476      uint32_t     m_cpt_read_fsm_dir_lock;        // wait DIR LOCK
     
    547568      uint32_t     m_cpt_read_WTF;
    548569
    549       uint32_t     m_cpt_cleanup_cost;  // Number of (flits * distance) for CLEANUPs
    550 
    551570      uint32_t     m_cpt_update_flits;  // Number of flits for UPDATEs
    552       uint32_t     m_cpt_update_cost;   // Number of (flits * distance) for UPDATEs
    553 
    554571      uint32_t     m_cpt_inval_cost;    // Number of (flits * distance) for INVALs
    555572
    556573      uint32_t     m_cpt_get;
    557 
    558574      uint32_t     m_cpt_put;
    559575
     
    573589      soclib::caba::DspinOutput<dspin_out_width>  p_dspin_clack;
    574590
     591#if MONITOR_MEMCACHE_FSM == 1
     592      sc_out<int> p_read_fsm;
     593      sc_out<int> p_write_fsm;
     594      sc_out<int> p_xram_rsp_fsm;
     595      sc_out<int> p_cas_fsm;
     596      sc_out<int> p_cleanup_fsm;
     597      sc_out<int> p_config_fsm;
     598      sc_out<int> p_alloc_heap_fsm;
     599      sc_out<int> p_alloc_dir_fsm;
     600      sc_out<int> p_alloc_trt_fsm;
     601      sc_out<int> p_alloc_upt_fsm;
     602      sc_out<int> p_alloc_ivt_fsm;
     603      sc_out<int> p_tgt_cmd_fsm;
     604      sc_out<int> p_tgt_rsp_fsm;
     605      sc_out<int> p_ixr_cmd_fsm;
     606      sc_out<int> p_ixr_rsp_fsm;
     607      sc_out<int> p_cc_send_fsm;
     608      sc_out<int> p_cc_receive_fsm;
     609      sc_out<int> p_multi_ack_fsm;
     610#endif
     611
    575612      VciMemCache(
    576613          sc_module_name name,                                // Instance Name
     
    580617          const soclib::common::IntTab       &tgtid_d,        // global index INT network
    581618          const size_t                       cc_global_id,    // global index CC network
     619          const size_t                       x_width,         // X width in platform
     620          const size_t                       y_width,         // Y width in platform
    582621          const size_t                       nways,           // Number of ways per set
    583622          const size_t                       nsets,           // Number of sets
     
    593632      ~VciMemCache();
    594633
    595       void clear_stats();
    596       void print_stats();
     634      void print_stats(bool activity_counters, bool stats);
    597635      void print_trace();
    598636      void cache_monitor(addr_t addr);
     
    605643      void genMoore();
    606644      void check_monitor(addr_t addr, data_t data, bool read);
     645      uint32_t req_distance(uint32_t req_srcid);
     646      bool is_local_req(uint32_t req_srcid);
    607647
    608648      // Component attributes
     
    618658      const size_t                       m_words;            // Number of words in a line
    619659      const size_t                       m_cc_global_id;     // global_index on cc network
     660      const size_t                       m_xwidth;           // number of x bits in platform
     661      const size_t                       m_ywidth;           // number of y bits in platform
    620662      size_t                             m_debug_start_cycle;
    621663      bool                               m_debug_ok;
     
    692734
    693735      sc_signal<int>         r_tgt_cmd_fsm;
    694       sc_signal<size_t>      r_tgt_cmd_srcid;           // srcid for response to config
    695       sc_signal<size_t>      r_tgt_cmd_trdid;           // trdid for response to config
    696       sc_signal<size_t>      r_tgt_cmd_pktid;           // pktid for response to config
    697736
    698737      ///////////////////////////////////////////////////////
     
    723762      sc_signal<bool>     r_config_to_ixr_cmd_req;    // valid request
    724763      sc_signal<size_t>   r_config_to_ixr_cmd_index;  // TRT index
    725 
    726764
    727765      // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache)
     
    824862      sc_signal<size_t>   r_write_upt_index;          // index in Update Table
    825863      sc_signal<bool>     r_write_sc_fail;            // sc command failed
    826       //sc_signal<bool>     r_write_pending_sc;         // sc command pending
    827       sc_signal<data_t>   r_write_sc_key;             // sc key
     864      sc_signal<data_t>   r_write_sc_key;             // sc command key
     865      sc_signal<bool>     r_write_bc_data_we;         // Write enable for data buffer
    828866 
    829867      // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
     
    836874      // Buffer between WRITE fsm and IXR_CMD fsm
    837875      sc_signal<bool>     r_write_to_ixr_cmd_req;     // valid request
    838       sc_signal<bool>     r_write_to_ixr_cmd_put;     // request type (GET/PUT)
    839876      sc_signal<size_t>   r_write_to_ixr_cmd_index;   // TRT index
    840877
     
    9651002      // Buffer between CAS fsm and IXR_CMD fsm (XRAM write)
    9661003      sc_signal<bool>     r_cas_to_ixr_cmd_req;   // valid request
    967       sc_signal<bool>     r_cas_to_ixr_cmd_put;   // request type (GET/PUT)
    9681004      sc_signal<size_t>   r_cas_to_ixr_cmd_index; // TRT index
    9691005
  • branches/RWT/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

    r540 r545  
    5858namespace soclib { namespace caba {
    5959
    60 const char *tgt_cmd_fsm_str[] =
    61 {
    62   "TGT_CMD_IDLE",
    63   "TGT_CMD_ERROR",
    64   "TGT_CMD_READ",
    65   "TGT_CMD_WRITE",
    66   "TGT_CMD_CAS",
    67   "TGT_CMD_CONFIG"
    68 };
    69 const char *tgt_rsp_fsm_str[] =
    70 {
    71   "TGT_RSP_CONFIG_IDLE",
    72   "TGT_RSP_TGT_CMD_IDLE",
    73   "TGT_RSP_READ_IDLE",
    74   "TGT_RSP_WRITE_IDLE",
    75   "TGT_RSP_CAS_IDLE",
    76   "TGT_RSP_XRAM_IDLE",
    77   "TGT_RSP_MULTI_ACK_IDLE",
    78   "TGT_RSP_CLEANUP_IDLE",
    79   "TGT_RSP_CONFIG",
    80   "TGT_RSP_TGT_CMD",
    81   "TGT_RSP_READ",
    82   "TGT_RSP_WRITE",
    83   "TGT_RSP_CAS",
    84   "TGT_RSP_XRAM",
    85   "TGT_RSP_MULTI_ACK",
    86   "TGT_RSP_CLEANUP"
    87 };
    88 const char *cc_receive_fsm_str[] =
    89 {
    90   "CC_RECEIVE_IDLE",
    91   "CC_RECEIVE_CLEANUP",
    92   "CC_RECEIVE_CLEANUP_EOP",
    93   "CC_RECEIVE_MULTI_ACK"
    94 };
    95 const char *cc_send_fsm_str[] =
    96 {
    97   "CC_SEND_CONFIG_IDLE",
    98   "CC_SEND_XRAM_RSP_IDLE",
    99   "CC_SEND_WRITE_IDLE",
    100   "CC_SEND_CAS_IDLE",
    101   "CC_SEND_CONFIG_INVAL_HEADER",
    102   "CC_SEND_CONFIG_INVAL_NLINE",
    103   "CC_SEND_CONFIG_BRDCAST_HEADER",
    104   "CC_SEND_CONFIG_BRDCAST_NLINE",
    105   "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
    106   "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
    107   "CC_SEND_XRAM_RSP_INVAL_HEADER",
    108   "CC_SEND_XRAM_RSP_INVAL_NLINE",
    109   "CC_SEND_READ_NCC_INVAL_HEADER",
    110   "CC_SEND_READ_NCC_INVAL_NLINE",
    111   "CC_SEND_WRITE_NCC_INVAL_HEADER",
    112   "CC_SEND_WRITE_NCC_INVAL_NLINE",
    113   "CC_SEND_WRITE_BRDCAST_HEADER",
    114   "CC_SEND_WRITE_BRDCAST_NLINE",
    115   "CC_SEND_WRITE_UPDT_HEADER",
    116   "CC_SEND_WRITE_UPDT_NLINE",
    117   "CC_SEND_WRITE_UPDT_DATA",
    118   "CC_SEND_CAS_BRDCAST_HEADER",
    119   "CC_SEND_CAS_BRDCAST_NLINE",
    120   "CC_SEND_CAS_UPDT_HEADER",
    121   "CC_SEND_CAS_UPDT_NLINE",
    122   "CC_SEND_CAS_UPDT_DATA",
    123   "CC_SEND_CAS_UPDT_DATA_HIGH"
    124 };
    125 const char *multi_ack_fsm_str[] =
    126 {
    127   "MULTI_ACK_IDLE",
    128   "MULTI_ACK_UPT_LOCK",
    129   "MULTI_ACK_UPT_CLEAR",
    130   "MULTI_ACK_WRITE_RSP",
    131 };
    132 const char *config_fsm_str[] =
    133 {
    134   "CONFIG_IDLE",
    135   "CONFIG_LOOP",
    136   "CONFIG_WAIT"
    137   "CONFIG_RSP",
    138   "CONFIG_DIR_REQ",
    139   "CONFIG_DIR_ACCESS",
    140   "CONFIG_IVT_LOCK",
    141   "CONFIG_BC_SEND",
    142   "CONFIG_INVAL_SEND"
    143   "CONFIG_HEAP_REQ",
    144   "CONFIG_HEAP_SCAN",
    145   "CONFIG_HEAP_LAST",
    146   "CONFIG_TRT_LOCK",
    147   "CONFIG_TRT_SET",
    148   "CONFIG_PUT_REQ"
    149 };
    150 const char *read_fsm_str[] =
    151 {
    152   "READ_IDLE",
    153   "READ_DIR_REQ",
    154   "READ_DIR_LOCK",
    155   "READ_IVT_LOCK",
    156   "READ_WAIT",
    157   "READ_DIR_HIT",
    158   "READ_HEAP_REQ",
    159   "READ_HEAP_LOCK",
    160   "READ_HEAP_WRITE",
    161   "READ_HEAP_ERASE",
    162   "READ_HEAP_LAST",
    163   "READ_RSP",
    164   "READ_TRT_LOCK",
    165   "READ_TRT_SET",
    166   "READ_TRT_REQ"
    167 };
    168 const char *write_fsm_str[] =
    169 {
    170   "WRITE_IDLE",
    171   "WRITE_NEXT",
    172   "WRITE_DIR_REQ",
    173   "WRITE_DIR_LOCK",
    174   "WRITE_IVT_LOCK_HIT_WB",
    175   "WRITE_DIR_HIT",
    176   "WRITE_UPT_LOCK",
    177   "WRITE_UPT_HEAP_LOCK",
    178   "WRITE_UPT_REQ",
    179   "WRITE_UPT_NEXT",
    180   "WRITE_UPT_DEC",
    181   "WRITE_RSP",
    182   "WRITE_MISS_IVT_LOCK",
    183   "WRITE_MISS_TRT_LOCK",
    184   "WRITE_MISS_TRT_DATA",
    185   "WRITE_MISS_TRT_SET",
    186   "WRITE_MISS_XRAM_REQ",
    187   "WRITE_BC_DIR_READ",
    188   "WRITE_BC_TRT_LOCK",
    189   "WRITE_BC_IVT_LOCK",
    190   "WRITE_BC_DIR_INVAL",
    191   "WRITE_BC_CC_SEND",
    192   "WRITE_BC_XRAM_REQ",
    193   "WRITE_WAIT"
    194 };
    195 const char *ixr_rsp_fsm_str[] =
    196 {
    197   "IXR_RSP_IDLE",
    198   "IXR_RSP_ACK",
    199   "IXR_RSP_TRT_ERASE",
    200   "IXR_RSP_TRT_READ"
    201 };
    202 const char *xram_rsp_fsm_str[] =
    203 {
    204   "XRAM_RSP_IDLE",
    205   "XRAM_RSP_TRT_COPY",
    206   "XRAM_RSP_TRT_DIRTY",
    207   "XRAM_RSP_DIR_LOCK",
    208   "XRAM_RSP_DIR_UPDT",
    209   "XRAM_RSP_DIR_RSP",
    210   "XRAM_RSP_IVT_LOCK",
    211   "XRAM_RSP_INVAL_WAIT",
    212   "XRAM_RSP_INVAL",
    213   "XRAM_RSP_WRITE_DIRTY",
    214   "XRAM_RSP_HEAP_REQ",
    215   "XRAM_RSP_HEAP_ERASE",
    216   "XRAM_RSP_HEAP_LAST",
    217   "XRAM_RSP_ERROR_ERASE",
    218   "XRAM_RSP_ERROR_RSP"
    219 };
    220 const char *ixr_cmd_fsm_str[] =
    221 {
    222   "IXR_CMD_READ_IDLE",
    223   "IXR_CMD_WRITE_IDLE",
    224   "IXR_CMD_CAS_IDLE",
    225   "IXR_CMD_XRAM_IDLE",
    226   "IXR_CMD_CLEANUP_IDLE",
    227   "IXR_CMD_CONFIG_IDLE",
    228   "IXR_CMD_READ_TRT",
    229   "IXR_CMD_WRITE_TRT",
    230   "IXR_CMD_CAS_TRT",
    231   "IXR_CMD_XRAM_TRT",
    232   "IXR_CMD_CLEANUP_TRT",
    233   "IXR_CMD_CONFIG_TRT",
    234   "IXR_CMD_READ_SEND",
    235   "IXR_CMD_WRITE_SEND",
    236   "IXR_CMD_CAS_SEND",
    237   "IXR_CMD_XRAM_SEND",
    238   "IXR_CMD_CLEANUP_DATA_SEND",
    239   "IXR_CMD_CONFIG_SEND"
    240 };
    241 const char *cas_fsm_str[] =
    242 {
    243   "CAS_IDLE",
    244   "CAS_DIR_REQ",
    245   "CAS_DIR_LOCK",
    246   "CAS_DIR_HIT_READ",
    247   "CAS_DIR_HIT_COMPARE",
    248   "CAS_DIR_HIT_WRITE",
    249   "CAS_UPT_LOCK",
    250   "CAS_UPT_HEAP_LOCK",
    251   "CAS_UPT_REQ",
    252   "CAS_UPT_NEXT",
    253   "CAS_BC_TRT_LOCK",
    254   "CAS_BC_IVT_LOCK",
    255   "CAS_BC_DIR_INVAL",
    256   "CAS_BC_CC_SEND",
    257   "CAS_BC_XRAM_REQ",
    258   "CAS_RSP_FAIL",
    259   "CAS_RSP_SUCCESS",
    260   "CAS_MISS_TRT_LOCK",
    261   "CAS_MISS_TRT_SET",
    262   "CAS_MISS_XRAM_REQ",
    263   "CAS_WAIT"
    264 };
    265 const char *cleanup_fsm_str[] =
    266 {
    267   "CLEANUP_IDLE",
    268   "CLEANUP_GET_NLINE",
    269   "CLEANUP_GET_DATA",
    270   "CLEANUP_DIR_REQ",
    271   "CLEANUP_DIR_LOCK",
    272   "CLEANUP_DIR_WRITE",
    273   "CLEANUP_IVT_LOCK_DATA",
    274   "CLEANUP_IVT_CLEAR_DATA",
    275   "CLEANUP_READ_RSP",
    276   "CLEANUP_HEAP_REQ",
    277   "CLEANUP_HEAP_LOCK",
    278   "CLEANUP_HEAP_SEARCH",
    279   "CLEANUP_HEAP_CLEAN",
    280   "CLEANUP_HEAP_FREE",
    281   "CLEANUP_IVT_LOCK",
    282   "CLEANUP_IVT_DECREMENT",
    283   "CLEANUP_IVT_CLEAR",
    284   "CLEANUP_WRITE_RSP",
    285   "CLEANUP_IXR_REQ",
    286   "CLEANUP_WAIT",
    287   "CLEANUP_SEND_CLACK"
    288 };
    289 const char *alloc_dir_fsm_str[] =
    290 {
    291   "ALLOC_DIR_RESET",
    292   "ALLOC_DIR_CONFIG",
    293   "ALLOC_DIR_READ",
    294   "ALLOC_DIR_WRITE",
    295   "ALLOC_DIR_CAS",
    296   "ALLOC_DIR_CLEANUP",
    297   "ALLOC_DIR_XRAM_RSP"
    298 };
    299 const char *alloc_trt_fsm_str[] =
    300 {
    301   "ALLOC_TRT_READ",
    302   "ALLOC_TRT_WRITE",
    303   "ALLOC_TRT_CAS",
    304   "ALLOC_TRT_XRAM_RSP",
    305   "ALLOC_TRT_IXR_RSP",
    306   "ALLOC_TRT_CLEANUP",
    307   "ALLOC_TRT_IXR_CMD",
    308   "ALLOC_TRT_CONFIG"
    309 };
    310 const char *alloc_upt_fsm_str[] =
    311 {
    312   "ALLOC_UPT_WRITE",
    313   "ALLOC_UPT_CAS",
    314   "ALLOC_UPT_MULTI_ACK"
    315 };
    316 const char *alloc_ivt_fsm_str[] =
    317 {
    318   "ALLOC_IVT_WRITE",
    319   "ALLOC_IVT_READ",
    320   "ALLOC_IVT_XRAM_RSP",
    321   "ALLOC_IVT_CLEANUP",
    322   "ALLOC_IVT_CAS",
    323   "ALLOC_IVT_CONFIG"
    324 };
    325 const char *alloc_heap_fsm_str[] =
    326 {
    327   "ALLOC_HEAP_RESET",
    328   "ALLOC_HEAP_READ",
    329   "ALLOC_HEAP_WRITE",
    330   "ALLOC_HEAP_CAS",
    331   "ALLOC_HEAP_CLEANUP",
    332   "ALLOC_HEAP_XRAM_RSP",
    333   "ALLOC_HEAP_CONFIG"
    334 };
     60    const char *tgt_cmd_fsm_str[] =
     61    {
     62        "TGT_CMD_IDLE",
     63        "TGT_CMD_READ",
     64        "TGT_CMD_WRITE",
     65        "TGT_CMD_CAS",
     66        "TGT_CMD_ERROR",
     67        "TGT_CMD_CONFIG"
     68    };
     69    const char *tgt_rsp_fsm_str[] =
     70    {
     71        "TGT_RSP_READ_IDLE",
     72        "TGT_RSP_WRITE_IDLE",
     73        "TGT_RSP_CAS_IDLE",
     74        "TGT_RSP_XRAM_IDLE",
     75        "TGT_RSP_MULTI_ACK_IDLE",
     76        "TGT_RSP_CLEANUP_IDLE",
     77        "TGT_RSP_CONFIG_IDLE",
     78        "TGT_RSP_TGT_CMD_IDLE",
     79        "TGT_RSP_READ",
     80        "TGT_RSP_WRITE",
     81        "TGT_RSP_CAS",
     82        "TGT_RSP_XRAM",
     83        "TGT_RSP_MULTI_ACK",
     84        "TGT_RSP_CLEANUP",
     85        "TGT_RSP_CONFIG",
     86        "TGT_RSP_TGT_CMD"
     87    };
     88    const char *cc_receive_fsm_str[] =
     89    {
     90        "CC_RECEIVE_IDLE",
     91        "CC_RECEIVE_CLEANUP",
     92        "CC_RECEIVE_CLEANUP_EOP",
     93        "CC_RECEIVE_MULTI_ACK"
     94    };
     95    const char *cc_send_fsm_str[] =
     96    {
     97        "CC_SEND_XRAM_RSP_IDLE",
     98        "CC_SEND_WRITE_IDLE",
     99        "CC_SEND_CAS_IDLE",
     100        "CC_SEND_CONFIG_IDLE",
     101        "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
     102        "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
     103        "CC_SEND_XRAM_RSP_INVAL_HEADER",
     104        "CC_SEND_XRAM_RSP_INVAL_NLINE",
     105        "CC_SEND_READ_NCC_INVAL_HEADER",
     106        "CC_SEND_READ_NCC_INVAL_NLINE",
     107        "CC_SEND_WRITE_NCC_INVAL_HEADER",
     108        "CC_SEND_WRITE_NCC_INVAL_NLINE",
     109        "CC_SEND_WRITE_BRDCAST_HEADER",
     110        "CC_SEND_WRITE_BRDCAST_NLINE",
     111        "CC_SEND_WRITE_UPDT_HEADER",
     112        "CC_SEND_WRITE_UPDT_NLINE",
     113        "CC_SEND_WRITE_UPDT_DATA",
     114        "CC_SEND_CAS_BRDCAST_HEADER",
     115        "CC_SEND_CAS_BRDCAST_NLINE",
     116        "CC_SEND_CAS_UPDT_HEADER",
     117        "CC_SEND_CAS_UPDT_NLINE",
     118        "CC_SEND_CAS_UPDT_DATA",
     119        "CC_SEND_CAS_UPDT_DATA_HIGH",
     120        "CC_SEND_CONFIG_INVAL_HEADER",
     121        "CC_SEND_CONFIG_INVAL_NLINE",
     122        "CC_SEND_CONFIG_BRDCAST_HEADER",
     123        "CC_SEND_CONFIG_BRDCAST_NLINE"
     124    };
     125    const char *multi_ack_fsm_str[] =
     126    {
     127        "MULTI_ACK_IDLE",
     128        "MULTI_ACK_UPT_LOCK",
     129        "MULTI_ACK_UPT_CLEAR",
     130        "MULTI_ACK_WRITE_RSP",
     131    };
     132    const char *config_fsm_str[] =
     133    {
     134        "CONFIG_IDLE",
     135        "CONFIG_LOOP",
     136        "CONFIG_WAIT"
     137        "CONFIG_RSP",
     138        "CONFIG_DIR_REQ",
     139        "CONFIG_DIR_ACCESS",
     140        "CONFIG_IVT_LOCK",
     141        "CONFIG_BC_SEND",
     142        "CONFIG_INVAL_SEND"
     143        "CONFIG_HEAP_REQ",
     144        "CONFIG_HEAP_SCAN",
     145        "CONFIG_HEAP_LAST",
     146        "CONFIG_TRT_LOCK",
     147        "CONFIG_TRT_SET",
     148        "CONFIG_PUT_REQ"
     149    };
     150    const char *read_fsm_str[] =
     151    {
     152        "READ_IDLE",
     153        "READ_DIR_REQ",
     154        "READ_DIR_LOCK",
     155        "READ_IVT_LOCK",
     156        "READ_WAIT",
     157        "READ_DIR_HIT",
     158        "READ_HEAP_REQ",
     159        "READ_HEAP_LOCK",
     160        "READ_HEAP_WRITE",
     161        "READ_HEAP_ERASE",
     162        "READ_HEAP_LAST",
     163        "READ_RSP",
     164        "READ_TRT_LOCK",
     165        "READ_TRT_SET",
     166        "READ_TRT_REQ"
     167    };
     168    const char *write_fsm_str[] =
     169    {
     170        "WRITE_IDLE",
     171        "WRITE_NEXT",
     172        "WRITE_DIR_REQ",
     173        "WRITE_DIR_LOCK",
     174        "WRITE_IVT_LOCK_HIT_WB",
     175        "WRITE_DIR_HIT",
     176        "WRITE_UPT_LOCK",
     177        "WRITE_UPT_HEAP_LOCK",
     178        "WRITE_UPT_REQ",
     179        "WRITE_UPT_NEXT",
     180        "WRITE_UPT_DEC",
     181        "WRITE_RSP",
     182        "WRITE_MISS_IVT_LOCK",
     183        "WRITE_MISS_TRT_LOCK",
     184        "WRITE_MISS_TRT_DATA",
     185        "WRITE_MISS_TRT_SET",
     186        "WRITE_MISS_XRAM_REQ",
     187        "WRITE_BC_DIR_READ",
     188        "WRITE_BC_TRT_LOCK",
     189        "WRITE_BC_IVT_LOCK",
     190        "WRITE_BC_DIR_INVAL",
     191        "WRITE_BC_CC_SEND",
     192        "WRITE_BC_XRAM_REQ",
     193        "WRITE_WAIT"
     194    };
     195    const char *ixr_rsp_fsm_str[] =
     196    {
     197        "IXR_RSP_IDLE",
     198        "IXR_RSP_ACK",
     199        "IXR_RSP_TRT_ERASE",
     200        "IXR_RSP_TRT_READ"
     201    };
     202    const char *xram_rsp_fsm_str[] =
     203    {
     204        "XRAM_RSP_IDLE",
     205        "XRAM_RSP_TRT_COPY",
     206        "XRAM_RSP_TRT_DIRTY",
     207        "XRAM_RSP_DIR_LOCK",
     208        "XRAM_RSP_DIR_UPDT",
     209        "XRAM_RSP_DIR_RSP",
     210        "XRAM_RSP_IVT_LOCK",
     211        "XRAM_RSP_INVAL_WAIT",
     212        "XRAM_RSP_INVAL",
     213        "XRAM_RSP_WRITE_DIRTY",
     214        "XRAM_RSP_HEAP_REQ",
     215        "XRAM_RSP_HEAP_ERASE",
     216        "XRAM_RSP_HEAP_LAST",
     217        "XRAM_RSP_ERROR_ERASE",
     218        "XRAM_RSP_ERROR_RSP"
     219    };
     220    const char *ixr_cmd_fsm_str[] =
     221    {
     222        "IXR_CMD_READ_IDLE",
     223        "IXR_CMD_WRITE_IDLE",
     224        "IXR_CMD_CAS_IDLE",
     225        "IXR_CMD_XRAM_IDLE",
     226        "IXR_CMD_CLEANUP_IDLE",
     227        "IXR_CMD_CONFIG_IDLE",
     228        "IXR_CMD_READ_TRT",
     229        "IXR_CMD_WRITE_TRT",
     230        "IXR_CMD_CAS_TRT",
     231        "IXR_CMD_XRAM_TRT",
     232        "IXR_CMD_CLEANUP_TRT",
     233        "IXR_CMD_CONFIG_TRT",
     234        "IXR_CMD_READ_SEND",
     235        "IXR_CMD_WRITE_SEND",
     236        "IXR_CMD_CAS_SEND",
     237        "IXR_CMD_XRAM_SEND",
     238        "IXR_CMD_CLEANUP_DATA_SEND",
     239        "IXR_CMD_CONFIG_SEND"
     240    };
     241    const char *cas_fsm_str[] =
     242    {
     243        "CAS_IDLE",
     244        "CAS_DIR_REQ",
     245        "CAS_DIR_LOCK",
     246        "CAS_DIR_HIT_READ",
     247        "CAS_DIR_HIT_COMPARE",
     248        "CAS_DIR_HIT_WRITE",
     249        "CAS_UPT_LOCK",
     250        "CAS_UPT_HEAP_LOCK",
     251        "CAS_UPT_REQ",
     252        "CAS_UPT_NEXT",
     253        "CAS_BC_TRT_LOCK",
     254        "CAS_BC_IVT_LOCK",
     255        "CAS_BC_DIR_INVAL",
     256        "CAS_BC_CC_SEND",
     257        "CAS_BC_XRAM_REQ",
     258        "CAS_RSP_FAIL",
     259        "CAS_RSP_SUCCESS",
     260        "CAS_MISS_TRT_LOCK",
     261        "CAS_MISS_TRT_SET",
     262        "CAS_MISS_XRAM_REQ",
     263        "CAS_WAIT"
     264    };
     265    const char *cleanup_fsm_str[] =
     266    {
     267        "CLEANUP_IDLE",
     268        "CLEANUP_GET_NLINE",
     269        "CLEANUP_GET_DATA",
     270        "CLEANUP_DIR_REQ",
     271        "CLEANUP_DIR_LOCK",
     272        "CLEANUP_DIR_WRITE",
     273        "CLEANUP_IVT_LOCK_DATA",
     274        "CLEANUP_IVT_CLEAR_DATA",
     275        "CLEANUP_READ_RSP",
     276        "CLEANUP_HEAP_REQ",
     277        "CLEANUP_HEAP_LOCK",
     278        "CLEANUP_HEAP_SEARCH",
     279        "CLEANUP_HEAP_CLEAN",
     280        "CLEANUP_HEAP_FREE",
     281        "CLEANUP_IVT_LOCK",
     282        "CLEANUP_IVT_DECREMENT",
     283        "CLEANUP_IVT_CLEAR",
     284        "CLEANUP_WRITE_RSP",
     285        "CLEANUP_IXR_REQ",
     286        "CLEANUP_WAIT",
     287        "CLEANUP_SEND_CLACK"
     288    };
     289    const char *alloc_dir_fsm_str[] =
     290    {
     291        "ALLOC_DIR_RESET",
     292        "ALLOC_DIR_READ",
     293        "ALLOC_DIR_WRITE",
     294        "ALLOC_DIR_CAS",
     295        "ALLOC_DIR_CLEANUP",
     296        "ALLOC_DIR_XRAM_RSP",
     297        "ALLOC_DIR_CONFIG"
     298    };
     299    const char *alloc_trt_fsm_str[] =
     300    {
     301        "ALLOC_TRT_READ",
     302        "ALLOC_TRT_WRITE",
     303        "ALLOC_TRT_CAS",
     304        "ALLOC_TRT_XRAM_RSP",
     305        "ALLOC_TRT_IXR_RSP",
     306        "ALLOC_TRT_CLEANUP",
     307        "ALLOC_TRT_IXR_CMD",
     308        "ALLOC_TRT_CONFIG"
     309    };
     310    const char *alloc_upt_fsm_str[] =
     311    {
     312        "ALLOC_UPT_WRITE",
     313        "ALLOC_UPT_CAS",
     314        "ALLOC_UPT_MULTI_ACK"
     315    };
     316    const char *alloc_ivt_fsm_str[] =
     317    {
     318        "ALLOC_IVT_WRITE",
     319        "ALLOC_IVT_READ",
     320        "ALLOC_IVT_XRAM_RSP",
     321        "ALLOC_IVT_CLEANUP",
     322        "ALLOC_IVT_CAS",
     323        "ALLOC_IVT_CONFIG"
     324    };
     325    const char *alloc_heap_fsm_str[] =
     326    {
     327        "ALLOC_HEAP_RESET",
     328        "ALLOC_HEAP_READ",
     329        "ALLOC_HEAP_WRITE",
     330        "ALLOC_HEAP_CAS",
     331        "ALLOC_HEAP_CLEANUP",
     332        "ALLOC_HEAP_XRAM_RSP",
     333        "ALLOC_HEAP_CONFIG"
     334    };
    335335
    336336#define tmpl(x) \
    337   template<typename vci_param_int, \
    338            typename vci_param_ext, \
    339            size_t dspin_in_width,  \
    340            size_t dspin_out_width> x \
    341   VciMemCache<vci_param_int, vci_param_ext, dspin_in_width, dspin_out_width>
    342 
    343 using namespace soclib::common;
    344 
    345 ////////////////////////////////
    346 //  Constructor
    347 ////////////////////////////////
    348 
    349 tmpl(/**/) ::VciMemCache(
    350   sc_module_name      name,
    351   const MappingTable  &mtp,              // mapping table for direct network
    352   const MappingTable  &mtx,              // mapping table for external network
    353   const IntTab        &srcid_x,          // global index on external network
    354   const IntTab        &tgtid_d,          // global index on direct network
    355   const size_t        cc_global_id,      // global index on cc network
    356   const size_t        nways,             // number of ways per set
    357   const size_t        nsets,             // number of associative sets
    358   const size_t        nwords,            // number of words in cache line
    359   const size_t        max_copies,        // max number of copies in heap
    360   const size_t        heap_size,         // number of heap entries
    361   const size_t        trt_lines,         // number of TRT entries
    362   const size_t        upt_lines,         // number of UPT entries
    363   const size_t        ivt_lines,         // number of IVT entries
    364   const size_t        debug_start_cycle,
    365   const bool          debug_ok)
    366 
    367   : soclib::caba::BaseModule(name),
    368 
    369     p_clk( "p_clk" ),
    370     p_resetn( "p_resetn" ),
    371     p_vci_tgt( "p_vci_tgt" ),
    372     p_vci_ixr( "p_vci_ixr" ),
    373     p_dspin_p2m( "p_dspin_p2m" ),
    374     p_dspin_m2p( "p_dspin_m2p" ),
    375     p_dspin_clack( "p_dspin_clack" ),
    376 
    377     m_seglist( mtp.getSegmentList(tgtid_d) ),
    378     m_nseg( 0 ),
    379     m_srcid_x( mtx.indexForId(srcid_x) ),
    380     m_initiators( 1 << vci_param_int::S ),
    381     m_heap_size( heap_size ),
    382     m_ways( nways ),
    383     m_sets( nsets ),
    384     m_words( nwords ),
    385     m_cc_global_id( cc_global_id ),
    386     m_debug_start_cycle( debug_start_cycle ),
    387     m_debug_ok( debug_ok ),
    388     m_trt_lines(trt_lines),
    389     m_trt(this->name(), trt_lines, nwords),
    390     m_upt_lines(upt_lines),
    391     m_upt(upt_lines),
    392     m_ivt(ivt_lines),
    393     m_cache_directory(nways, nsets, nwords, vci_param_int::N),
    394     m_cache_data(nways, nsets, nwords),
    395     m_heap(m_heap_size),
    396     m_max_copies( max_copies ),
    397     m_llsc_table(),
     337    template<typename vci_param_int, \
     338    typename vci_param_ext, \
     339    size_t dspin_in_width,  \
     340    size_t dspin_out_width> x \
     341    VciMemCache<vci_param_int, vci_param_ext, dspin_in_width, dspin_out_width>
     342
     343    using namespace soclib::common;
     344
     345    ////////////////////////////////
     346    //  Constructor
     347    ////////////////////////////////
     348
     349    tmpl(/**/) ::VciMemCache(
     350            sc_module_name      name,
     351            const MappingTable  &mtp,              // mapping table for direct network
     352            const MappingTable  &mtx,              // mapping table for external network
     353            const IntTab        &srcid_x,          // global index on external network
     354            const IntTab        &tgtid_d,          // global index on direct network
     355            const size_t        cc_global_id,      // global index on cc network
     356            const size_t        x_width,           // number of x bits in platform
     357            const size_t        y_width,           // number of x bits in platform
     358            const size_t        nways,             // number of ways per set
     359            const size_t        nsets,             // number of associative sets
     360            const size_t        nwords,            // number of words in cache line
     361            const size_t        max_copies,        // max number of copies in heap
     362            const size_t        heap_size,         // number of heap entries
     363            const size_t        trt_lines,         // number of TRT entries
     364            const size_t        upt_lines,         // number of UPT entries
     365            const size_t        ivt_lines,         // number of IVT entries
     366            const size_t        debug_start_cycle,
     367            const bool          debug_ok)
     368
     369        : soclib::caba::BaseModule(name),
     370
     371        p_clk( "p_clk" ),
     372        p_resetn( "p_resetn" ),
     373        p_vci_tgt( "p_vci_tgt" ),
     374        p_vci_ixr( "p_vci_ixr" ),
     375        p_dspin_p2m( "p_dspin_p2m" ),
     376        p_dspin_m2p( "p_dspin_m2p" ),
     377        p_dspin_clack( "p_dspin_clack" ),
     378
     379        m_seglist( mtp.getSegmentList(tgtid_d) ),
     380        m_nseg( 0 ),
     381        m_srcid_x( mtx.indexForId(srcid_x) ),
     382        m_initiators( 1 << vci_param_int::S ),
     383        m_heap_size( heap_size ),
     384        m_ways( nways ),
     385        m_sets( nsets ),
     386        m_words( nwords ),
     387        m_cc_global_id( cc_global_id ),
     388        m_xwidth(x_width),
     389        m_ywidth(y_width),
     390        m_debug_start_cycle( debug_start_cycle ),
     391        m_debug_ok( debug_ok ),
     392        m_trt_lines(trt_lines),
     393        m_trt(this->name(), trt_lines, nwords),
     394        m_upt_lines(upt_lines),
     395        m_upt(upt_lines),
     396        m_ivt(ivt_lines),
     397        m_cache_directory(nways, nsets, nwords, vci_param_int::N),
     398        m_cache_data(nways, nsets, nwords),
     399        m_heap(m_heap_size),
     400        m_max_copies( max_copies ),
     401        m_llsc_table(),
    398402
    399403#define L2 soclib::common::uint32_log2
    400     m_x(L2(m_words), 2),
    401     m_y(L2(m_sets), L2(m_words) + 2),
    402     m_z(vci_param_int::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
    403     m_nline(vci_param_int::N - L2(m_words) - 2, L2(m_words) + 2),
     404        m_x(L2(m_words), 2),
     405        m_y(L2(m_sets), L2(m_words) + 2),
     406        m_z(vci_param_int::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
     407        m_nline(vci_param_int::N - L2(m_words) - 2, L2(m_words) + 2),
    404408#undef L2
    405409
    406     // XMIN(5 bits) / XMAX(5 bits) / YMIN(5 bits) / YMAX(5 bits)
    407     //   0b00000    /   0b11111    /   0b00000    /   0b11111
    408     m_broadcast_boundaries(0x7C1F),
    409 
    410     r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    411 
    412     //  FIFOs
    413     m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
    414     m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
    415     m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
    416     m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
    417     m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
    418 
    419     m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
    420     m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
    421     m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
    422     m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
    423     m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
    424     m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
    425     m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
    426 
    427     m_cmd_cas_addr_fifo("m_cmd_cas_addr_fifo",4),
    428     m_cmd_cas_eop_fifo("m_cmd_cas_eop_fifo",4),
    429     m_cmd_cas_srcid_fifo("m_cmd_cas_srcid_fifo",4),
    430     m_cmd_cas_trdid_fifo("m_cmd_cas_trdid_fifo",4),
    431     m_cmd_cas_pktid_fifo("m_cmd_cas_pktid_fifo",4),
    432     m_cmd_cas_wdata_fifo("m_cmd_cas_wdata_fifo",4),
    433 
    434     m_cc_receive_to_cleanup_fifo("m_cc_receive_to_cleanup_fifo", 4),
    435     m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
    436 
    437     r_config_fsm( "r_config_fsm" ),
    438 
    439     m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ),
    440     m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ),
    441 
    442     r_read_fsm( "r_read_fsm" ),
    443 
    444     r_write_fsm( "r_write_fsm" ),
    445 
    446     m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
    447     m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
    448 
    449     r_multi_ack_fsm("r_multi_ack_fsm"),
    450 
    451     r_cleanup_fsm("r_cleanup_fsm"),
    452 
    453     r_cas_fsm("r_cas_fsm"),
    454 
    455     m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
    456     m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
    457 
    458     r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
    459     r_xram_rsp_fsm("r_xram_rsp_fsm"),
    460 
    461     m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
    462     m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
    463 
    464     r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
    465 
    466     r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
    467 
    468     r_cc_send_fsm("r_cc_send_fsm"),
    469     r_cc_receive_fsm("r_cc_receive_fsm"),
    470 
    471     r_alloc_dir_fsm("r_alloc_dir_fsm"),
    472     r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"),
    473     r_alloc_trt_fsm("r_alloc_trt_fsm"),
    474     r_alloc_upt_fsm("r_alloc_upt_fsm"),
    475     r_alloc_ivt_fsm("r_alloc_ivt_fsm"),
    476     r_alloc_heap_fsm("r_alloc_heap_fsm"),
    477     r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
    478 {
    479     std::cout << "  - Building VciMemCache : " << name << std::endl;
    480 
    481     assert(IS_POW_OF_2(nsets));
    482     assert(IS_POW_OF_2(nwords));
    483     assert(IS_POW_OF_2(nways));
    484     assert(nsets);
    485     assert(nwords);
    486     assert(nways);
    487 
    488     // check Transaction table size
    489     assert((uint32_log2(trt_lines) <= vci_param_ext::T) and
    490     "MEMC ERROR : Need more bits for VCI TRDID field");
    491 
    492     // check internal and external data width
    493     assert( (vci_param_int::B == 4 ) and
    494     "MEMC ERROR : VCI internal data width must be 32 bits");
    495 
    496     assert( (vci_param_ext::B == 8) and
    497     "MEMC ERROR : VCI external data width must be 64 bits");
    498 
    499     // Check coherence between internal & external addresses
    500     assert( (vci_param_int::N == vci_param_ext::N) and
    501     "MEMC ERROR : VCI internal & external addresses must have the same width");
    502 
    503     // Get the segments associated to the MemCache
    504     std::list<soclib::common::Segment>::iterator seg;
    505     size_t i = 0;
    506 
    507     for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++)
     410        // XMIN(5 bits) / XMAX(5 bits) / YMIN(5 bits) / YMAX(5 bits)
     411        //   0b00000    /   0b11111    /   0b00000    /   0b11111
     412        m_broadcast_boundaries(0x7C1F),
     413
     414        r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
     415
     416        //  FIFOs
     417        m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
     418        m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
     419        m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
     420        m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
     421        m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
     422
     423        m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
     424        m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
     425        m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
     426        m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
     427        m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
     428        m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
     429        m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
     430
     431        m_cmd_cas_addr_fifo("m_cmd_cas_addr_fifo",4),
     432        m_cmd_cas_eop_fifo("m_cmd_cas_eop_fifo",4),
     433        m_cmd_cas_srcid_fifo("m_cmd_cas_srcid_fifo",4),
     434        m_cmd_cas_trdid_fifo("m_cmd_cas_trdid_fifo",4),
     435        m_cmd_cas_pktid_fifo("m_cmd_cas_pktid_fifo",4),
     436        m_cmd_cas_wdata_fifo("m_cmd_cas_wdata_fifo",4),
     437
     438        m_cc_receive_to_cleanup_fifo("m_cc_receive_to_cleanup_fifo", 4),
     439        m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
     440
     441        r_config_fsm( "r_config_fsm" ),
     442
     443        m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ),
     444        m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ),
     445
     446        r_read_fsm( "r_read_fsm" ),
     447
     448        r_write_fsm( "r_write_fsm" ),
     449
     450        m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
     451        m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
     452
     453        r_multi_ack_fsm("r_multi_ack_fsm"),
     454
     455        r_cleanup_fsm("r_cleanup_fsm"),
     456
     457        r_cas_fsm("r_cas_fsm"),
     458
     459        m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
     460        m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
     461
     462        r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
     463        r_xram_rsp_fsm("r_xram_rsp_fsm"),
     464
     465        m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
     466        m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
     467
     468        r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
     469
     470        r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
     471
     472        r_cc_send_fsm("r_cc_send_fsm"),
     473        r_cc_receive_fsm("r_cc_receive_fsm"),
     474
     475        r_alloc_dir_fsm("r_alloc_dir_fsm"),
     476        r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"),
     477        r_alloc_trt_fsm("r_alloc_trt_fsm"),
     478        r_alloc_upt_fsm("r_alloc_upt_fsm"),
     479        r_alloc_ivt_fsm("r_alloc_ivt_fsm"),
     480        r_alloc_heap_fsm("r_alloc_heap_fsm"),
     481        r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
     482#if MONITOR_MEMCACHE_FSM == 1
     483            ,
     484        p_read_fsm("p_read_fsm"),
     485        p_write_fsm("p_write_fsm"),
     486        p_xram_rsp_fsm("p_xram_rsp_fsm"),
     487        p_cas_fsm("p_cas_fsm"),
     488        p_cleanup_fsm("p_cleanup_fsm"),
     489        p_config_fsm("p_config_fsm"),
     490        p_alloc_heap_fsm("p_alloc_heap_fsm"),
     491        p_alloc_dir_fsm("p_alloc_dir_fsm"),
     492        p_alloc_trt_fsm("p_alloc_trt_fsm"),
     493        p_alloc_upt_fsm("p_alloc_upt_fsm"),
     494        p_alloc_ivt_fsm("p_alloc_ivt_fsm"),
     495        p_tgt_cmd_fsm("p_tgt_cmd_fsm"),
     496        p_tgt_rsp_fsm("p_tgt_rsp_fsm"),
     497        p_ixr_cmd_fsm("p_ixr_cmd_fsm"),
     498        p_ixr_rsp_fsm("p_ixr_rsp_fsm"),
     499        p_cc_send_fsm("p_cc_send_fsm"),
     500        p_cc_receive_fsm("p_cc_receive_fsm"),
     501        p_multi_ack_fsm("p_multi_ack_fsm")
     502#endif
     503        {
     504            std::cout << "  - Building VciMemCache : " << name << std::endl;
     505
     506            assert(IS_POW_OF_2(nsets));
     507            assert(IS_POW_OF_2(nwords));
     508            assert(IS_POW_OF_2(nways));
     509            assert(nsets);
     510            assert(nwords);
     511            assert(nways);
     512
     513            // check Transaction table size
     514            assert((uint32_log2(trt_lines) <= vci_param_ext::T) and
     515                    "MEMC ERROR : Need more bits for VCI TRDID field");
     516
     517            // check internal and external data width
     518            assert( (vci_param_int::B == 4 ) and
     519                    "MEMC ERROR : VCI internal data width must be 32 bits");
     520
     521            assert( (vci_param_ext::B == 8) and
     522                    "MEMC ERROR : VCI external data width must be 64 bits");
     523
     524            // Check coherence between internal & external addresses
     525            assert( (vci_param_int::N == vci_param_ext::N) and
     526                    "MEMC ERROR : VCI internal & external addresses must have the same width");
     527
     528            // Get the segments associated to the MemCache
     529            std::list<soclib::common::Segment>::iterator seg;
     530            size_t i = 0;
     531
     532            for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++)
     533            {
     534                std::cout << "    => segment " << seg->name()
     535                    << " / base = " << std::hex << seg->baseAddress()
     536                    << " / size = " << seg->size() << std::endl;
     537                m_nseg++;
     538            }
     539
     540            m_seg = new soclib::common::Segment*[m_nseg];
     541
     542            for(seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++)
     543            {
     544                if ( seg->special() ) m_seg_config = i;
     545                m_seg[i] = & (*seg);
     546                i++;
     547            }
     548
     549            // Allocation for IXR_RSP FSM
     550            r_ixr_rsp_to_xram_rsp_rok  = new sc_signal<bool>[m_trt_lines];
     551
     552            // Allocation for XRAM_RSP FSM
     553            r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
     554            r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
     555            //r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords];
     556
     557            // Allocation for READ FSM
     558            r_read_data                = new sc_signal<data_t>[nwords];
     559            r_read_to_tgt_rsp_data     = new sc_signal<data_t>[nwords];
     560
     561            // Allocation for WRITE FSM
     562            r_write_data               = new sc_signal<data_t>[nwords];
     563            r_write_be                 = new sc_signal<be_t>[nwords];
     564            r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
     565            r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
     566            //r_write_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
     567
     568            // Allocation for CAS FSM
     569            //r_cas_to_ixr_cmd_data      = new sc_signal<data_t>[nwords];
     570            r_cas_data                 = new sc_signal<data_t>[nwords];
     571            r_cas_rdata                = new sc_signal<data_t>[2];
     572
     573            // Allocation for IXR_CMD FSM
     574            r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
     575
     576            // Allocation for ODCCP
     577            r_cleanup_data             = new sc_signal<data_t>[nwords];
     578            r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
     579            r_cleanup_to_tgt_rsp_data  = new sc_signal<data_t>[nwords];
     580            r_cleanup_old_data         = new sc_signal<data_t>[nwords];
     581
     582            // Allocation for debug
     583            m_debug_previous_data      = new data_t[nwords];
     584            m_debug_data               = new data_t[nwords];
     585
     586            SC_METHOD(transition);
     587            dont_initialize();
     588            sensitive << p_clk.pos();
     589
     590            SC_METHOD(genMoore);
     591            dont_initialize();
     592            sensitive << p_clk.neg();
     593        } // end constructor
     594
     595    /////////////////////////////////////////////////////
     596    tmpl(void) ::cache_monitor(addr_t addr)
     597        /////////////////////////////////////////////////////
    508598    {
    509         std::cout << "    => segment " << seg->name()
    510                   << " / base = " << std::hex << seg->baseAddress()
    511                   << " / size = " << seg->size() << std::endl;
    512         m_nseg++;
     599        size_t way = 0;
     600        size_t set = 0;
     601        DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
     602
     603        bool data_change = false;
     604
     605        if ( entry.valid )
     606        {
     607            for ( size_t word = 0 ; word<m_words ; word++ )
     608            {
     609                m_debug_data[word] = m_cache_data.read(way, set, word);
     610                if ( m_debug_previous_valid and
     611                        (m_debug_data[word] != m_debug_previous_data[word]) )
     612                {
     613                    data_change = true;
     614                }
     615            }
     616        }
     617
     618        // print values if any change
     619        if ( (entry.valid != m_debug_previous_valid) or
     620                (entry.valid and (entry.count != m_debug_previous_count)) or
     621                (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change )
     622        {
     623            std::cout << "Monitor MEMC " << name()
     624                << " at cycle " << std::dec << m_cpt_cycles
     625                << " for address " << std::hex << addr
     626                << " / VAL = " << std::dec << entry.valid
     627                << " / WAY = " << way
     628                << " / COUNT = " << entry.count
     629                << " / DIRTY = " << entry.dirty
     630                << " / DATA_CHANGE = " << data_change
     631                << std::endl;
     632            std::cout << std::hex << "     /0:" << m_debug_data[0]
     633                << "/1:" << m_debug_data[1]
     634                << "/2:" << m_debug_data[2]
     635                << "/3:" << m_debug_data[3]
     636                << "/4:" << m_debug_data[4]
     637                << "/5:" << m_debug_data[5]
     638                << "/6:" << m_debug_data[6]
     639                << "/7:" << m_debug_data[7]
     640                << "/8:" << m_debug_data[8]
     641                << "/9:" << m_debug_data[9]
     642                << "/A:" << m_debug_data[10]
     643                << "/B:" << m_debug_data[11]
     644                << "/C:" << m_debug_data[12]
     645                << "/D:" << m_debug_data[13]
     646                << "/E:" << m_debug_data[14]
     647                << "/F:" << m_debug_data[15]
     648                << std::endl;
     649        }
     650        m_debug_previous_count = entry.count;
     651        m_debug_previous_valid = entry.valid;
     652        m_debug_previous_dirty = entry.dirty;
     653        for( size_t word=0 ; word<m_words ; word++ )
     654            m_debug_previous_data[word] = m_debug_data[word];
    513655    }
    514656
    515     m_seg = new soclib::common::Segment*[m_nseg];
    516 
    517     for(seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++)
     657
     658    /////////////////////////////////////////////////////
     659    tmpl(uint32_t)::req_distance(uint32_t req_srcid)
     660        /////////////////////////////////////////////////////
    518661    {
    519         if ( seg->special() ) m_seg_config = i;
    520         m_seg[i] = & (*seg);
    521         i++;
     662        const uint32_t srcid_width = vci_param_int::S;
     663        uint8_t self_x_srcid = m_cc_global_id >> (srcid_width - m_xwidth);
     664        uint8_t self_y_srcid = (m_cc_global_id >> (srcid_width - m_ywidth)) & ((1 << m_xwidth) - 1);
     665
     666        uint8_t x_srcid = req_srcid >> (srcid_width - m_xwidth);
     667        uint8_t y_srcid = (req_srcid >> (srcid_width - m_ywidth - m_xwidth)) & ((1 << m_xwidth) - 1);
     668        return abs(self_x_srcid - x_srcid) + abs(self_y_srcid - y_srcid);
    522669    }
    523670
    524     // Allocation for IXR_RSP FSM
    525     r_ixr_rsp_to_xram_rsp_rok  = new sc_signal<bool>[m_trt_lines];
    526 
    527     // Allocation for XRAM_RSP FSM
    528     r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
    529     r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
    530     //r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords];
    531 
    532     // Allocation for READ FSM
    533     r_read_data                = new sc_signal<data_t>[nwords];
    534     r_read_to_tgt_rsp_data     = new sc_signal<data_t>[nwords];
    535 
    536     // Allocation for WRITE FSM
    537     r_write_data               = new sc_signal<data_t>[nwords];
    538     r_write_be                 = new sc_signal<be_t>[nwords];
    539     r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
    540     r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
    541     //r_write_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
    542 
    543     // Allocation for CAS FSM
    544     //r_cas_to_ixr_cmd_data      = new sc_signal<data_t>[nwords];
    545     r_cas_data                 = new sc_signal<data_t>[nwords];
    546     r_cas_rdata                = new sc_signal<data_t>[2];
    547 
    548     // Allocation for IXR_CMD FSM
    549     r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
    550 
    551     // Allocation for ODCCP
    552     r_cleanup_data             = new sc_signal<data_t>[nwords];
    553     r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
    554     r_cleanup_to_tgt_rsp_data  = new sc_signal<data_t>[nwords];
    555     r_cleanup_old_data         = new sc_signal<data_t>[nwords];
    556 
    557     // Allocation for debug
    558     m_debug_previous_data      = new data_t[nwords];
    559     m_debug_data               = new data_t[nwords];
    560 
    561     SC_METHOD(transition);
    562     dont_initialize();
    563     sensitive << p_clk.pos();
    564 
    565     SC_METHOD(genMoore);
    566     dont_initialize();
    567     sensitive << p_clk.neg();
    568 } // end constructor
    569 
    570 /////////////////////////////////////////////////////
    571 tmpl(void) ::cache_monitor(addr_t addr)
    572 /////////////////////////////////////////////////////
    573 {
    574     size_t way = 0;
    575     size_t set = 0;
    576     DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
    577 
    578     bool data_change = false;
    579 
    580     if ( entry.valid )
    581      {
    582         for ( size_t word = 0 ; word<m_words ; word++ )
    583         {
    584             m_debug_data[word] = m_cache_data.read(way, set, word);
    585             if ( m_debug_previous_valid and
    586                  (m_debug_data[word] != m_debug_previous_data[word]) )
    587             {
    588                 data_change = true;
    589             }
    590          }
    591      }
    592    
    593     // print values if any change
    594     if ( (entry.valid != m_debug_previous_valid) or
    595          (entry.valid and (entry.count != m_debug_previous_count)) or
    596          (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change )
     671
     672    /////////////////////////////////////////////////////
     673    tmpl(bool)::is_local_req(uint32_t req_srcid)
     674        /////////////////////////////////////////////////////
    597675    {
    598          std::cout << "Monitor MEMC " << name()
    599                    << " at cycle " << std::dec << m_cpt_cycles
    600                    << " for address " << std::hex << addr
    601                    << " / VAL = " << std::dec << entry.valid
    602                    << " / WAY = " << way
    603                    << " / COUNT = " << entry.count
    604                    << " / DIRTY = " << entry.dirty
    605                    << " / DATA_CHANGE = " << data_change
    606                    << std::endl;
    607          std::cout << std::hex << "     /0:" << m_debug_data[0]
    608                    << "/1:" << m_debug_data[1]
    609                    << "/2:" << m_debug_data[2]
    610                    << "/3:" << m_debug_data[3]
    611                    << "/4:" << m_debug_data[4]
    612                    << "/5:" << m_debug_data[5]
    613                    << "/6:" << m_debug_data[6]
    614                    << "/7:" << m_debug_data[7]
    615                    << "/8:" << m_debug_data[8]
    616                    << "/9:" << m_debug_data[9]
    617                    << "/A:" << m_debug_data[10]
    618                    << "/B:" << m_debug_data[11]
    619                    << "/C:" << m_debug_data[12]
    620                    << "/D:" << m_debug_data[13]
    621                    << "/E:" << m_debug_data[14]
    622                    << "/F:" << m_debug_data[15]
    623                    << std::endl;
     676        return req_distance(req_srcid) == 0;
    624677    }
    625     m_debug_previous_count = entry.count;
    626     m_debug_previous_valid = entry.valid;
    627     m_debug_previous_dirty = entry.dirty;
    628     for( size_t word=0 ; word<m_words ; word++ )
    629         m_debug_previous_data[word] = m_debug_data[word];
    630 }
    631 
    632 //////////////////////////////////////////////////
    633 tmpl(void) ::print_trace()
    634 //////////////////////////////////////////////////
    635 {
    636   std::cout << "MEMC " << name() << std::endl;
    637   std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]
     678
     679
     680    //////////////////////////////////////////////////
     681    tmpl(void) ::print_trace()
     682        //////////////////////////////////////////////////
     683    {
     684        std::cout << "MEMC " << name() << std::endl;
     685        std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]
    638686            << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]
    639687            << " | " << read_fsm_str[r_read_fsm.read()]
     
    642690            << " | " << config_fsm_str[r_config_fsm.read()]
    643691            << " | " << cleanup_fsm_str[r_cleanup_fsm.read()] << std::endl;
    644   std::cout << "  "  << cc_send_fsm_str[r_cc_send_fsm.read()]
     692        std::cout << "  "  << cc_send_fsm_str[r_cc_send_fsm.read()]
    645693            << " | " << cc_receive_fsm_str[r_cc_receive_fsm.read()]
    646694            << " | " << multi_ack_fsm_str[r_multi_ack_fsm.read()]
     
    648696            << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]
    649697            << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm.read()] << std::endl;
    650   std::cout << "  "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]
     698        std::cout << "  "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]
    651699            << " | " << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]
    652700            << " | " << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]
    653701            << " | " << alloc_ivt_fsm_str[r_alloc_ivt_fsm.read()]
    654702            << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
    655 }
    656 
    657 /////////////////////////////////////////
    658 tmpl(void) ::clear_stats()
    659 /////////////////////////////////////////
    660 {
    661 
    662     m_cpt_cycles                  = 0;
    663     m_cpt_read                    = 0;
    664     m_cpt_read_miss               = 0;
    665     m_cpt_write                   = 0;
    666     m_cpt_write_miss              = 0;
    667     m_cpt_write_cells             = 0;
    668     m_cpt_write_dirty             = 0;
    669     m_cpt_update                  = 0;
    670     m_cpt_update_mult             = 0;
    671     m_cpt_inval_brdcast           = 0;
    672     m_cpt_inval                   = 0;
    673     m_cpt_inval_mult              = 0;
    674     m_cpt_cleanup                 = 0;
    675     m_cpt_ll                      = 0;
    676     m_cpt_sc                      = 0;
    677     m_cpt_cas                     = 0;
    678     m_cpt_trt_full                = 0;
    679     m_cpt_trt_rb                  = 0;
    680     m_cpt_dir_unused              = 0;
    681     m_cpt_ivt_unused              = 0;
    682     m_cpt_upt_unused              = 0;
    683     m_cpt_heap_unused             = 0;
    684     m_cpt_trt_unused              = 0;
    685     m_cpt_read_fsm_n_dir_lock     = 0;
    686     m_cpt_read_fsm_dir_lock       = 0;
    687     m_cpt_read_fsm_dir_used       = 0;
    688     m_cpt_read_fsm_trt_lock       = 0;
    689     m_cpt_read_fsm_heap_lock      = 0;
    690     m_cpt_write_fsm_dir_lock      = 0;
    691     m_cpt_write_fsm_n_dir_lock    = 0;
    692     m_cpt_write_fsm_upt_lock      = 0;
    693     m_cpt_write_fsm_heap_lock     = 0;
    694     m_cpt_write_fsm_dir_used      = 0;
    695     m_cpt_write_fsm_trt_lock      = 0;
    696     m_cpt_cas_fsm_n_dir_lock      = 0;
    697     m_cpt_cas_fsm_dir_lock        = 0;
    698     m_cpt_cas_fsm_upt_lock        = 0;
    699     m_cpt_cas_fsm_heap_lock       = 0;
    700     m_cpt_cas_fsm_trt_lock        = 0;
    701     m_cpt_cas_fsm_dir_used        = 0;
    702     m_cpt_xram_rsp_fsm_n_dir_lock = 0;
    703     m_cpt_xram_rsp_fsm_dir_lock   = 0;
    704     m_cpt_xram_rsp_fsm_trt_lock   = 0;
    705     m_cpt_xram_rsp_fsm_upt_lock   = 0;
    706     m_cpt_xram_rsp_fsm_heap_lock  = 0;
    707     m_cpt_xram_rsp_fsm_dir_used   = 0;
    708     m_cpt_cleanup_fsm_dir_lock    = 0;
    709     m_cpt_cleanup_fsm_n_dir_lock  = 0;
    710     m_cpt_cleanup_fsm_heap_lock   = 0;
    711     m_cpt_cleanup_fsm_ivt_lock    = 0;
    712     m_cpt_cleanup_fsm_dir_used    = 0;
    713     m_cpt_ixr_fsm_trt_lock        = 0;
    714     m_cpt_multi_ack_fsm_upt_lock  = 0;
    715     m_cpt_read_data_unc           = 0;   
    716     m_cpt_read_data_miss_CC       = 0;   
    717     m_cpt_read_ins_unc            = 0;       
    718     m_cpt_read_ins_miss           = 0;     
    719     m_cpt_read_ll_CC              = 0;       
    720     m_cpt_read_data_miss_NCC      = 0;       
    721     m_cpt_read_ll_NCC             = 0;   
    722     m_cpt_read_WTF                = 0;   
    723     m_cpt_cleanup_data            = 0;     
    724     m_cpt_ncc_to_cc_read          = 0;     
    725     m_cpt_ncc_to_cc_write         = 0;       
    726     m_cpt_ncc_to_cc               = 0;       
    727 }
    728 
    729 /////////////////////////////////////////
    730 tmpl(void) ::print_stats()
    731 /////////////////////////////////////////
    732 {
    733   std::cout << "----------------------------------" << std::dec << std::endl;
    734   std::cout
    735       << "MEM_CACHE " << name() << " / Time = " << m_cpt_cycles << std::endl
    736       << "- READ RATE                              = " << (double) m_cpt_read/m_cpt_cycles << std::endl
    737       << "- READ TOTAL                             = " << m_cpt_read << std::endl
    738       << "- READ MISS RATE                         = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
    739       << "- WRITE RATE                             = " << (double) m_cpt_write/m_cpt_cycles << std::endl
    740       << "- WRITE TOTAL                            = " << m_cpt_write << std::endl
    741       << "- WRITE MISS RATE                        = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
    742       << "- WRITE BURST LENGTH                     = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
    743       << "- WRITE BURST TOTAL                      = " << m_cpt_write_cells << std::endl
    744       << "- REQUESTS TRT FULL                      = " << m_cpt_trt_full << std::endl
    745       << "- READ TRT BLOKED HIT                    = " << m_cpt_trt_rb << std::endl
    746       << "- UPDATE RATE                            = " << (double) m_cpt_update/m_cpt_cycles << std::endl
    747       << "- UPDATE ARITY                           = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
    748       << "- INVAL MULTICAST RATE                   = " << (double)(m_cpt_inval-m_cpt_inval_brdcast) /m_cpt_cycles << std::endl
    749       << "- INVAL MULTICAST ARITY                  = " << (double) m_cpt_inval_mult/ (m_cpt_inval-m_cpt_inval_brdcast) << std::endl
    750       << "- INVAL BROADCAST RATE                   = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
    751       << "- SAVE DIRTY RATE                        = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
    752       << "- CLEANUP RATE                           = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
    753       << "- LL RATE                                = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
    754       << "- SC RATE                                = " << (double) m_cpt_sc/m_cpt_cycles << std::endl
    755       << "- CAS RATE                               = " << (double) m_cpt_cas/m_cpt_cycles << std::endl << std::endl
    756 
    757       << "- WAIT DIR LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_dir_lock/m_cpt_read_fsm_n_dir_lock << std::endl
    758       << "- NB CYCLES IN DIR LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_dir_used/m_cpt_read_fsm_n_dir_lock << std::endl
    759       << "- WAIT DIR LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_dir_lock/m_cpt_write_fsm_n_dir_lock << std::endl
    760       << "- NB CYCLES IN DIR LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_dir_used/m_cpt_write_fsm_n_dir_lock << std::endl
    761       << "- WAIT DIR LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_dir_lock/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
    762       << "- NB CYCLES IN DIR LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_dir_used/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
    763       << "- WAIT DIR LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_dir_lock/m_cpt_cleanup_fsm_n_dir_lock << std::endl
    764       << "- NB CYCLES IN DIR LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_dir_used/m_cpt_cleanup_fsm_n_dir_lock << std::endl
    765       << "- WAIT DIR LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_dir_lock/m_cpt_cas_fsm_n_dir_lock << std::endl
    766       << "- NB CYCLES IN LOCK in CAS_FSM           = " << (double) m_cpt_cas_fsm_dir_used/m_cpt_cas_fsm_n_dir_lock << std::endl
    767       << "- DIR UNUSED RATE                        = " << (double) m_cpt_dir_unused/m_cpt_cycles << std::endl << std::endl
    768      
    769       << "- WAIT TRT LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_trt_lock/m_cpt_read_fsm_n_trt_lock << std::endl
    770       << "- NB CYCLES IN TRT LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_trt_used/m_cpt_read_fsm_n_trt_lock << std::endl
    771       << "- WAIT TRT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_trt_lock/m_cpt_write_fsm_n_trt_lock << std::endl
    772       << "- NB CYCLES IN TRT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_trt_used/m_cpt_write_fsm_n_trt_lock << std::endl
    773       << "- WAIT TRT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_trt_lock/m_cpt_cas_fsm_n_trt_lock << std::endl
    774       << "- NB CYCLES IN TRT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_trt_used/m_cpt_cas_fsm_n_trt_lock << std::endl
    775       << "- WAIT TRT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_trt_lock/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
    776       << "- NB CYCLES IN TRT LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_trt_used/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
    777       << "- WAIT TRT LOCK in IXR_FSM               = " << (double) m_cpt_ixr_fsm_trt_lock/m_cpt_ixr_fsm_n_trt_lock << std::endl
    778       << "- NB CYCLES IN TRT LOCK in IXR_FSM       = " << (double) m_cpt_ixr_fsm_trt_used/m_cpt_ixr_fsm_n_trt_lock << std::endl
    779       << "- TRT UNUSED RATE                        = " << (double) m_cpt_trt_unused/m_cpt_cycles << std::endl << std::endl
    780      
    781       << "- WAIT UPT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_upt_lock/m_cpt_write_fsm_n_upt_lock << std::endl
    782       << "- NB CYCLES IN UPT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_upt_used/m_cpt_write_fsm_n_upt_lock << std::endl
    783       << "- WAIT UPT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_upt_lock/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
    784       << "- NB CYCLES IN UPT LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_upt_used/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
    785       << "- WAIT UPT LOCK in MULTIACK_FSM          = " << (double) m_cpt_multi_ack_fsm_upt_lock/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
    786       << "- NB CYCLES IN UPT LOCK in MULTIACK_FSM  = " << (double) m_cpt_multi_ack_fsm_upt_used/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
    787       << "- WAIT UPT LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_ivt_lock/m_cpt_cleanup_fsm_n_upt_lock << std::endl
    788       << "- NB CYCLES IN UPT LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_ivt_used/m_cpt_cleanup_fsm_n_upt_lock << std::endl
    789       << "- WAIT UPT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_upt_lock/m_cpt_cas_fsm_n_upt_lock << std::endl
    790       << "- NB CYCLES IN UPT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_upt_used/m_cpt_cas_fsm_n_upt_lock << std::endl
    791       << "- UPT UNUSED RATE                        = " << (double) m_cpt_upt_unused/m_cpt_cycles << std::endl << std::endl
    792       << "- IVT UNUSED RATE                        = " << (double) m_cpt_ivt_unused/m_cpt_cycles << std::endl << std::endl
    793      
    794       << "- WAIT HEAP LOCK in READ_FSM             = " << (double) m_cpt_read_fsm_heap_lock/m_cpt_read_fsm_n_heap_lock << std::endl
    795       << "- NB CYCLES IN HEAP LOCK in READ_FSM     = " << (double) m_cpt_read_fsm_heap_used/m_cpt_read_fsm_n_heap_lock << std::endl
    796       << "- WAIT HEAP LOCK in WRITE_FSM            = " << (double) m_cpt_write_fsm_heap_lock/m_cpt_write_fsm_n_heap_lock << std::endl
    797       << "- NB CYCLES IN HEAP LOCK in WRITE_FSM    = " << (double) m_cpt_write_fsm_heap_used/m_cpt_write_fsm_n_heap_lock << std::endl
    798       << "- WAIT HEAP LOCK in XRAM_FSM             = " << (double) m_cpt_xram_rsp_fsm_heap_lock/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
    799       << "- NB CYCLES IN HEAP LOCK in XRAM_FSM     = " << (double) m_cpt_xram_rsp_fsm_heap_used/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
    800       << "- WAIT HEAP LOCK in CLEANUP_FSM          = " << (double) m_cpt_cleanup_fsm_heap_lock/m_cpt_cleanup_fsm_n_heap_lock << std::endl
    801       << "- NB CYCLES IN HEAP LOCK in CLEANUP_FSM  = " << (double) m_cpt_cleanup_fsm_heap_used/m_cpt_cleanup_fsm_n_heap_lock << std::endl
    802       << "- WAIT HEAP LOCK in CAS_FSM              = " << (double) m_cpt_cas_fsm_heap_lock/m_cpt_cas_fsm_n_heap_lock << std::endl
    803       << "- NB CYCLES IN HEAP LOCK in CAS_FSM      = " << (double) m_cpt_cas_fsm_heap_used/m_cpt_cas_fsm_n_heap_lock << std::endl
    804       << "- HEAP UNUSED RATE                       = " << (double) m_cpt_heap_unused/m_cpt_cycles << std::endl
    805 
    806       << "- READ DATA UNC                          = " << (double) m_cpt_read_data_unc << std::endl
    807       << "- READ DATA MISS CC                      = " << (double) m_cpt_read_data_miss_CC << std::endl
    808       << "- READ INS UNC                           = " << (double) m_cpt_read_ins_unc << std::endl
    809       << "- READ INS MISS                          = " << (double) m_cpt_read_ins_miss << std::endl
    810       << "- READ LL CC                             = " << (double) m_cpt_read_ll_CC << std::endl
    811       << "- READ DATA MISS NCC                     = " << (double) m_cpt_read_data_miss_NCC << std::endl
    812       << "- READ LL NCC                            = " << (double) m_cpt_read_ll_NCC << std::endl
    813       << "- READ OTHER                             = " << (double) m_cpt_read_WTF << std::endl
    814       << "- CLEANUP + DATA                         = " << (double) m_cpt_cleanup_data << std::endl
    815       << "- NCC TO CC READ                         = " << (double) m_cpt_ncc_to_cc_read << std::endl
    816       << "- NCC TO CC WRITE                        = " << (double) m_cpt_ncc_to_cc_write << std::endl
    817       << "- NCC TO CC                              = " << (double) m_cpt_ncc_to_cc << std::endl;
    818 }
    819 
    820 /////////////////////////////////
    821 tmpl(/**/) ::~VciMemCache()
    822 /////////////////////////////////
    823 {
    824   delete [] r_ixr_rsp_to_xram_rsp_rok;
    825 
    826   delete [] r_xram_rsp_victim_data;
    827   delete [] r_xram_rsp_to_tgt_rsp_data;
    828 
    829   delete [] r_read_data;
    830   delete [] r_read_to_tgt_rsp_data;
    831 
    832   delete [] r_write_data;
    833   delete [] r_write_be;
    834   delete [] r_write_to_cc_send_data;
    835 
    836   delete [] r_cleanup_data;
    837   delete [] r_cleanup_to_ixr_cmd_data;
    838   delete [] r_cleanup_to_tgt_rsp_data;
    839   delete [] r_cleanup_old_data;
    840 }
    841 
    842 //////////////////////////////////
    843 tmpl(void) ::transition()
    844 //////////////////////////////////
    845 {
    846   using soclib::common::uint32_log2;
    847 
    848   // RESET
    849   if(! p_resetn.read())
    850   {
    851 
    852     // Initializing FSMs
    853     r_tgt_cmd_fsm    = TGT_CMD_IDLE;
    854     r_config_fsm     = CONFIG_IDLE;
    855     r_tgt_rsp_fsm    = TGT_RSP_TGT_CMD_IDLE;
    856     r_cc_send_fsm    = CC_SEND_XRAM_RSP_IDLE;
    857     r_cc_receive_fsm = CC_RECEIVE_IDLE;
    858     r_multi_ack_fsm  = MULTI_ACK_IDLE;
    859     r_read_fsm       = READ_IDLE;
    860     r_write_fsm      = WRITE_IDLE;
    861     r_cas_fsm        = CAS_IDLE;
    862     r_cleanup_fsm    = CLEANUP_IDLE;
    863     r_alloc_dir_fsm  = ALLOC_DIR_RESET;
    864     r_alloc_heap_fsm = ALLOC_HEAP_RESET;
    865     r_alloc_trt_fsm  = ALLOC_TRT_READ;
    866     r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
    867     r_alloc_ivt_fsm  = ALLOC_IVT_XRAM_RSP;
    868     r_ixr_rsp_fsm    = IXR_RSP_IDLE;
    869     r_xram_rsp_fsm   = XRAM_RSP_IDLE;
    870     r_ixr_cmd_fsm    = IXR_CMD_READ_IDLE;
    871 
    872     m_debug                = false;
    873     m_debug_previous_valid = false;
    874     m_debug_previous_dirty = false;
    875     m_debug_previous_count = 0;
    876 
    877     //  Initializing Tables
    878     m_trt.init();
    879     m_upt.init();
    880     m_ivt.init();
    881     m_llsc_table.init();
    882 
    883     // initializing FIFOs and communication Buffers
    884 
    885     m_cmd_read_addr_fifo.init();
    886     m_cmd_read_length_fifo.init();
    887     m_cmd_read_srcid_fifo.init();
    888     m_cmd_read_trdid_fifo.init();
    889     m_cmd_read_pktid_fifo.init();
    890 
    891     m_cmd_write_addr_fifo.init();
    892     m_cmd_write_eop_fifo.init();
    893     m_cmd_write_srcid_fifo.init();
    894     m_cmd_write_trdid_fifo.init();
    895     m_cmd_write_pktid_fifo.init();
    896     m_cmd_write_data_fifo.init();
    897 
    898     m_cmd_cas_addr_fifo.init()  ;
    899     m_cmd_cas_srcid_fifo.init() ;
    900     m_cmd_cas_trdid_fifo.init() ;
    901     m_cmd_cas_pktid_fifo.init() ;
    902     m_cmd_cas_wdata_fifo.init() ;
    903     m_cmd_cas_eop_fifo.init()   ;
    904 
    905     r_config_cmd  = MEMC_CMD_NOP;
    906     r_config_lock = false;
    907 
    908     m_config_to_cc_send_inst_fifo.init();
    909     m_config_to_cc_send_srcid_fifo.init();
    910 
    911     r_tgt_cmd_to_tgt_rsp_req = false;
    912 
    913     r_read_to_tgt_rsp_req = false;
    914     r_read_to_ixr_cmd_req = false;
    915     r_read_to_cc_send_req = false;
    916     r_read_to_cleanup_req = false;
    917 
    918     r_write_to_tgt_rsp_req          = false;
    919     r_write_to_ixr_cmd_req          = false;
    920     r_write_to_cc_send_multi_req    = false;
    921     r_write_to_cc_send_brdcast_req  = false;
    922     r_write_to_multi_ack_req        = false;
    923 
    924     m_write_to_cc_send_inst_fifo.init();
    925     m_write_to_cc_send_srcid_fifo.init();
    926 
    927     r_cleanup_to_tgt_rsp_req      = false;
    928 
    929     m_cc_receive_to_cleanup_fifo.init();
    930 
    931     r_multi_ack_to_tgt_rsp_req     = false;
    932 
    933     m_cc_receive_to_multi_ack_fifo.init();
    934 
    935     r_cas_to_tgt_rsp_req          = false;
    936     r_cas_cpt                     = 0    ;
    937     r_cas_lfsr                    = -1   ;
    938     r_cas_to_ixr_cmd_req          = false;
    939     r_cas_to_cc_send_multi_req    = false;
    940     r_cas_to_cc_send_brdcast_req  = false;
    941 
    942     m_cas_to_cc_send_inst_fifo.init();
    943     m_cas_to_cc_send_srcid_fifo.init();
     703    }
     704
     705
     706    /////////////////////////////////////////
     707    tmpl(void)::print_stats(bool activity_counters = true, bool stats = true)
     708    {
     709        std::cout << "**********************************" << std::dec << std::endl;
     710        std::cout << "*** MEM_CACHE " << name() << std::endl;
     711        std::cout << "**********************************" << std::dec << std::endl;
     712        if (activity_counters) {
     713            std::cout << "----------------------------------" << std::dec << std::endl;
     714            std::cout << "---     Activity Counters      ---" << std::dec << std::endl;
     715            std::cout << "----------------------------------" << std::dec << std::endl;
     716            std::cout
     717                << "[001] NUMBER OF CYCLES          = " << m_cpt_cycles << std::endl
     718                << std::endl
     719                << "[002] LOCAL READ                = " << m_cpt_read_local << std::endl
     720                << "[003] REMOTE READ               = " << m_cpt_read_remote << std::endl
     721                << "[004] READ COST (FLITS * DIST)  = " << m_cpt_read_cost << std::endl
     722                << std::endl
     723                << "[005] LOCAL WRITE               = " << m_cpt_write_local << std::endl
     724                << "[006] REMOTE WRITE              = " << m_cpt_write_remote << std::endl
     725                << "[007] WRITE FLITS LOCAL         = " << m_cpt_write_flits_local << std::endl
     726                << "[008] WRITE FLITS REMOTE        = " << m_cpt_write_flits_remote << std::endl
     727                << "[009] WRITE COST (FLITS * DIST) = " << m_cpt_write_cost << std::endl
     728                << std::endl
     729                << "[010] LOCAL LL                  = " << m_cpt_ll_local << std::endl
     730                << "[011] REMOTE LL                 = " << m_cpt_ll_remote << std::endl
     731                << "[012] LL COST (FLITS * DIST)    = " << m_cpt_ll_cost << std::endl
     732                << std::endl
     733                << "[013] LOCAL SC                  = " << m_cpt_sc_local << std::endl
     734                << "[014] REMOTE SC                 = " << m_cpt_sc_remote << std::endl
     735                << "[015] SC COST (FLITS * DIST)    = " << m_cpt_sc_cost << std::endl
     736                << std::endl
     737                << "[016] LOCAL CAS                 = " << m_cpt_cas_local << std::endl
     738                << "[017] REMOTE CAS                = " << m_cpt_cas_remote << std::endl
     739                << "[018] CAS COST (FLITS * DIST)   = " << m_cpt_cas_cost << std::endl
     740                << std::endl
     741                << "[019] REQUESTS TRIG. UPDATE     = " << m_cpt_update << std::endl
     742                << "[020] LOCAL UPDATE              = " << m_cpt_update_local << std::endl
     743                << "[021] REMOTE UPDATE             = " << m_cpt_update_remote << std::endl
     744                << "[022] UPDT COST (FLITS * DIST)  = " << m_cpt_update_cost << std::endl
     745                << std::endl
     746                << "[023] REQUESTS TRIG. M_INV      = " << m_cpt_m_inval << std::endl
     747                << "[024] LOCAL M_INV               = " << m_cpt_m_inval_local << std::endl
     748                << "[025] REMOTE M_INV              = " << m_cpt_m_inval_remote << std::endl
     749                << "[026] M_INV COST (FLITS * DIST) = " << m_cpt_m_inval_cost << std::endl
     750                << std::endl
     751                << "[027] BROADCAT INVAL            = " << m_cpt_br_inval << std::endl
     752                << std::endl
     753                << "[028] LOCAL CLEANUP             = " << m_cpt_cleanup_local << std::endl
     754                << "[029] REMOTE CLEANUP            = " << m_cpt_cleanup_remote << std::endl
     755                << "[030] CLNUP COST (FLITS * DIST) = " << m_cpt_cleanup_cost << std::endl
     756                << std::endl
     757                << std::endl
     758                << "[031] READ MISS                 = " << m_cpt_read_miss << std::endl
     759                << "[032] WRITE MISS                = " << m_cpt_write_miss << std::endl
     760                << "[033] WRITE DIRTY               = " << m_cpt_write_dirty << std::endl
     761                << "[034] RD BLOCKED BY HIT IN TRT  = " << m_cpt_trt_rb << std::endl
     762                << "[035] TRANS BLOCKED BY FULL TRT = " << m_cpt_trt_full << std::endl
     763                << "[036] PUT (UNIMPLEMENTED)       = " << m_cpt_put << std::endl
     764                << "[037] GET (UNIMPLEMENTED)       = " << m_cpt_get << std::endl
     765                << "[038] WRITE BROADCAST           = " << m_cpt_write_broadcast << std::endl
     766                << std::endl;
     767        }
     768
     769        if (stats) {
     770            std::cout << "----------------------------------" << std::dec << std::endl;
     771            std::cout << "---      Calculated Stats      ---" << std::dec << std::endl;
     772            std::cout << "----------------------------------" << std::dec << std::endl;
     773            std::cout
     774                << "[100] READ TOTAL            = " << m_cpt_read_local + m_cpt_read_remote << std::endl
     775                << "[101] READ RATE             = " << (double) (m_cpt_read_local + m_cpt_read_remote) / m_cpt_cycles << std::endl
     776                << "[102] LOCAL READ RATE       = " << (double) m_cpt_read_local / m_cpt_cycles << std::endl
     777                << "[103] REMOTE READ RATE      = " << (double) m_cpt_read_remote / m_cpt_cycles << std::endl
     778                << "[104] READ MISS RATE        = " << (double) m_cpt_read_miss / (m_cpt_read_local + m_cpt_read_remote) << std::endl
     779                << std::endl
     780                << "[105] WRITE TOTAL           = " << m_cpt_write_local + m_cpt_write_remote << std::endl
     781                << "[106] WRITE RATE            = " << (double) (m_cpt_write_local + m_cpt_write_remote) / m_cpt_cycles << std::endl
     782                << "[107] LOCAL WRITE RATE      = " << (double) m_cpt_write_local / m_cpt_cycles << std::endl
     783                << "[108] REMOTE WRITE RATE     = " << (double) m_cpt_write_remote / m_cpt_cycles << std::endl
     784                << "[109] WRITE MISS RATE       = " << (double) m_cpt_write_miss / (m_cpt_write_local + m_cpt_write_remote) << std::endl
     785                << "[110] WRITE BURST TOTAL     = " << m_cpt_write_flits_local + m_cpt_write_flits_remote << std::endl
     786                << "[111] WRITE BURST AVERAGE   = " << (double) (m_cpt_write_flits_local + m_cpt_write_flits_remote) / (m_cpt_write_local + m_cpt_write_remote) << std::endl
     787                << "[112] LOCAL WRITE BURST AV. = " << (double) m_cpt_write_flits_local / (m_cpt_write_local + m_cpt_write_remote) << std::endl
     788                << "[113] REMOTE WRITE BURST AV = " << (double) m_cpt_write_flits_remote / (m_cpt_write_local + m_cpt_write_remote) << std::endl
     789                << std::endl
     790                << "[114] UPDATE RATE                = " << (double) m_cpt_update / m_cpt_cycles << std::endl
     791                << "[115] AV. UPDATE PER UP REQ      = " << (double) (m_cpt_update_local + m_cpt_update_remote) / m_cpt_update << std::endl
     792                << "[116] AV. LOC UPDT PER UP REQ    = " << (double) m_cpt_update_local / m_cpt_update << std::endl
     793                << "[117] AV. REMOTE UPDT PER UP REQ = " << (double) m_cpt_update_remote / m_cpt_update << std::endl
     794                << std::endl
     795                << "[118] INVAL MULTICAST RATE  = " << (double) m_cpt_m_inval / m_cpt_cycles << std::endl
     796                << "[119] AVE. INVAL PER M_INV  = " << (double) (m_cpt_m_inval_local + m_cpt_m_inval_remote) / m_cpt_m_inval << std::endl
     797                << "[120] AV. LOC INV PER M_INV = " << (double) m_cpt_m_inval_local / m_cpt_m_inval << std::endl
     798                << "[121] AV. REM INV PER M_INV = " << (double) m_cpt_m_inval_remote / m_cpt_m_inval << std::endl
     799                << std::endl
     800                << "[122] INVAL BROADCAST RATE  = " << (double) m_cpt_br_inval / m_cpt_cycles << std::endl
     801                << "[123] WRITE DIRTY RATE      = " << (double) m_cpt_write_dirty / m_cpt_cycles << std::endl
     802                << std::endl
     803                << "[124] CLEANUP RATE          = " << (double) (m_cpt_cleanup_local + m_cpt_cleanup_remote) / m_cpt_cycles << std::endl
     804                << "[125] LOCAL CLEANUP RATE    = " << (double) m_cpt_cleanup_local / m_cpt_cycles << std::endl
     805                << "[126] REMOTE CLEANUP RATE   = " << (double) m_cpt_cleanup_remote / m_cpt_cycles << std::endl
     806                << "[127] LL RATE               = " << (double) (m_cpt_ll_local + m_cpt_ll_remote) / m_cpt_cycles << std::endl
     807                << "[128] LOCAL LL RATE         = " << (double) m_cpt_ll_local / m_cpt_cycles << std::endl
     808                << "[129] REMOTE LL RATE        = " << (double) m_cpt_ll_remote / m_cpt_cycles << std::endl
     809                << "[130] SC RATE               = " << (double) (m_cpt_sc_local + m_cpt_sc_remote) / m_cpt_cycles << std::endl
     810                << "[131] LOCAL SC RATE         = " << (double) m_cpt_sc_local / m_cpt_cycles << std::endl
     811                << "[132] REMOTE SC RATE        = " << (double) m_cpt_sc_remote / m_cpt_cycles << std::endl
     812                << "[133] CAS RATE              = " << (double) (m_cpt_cas_local + m_cpt_cas_remote) / m_cpt_cycles << std::endl
     813                << "[134] LOCAL CAS RATE        = " << (double) m_cpt_cas_local / m_cpt_cycles << std::endl
     814                << "[135] REMOTE CAS RATE       = " << (double) m_cpt_cas_remote / m_cpt_cycles << std::endl
     815                << std::endl
     816                << std::endl;
     817        }
     818    }
     819
     820
     821    /////////////////////////////////
     822    tmpl(/**/) ::~VciMemCache()
     823        /////////////////////////////////
     824    {
     825        delete [] m_seg;
     826
     827        delete [] r_ixr_rsp_to_xram_rsp_rok;
     828        delete [] r_xram_rsp_victim_data;
     829        delete [] r_xram_rsp_to_tgt_rsp_data;
     830
     831        delete [] r_read_data;
     832        delete [] r_read_to_tgt_rsp_data;
     833
     834        delete [] r_write_data;
     835        delete [] r_write_be;
     836        delete [] r_write_to_cc_send_data;
     837        delete [] r_write_to_cc_send_be;
     838        delete [] r_cleanup_data;
     839        delete [] r_cleanup_to_ixr_cmd_data;
     840        delete [] r_cleanup_to_tgt_rsp_data;
     841        delete [] r_cleanup_old_data;
     842
     843        delete [] r_cas_data;
     844        delete [] r_cas_rdata;
     845
     846        delete [] r_ixr_cmd_wdata;
     847        delete [] m_debug_previous_data;
     848        delete [] m_debug_data;
     849
     850        print_stats();
     851    }
     852
     853    //////////////////////////////////
     854    tmpl(void) ::transition()
     855        //////////////////////////////////
     856    {
     857        using soclib::common::uint32_log2;
     858
     859        // RESET
     860        if(! p_resetn.read())
     861        {
     862
     863            // Initializing FSMs
     864            r_tgt_cmd_fsm    = TGT_CMD_IDLE;
     865            r_config_fsm     = CONFIG_IDLE;
     866            r_tgt_rsp_fsm    = TGT_RSP_READ_IDLE;
     867            r_cc_send_fsm    = CC_SEND_XRAM_RSP_IDLE;
     868            r_cc_receive_fsm = CC_RECEIVE_IDLE;
     869            r_multi_ack_fsm  = MULTI_ACK_IDLE;
     870            r_read_fsm       = READ_IDLE;
     871            r_write_fsm      = WRITE_IDLE;
     872            r_cas_fsm        = CAS_IDLE;
     873            r_cleanup_fsm    = CLEANUP_IDLE;
     874            r_alloc_dir_fsm  = ALLOC_DIR_RESET;
     875            r_alloc_heap_fsm = ALLOC_HEAP_RESET;
     876            r_alloc_trt_fsm  = ALLOC_TRT_READ;
     877            r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
     878            r_alloc_ivt_fsm  = ALLOC_IVT_WRITE;
     879            r_ixr_rsp_fsm    = IXR_RSP_IDLE;
     880            r_xram_rsp_fsm   = XRAM_RSP_IDLE;
     881            r_ixr_cmd_fsm    = IXR_CMD_READ_IDLE;
     882
     883            m_debug                = false;
     884            m_debug_previous_valid = false;
     885            m_debug_previous_dirty = false;
     886            m_debug_previous_count = 0;
     887
     888            //  Initializing Tables
     889            m_trt.init();
     890            m_upt.init();
     891            m_ivt.init();
     892            m_llsc_table.init();
     893
     894            // initializing FIFOs and communication Buffers
     895
     896            m_cmd_read_addr_fifo.init();
     897            m_cmd_read_length_fifo.init();
     898            m_cmd_read_srcid_fifo.init();
     899            m_cmd_read_trdid_fifo.init();
     900            m_cmd_read_pktid_fifo.init();
     901
     902            m_cmd_write_addr_fifo.init();
     903            m_cmd_write_eop_fifo.init();
     904            m_cmd_write_srcid_fifo.init();
     905            m_cmd_write_trdid_fifo.init();
     906            m_cmd_write_pktid_fifo.init();
     907            m_cmd_write_data_fifo.init();
     908
     909            m_cmd_cas_addr_fifo.init()  ;
     910            m_cmd_cas_srcid_fifo.init() ;
     911            m_cmd_cas_trdid_fifo.init() ;
     912            m_cmd_cas_pktid_fifo.init() ;
     913            m_cmd_cas_wdata_fifo.init() ;
     914            m_cmd_cas_eop_fifo.init()   ;
     915
     916            r_config_cmd  = MEMC_CMD_NOP;
     917            r_config_lock = false;
     918
     919            m_config_to_cc_send_inst_fifo.init();
     920            m_config_to_cc_send_srcid_fifo.init();
     921
     922            r_tgt_cmd_to_tgt_rsp_req = false;
     923
     924            r_read_to_tgt_rsp_req = false;
     925            r_read_to_ixr_cmd_req = false;
     926            r_read_to_cc_send_req = false;
     927            r_read_to_cleanup_req = false;
     928
     929            r_write_to_tgt_rsp_req          = false;
     930            r_write_to_ixr_cmd_req          = false;
     931            r_write_to_cc_send_multi_req    = false;
     932            r_write_to_cc_send_brdcast_req  = false;
     933            r_write_to_multi_ack_req        = false;
     934
     935            m_write_to_cc_send_inst_fifo.init();
     936            m_write_to_cc_send_srcid_fifo.init();
     937
     938            r_cleanup_to_tgt_rsp_req      = false;
     939
     940            m_cc_receive_to_cleanup_fifo.init();
     941
     942            r_multi_ack_to_tgt_rsp_req     = false;
     943
     944            m_cc_receive_to_multi_ack_fifo.init();
     945
     946            r_cas_to_tgt_rsp_req          = false;
     947            r_cas_cpt                     = 0    ;
     948            r_cas_lfsr                    = -1   ;
     949            r_cas_to_ixr_cmd_req          = false;
     950            r_cas_to_cc_send_multi_req    = false;
     951            r_cas_to_cc_send_brdcast_req  = false;
     952
     953            m_cas_to_cc_send_inst_fifo.init();
     954            m_cas_to_cc_send_srcid_fifo.init();
    944955#if L1_MULTI_CACHE
    945     m_cas_to_cc_send_cache_id_fifo.init();
    946 #endif
    947 
    948     for(size_t i=0; i<m_trt_lines ; i++)
    949     {
    950       r_ixr_rsp_to_xram_rsp_rok[i] = false;
    951     }
    952 
    953     r_xram_rsp_to_tgt_rsp_req          = false;
    954     r_xram_rsp_to_cc_send_multi_req    = false;
    955     r_xram_rsp_to_cc_send_brdcast_req  = false;
    956     r_xram_rsp_to_ixr_cmd_req          = false;
    957     r_xram_rsp_trt_index               = 0;
    958 
    959     m_xram_rsp_to_cc_send_inst_fifo.init();
    960     m_xram_rsp_to_cc_send_srcid_fifo.init();
    961 
    962     r_alloc_dir_reset_cpt  = 0;
    963     r_alloc_heap_reset_cpt = 0;
    964 
    965     r_tgt_rsp_key_sent  = false;
    966 
    967     // ODCCP
    968     r_cleanup_data_index       = 0;
    969     r_cleanup_trdid            = 0;
    970     r_cleanup_pktid            = 0;
    971     r_cleanup_contains_data    = false;
    972     r_cleanup_ncc              = false;
    973     r_cleanup_to_ixr_cmd_ncc_l1_dirty    = false;
    974     r_xram_rsp_to_ixr_cmd_inval_ncc_pending    = false;
    975     r_cleanup_to_ixr_cmd_req   = false;
    976     r_cleanup_to_ixr_cmd_srcid = 0;
    977     r_cleanup_to_ixr_cmd_pktid = 0;
    978     r_cleanup_to_ixr_cmd_nline = 0;
    979     for (size_t word = 0; word < m_words; word ++)
    980     {
    981       r_cleanup_to_ixr_cmd_data[word] = 0;
    982       r_cleanup_data[word] = 0;
    983     }
    984 
    985 
    986     // Activity counters
    987     m_cpt_cycles                  = 0;
    988     m_cpt_read                    = 0;
    989     m_cpt_read_miss               = 0;
    990     m_cpt_write                   = 0;
    991     m_cpt_write_miss              = 0;
    992     m_cpt_write_cells             = 0;
    993     m_cpt_write_dirty             = 0;
    994     m_cpt_update                  = 0;
    995     m_cpt_update_mult             = 0;
    996     m_cpt_inval_brdcast           = 0;
    997     m_cpt_inval                   = 0;
    998     m_cpt_inval_mult              = 0;
    999     m_cpt_cleanup                 = 0;
    1000     m_cpt_ll                      = 0;
    1001     m_cpt_sc                      = 0;
    1002     m_cpt_cas                     = 0;
    1003     m_cpt_trt_full                = 0;
    1004     m_cpt_trt_rb                  = 0;
    1005     m_cpt_dir_unused              = 0;
    1006     m_cpt_upt_unused              = 0;
    1007     m_cpt_ivt_unused              = 0;
    1008     m_cpt_heap_unused             = 0;
    1009     m_cpt_trt_unused              = 0;
    1010     m_cpt_read_fsm_n_dir_lock     = 0;
    1011     m_cpt_read_fsm_dir_lock       = 0;
    1012     m_cpt_read_fsm_dir_used       = 0;
    1013     m_cpt_read_fsm_trt_lock       = 0;
    1014     m_cpt_read_fsm_heap_lock      = 0;
    1015     m_cpt_write_fsm_dir_lock      = 0;
    1016     m_cpt_write_fsm_n_dir_lock    = 0;
    1017     m_cpt_write_fsm_upt_lock      = 0;
    1018     m_cpt_write_fsm_heap_lock     = 0;
    1019     m_cpt_write_fsm_dir_used      = 0;
    1020     m_cpt_write_fsm_trt_lock      = 0;
    1021     m_cpt_cas_fsm_n_dir_lock      = 0;
    1022     m_cpt_cas_fsm_dir_lock        = 0;
    1023     m_cpt_cas_fsm_upt_lock        = 0;
    1024     m_cpt_cas_fsm_heap_lock       = 0;
    1025     m_cpt_cas_fsm_trt_lock        = 0;
    1026     m_cpt_cas_fsm_dir_used        = 0;
    1027     m_cpt_xram_rsp_fsm_n_dir_lock = 0;
    1028     m_cpt_xram_rsp_fsm_dir_lock   = 0;
    1029     m_cpt_xram_rsp_fsm_trt_lock   = 0;
    1030     m_cpt_xram_rsp_fsm_upt_lock   = 0;
    1031     m_cpt_xram_rsp_fsm_heap_lock  = 0;
    1032     m_cpt_xram_rsp_fsm_dir_used   = 0;
    1033     m_cpt_cleanup_fsm_dir_lock    = 0;
    1034     m_cpt_cleanup_fsm_n_dir_lock  = 0;
    1035     m_cpt_cleanup_fsm_heap_lock   = 0;
    1036     m_cpt_cleanup_fsm_ivt_lock    = 0;
    1037     m_cpt_cleanup_fsm_dir_used    = 0;
    1038     m_cpt_ixr_fsm_trt_lock        = 0;
    1039     m_cpt_multi_ack_fsm_upt_lock  = 0;
    1040     m_cpt_read_data_unc           = 0;   
    1041     m_cpt_read_data_miss_CC       = 0;   
    1042     m_cpt_read_ins_unc            = 0;       
    1043     m_cpt_read_ins_miss           = 0;     
    1044     m_cpt_read_ll_CC              = 0;       
    1045     m_cpt_read_data_miss_NCC      = 0;       
    1046     m_cpt_read_ll_NCC             = 0;   
    1047     m_cpt_read_WTF                = 0;   
    1048     m_cpt_cleanup_data            = 0;     
    1049     m_cpt_ncc_to_cc_read          = 0;     
    1050     m_cpt_ncc_to_cc_write         = 0;       
    1051     m_cpt_ncc_to_cc               = 0;       
    1052     return;
    1053   }
    1054 
    1055   bool    cmd_read_fifo_put = false;
    1056   bool    cmd_read_fifo_get = false;
    1057 
    1058   bool    cmd_write_fifo_put = false;
    1059   bool    cmd_write_fifo_get = false;
    1060 
    1061   bool    cmd_cas_fifo_put = false;
    1062   bool    cmd_cas_fifo_get = false;
    1063 
    1064   bool    cc_receive_to_cleanup_fifo_get = false;
    1065   bool    cc_receive_to_cleanup_fifo_put = false;
    1066 
    1067   bool    cc_receive_to_multi_ack_fifo_get = false;
    1068   bool    cc_receive_to_multi_ack_fifo_put = false;
    1069 
    1070   bool    write_to_cc_send_fifo_put   = false;
    1071   bool    write_to_cc_send_fifo_get   = false;
    1072   bool    write_to_cc_send_fifo_inst  = false;
    1073   size_t  write_to_cc_send_fifo_srcid = 0;
    1074 
    1075   bool    xram_rsp_to_cc_send_fifo_put   = false;
    1076   bool    xram_rsp_to_cc_send_fifo_get   = false;
    1077   bool    xram_rsp_to_cc_send_fifo_inst  = false;
    1078   size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
    1079 
    1080   bool    config_to_cc_send_fifo_put   = false;
    1081   bool    config_to_cc_send_fifo_get   = false;
    1082   bool    config_to_cc_send_fifo_inst  = false;
    1083   size_t  config_to_cc_send_fifo_srcid = 0;
    1084 
    1085   bool    cas_to_cc_send_fifo_put   = false;
    1086   bool    cas_to_cc_send_fifo_get   = false;
    1087   bool    cas_to_cc_send_fifo_inst  = false;
    1088   size_t  cas_to_cc_send_fifo_srcid = 0;
    1089 
    1090   m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     956            m_cas_to_cc_send_cache_id_fifo.init();
     957#endif
     958
     959            for(size_t i=0; i<m_trt_lines ; i++)
     960            {
     961                r_ixr_rsp_to_xram_rsp_rok[i] = false;
     962            }
     963
     964            r_xram_rsp_to_tgt_rsp_req          = false;
     965            r_xram_rsp_to_cc_send_multi_req    = false;
     966            r_xram_rsp_to_cc_send_brdcast_req  = false;
     967            r_xram_rsp_to_ixr_cmd_req          = false;
     968            r_xram_rsp_trt_index               = 0;
     969
     970            m_xram_rsp_to_cc_send_inst_fifo.init();
     971            m_xram_rsp_to_cc_send_srcid_fifo.init();
     972
     973            r_alloc_dir_reset_cpt  = 0;
     974            r_alloc_heap_reset_cpt = 0;
     975
     976            r_tgt_rsp_key_sent  = false;
     977
     978            // ODCCP
     979            r_cleanup_data_index       = 0;
     980            r_cleanup_trdid            = 0;
     981            r_cleanup_pktid            = 0;
     982            r_cleanup_contains_data    = false;
     983            r_cleanup_ncc              = false;
     984            r_cleanup_to_ixr_cmd_ncc_l1_dirty    = false;
     985            r_xram_rsp_to_ixr_cmd_inval_ncc_pending    = false;
     986            r_cleanup_to_ixr_cmd_req   = false;
     987            r_cleanup_to_ixr_cmd_srcid = 0;
     988            r_cleanup_to_ixr_cmd_pktid = 0;
     989            r_cleanup_to_ixr_cmd_nline = 0;
     990            for (size_t word = 0; word < m_words; word ++)
     991            {
     992                r_cleanup_to_ixr_cmd_data[word] = 0;
     993                r_cleanup_data[word] = 0;
     994            }
     995
     996
     997            // Activity counters
     998            m_cpt_cycles                  = 0;
     999            m_cpt_read_local         = 0;
     1000            m_cpt_read_remote        = 0;
     1001            m_cpt_read_cost          = 0;
     1002            m_cpt_write_local        = 0;
     1003            m_cpt_write_remote       = 0;
     1004            m_cpt_write_flits_local  = 0;
     1005            m_cpt_write_flits_remote = 0;
     1006            m_cpt_write_cost         = 0;
     1007            m_cpt_ll_local           = 0;
     1008            m_cpt_ll_remote          = 0;
     1009            m_cpt_ll_cost            = 0;
     1010            m_cpt_sc_local           = 0;
     1011            m_cpt_sc_remote          = 0;
     1012            m_cpt_sc_cost            = 0;
     1013            m_cpt_cas_local          = 0;
     1014            m_cpt_cas_remote         = 0;
     1015            m_cpt_cas_cost           = 0;
     1016            m_cpt_update             = 0;
     1017            m_cpt_update_local       = 0;
     1018            m_cpt_update_remote      = 0;
     1019            m_cpt_update_cost        = 0;
     1020            m_cpt_m_inval            = 0;
     1021            m_cpt_m_inval_local      = 0;
     1022            m_cpt_m_inval_remote     = 0;
     1023            m_cpt_m_inval_cost       = 0;
     1024            m_cpt_br_inval           = 0;
     1025            m_cpt_cleanup_local      = 0;
     1026            m_cpt_cleanup_remote     = 0;
     1027            m_cpt_cleanup_cost       = 0;
     1028
     1029            m_cpt_read_miss               = 0;
     1030            m_cpt_write_miss              = 0;
     1031            m_cpt_write_dirty             = 0;
     1032            m_cpt_write_broadcast = 0;
     1033            m_cpt_trt_rb          = 0;
     1034            m_cpt_trt_full                = 0;
     1035            m_cpt_get             = 0;
     1036            m_cpt_put             = 0;
     1037            m_cpt_dir_unused              = 0;
     1038            m_cpt_upt_unused              = 0;
     1039            m_cpt_ivt_unused              = 0;
     1040            m_cpt_heap_unused             = 0;
     1041            m_cpt_trt_unused              = 0;
     1042            m_cpt_read_fsm_n_dir_lock     = 0;
     1043            m_cpt_read_fsm_dir_lock       = 0;
     1044            m_cpt_read_fsm_dir_used       = 0;
     1045            m_cpt_read_fsm_trt_lock       = 0;
     1046            m_cpt_read_fsm_heap_lock      = 0;
     1047            m_cpt_write_fsm_dir_lock      = 0;
     1048            m_cpt_write_fsm_n_dir_lock    = 0;
     1049            m_cpt_write_fsm_upt_lock      = 0;
     1050            m_cpt_write_fsm_heap_lock     = 0;
     1051            m_cpt_write_fsm_dir_used      = 0;
     1052            m_cpt_write_fsm_trt_lock      = 0;
     1053            m_cpt_cas_fsm_n_dir_lock      = 0;
     1054            m_cpt_cas_fsm_dir_lock        = 0;
     1055            m_cpt_cas_fsm_upt_lock        = 0;
     1056            m_cpt_cas_fsm_heap_lock       = 0;
     1057            m_cpt_cas_fsm_trt_lock        = 0;
     1058            m_cpt_cas_fsm_dir_used        = 0;
     1059            m_cpt_xram_rsp_fsm_n_dir_lock = 0;
     1060            m_cpt_xram_rsp_fsm_dir_lock   = 0;
     1061            m_cpt_xram_rsp_fsm_trt_lock   = 0;
     1062            m_cpt_xram_rsp_fsm_upt_lock   = 0;
     1063            m_cpt_xram_rsp_fsm_heap_lock  = 0;
     1064            m_cpt_xram_rsp_fsm_dir_used   = 0;
     1065            m_cpt_cleanup_fsm_dir_lock    = 0;
     1066            m_cpt_cleanup_fsm_n_dir_lock  = 0;
     1067            m_cpt_cleanup_fsm_heap_lock   = 0;
     1068            m_cpt_cleanup_fsm_ivt_lock    = 0;
     1069            m_cpt_cleanup_fsm_dir_used    = 0;
     1070            m_cpt_ixr_fsm_trt_lock        = 0;
     1071            m_cpt_multi_ack_fsm_upt_lock  = 0;
     1072            m_cpt_read_data_unc           = 0;   
     1073            m_cpt_read_data_miss_CC       = 0;   
     1074            m_cpt_read_ins_unc            = 0;       
     1075            m_cpt_read_ins_miss           = 0;     
     1076            m_cpt_read_ll_CC              = 0;       
     1077            m_cpt_read_data_miss_NCC      = 0;       
     1078            m_cpt_read_ll_NCC             = 0;   
     1079            m_cpt_read_WTF                = 0;   
     1080            m_cpt_cleanup_data            = 0;     
     1081            m_cpt_ncc_to_cc_read          = 0;     
     1082            m_cpt_ncc_to_cc_write         = 0;       
     1083            m_cpt_ncc_to_cc               = 0;       
     1084            return;
     1085        }
     1086
     1087        bool    cmd_read_fifo_put = false;
     1088        bool    cmd_read_fifo_get = false;
     1089
     1090        bool    cmd_write_fifo_put = false;
     1091        bool    cmd_write_fifo_get = false;
     1092
     1093        bool    cmd_cas_fifo_put = false;
     1094        bool    cmd_cas_fifo_get = false;
     1095
     1096        bool    cc_receive_to_cleanup_fifo_get = false;
     1097        bool    cc_receive_to_cleanup_fifo_put = false;
     1098
     1099        bool    cc_receive_to_multi_ack_fifo_get = false;
     1100        bool    cc_receive_to_multi_ack_fifo_put = false;
     1101
     1102        bool    write_to_cc_send_fifo_put   = false;
     1103        bool    write_to_cc_send_fifo_get   = false;
     1104        bool    write_to_cc_send_fifo_inst  = false;
     1105        size_t  write_to_cc_send_fifo_srcid = 0;
     1106
     1107        bool    xram_rsp_to_cc_send_fifo_put   = false;
     1108        bool    xram_rsp_to_cc_send_fifo_get   = false;
     1109        bool    xram_rsp_to_cc_send_fifo_inst  = false;
     1110        size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
     1111
     1112        bool    config_to_cc_send_fifo_put   = false;
     1113        bool    config_to_cc_send_fifo_get   = false;
     1114        bool    config_to_cc_send_fifo_inst  = false;
     1115        size_t  config_to_cc_send_fifo_srcid = 0;
     1116
     1117        bool    cas_to_cc_send_fifo_put   = false;
     1118        bool    cas_to_cc_send_fifo_get   = false;
     1119        bool    cas_to_cc_send_fifo_inst  = false;
     1120        size_t  cas_to_cc_send_fifo_srcid = 0;
     1121
     1122        m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    10911123
    10921124#if DEBUG_MEMC_GLOBAL
    1093 if(m_debug)
    1094 {
    1095     std::cout
    1096         << "---------------------------------------------"           << std::dec << std::endl
    1097         << "MEM_CACHE "            << name()
    1098         << " ; Time = "            << m_cpt_cycles                                << std::endl
    1099         << " - TGT_CMD FSM    = "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]       << std::endl
    1100         << " - TGT_RSP FSM    = "  << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]       << std::endl
    1101         << " - CC_SEND FSM  = "    << cc_send_fsm_str[r_cc_send_fsm.read()]       << std::endl
    1102         << " - CC_RECEIVE FSM  = " << cc_receive_fsm_str[r_cc_receive_fsm.read()] << std::endl
    1103         << " - MULTI_ACK FSM  = "  << multi_ack_fsm_str[r_multi_ack_fsm.read()]   << std::endl
    1104         << " - READ FSM       = "  << read_fsm_str[r_read_fsm.read()]             << std::endl
    1105         << " - WRITE FSM      = "  << write_fsm_str[r_write_fsm.read()]           << std::endl
    1106         << " - CAS FSM        = "  << cas_fsm_str[r_cas_fsm.read()]               << std::endl
    1107         << " - CLEANUP FSM    = "  << cleanup_fsm_str[r_cleanup_fsm.read()]       << std::endl
    1108         << " - IXR_CMD FSM    = "  << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()]       << std::endl
    1109         << " - IXR_RSP FSM    = "  << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]       << std::endl
    1110         << " - XRAM_RSP FSM   = "  << xram_rsp_fsm_str[r_xram_rsp_fsm.read()]     << std::endl
    1111         << " - ALLOC_DIR FSM  = "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]   << std::endl
    1112         << " - ALLOC_TRT FSM  = "  << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]   << std::endl
    1113         << " - ALLOC_UPT FSM  = "  << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]   << std::endl
    1114         << " - ALLOC_HEAP FSM = "  << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
    1115 }
    1116 #endif
    1117 
    1118   ////////////////////////////////////////////////////////////////////////////////////
    1119   //    TGT_CMD FSM
    1120   ////////////////////////////////////////////////////////////////////////////////////
    1121   // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors,
    1122   // and dispatch these commands to the proper FSM through dedicated FIFOs.
    1123   //
    1124   // There are 5 types of commands accepted in the XRAM segment:
    1125   // - READ   : A READ request has a length of 1 VCI flit. It can be a single word
    1126   //            or an entire cache line, depending on the PLEN value => READ FSM
    1127   // - WRITE  : A WRITE request has a maximum length of 16 flits, and can only
    1128   //            concern words in a same line => WRITE FSM
    1129   // - CAS    : A CAS request has a length of 2 flits or 4 flits => CAS FSM
    1130   // - LL     : An LL request has a length of 1 flit => READ FSM
    1131   // - SC     : An SC request has a length of 2 flits. First flit contains the
    1132   //            acces key, second flit the data to write => WRITE FSM.
    1133   //
    1134   // The READ/WRITE commands accepted in the configuration segment are targeting
    1135   // configuration or status registers. They must contain one single flit.
    1136   // - For almost all addressable registers, the response is returned immediately.
    1137   // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
    1138   ////////////////////////////////////////////////////////////////////////////////////
    1139 
    1140   switch(r_tgt_cmd_fsm.read())
    1141   {
    1142     //////////////////
    1143     case TGT_CMD_IDLE:     // waiting a VCI command (RAM or CONFIG)
    1144     if(p_vci_tgt.cmdval)
    1145     {
     1125        if(m_debug)
     1126        {
     1127            std::cout
     1128                << "---------------------------------------------"           << std::dec << std::endl
     1129                << "MEM_CACHE "            << name()
     1130                << " ; Time = "            << m_cpt_cycles                                << std::endl
     1131                << " - TGT_CMD FSM    = "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]       << std::endl
     1132                << " - TGT_RSP FSM    = "  << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]       << std::endl
     1133                << " - CC_SEND FSM  = "    << cc_send_fsm_str[r_cc_send_fsm.read()]       << std::endl
     1134                << " - CC_RECEIVE FSM  = " << cc_receive_fsm_str[r_cc_receive_fsm.read()] << std::endl
     1135                << " - MULTI_ACK FSM  = "  << multi_ack_fsm_str[r_multi_ack_fsm.read()]   << std::endl
     1136                << " - READ FSM       = "  << read_fsm_str[r_read_fsm.read()]             << std::endl
     1137                << " - WRITE FSM      = "  << write_fsm_str[r_write_fsm.read()]           << std::endl
     1138                << " - CAS FSM        = "  << cas_fsm_str[r_cas_fsm.read()]               << std::endl
     1139                << " - CLEANUP FSM    = "  << cleanup_fsm_str[r_cleanup_fsm.read()]       << std::endl
     1140                << " - IXR_CMD FSM    = "  << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()]       << std::endl
     1141                << " - IXR_RSP FSM    = "  << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]       << std::endl
     1142                << " - XRAM_RSP FSM   = "  << xram_rsp_fsm_str[r_xram_rsp_fsm.read()]     << std::endl
     1143                << " - ALLOC_DIR FSM  = "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]   << std::endl
     1144                << " - ALLOC_TRT FSM  = "  << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]   << std::endl
     1145                << " - ALLOC_UPT FSM  = "  << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]   << std::endl
     1146                << " - ALLOC_HEAP FSM = "  << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
     1147        }
     1148#endif
     1149
     1150        ////////////////////////////////////////////////////////////////////////////////////
     1151        //    TGT_CMD FSM
     1152        ////////////////////////////////////////////////////////////////////////////////////
     1153        // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors,
     1154        // and dispatch these commands to the proper FSM through dedicated FIFOs.
     1155        //
     1156        // There are 5 types of commands accepted in the XRAM segment:
     1157        // - READ   : A READ request has a length of 1 VCI flit. It can be a single word
     1158        //            or an entire cache line, depending on the PLEN value => READ FSM
     1159        // - WRITE  : A WRITE request has a maximum length of 16 flits, and can only
     1160        //            concern words in a same line => WRITE FSM
     1161        // - CAS    : A CAS request has a length of 2 flits or 4 flits => CAS FSM
     1162        // - LL     : An LL request has a length of 1 flit => READ FSM
     1163        // - SC     : An SC request has a length of 2 flits. First flit contains the
     1164        //            acces key, second flit the data to write => WRITE FSM.
     1165        //
     1166        // The READ/WRITE commands accepted in the configuration segment are targeting
     1167        // configuration or status registers. They must contain one single flit.
     1168        // - For almost all addressable registers, the response is returned immediately.
     1169        // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
     1170        ////////////////////////////////////////////////////////////////////////////////////
     1171        switch(r_tgt_cmd_fsm.read())
     1172        {
     1173            //////////////////
     1174            case TGT_CMD_IDLE:     // waiting a VCI command (RAM or CONFIG)
     1175                if(p_vci_tgt.cmdval)
     1176                {
    11461177
    11471178
    11481179#if DEBUG_MEMC_TGT_CMD
    1149 if(m_debug)
    1150 std::cout << "  <MEMC " << name()
    1151           << " TGT_CMD_IDLE> Receive command from srcid "
    1152           << std::hex << p_vci_tgt.srcid.read()
    1153           << " / address " << std::hex << p_vci_tgt.address.read() << std::endl;
    1154 #endif
    1155         // checking segmentation violation
    1156         addr_t      address  = p_vci_tgt.address.read();
    1157         uint32_t    plen     = p_vci_tgt.plen.read();
    1158         bool        found    = false;
    1159         bool        config   = false;
    1160 
    1161         // register arguments for response (segmentation violation or config)
    1162         r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
    1163         r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
    1164         r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
    1165 
    1166         for(size_t seg_id = 0 ; (seg_id < m_nseg) and not found ; seg_id++)
     1180                    if(m_debug)
     1181                        std::cout << "  <MEMC " << name()
     1182                            << " TGT_CMD_IDLE> Receive command from srcid "
     1183                            << std::hex << p_vci_tgt.srcid.read()
     1184                            << " / address " << std::hex << p_vci_tgt.address.read() << std::endl;
     1185#endif
     1186                    // checking segmentation violation
     1187                    addr_t      address  = p_vci_tgt.address.read();
     1188                    uint32_t    plen     = p_vci_tgt.plen.read();
     1189                    bool        found    = false;
     1190                    bool        config   = false;
     1191
     1192                    for (size_t seg_id = 0; (seg_id < m_nseg) && !found; seg_id++)
     1193                    {
     1194                        if (m_seg[seg_id]->contains(address) &&
     1195                                m_seg[seg_id]->contains(address + plen - vci_param_int::B) )
     1196                        {
     1197                            found = true;
     1198                            if ( m_seg[seg_id]->special() ) config = true;
     1199                        }
     1200                    }
     1201
     1202                    if (!found)                /////////// out of segment error
     1203                    {
     1204                        r_tgt_cmd_fsm   = TGT_CMD_ERROR;
     1205                    }
     1206                    else if ( config )              /////////// configuration command
     1207                    {
     1208                        if (!p_vci_tgt.eop.read()) r_tgt_cmd_fsm = TGT_CMD_ERROR;
     1209                        else                            r_tgt_cmd_fsm = TGT_CMD_CONFIG;
     1210                    }
     1211                    else                            //////////// memory access
     1212                    {
     1213                        if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ )
     1214                        {
     1215                            // check that the pktid is either :
     1216                            // TYPE_READ_DATA_UNC
     1217                            // TYPE_READ_DATA_MISS
     1218                            // TYPE_READ_INS_UNC
     1219                            // TYPE_READ_INS_MISS
     1220                            // ==> bit2 must be zero with the TSAR encoding
     1221                            // ==> mask = 0b0100 = 0x4
     1222                            assert( ((p_vci_tgt.pktid.read() & 0x4) == 0x0) and
     1223                                    "The type specified in the pktid field is incompatible with the READ CMD");
     1224                            r_tgt_cmd_fsm = TGT_CMD_READ;
     1225                        }
     1226                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)
     1227                        {
     1228                            // check that the pktid is TYPE_WRITE
     1229                            // ==> TYPE_WRITE = X100 with the TSAR encoding
     1230                            // ==> mask = 0b0111 = 0x7
     1231                            assert(((p_vci_tgt.pktid.read() & 0x7) == 0x4) and
     1232                                    "The type specified in the pktid field is incompatible with the WRITE CMD");
     1233                            r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1234                        }
     1235                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ)
     1236                        {
     1237                            // check that the pktid is TYPE_LL
     1238                            // ==> TYPE_LL = X110 with the TSAR encoding
     1239                            // ==> mask = 0b0111 = 0x7
     1240                            assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) and
     1241                                    "The type specified in the pktid field is incompatible with the LL CMD");
     1242                            r_tgt_cmd_fsm = TGT_CMD_READ;
     1243                        }
     1244                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)
     1245                        {
     1246                            // check that the pktid is either :
     1247                            // TYPE_CAS
     1248                            // TYPE_SC
     1249                            // ==> TYPE_CAS = X101 with the TSAR encoding
     1250                            // ==> TYPE_SC  = X111 with the TSAR encoding
     1251                            // ==> mask = 0b0101 = 0x5
     1252                            assert(((p_vci_tgt.pktid.read() & 0x5) == 0x5) and
     1253                                    "The type specified in the pktid field is incompatible with the NOP CMD");
     1254
     1255                            if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS;
     1256                            else                                           r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1257                        }
     1258                        else
     1259                        {
     1260                            r_tgt_cmd_fsm = TGT_CMD_ERROR;
     1261                        }
     1262                    }
     1263                }
     1264                break;
     1265
     1266                ///////////////////
     1267            case TGT_CMD_ERROR:  // response error must be sent
     1268
     1269                // wait if pending request
     1270                if(r_tgt_cmd_to_tgt_rsp_req.read()) break;
     1271
     1272                // consume all the command packet flits before sending response error
     1273                if ( p_vci_tgt.cmdval and p_vci_tgt.eop )
     1274                {
     1275                    r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
     1276                    r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
     1277                    r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
     1278                    r_tgt_cmd_to_tgt_rsp_req   = true;
     1279                    r_tgt_cmd_to_tgt_rsp_error = 1;
     1280                    r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1281
     1282#if DEBUG_MEMC_TGT_CMD
     1283                    if(m_debug)
     1284                        std::cout << "  <MEMC " << name()
     1285                            << " TGT_CMD_ERROR> Segmentation violation:"
     1286                            << " address = " << std::hex << p_vci_tgt.address.read()
     1287                            << " / srcid = " << p_vci_tgt.srcid.read()
     1288                            << " / trdid = " << p_vci_tgt.trdid.read()
     1289                            << " / pktid = " << p_vci_tgt.pktid.read()
     1290                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1291#endif
     1292
     1293                }
     1294                break;
     1295
     1296                ////////////////////
     1297            case TGT_CMD_CONFIG:    // execute config request and return response
     1298                {
     1299                    addr_t   seg_base = m_seg[m_seg_config]->baseAddress();
     1300                    addr_t   address  = p_vci_tgt.address.read();
     1301                    size_t   cell     = (address - seg_base)/vci_param_int::B;
     1302
     1303                    bool     need_rsp;
     1304                    size_t   error; 
     1305                    uint32_t rdata = 0;         // default value
     1306                    uint32_t wdata = p_vci_tgt.wdata.read();     
     1307
     1308                    if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
     1309                            and (cell == MEMC_LOCK) )
     1310                    {
     1311                        rdata            = (uint32_t)r_config_lock.read();
     1312                        need_rsp         = true;
     1313                        error            = 0;
     1314                        r_config_lock    = true;
     1315                    }
     1316                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
     1317                            and (cell == MEMC_LOCK))
     1318                    {
     1319                        need_rsp         = true;
     1320                        error            = 0;
     1321                        r_config_lock    = false;
     1322                    }
     1323                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
     1324                            and (cell == MEMC_ADDR_LO))
     1325                    {
     1326                        assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
     1327                                "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
     1328
     1329                        need_rsp         = true;
     1330                        error            = 0;
     1331                        r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
     1332                            ((addr_t)wdata);
     1333                    }
     1334                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
     1335                            and (cell == MEMC_ADDR_HI))
     1336                    {
     1337                        need_rsp         = true;
     1338                        error            = 0;
     1339                        r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
     1340                            (((addr_t) wdata) << 32);
     1341                    }
     1342                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
     1343                            and (cell == MEMC_BUF_LENGTH))
     1344                    {
     1345                        need_rsp         = true;
     1346                        error            = 0;
     1347                        size_t lines     = wdata / (m_words << 2);
     1348                        if (wdata % (m_words << 2)) lines++;
     1349                        r_config_cmd_lines  = lines;
     1350                        r_config_rsp_lines  = lines;
     1351                    }
     1352                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
     1353                            and (cell == MEMC_CMD_TYPE))
     1354                    {
     1355                        need_rsp         = false;
     1356                        error            = 0;
     1357                        r_config_cmd     = wdata;
     1358                        r_config_srcid   = p_vci_tgt.srcid.read();
     1359                        r_config_trdid   = p_vci_tgt.trdid.read();
     1360                        r_config_pktid   = p_vci_tgt.pktid.read();
     1361                    }
     1362                    else
     1363                    {
     1364                        need_rsp         = true;
     1365                        error            = 1;
     1366                    }
     1367
     1368                    if ( need_rsp )
     1369                    {
     1370                        // blocked if previous pending request to TGT_RSP FSM
     1371                        if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break;
     1372
     1373                        r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
     1374                        r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
     1375                        r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
     1376                        r_tgt_cmd_to_tgt_rsp_req   = true;
     1377                        r_tgt_cmd_to_tgt_rsp_error = error;
     1378                        r_tgt_cmd_to_tgt_rsp_rdata = rdata;
     1379                        r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1380                    }
     1381                    else
     1382                    {
     1383                        r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1384                    }
     1385
     1386#if DEBUG_MEMC_TGT_CMD
     1387                    if(m_debug)
     1388                        std::cout << "  <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:"
     1389                            << " address = " << std::hex << p_vci_tgt.address.read()
     1390                            << " / wdata = " << p_vci_tgt.wdata.read()
     1391                            << " / need_rsp = " << need_rsp
     1392                            << " / error = " << error << std::endl;
     1393#endif
     1394                    break;
     1395                }
     1396                //////////////////
     1397            case TGT_CMD_READ:    // Push a read request into read fifo
     1398
     1399                // check that the read does not cross a cache line limit.
     1400                if ( ((m_x[(addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) and
     1401                        (p_vci_tgt.cmd.read() != vci_param_int::CMD_LOCKED_READ))
     1402                {
     1403                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1404                        << " illegal address/plen for VCI read command" << std::endl;
     1405                    exit(0);
     1406                }
     1407                // check single flit
     1408                if(!p_vci_tgt.eop.read())
     1409                {
     1410                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1411                        << " read command packet must contain one single flit" << std::endl;
     1412                    exit(0);
     1413                }
     1414                // check plen for LL
     1415                if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and
     1416                        (p_vci_tgt.plen.read() != 8) )
     1417                {
     1418                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1419                        << " ll command packets must have a plen of 8" << std::endl;
     1420                    exit(0);
     1421                }
     1422
     1423                if ( p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok() )
     1424                {
     1425
     1426#if DEBUG_MEMC_TGT_CMD
     1427                    if(m_debug)
     1428                        std::cout << "  <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:"
     1429                            << " address = " << std::hex << p_vci_tgt.address.read()
     1430                            << " / srcid = " << p_vci_tgt.srcid.read()
     1431                            << " / trdid = " << p_vci_tgt.trdid.read()
     1432                            << " / pktid = " << p_vci_tgt.pktid.read()
     1433                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1434#endif
     1435                    cmd_read_fifo_put = true;
     1436                    // <Activity counters>
     1437                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) {
     1438                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_ll_local++;
     1439                        else                                      m_cpt_ll_remote++;
     1440                        m_cpt_ll_cost += req_distance(p_vci_tgt.srcid.read()); // LL on a single word
     1441                    }
     1442                    else {
     1443                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_read_local++;
     1444                        else                                      m_cpt_read_remote++;
     1445                        m_cpt_read_cost += m_words * req_distance(p_vci_tgt.srcid.read());
     1446                    }
     1447                    // </Activity counters>
     1448                    r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1449                }
     1450                break;
     1451
     1452                ///////////////////
     1453            case TGT_CMD_WRITE:
     1454                if(p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok())
     1455                {
     1456
     1457#if DEBUG_MEMC_TGT_CMD
     1458                    if(m_debug)
     1459                        std::cout << "  <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:"
     1460                            << " address = " << std::hex << p_vci_tgt.address.read()
     1461                            << " / srcid = " << p_vci_tgt.srcid.read()
     1462                            << " / trdid = " << p_vci_tgt.trdid.read()
     1463                            << " / pktid = " << p_vci_tgt.pktid.read()
     1464                            << " / wdata = " << p_vci_tgt.wdata.read()
     1465                            << " / be = " << p_vci_tgt.be.read()
     1466                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1467#endif
     1468                    cmd_write_fifo_put = true;
     1469                    // <Activity counters>
     1470                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
     1471                        m_cpt_sc_cost += req_distance(p_vci_tgt.srcid.read());
     1472                    }
     1473                    else {
     1474                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_flits_local++;
     1475                        else                                      m_cpt_write_flits_remote++;
     1476                        m_cpt_write_cost += req_distance(p_vci_tgt.srcid.read());
     1477                    }
     1478                    // </Activity counters>
     1479
     1480                    if (p_vci_tgt.eop) {
     1481                        // <Activity counters>
     1482                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
     1483                            if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_sc_local++;
     1484                            else                                      m_cpt_sc_remote++;
     1485
     1486                        }
     1487                        else {
     1488                            if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_local++;
     1489                            else                                      m_cpt_write_remote++;
     1490                        }
     1491                        // </Activity counters>
     1492                        r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1493                    }
     1494                }
     1495                break;
     1496
     1497                /////////////////
     1498            case TGT_CMD_CAS:
     1499                if((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16))
     1500                {
     1501                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state"
     1502                        << "illegal format for CAS command " << std::endl;
     1503                    exit(0);
     1504                }
     1505
     1506                if(p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok())
     1507                {
     1508
     1509#if DEBUG_MEMC_TGT_CMD
     1510                    if(m_debug)
     1511                        std::cout << "  <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:"
     1512                            << " address = " << std::hex << p_vci_tgt.address.read()
     1513                            << " srcid = " << p_vci_tgt.srcid.read()
     1514                            << " trdid = " << p_vci_tgt.trdid.read()
     1515                            << " pktid = " << p_vci_tgt.pktid.read()
     1516                            << " wdata = " << p_vci_tgt.wdata.read()
     1517                            << " be = " << p_vci_tgt.be.read()
     1518                            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1519#endif
     1520                    cmd_cas_fifo_put = true;
     1521                    if (p_vci_tgt.eop) {
     1522                        // <Activity counters>
     1523                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_cas_local++;
     1524                        else                                      m_cpt_cas_remote++;
     1525                        m_cpt_cas_cost += req_distance(p_vci_tgt.srcid.read());
     1526                        // </Activity counters>
     1527                        r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1528                    }
     1529                }
     1530                break;
     1531        } // end switch tgt_cmd_fsm
     1532
     1533        /////////////////////////////////////////////////////////////////////////
     1534        //    MULTI_ACK FSM
     1535        /////////////////////////////////////////////////////////////////////////
     1536        // This FSM controls the response to the multicast update requests sent
     1537        // by the memory cache to the L1 caches and update the UPT.
     1538        //
     1539        // - The FSM decrements the proper entry in UPT,
     1540        //   and clear the UPT entry when all responses have been received.
     1541        // - If required, it sends a request to the TGT_RSP FSM to complete
     1542        //   a pending  write transaction.
     1543        //
     1544        // All those multi-ack packets are one flit packet.
     1545        // The index in the UPT is defined in the TRDID field.
     1546        ////////////////////////////////////////////////////////////////////////
     1547
     1548        switch(r_multi_ack_fsm.read())
    11671549        {
    1168             if( m_seg[seg_id]->contains(address) and
    1169                 m_seg[seg_id]->contains(address + plen - vci_param_int::B) )
     1550            ////////////////////
     1551            case MULTI_ACK_IDLE:
     1552                {
     1553                    bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok();
     1554
     1555                    // No CC_RECEIVE FSM request and no WRITE FSM request
     1556                    if( not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read())
     1557                        break;
     1558
     1559                    uint8_t updt_index;
     1560
     1561                    // handling WRITE FSM request to decrement update table response
     1562                    // counter if no CC_RECEIVE FSM request
     1563                    if(not multi_ack_fifo_rok)
     1564                    {
     1565                        updt_index               = r_write_to_multi_ack_upt_index.read();
     1566                        r_write_to_multi_ack_req = false;
     1567                    }
     1568                    // Handling CC_RECEIVE FSM request
     1569                    else
     1570                    {
     1571                        uint64_t flit = m_cc_receive_to_multi_ack_fifo.read();
     1572                        updt_index    = DspinDhccpParam::dspin_get(flit,
     1573                                DspinDhccpParam::MULTI_ACK_UPDT_INDEX);
     1574
     1575                        cc_receive_to_multi_ack_fifo_get = true;
     1576                    }
     1577
     1578                    assert((updt_index < m_upt.size()) and
     1579                            "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : "
     1580                            "index too large for UPT");
     1581
     1582                    r_multi_ack_upt_index = updt_index;
     1583                    r_multi_ack_fsm       = MULTI_ACK_UPT_LOCK;
     1584
     1585#if DEBUG_MEMC_MULTI_ACK
     1586                    if(m_debug)
     1587                    {
     1588                        if (multi_ack_fifo_rok)
     1589                        {
     1590                            std::cout << "  <MEMC " << name()
     1591                                << " MULTI_ACK_IDLE> Response for UPT entry "
     1592                                << (size_t)updt_index << std::endl;
     1593                        }
     1594                        else
     1595                        {
     1596                            std::cout << "  <MEMC " << name()
     1597                                << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry "
     1598                                << updt_index << std::endl;
     1599                        }
     1600                    }
     1601#endif
     1602                    break;
     1603                }
     1604
     1605                ////////////////////////
     1606            case MULTI_ACK_UPT_LOCK:
     1607                {
     1608                    m_cpt_multi_ack_fsm_upt_lock++;
     1609                    // get lock to the UPDATE table
     1610                    if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)  break;
     1611
     1612                    // decrement the number of expected responses
     1613                    size_t count = 0;
     1614                    bool valid   = m_upt.decrement(r_multi_ack_upt_index.read(), count);
     1615
     1616                    /*ODCCP*/ //m_upt.print();
     1617
     1618                    if(not valid)
     1619                    {
     1620                        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1621                            << " MULTI_ACK_UPT_LOCK state" << std::endl
     1622                            << "unsuccessful access to decrement the UPT" << std::endl;
     1623                        exit(0);
     1624                    }
     1625
     1626                    if(count == 0)
     1627                    {
     1628                        r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR;
     1629                    }
     1630                    else
     1631                    {
     1632                        r_multi_ack_fsm = MULTI_ACK_IDLE;
     1633                    }
     1634
     1635#if DEBUG_MEMC_MULTI_ACK
     1636                    if(m_debug)
     1637                        std::cout << "  <MEMC " << name()
     1638                            << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:"
     1639                            << " entry = "       << r_multi_ack_upt_index.read()
     1640                            << " / rsp_count = " << std::dec << count << std::endl;
     1641                    m_cpt_multi_ack_fsm_n_upt_lock++;
     1642#endif
     1643                    break;
     1644                }
     1645
     1646                /////////////////////////
     1647            case MULTI_ACK_UPT_CLEAR:   // Clear UPT entry / Test if rsp or ack required
     1648                {
     1649                    if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)
     1650                    {
     1651                        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1652                            << " MULTI_ACK_UPT_CLEAR state"
     1653                            << " bad UPT allocation" << std::endl;
     1654                        exit(0);
     1655                    }
     1656
     1657                    r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read());
     1658                    r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read());
     1659                    r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read());
     1660                    r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
     1661                    bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
     1662
     1663                    // clear the UPT entry
     1664                    m_upt.clear(r_multi_ack_upt_index.read());
     1665
     1666                    if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
     1667                    else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
     1668
     1669#if DEBUG_MEMC_MULTI_ACK
     1670                    if(m_debug)
     1671                        std::cout <<  "  <MEMC " << name()
     1672                            << " MULTI_ACK_UPT_CLEAR> Clear UPT entry "
     1673                            << std::dec << r_multi_ack_upt_index.read() << std::endl;
     1674#endif
     1675                    break;
     1676                }
     1677                /////////////////////////
     1678            case MULTI_ACK_WRITE_RSP:     // Post a response request to TGT_RSP FSM
     1679                // Wait if pending request
     1680                {
     1681                    if ( r_multi_ack_to_tgt_rsp_req.read() ) break;
     1682
     1683                    r_multi_ack_to_tgt_rsp_req   = true;
     1684                    r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read();
     1685                    r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read();
     1686                    r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read();
     1687                    r_multi_ack_fsm              = MULTI_ACK_IDLE;
     1688
     1689#if DEBUG_MEMC_MULTI_ACK
     1690                    if(m_debug)
     1691                        std::cout << "  <MEMC " << name() << " MULTI_ACK_WRITE_RSP>"
     1692                            << " Request TGT_RSP FSM to send a response to srcid "
     1693                            << std::hex << r_multi_ack_srcid.read() << std::endl;
     1694#endif
     1695                    break;
     1696                }
     1697        } // end switch r_multi_ack_fsm
     1698
     1699        ////////////////////////////////////////////////////////////////////////////////////
     1700        //    CONFIG FSM
     1701        ////////////////////////////////////////////////////////////////////////////////////
     1702        // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC).
     1703        // The target buffer can have any size, and there is one single command for
     1704        // all cache lines covered by the target buffer.
     1705        //
     1706        // An INVAL or SYNC configuration operation is defined by the following registers:
     1707        // - bool      r_config_cmd        : INVAL / SYNC / NOP
     1708
     1709        // - uint64_t  r_config_address    : buffer base address
     1710        // - uint32_t  r_config_cmd_lines  : number of lines to be handled
     1711        // - uint32_t  r_config_rsp_lines  : number of lines not completed
     1712
     1713        //
     1714        // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
     1715        //
     1716        // all cache lines covered by the buffer. The various lines of a given buffer
     1717        // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
     1718        // the command for line (n+1). It decrements the r_config_cmd_lines counter until
     1719        // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
     1720        //
     1721        // - INVAL request:
     1722        //   For each line, it access to the DIR.
     1723        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1724        //   In case of hit, with no copies in L1 caches, the line is invalidated and
     1725        //   a response is requested to TGT_RSP FSM.
     1726        //   If there is copies, a multi-inval, or a broadcast-inval coherence transaction
     1727        //
     1728        //   is launched and registered in UPT. The multi-inval transaction completion
     1729        //   is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter.
     1730        //   The CONFIG INVAL response is sent only when the last line has been invalidated.
     1731        //   TODO : The target buffer address must be aligned on a cache line boundary.
     1732        //   This constraint can be released, but it requires to make 2 PUT transactions
     1733        //   for the first and the last line...
     1734        //
     1735        // - SYNC request:
     1736        //   For each line, it access to the DIR.
     1737        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1738        //   In case of hit, a PUT transaction is registered in TRT and a request is sent
     1739        //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
     1740        //   when a PUT response is received.
     1741        //   The CONFIG SYNC response is sent only when the last PUT response is received.
     1742        //
     1743        // From the software point of view, a configuration request is a sequence
     1744        // of 6 atomic accesses in an uncached segment. A dedicated lock is used
     1745        // to handle only one configuration command at a given time:
     1746        // - Read  MEMC_LOCK       : Get the lock
     1747        // - Write MEMC_ADDR_LO    : Set the buffer address LSB
     1748        // - Write MEMC_ADDR_HI    : Set the buffer address MSB
     1749        // - Write MEMC_BUF_LENGTH : set buffer length (bytes)
     1750        // - Write MEMC_CMD_TYPE   : launch the actual operation
     1751        // - WRITE MEMC_LOCK       : release the lock
     1752        ////////////////////////////////////////////////////////////////////////////////////
     1753
     1754        switch( r_config_fsm.read() )
     1755        {
     1756            /////////////////
     1757            case CONFIG_IDLE:  // waiting a config request
     1758                {
     1759                    if ( r_config_cmd.read() != MEMC_CMD_NOP ) 
     1760                    {
     1761                        r_config_fsm    = CONFIG_LOOP;
     1762
     1763#if DEBUG_MEMC_CONFIG
     1764                        if(m_debug)
     1765                            std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
     1766                                << " address = " << std::hex << r_config_address.read()
     1767                                << " / nlines = " << std::dec << r_config_cmd_lines.read()
     1768                                << " / type = " << r_config_cmd.read() << std::endl;
     1769#endif
     1770                    }
     1771                    break;
     1772                }
     1773                /////////////////
     1774            case CONFIG_LOOP:   // test last line to be handled
     1775                {
     1776                    if ( r_config_cmd_lines.read() == 0 )
     1777                    {
     1778                        r_config_cmd = MEMC_CMD_NOP;
     1779                        r_config_fsm = CONFIG_WAIT;
     1780                    }
     1781                    else
     1782                    {
     1783                        r_config_fsm = CONFIG_DIR_REQ;
     1784                    }
     1785
     1786#if DEBUG_MEMC_CONFIG
     1787                    if(m_debug)
     1788                        std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
     1789                            << " address = " << std::hex << r_config_address.read()   
     1790                            << " / nlines = " << std::dec << r_config_cmd_lines.read()
     1791                            << " / command = " << r_config_cmd.read() << std::endl;
     1792#endif
     1793                    break;
     1794                }
     1795                /////////////////
     1796            case CONFIG_WAIT:   // wait completion (last response)
     1797                {
     1798                    if ( r_config_rsp_lines.read() == 0 )  // last response received
     1799                    {
     1800                        r_config_fsm = CONFIG_RSP;
     1801                    }
     1802
     1803#if DEBUG_MEMC_CONFIG
     1804                    if(m_debug)
     1805                        std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
     1806                            << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     1807#endif
     1808                    break;
     1809                }
     1810                ////////////////
     1811            case CONFIG_RSP:  // request TGT_RSP FSM to return response
     1812                {
     1813                    if ( not r_config_to_tgt_rsp_req.read() )
     1814                    {
     1815                        r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
     1816                        r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
     1817                        r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
     1818                        r_config_to_tgt_rsp_error  = false;
     1819                        r_config_to_tgt_rsp_req    = true;
     1820                        r_config_fsm               = CONFIG_IDLE;
     1821
     1822#if DEBUG_MEMC_CONFIG
     1823                        if(m_debug)
     1824                            std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
     1825                                << " error = " << r_config_to_tgt_rsp_error.read()
     1826                                << " / rsrcid = " << std::hex << r_config_srcid.read()
     1827                                << " / rtrdid = " << std::hex << r_config_trdid.read()
     1828                                << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     1829#endif
     1830                    }
     1831                    break;
     1832
     1833                }
     1834
     1835                ////////////////////
     1836            case CONFIG_DIR_REQ:  // Request directory lock
     1837                {
     1838                    if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
     1839                    {
     1840                        r_config_fsm = CONFIG_DIR_ACCESS;
     1841                    }
     1842
     1843#if DEBUG_MEMC_CONFIG
     1844                    if(m_debug)
     1845                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
     1846                            << " Request DIR access" << std::endl;
     1847#endif
     1848                    break;
     1849                }
     1850                ///////////////////////
     1851            case CONFIG_DIR_ACCESS:   // Access directory and decode config command
     1852                {
     1853                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1854                            "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
     1855
     1856                    size_t way = 0;
     1857                    DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
     1858
     1859                    r_config_dir_way        = way;
     1860                    r_config_dir_copy_inst  = entry.owner.inst;
     1861                    r_config_dir_copy_srcid = entry.owner.srcid;
     1862                    r_config_dir_is_cnt     = entry.is_cnt;
     1863                    r_config_dir_count      = entry.count;
     1864                    r_config_dir_lock       = entry.lock;
     1865                    r_config_dir_ptr        = entry.ptr;
     1866
     1867                    if (entry.valid and                            // hit & inval command
     1868                            (r_config_cmd.read() == MEMC_CMD_INVAL))
     1869                    {
     1870                        r_config_fsm    = CONFIG_IVT_LOCK;
     1871                    }
     1872                    else if ( entry.valid and                       // hit & sync command
     1873                            entry.dirty and
     1874                            (r_config_cmd.read() == MEMC_CMD_SYNC) )
     1875                    {
     1876                        r_config_fsm = CONFIG_TRT_LOCK;
     1877                    }
     1878                    else                                            // return to LOOP
     1879                    {
     1880                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1881                        r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     1882                        r_config_address   = r_config_address.read() + (m_words<<2);
     1883                        r_config_fsm       = CONFIG_LOOP;
     1884                    }
     1885
     1886#if DEBUG_MEMC_CONFIG
     1887                    if(m_debug)
     1888                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
     1889                            << " address = " << std::hex << r_config_address.read()
     1890                            << " / hit = " << std::dec << entry.valid
     1891                            << " / dirty = " << entry.dirty
     1892                            << " / count = " << entry.count
     1893                            << " / is_cnt = " << entry.is_cnt << std::endl;
     1894#endif
     1895                    break;
     1896                }
     1897                /////////////////////
     1898            case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
     1899                // to a dirty cache line
     1900                // keep DIR lock, and try to get TRT lock
     1901                // return to LOOP state if TRT full
     1902                // reset dirty bit in DIR and register a PUT
     1903                // trabsaction in TRT if not full.
     1904                {
     1905                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1906                            "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
     1907
     1908                    if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
     1909                    {
     1910                        size_t index = 0;
     1911                        bool   wok   = not m_trt.full(index);
     1912
     1913                        if ( not wok )
     1914                        {
     1915                            r_config_fsm = CONFIG_LOOP;
     1916                        }
     1917                        else
     1918                        {
     1919                            size_t          way = r_config_dir_way.read();
     1920                            size_t          set = m_y[r_config_address.read()];
     1921
     1922                            // reset dirty bit in DIR
     1923                            DirectoryEntry  entry;
     1924                            entry.valid       = true;
     1925                            entry.dirty       = false;
     1926                            entry.tag         = m_z[r_config_address.read()];
     1927                            entry.is_cnt      = r_config_dir_is_cnt.read();
     1928                            entry.lock        = r_config_dir_lock.read();
     1929                            entry.ptr         = r_config_dir_ptr.read();
     1930                            entry.count       = r_config_dir_count.read();
     1931                            entry.owner.inst  = r_config_dir_copy_inst.read();
     1932                            entry.owner.srcid = r_config_dir_copy_srcid.read();
     1933                            m_cache_directory.write( set, way, entry );
     1934
     1935                            r_config_trt_index = index;
     1936                            r_config_fsm       = CONFIG_TRT_SET;
     1937                        }
     1938
     1939#if DEBUG_MEMC_CONFIG
     1940                        if(m_debug)
     1941                            std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
     1942                                << " wok = " << std::dec << wok
     1943                                << " index = " << index << std::endl;
     1944#endif
     1945                    }
     1946                    break;
     1947                }
     1948                ////////////////////
     1949            case CONFIG_TRT_SET:       // read data in cache
     1950                // and post a PUT request in TRT
     1951                {
     1952                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1953                            "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
     1954
     1955                    assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
     1956                            "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
     1957
     1958                    // read data into cache
     1959                    size_t          way = r_config_dir_way.read();
     1960                    size_t          set = m_y[r_config_address.read()];
     1961                    std::vector<data_t> data_vector;
     1962                    data_vector.clear();
     1963                    for(size_t word=0; word<m_words; word++)
     1964                    {
     1965                        uint32_t data = m_cache_data.read( way, set, word );
     1966                        data_vector.push_back( data );
     1967                    }
     1968
     1969                    // post the PUT request in TRT
     1970                    m_trt.set( r_config_trt_index.read(),
     1971                            false,                               // PUT transaction
     1972                            m_nline[r_config_address.read()],    // line index
     1973                            0,                                   // srcid:       unused
     1974                            0,                                   // trdid:       unused
     1975                            0,                                   // pktid:       unused
     1976                            false,                               // not proc_read
     1977                            0,                                   // read_length: unused
     1978                            0,                                   // word_index:  unused
     1979                            std::vector<be_t>(m_words,0xF),      // byte-enable:     unused
     1980                            data_vector,                         // data to be written
     1981                            0,                                   // ll_key:          unused
     1982                            true );                              // requested by config FSM
     1983                    r_config_fsm = CONFIG_PUT_REQ;
     1984
     1985#if DEBUG_MEMC_CONFIG
     1986                    if(m_debug)
     1987                        std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
     1988                            << " address = " << std::hex << r_config_address.read()
     1989                            << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     1990#endif
     1991                    break;
     1992                }
     1993                ////////////////////
     1994            case CONFIG_PUT_REQ:       // post PUT request to IXR_CMD_FSM
     1995                {
     1996                    if ( not r_config_to_ixr_cmd_req.read() )
     1997                    {
     1998                        r_config_to_ixr_cmd_req   = true;
     1999                        r_config_to_ixr_cmd_index = r_config_trt_index.read();
     2000
     2001                        // prepare next iteration
     2002                        r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     2003                        r_config_address                = r_config_address.read() + (m_words<<2);
     2004                        r_config_fsm                    = CONFIG_LOOP;
     2005
     2006#if DEBUG_MEMC_CONFIG
     2007                        if(m_debug)
     2008                            std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
     2009                                << " / address = " << std::hex << r_config_address.read() << std::endl;
     2010#endif
     2011                    }
     2012                    break;
     2013                }
     2014                /////////////////////
     2015            case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
     2016                // Keep DIR lock and Try to get IVT lock.
     2017                // Return to LOOP state if IVT full.
     2018                // Register inval in IVT, and invalidate the
     2019                // directory if IVT not full.
     2020                {
     2021                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     2022                            "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
     2023
     2024                    if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
     2025                    {
     2026                        size_t set        = m_y[(addr_t)(r_config_address.read())];
     2027                        size_t way        = r_config_dir_way.read();
     2028
     2029                        if ( r_config_dir_count.read() == 0 )     // inval DIR and return to LOOP
     2030                        {
     2031                            m_cache_directory.inval( way, set );
     2032                            r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
     2033                            r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
     2034                            r_config_address    = r_config_address.read() + (m_words<<2);
     2035                            r_config_fsm        = CONFIG_LOOP;
     2036
     2037#if DEBUG_MEMC_CONFIG
     2038                            if(m_debug)
     2039                                std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2040                                    << " No copies in L1 : inval DIR entry"  << std::endl;
     2041#endif
     2042                        }
     2043                        else    // try to register inval in IVT
     2044                        {
     2045                            bool        wok       = false;
     2046                            size_t      index     = 0;
     2047                            bool        broadcast = r_config_dir_is_cnt.read();
     2048                            size_t      srcid     = r_config_srcid.read();
     2049                            size_t      trdid     = r_config_trdid.read();
     2050                            size_t      pktid     = r_config_pktid.read();
     2051                            addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
     2052                            size_t      nb_copies = r_config_dir_count.read();
     2053
     2054                            wok = m_ivt.set(false,       // it's an inval transaction
     2055                                    broadcast,   
     2056                                    false,       // no response required
     2057                                    true,        // acknowledge required
     2058                                    srcid,
     2059                                    trdid,
     2060                                    pktid,
     2061                                    nline,
     2062                                    nb_copies,
     2063                                    index);
     2064
     2065                            if ( wok )  // IVT success => inval DIR slot
     2066                            {
     2067                                m_cache_directory.inval( way, set );
     2068                                r_config_ivt_index = index;
     2069                                if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
     2070                                else              r_config_fsm = CONFIG_INVAL_SEND;
     2071
     2072#if DEBUG_MEMC_CONFIG
     2073                                if(m_debug)
     2074                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2075                                        << " Inval DIR entry and register inval in IVT"
     2076                                        << " : index = " << std::dec << index
     2077                                        << " / broadcast = " << broadcast << std::endl;
     2078#endif
     2079                            }
     2080                            else       // IVT full => release both DIR and IVT locks
     2081                            {
     2082                                r_config_fsm = CONFIG_LOOP;
     2083
     2084#if DEBUG_MEMC_CONFIG
     2085                                if(m_debug)
     2086                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2087                                        << " IVT full : release DIR & IVT locks and retry" << std::endl;
     2088#endif
     2089                            }
     2090                        }
     2091                    }
     2092                    break;
     2093                }
     2094                ////////////////////
     2095            case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
     2096                {
     2097                    if( not r_config_to_cc_send_multi_req.read() and
     2098                            not r_config_to_cc_send_brdcast_req.read() )
     2099                    {
     2100                        // post bc inval request
     2101                        r_config_to_cc_send_multi_req   = false;
     2102                        r_config_to_cc_send_brdcast_req = true;
     2103                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
     2104                        r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
     2105
     2106                        // prepare next iteration
     2107                        r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     2108                        r_config_address                = r_config_address.read() + (m_words<<2);
     2109                        r_config_fsm                    = CONFIG_LOOP;
     2110
     2111#if DEBUG_MEMC_CONFIG
     2112                        if(m_debug)
     2113                            std::cout << "  <MEMC " << name() << " CONFIG_BC_SEND>"
     2114                                << " Post a broadcast inval request to CC_SEND FSM"
     2115                                << " / address = " << r_config_address.read() <<std::endl;
     2116#endif
     2117                    }
     2118                    break;
     2119                }
     2120                ///////////////////////
     2121            case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
     2122                {
     2123                    if( not r_config_to_cc_send_multi_req.read() and
     2124                            not r_config_to_cc_send_brdcast_req.read() )
     2125                    {
     2126                        r_config_to_cc_send_multi_req   = true;
     2127                        r_config_to_cc_send_brdcast_req = false;
     2128                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
     2129                        r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
     2130
     2131                        // post data into FIFO
     2132                        config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
     2133                        config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
     2134                        config_to_cc_send_fifo_put      = true;
     2135
     2136                        if ( r_config_dir_count.read() == 1 )  // one copy
     2137                        {
     2138                            // prepare next iteration
     2139                            r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2140                            r_config_address            = r_config_address.read() + (m_words<<2);
     2141                            r_config_fsm                = CONFIG_LOOP;
     2142                        }
     2143                        else                                   // several copies
     2144                        {
     2145                            r_config_fsm = CONFIG_HEAP_REQ;
     2146                        }
     2147
     2148#if DEBUG_MEMC_CONFIG
     2149                        if(m_debug)
     2150                            std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
     2151                                << " Post multi inval request to CC_SEND FSM"
     2152                                << " / address = " << std::hex << r_config_address.read()
     2153                                << " / copy = " << r_config_dir_copy_srcid.read()
     2154                                << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
     2155#endif
     2156                    }
     2157                    break;
     2158                }
     2159                /////////////////////
     2160            case CONFIG_HEAP_REQ:  // Try to get access to Heap
     2161                {
     2162                    if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
     2163                    {
     2164                        r_config_fsm       = CONFIG_HEAP_SCAN;
     2165                        r_config_heap_next = r_config_dir_ptr.read();
     2166                    }
     2167
     2168#if DEBUG_MEMC_CONFIG
     2169                    if(m_debug)
     2170                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
     2171                            << " Requesting HEAP lock" << std::endl;
     2172#endif
     2173                    break;
     2174                }
     2175                //////////////////////
     2176            case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
     2177                {
     2178                    HeapEntry entry = m_heap.read( r_config_heap_next.read() );
     2179                    bool last_copy  = (entry.next == r_config_heap_next.read());
     2180
     2181                    config_to_cc_send_fifo_srcid = entry.owner.srcid;
     2182                    config_to_cc_send_fifo_inst  = entry.owner.inst;
     2183                    // config_to_cc_send_fifo_last  = last_copy;
     2184                    config_to_cc_send_fifo_put   = true;
     2185
     2186                    if ( m_config_to_cc_send_inst_fifo.wok() ) // inval request accepted
     2187                    {
     2188                        r_config_heap_next = entry.next;
     2189                        if ( last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
     2190                    }
     2191
     2192#if DEBUG_MEMC_CONFIG
     2193                    if(m_debug)
     2194                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
     2195                            << " Post multi inval request to CC_SEND FSM"
     2196                            << " / address = " << std::hex << r_config_address.read()
     2197                            << " / copy = " << entry.owner.srcid
     2198                            << " / inst = " << std::dec << entry.owner.inst << std::endl;
     2199#endif
     2200                    break;
     2201                }
     2202                //////////////////////
     2203            case CONFIG_HEAP_LAST:      // HEAP housekeeping
     2204                {
     2205                    size_t free_pointer = m_heap.next_free_ptr();
     2206                    HeapEntry last_entry;
     2207                    last_entry.owner.srcid = 0;
     2208                    last_entry.owner.inst  = false;
     2209
     2210                    if ( m_heap.is_full() )
     2211                    {
     2212                        last_entry.next = r_config_dir_ptr.read();
     2213                        m_heap.unset_full();
     2214                    }
     2215                    else
     2216                    {
     2217                        last_entry.next = free_pointer;
     2218                    }
     2219
     2220                    m_heap.write_free_ptr( r_config_dir_ptr.read() );
     2221                    m_heap.write( r_config_heap_next.read(), last_entry );
     2222
     2223                    // prepare next iteration
     2224                    r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2225                    r_config_address            = r_config_address.read() + (m_words<<2);
     2226                    r_config_fsm                = CONFIG_LOOP;
     2227
     2228#if DEBUG_MEMC_CONFIG
     2229                    if(m_debug)
     2230                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
     2231                            << " Heap housekeeping" << std::endl;
     2232#endif
     2233                    break;
     2234                }
     2235        }  // end switch r_config_fsm
     2236
     2237        ////////////////////////////////////////////////////////////////////////////////////
     2238        //    READ FSM
     2239        ////////////////////////////////////////////////////////////////////////////////////
     2240        // The READ FSM controls the VCI read  and ll requests.
     2241        // It takes the lock protecting the cache directory to check the cache line status:
     2242        // - In case of HIT
     2243        //   The fsm copies the data (one line, or one single word)
     2244        //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
     2245        //   The requesting initiator is registered in the cache directory.
     2246        //   If the number of copy is larger than 1, the new copy is registered
     2247        //   in the HEAP.
     2248        //   If the number of copy is larger than the threshold, the HEAP is cleared,
     2249        //   and the corresponding line switches to the counter mode.
     2250        // - In case of MISS
     2251        //   The READ fsm takes the lock protecting the transaction tab.
     2252        //   If a read transaction to the XRAM for this line already exists,
     2253        //   or if the transaction tab is full, the fsm is stalled.
     2254        //   If a TRT entry is free, the READ request is registered in TRT,
     2255        //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
     2256        //   The READ FSM returns in the IDLE state as the read transaction will be
     2257        //   completed when the missing line will be received.
     2258        ////////////////////////////////////////////////////////////////////////////////////
     2259
     2260        switch(r_read_fsm.read())
     2261        {
     2262            ///////////////
     2263            case READ_IDLE:  // waiting a read request
     2264                {
     2265                    if(m_cmd_read_addr_fifo.rok())
     2266                    {
     2267
     2268#if DEBUG_MEMC_READ
     2269                        if(m_debug)
     2270                            std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
     2271                                << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
     2272                                << " / srcid = " << m_cmd_read_srcid_fifo.read()
     2273                                << " / trdid = " << m_cmd_read_trdid_fifo.read()
     2274                                << " / pktid = " << m_cmd_read_pktid_fifo.read()
     2275                                << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2276#endif
     2277                        r_read_coherent = false; //WB by default
     2278                        r_read_ll_done  = false;
     2279                        r_read_fsm = READ_DIR_REQ;
     2280                    }
     2281                    break;
     2282                }
     2283
     2284                //////////////////
     2285            case READ_DIR_REQ:  // Get the lock to the directory
     2286                {
     2287                    if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
     2288                    {
     2289                        r_read_fsm = READ_DIR_LOCK;
     2290                        m_cpt_read_fsm_n_dir_lock++;
     2291                    }
     2292
     2293#if DEBUG_MEMC_READ
     2294                    if(m_debug)
     2295                        std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
     2296#endif
     2297
     2298                    m_cpt_read_fsm_dir_lock++;
     2299
     2300                    break;
     2301                }
     2302
     2303                ///////////////////
     2304            case READ_DIR_LOCK:  // check directory for hit / miss
     2305                {
     2306                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2307                            "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
     2308
     2309                    size_t way = 0;
     2310                    DirectoryEntry entry =
     2311                        m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2312                    if(((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) and not r_read_ll_done.read())   // access the global table ONLY when we have an LL cmd
     2313                    {
     2314                        r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     2315                        /**//*std::cout << "MEMCACHE : from proc " << m_cmd_read_srcid_fifo.read()
     2316                              << " | @ " << std::hex << m_cmd_read_addr_fifo.read()
     2317                              << " | LL" << std::endl;*/
     2318                        r_read_ll_done  = true;
     2319                    }
     2320                    r_read_is_cnt     = entry.is_cnt;
     2321                    r_read_dirty      = entry.dirty;
     2322                    r_read_lock       = entry.lock;
     2323                    r_read_tag        = entry.tag;
     2324                    r_read_way        = way;
     2325                    r_read_count      = entry.count;
     2326                    r_read_copy       = entry.owner.srcid;
     2327
     2328                    r_read_copy_inst  = entry.owner.inst;
     2329                    r_read_ptr        = entry.ptr; // pointer to the heap
     2330
     2331                    // check if this is a cached read, this means pktid is either
     2332                    // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2333                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2334                    bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
     2335
     2336                    if(entry.valid)    // hit
     2337                    {
     2338                        r_read_coherent = entry.cache_coherent;
     2339                        if (entry.cache_coherent or (entry.count == 0))// or (entry.owner.srcid == m_cmd_read_srcid_fifo.read())) //hit on a WT line or the owner has no more copy (if LL, the owner must be invalidated even if he made the request)
     2340                        {
     2341                            // test if we need to register a new copy in the heap
     2342                            if(entry.is_cnt || (entry.count == 0) || !cached_read)
     2343                            {
     2344                                r_read_fsm = READ_DIR_HIT;
     2345                            }
     2346                            else
     2347                            {
     2348                                //std::cout << "is LL = " << ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) << std::endl;
     2349                                //std::cout << "coherent = " << entry.cache_coherent << " | count = " << std::dec << entry.count << " | cached = " << cached_read << std::endl;
     2350                                r_read_fsm = READ_HEAP_REQ;
     2351                            }
     2352                        }
     2353                        else //hit on a WB line owned by an other proc
     2354                        {
     2355                            r_read_fsm = READ_IVT_LOCK;
     2356                        }
     2357                    }
     2358                    else      // miss
     2359                    {
     2360                        r_read_fsm = READ_TRT_LOCK;
     2361                    }
     2362
     2363#if DEBUG_MEMC_READ
     2364                    if(m_debug)
     2365                    {
     2366                        std::cout << "  <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: "
     2367                            << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     2368                            << " / hit = " << std::dec << entry.valid
     2369                            << " / count = " <<std::dec << entry.count
     2370                            << " / is_cnt = " << entry.is_cnt
     2371                            << " / is_coherent = " << entry.cache_coherent;
     2372                        if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl;
     2373                        else                                                std::cout << std::endl;
     2374                    }
     2375#endif
     2376                    break;
     2377                }
     2378
     2379                ///////////////////
     2380            case READ_IVT_LOCK:
     2381                {
     2382                    if (r_alloc_ivt_fsm.read() == ALLOC_IVT_READ)
     2383                    {
     2384                        size_t index;
     2385                        addr_t nline = m_nline[(addr_t)(m_cmd_read_addr_fifo.read())];
     2386                        /*std::cout << "nline = " << std::dec <<  nline << std::endl
     2387                          << "inval en cours sur la ligne = " << m_upt.search_inval(nline, index) << std::endl
     2388                          << "UPT full = " << m_upt.is_full() << std::endl
     2389                          << "CC_SEND req = " << r_read_to_cc_send_req.read() << std::endl
     2390                          << "CLENAUP req = " <<r_read_to_cleanup_req.read() << std::endl;*/
     2391                        if(m_ivt.search_inval(nline, index) or m_ivt.is_full() or r_read_to_cc_send_req.read() or r_read_to_cleanup_req.read()) //Check pending inval
     2392                        {
     2393                            r_read_fsm = READ_WAIT;
     2394#if DEBUG_MEMC_READ
     2395                            if(m_debug)
     2396                            {
     2397                                std::cout
     2398                                    << "  <MEMC " << name() << " READ_IVT_LOCK>"
     2399                                    << " Wait cleanup completion"
     2400                                    << std::endl;
     2401                            }
     2402#endif
     2403                        }
     2404                        else
     2405                        {
     2406                            r_read_to_cc_send_req = true;
     2407                            r_read_to_cc_send_dest = r_read_copy.read();
     2408                            r_read_to_cc_send_nline = nline;
     2409                            r_read_to_cc_send_inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2410                            r_read_to_cleanup_req = true;
     2411                            r_read_to_cleanup_nline = nline;
     2412                            r_read_to_cleanup_srcid = m_cmd_read_srcid_fifo.read();
     2413                            r_read_to_cleanup_length  = m_cmd_read_length_fifo.read();
     2414                            r_read_to_cleanup_first_word = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2415                            r_read_to_cleanup_cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
     2416                            r_read_to_cleanup_addr = m_cmd_read_addr_fifo.read();
     2417                            r_read_to_cleanup_is_ll= ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL);
     2418                            r_read_to_cleanup_ll_key = r_read_ll_key.read();
     2419                            //std::cout << "cleanup req (read) on line " << nline << " /on proc " << r_read_copy.read() << std::endl;
     2420
     2421                            m_ivt.set(false,     // it's an inval transaction
     2422                                    false,     // it's not a broadcast
     2423                                    false,     // it needs a read response
     2424                                    false,     // no acknowledge required
     2425                                    m_cmd_read_srcid_fifo.read(),
     2426                                    m_cmd_read_trdid_fifo.read(),
     2427                                    m_cmd_read_pktid_fifo.read(),
     2428                                    nline,
     2429                                    0x1, //Expect only one answer
     2430                                    index);
     2431
     2432                            cmd_read_fifo_get = true;
     2433                            r_read_fsm = READ_IDLE;
     2434#if DEBUG_MEMC_READ
     2435                            if(m_debug)
     2436                            {
     2437                                std::cout
     2438                                    << "  <MEMC " << name() << " READ_IVT_LOCK>"
     2439                                    << " Inval req on an NCC line"
     2440                                    << std::endl;
     2441                            }
     2442#endif
     2443                        }
     2444                    }
     2445
     2446
     2447                    break;
     2448                }
     2449
     2450                //////////////////
     2451            case READ_WAIT://Release the locks
     2452                {
     2453                    r_read_fsm = READ_DIR_REQ;
     2454#if DEBUG_MEMC_READ
     2455                    if(m_debug)
     2456                    {
     2457                        std::cout
     2458                            << "  <MEMC " << name() << " READ_WAIT>" << std::endl;
     2459                    }
     2460#endif
     2461                    break;
     2462                }
     2463                ///////////////////                     
     2464            case READ_DIR_HIT:    //  read data in cache & update the directory
     2465                //  we enter this state in 3 cases:
     2466                //  - the read request is uncachable
     2467                //  - the cache line is in counter mode
     2468                //  - the cache line is valid but not replicated
     2469
     2470                {
     2471                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2472                            "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
     2473                    // check if this is an instruction read, this means pktid is either
     2474                    // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     2475                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2476                    bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2477                    // check if this is a cached read, this means pktid is either
     2478                    // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2479                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2480                    bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
     2481                    bool is_cnt       = r_read_is_cnt.read();
     2482
     2483                    // read data in the cache
     2484                    size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
     2485                    size_t way        = r_read_way.read();
     2486
     2487                    m_cache_data.read_line(way, set, r_read_data);
     2488
     2489                    // update the cache directory
     2490                    DirectoryEntry entry;
     2491                    entry.valid   = true;
     2492                    entry.cache_coherent = r_read_coherent.read() or inst_read or (!(cached_read)) or (r_read_copy.read() != m_cmd_read_srcid_fifo.read());
     2493                    r_read_coherent = r_read_coherent.read() or inst_read or (!(cached_read)) or (r_read_copy.read() != m_cmd_read_srcid_fifo.read());
     2494                    entry.is_cnt  = is_cnt;
     2495                    entry.dirty   = r_read_dirty.read();
     2496                    entry.tag     = r_read_tag.read();
     2497                    entry.lock    = r_read_lock.read();
     2498                    entry.ptr     = r_read_ptr.read();
     2499                    if(cached_read)   // Cached read => we must update the copies
     2500                    {
     2501                        if(!is_cnt)  // Not counter mode
     2502                        {
     2503                            entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2504                            entry.owner.inst     = inst_read;
     2505                            entry.count          = r_read_count.read() + 1;
     2506                        }
     2507                        else  // Counter mode
     2508                        {
     2509                            entry.owner.srcid    = 0;
     2510                            entry.owner.inst     = false;
     2511                            entry.count          = r_read_count.read() + 1;
     2512                        }
     2513                    }
     2514                    else            // Uncached read
     2515                    {
     2516                        entry.owner.srcid     = r_read_copy.read();
     2517                        entry.owner.inst      = r_read_copy_inst.read();
     2518                        entry.count           = r_read_count.read();
     2519                    }
     2520
     2521#if DEBUG_MEMC_READ
     2522                    if(m_debug)
     2523                        std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
     2524                            << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
     2525                            << " / set = " << std::dec << set
     2526                            << " / way = " << way
     2527                            << " / owner_id = " << std::hex << entry.owner.srcid
     2528                            << " / owner_ins = " << std::dec << entry.owner.inst
     2529                            << " / coherent = " << entry.cache_coherent
     2530                            << " / count = " << entry.count
     2531                            << " / is_cnt = " << entry.is_cnt << std::endl;
     2532#endif
     2533
     2534                    m_cache_directory.write(set, way, entry);
     2535                    r_read_fsm    = READ_RSP;
     2536                    break;
     2537                }
     2538                ///////////////////
     2539            case READ_HEAP_REQ:    // Get the lock to the HEAP directory
     2540                {
     2541                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2542                    {
     2543                        r_read_fsm = READ_HEAP_LOCK;
     2544                        m_cpt_read_fsm_n_heap_lock++;
     2545                    }
     2546
     2547#if DEBUG_MEMC_READ
     2548                    if(m_debug)
     2549                        std::cout << "  <MEMC " << name() << " READ_HEAP_REQ>"
     2550                            << " Requesting HEAP lock " << std::endl;
     2551#endif
     2552
     2553                    m_cpt_read_fsm_heap_lock++;
     2554
     2555                    break;
     2556                }
     2557
     2558                ////////////////////
     2559            case READ_HEAP_LOCK:   // read data in cache, update the directory
     2560                // and prepare the HEAP update
     2561                {
     2562                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2563                    {
     2564                        // enter counter mode when we reach the limit of copies or the heap is full
     2565                        bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full();
     2566
     2567                        if (!r_read_coherent.read())
     2568                        {
     2569                            std::cout << "Address = " << std::hex << (m_cmd_read_addr_fifo.read()) << std::dec << " |count = " << r_read_count.read() << std::endl;
     2570                        }
     2571                        assert (r_read_coherent.read() && "accÚs au heap sur ncc");
     2572                        // read data in the cache
     2573                        size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
     2574                        size_t way = r_read_way.read();
     2575
     2576                        m_cache_data.read_line(way, set, r_read_data);
     2577
     2578                        // update the cache directory
     2579                        DirectoryEntry entry;
     2580                        entry.valid  = true;
     2581                        entry.cache_coherent = r_read_coherent.read();
     2582                        entry.is_cnt = go_cnt;
     2583                        entry.dirty  = r_read_dirty.read();
     2584                        entry.tag    = r_read_tag.read();
     2585                        entry.lock   = r_read_lock.read();
     2586                        entry.count  = r_read_count.read() + 1;
     2587
     2588                        if(not go_cnt)         // Not entering counter mode
     2589                        {
     2590                            entry.owner.srcid    = r_read_copy.read();
     2591                            entry.owner.inst     = r_read_copy_inst.read();
     2592                            entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
     2593                        }
     2594                        else                // Entering Counter mode
     2595                        {
     2596                            entry.owner.srcid    = 0;
     2597                            entry.owner.inst     = false;
     2598                            entry.ptr            = 0;
     2599                        }
     2600
     2601                        m_cache_directory.write(set, way, entry);
     2602
     2603                        // prepare the heap update (add an entry, or clear the linked list)
     2604                        if(not go_cnt)      // not switching to counter mode
     2605                        {
     2606                            // We test if the next free entry in the heap is the last
     2607                            HeapEntry heap_entry = m_heap.next_free_entry();
     2608                            r_read_next_ptr      = heap_entry.next;
     2609                            r_read_last_free     = (heap_entry.next == m_heap.next_free_ptr());
     2610
     2611                            r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
     2612                        }
     2613                        else            // switching to counter mode
     2614                        {
     2615                            if(r_read_count.read() >1)              // heap must be cleared
     2616                            {
     2617                                HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2618                                r_read_next_ptr      = m_heap.next_free_ptr();
     2619                                m_heap.write_free_ptr(r_read_ptr.read());
     2620
     2621                                if(next_entry.next == r_read_ptr.read())    // last entry
     2622                                {
     2623                                    r_read_fsm = READ_HEAP_LAST;    // erase the entry
     2624                                }
     2625                                else                                        // not the last entry
     2626                                {
     2627                                    r_read_ptr = next_entry.next;
     2628                                    r_read_fsm = READ_HEAP_ERASE;   // erase the list
     2629                                }
     2630                            }
     2631                            else  // the heap is not used / nothing to do
     2632                            {
     2633                                r_read_fsm = READ_RSP;
     2634                            }
     2635                        }
     2636
     2637#if DEBUG_MEMC_READ
     2638                        if(m_debug)
     2639                            std::cout << "  <MEMC " << name() << " READ_HEAP_LOCK> Update directory:"
     2640                                << " tag = " << std::hex << entry.tag
     2641                                << " set = " << std::dec << set
     2642                                << " way = " << way
     2643                                << " count = " << entry.count
     2644                                << " is_cnt = " << entry.is_cnt << std::endl;
     2645#endif
     2646                    }
     2647                    else
     2648                    {
     2649                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK"
     2650                            << "Bad HEAP allocation"   << std::endl;
     2651                        exit(0);
     2652                    }
     2653                    break;
     2654                }
     2655                /////////////////////
     2656            case READ_HEAP_WRITE:       // add an entry in the heap
     2657                {
     2658                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2659                    {
     2660                        HeapEntry heap_entry;
     2661                        heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2662                        heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2663
     2664                        if(r_read_count.read() == 1)  // creation of a new linked list
     2665                        {
     2666                            heap_entry.next         = m_heap.next_free_ptr();
     2667                        }
     2668                        else                         // head insertion in existing list
     2669                        {
     2670                            heap_entry.next         = r_read_ptr.read();
     2671                        }
     2672                        m_heap.write_free_entry(heap_entry);
     2673                        m_heap.write_free_ptr(r_read_next_ptr.read());
     2674                        if(r_read_last_free.read())  m_heap.set_full();
     2675
     2676                        r_read_fsm = READ_RSP;
     2677
     2678#if DEBUG_MEMC_READ
     2679                        if(m_debug)
     2680                            std::cout << "  <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:"
     2681                                << " owner_id = " << std::hex << heap_entry.owner.srcid
     2682                                << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl;
     2683#endif
     2684                    }
     2685                    else
     2686                    {
     2687                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE"
     2688                            << "Bad HEAP allocation" << std::endl;
     2689                        exit(0);
     2690                    }
     2691                    break;
     2692                }
     2693                /////////////////////
     2694            case READ_HEAP_ERASE:
     2695                {
     2696                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2697                    {
     2698                        HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2699                        if(next_entry.next == r_read_ptr.read())
     2700                        {
     2701                            r_read_fsm = READ_HEAP_LAST;
     2702                        }
     2703                        else
     2704                        {
     2705                            r_read_ptr = next_entry.next;
     2706                            r_read_fsm = READ_HEAP_ERASE;
     2707                        }
     2708                    }
     2709                    else
     2710                    {
     2711                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE"
     2712                            << "Bad HEAP allocation" << std::endl;
     2713                        exit(0);
     2714                    }
     2715                    break;
     2716                }
     2717
     2718                ////////////////////
     2719            case READ_HEAP_LAST:
     2720                {
     2721                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2722                    {
     2723                        HeapEntry last_entry;
     2724                        last_entry.owner.srcid    = 0;
     2725                        last_entry.owner.inst     = false;
     2726
     2727                        if(m_heap.is_full())
     2728                        {
     2729                            last_entry.next       = r_read_ptr.read();
     2730                            m_heap.unset_full();
     2731                        }
     2732                        else
     2733                        {
     2734                            last_entry.next       = r_read_next_ptr.read();
     2735                        }
     2736                        m_heap.write(r_read_ptr.read(),last_entry);
     2737                        r_read_fsm = READ_RSP;
     2738                    }
     2739                    else
     2740                    {
     2741                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST"
     2742                            << "Bad HEAP allocation" << std::endl;
     2743                        exit(0);
     2744                    }
     2745                    break;
     2746                }
     2747                //////////////
     2748            case READ_RSP:    //  request the TGT_RSP FSM to return data
     2749                {
     2750                    if(!r_read_to_tgt_rsp_req)
     2751                    {
     2752                        for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
     2753                        r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2754                        r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     2755                        r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     2756                        /*RWT*/
     2757                        //BUG pktid
     2758                        if (r_read_coherent.read())
     2759                        {
     2760                            r_read_to_tgt_rsp_pktid = 0x0 + m_cmd_read_pktid_fifo.read();
     2761                            //std::cout << "READ RSP COHERENT on word" << std::hex << m_x[(addr_t) m_cmd_read_addr_fifo.read()] << std::dec << std::endl;
     2762                        }
     2763                        else
     2764                        {
     2765                            r_read_to_tgt_rsp_pktid = 0x8 + m_cmd_read_pktid_fifo.read();
     2766                        }
     2767                        r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     2768                        r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     2769                        cmd_read_fifo_get        = true;
     2770                        r_read_to_tgt_rsp_req    = true;
     2771                        r_read_fsm               = READ_IDLE;
     2772
     2773#if DEBUG_MEMC_READ
     2774                        if(m_debug)
     2775                            std::cout << "  <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:"
     2776                                << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
     2777                                << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     2778                                << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2779#endif
     2780                    }
     2781                    break;
     2782                }
     2783                ///////////////////
     2784            case READ_TRT_LOCK: // read miss : check the Transaction Table
     2785                {
     2786                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2787                    {
     2788                        size_t      index     = 0;
     2789                        addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
     2790                        bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
     2791                        bool        hit_write = m_trt.hit_write(m_nline[addr]);
     2792                        bool        wok       = !m_trt.full(index);
     2793
     2794                        if(hit_read or !wok or hit_write)    // missing line already requested or no space
     2795                        {
     2796                            if(!wok)
     2797                            {
     2798                                m_cpt_trt_full++;
     2799                            }
     2800                            if(hit_read or hit_write)   m_cpt_trt_rb++;
     2801                            r_read_fsm = READ_IDLE;
     2802                        }
     2803                        else                  // missing line is requested to the XRAM
     2804                        {
     2805                            m_cpt_read_miss++;
     2806                            r_read_trt_index = index;
     2807                            r_read_fsm       = READ_TRT_SET;
     2808                        }
     2809
     2810#if DEBUG_MEMC_READ
     2811                        if(m_debug)
     2812                            std::cout << "  <MEMC " << name() << " READ_TRT_LOCK> Check TRT:"
     2813                                << " hit_read = " << hit_read
     2814                                << " / hit_write = " << hit_write
     2815                                << " / full = " << !wok << std::endl;
     2816                        m_cpt_read_fsm_n_trt_lock++;
     2817#endif
     2818                    }
     2819
     2820                    m_cpt_read_fsm_trt_lock++;
     2821
     2822                    break;
     2823                }
     2824
     2825                //////////////////
     2826            case READ_TRT_SET:      // register get transaction in TRT
     2827                {
     2828                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2829                    {
     2830                        m_trt.set(r_read_trt_index.read(),
     2831                                true,
     2832                                m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
     2833                                m_cmd_read_srcid_fifo.read(),
     2834                                m_cmd_read_trdid_fifo.read(),
     2835                                m_cmd_read_pktid_fifo.read(),
     2836                                true,
     2837                                m_cmd_read_length_fifo.read(),
     2838                                m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
     2839                                std::vector<be_t> (m_words,0),
     2840                                std::vector<data_t> (m_words,0),
     2841                                r_read_ll_key.read());
     2842
     2843#if DEBUG_MEMC_READ
     2844                        if(m_debug)
     2845                            std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TGT:"
     2846                                << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     2847                                << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
     2848#endif
     2849                        r_read_fsm = READ_TRT_REQ;
     2850                    }
     2851                    break;
     2852                }
     2853
     2854                //////////////////
     2855            case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
     2856                {
     2857                    if(not r_read_to_ixr_cmd_req)
     2858                    {
     2859                        cmd_read_fifo_get       = true;
     2860                        r_read_to_ixr_cmd_req   = true;
     2861                        //r_read_to_ixr_cmd_nline = m_nline[(addr_t)(m_cmd_read_addr_fifo.read())];
     2862                        r_read_to_ixr_cmd_index = r_read_trt_index.read();
     2863                        r_read_fsm              = READ_IDLE;
     2864
     2865#if DEBUG_MEMC_READ
     2866                        if(m_debug)
     2867                            std::cout << "  <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address "
     2868                                << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
     2869#endif
     2870                    }
     2871                    break;
     2872                }
     2873        } // end switch read_fsm
     2874
     2875        ///////////////////////////////////////////////////////////////////////////////////
     2876        //    WRITE FSM
     2877        ///////////////////////////////////////////////////////////////////////////////////
     2878        // The WRITE FSM handles the write bursts and sc requests sent by the processors.
     2879        // All addresses in a burst must be in the same cache line.
     2880        // A complete write burst is consumed in the FIFO & copied to a local buffer.
     2881        // Then the FSM takes the lock protecting the cache directory, to check
     2882        // if the line is in the cache.
     2883        //
     2884        // - In case of HIT, the cache is updated.
     2885        //   If there is no other copy, an acknowledge response is immediately
     2886        //   returned to the writing processor.
     2887        //   If the data is cached by other processors, a coherence transaction must
     2888        //   be launched (sc requests always require a coherence transaction):
     2889        //   It is a multicast update if the line is not in counter mode: the processor
     2890        //   takes the lock protecting the Update Table (UPT) to register this transaction.
     2891        //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
     2892        //   a multi-update request to all owners of the line (but the writer),
     2893        //   through the CC_SEND FSM. In case of coherence transaction, the WRITE FSM
     2894        //   does not respond to the writing processor, as this response will be sent by
     2895        //   the MULTI_ACK FSM when all update responses have been received.
     2896        //   It is a broadcast invalidate if the line is in counter mode: The line
     2897        //   should be erased in memory cache, and written in XRAM with a PUT transaction,
     2898        //   after registration in TRT.
     2899        //
     2900        // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
     2901        //   table (TRT). If a read transaction to the XRAM for this line already exists,
     2902        //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
     2903        //   the WRITE FSM register a new transaction in TRT, and sends a GET request
     2904        //   to the XRAM. If the TRT is full, it releases the lock, and waits.
     2905        //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
     2906        /////////////////////////////////////////////////////////////////////////////////////
     2907
     2908        switch(r_write_fsm.read())
     2909        {
     2910            ////////////////
     2911            case WRITE_IDLE:  // copy first word of a write burst in local buffer
     2912                {
     2913                    if (not m_cmd_write_addr_fifo.rok()) break;
     2914                    // consume a word in the FIFO & write it in the local buffer
     2915                    cmd_write_fifo_get  = true;
     2916                    size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     2917
     2918                    r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     2919                    r_write_word_index  = index;
     2920                    r_write_word_count  = 0;
     2921                    r_write_data[index] = m_cmd_write_data_fifo.read();
     2922                    r_write_srcid       = m_cmd_write_srcid_fifo.read();
     2923                    r_write_trdid       = m_cmd_write_trdid_fifo.read();
     2924                    r_write_pktid       = m_cmd_write_pktid_fifo.read();
     2925
     2926                    // if SC command, get the SC key
     2927                    if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     2928                    {
     2929                        assert( not m_cmd_write_eop_fifo.read() &&
     2930                                "MEMC ERROR in WRITE_IDLE state: "
     2931                                "invalid packet format for SC command");
     2932
     2933                        r_write_sc_key = m_cmd_write_data_fifo.read();
     2934                    }
     2935                    // initialize the be field for all words
     2936                    for(size_t word=0 ; word<m_words ; word++)
     2937                    {
     2938                        if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     2939                        else              r_write_be[word] = 0x0;
     2940                    }
     2941
     2942                    if (m_cmd_write_eop_fifo.read())
     2943                    {
     2944                        r_write_fsm = WRITE_DIR_REQ;
     2945                    }
     2946                    else
     2947                    {
     2948                        r_write_fsm = WRITE_NEXT;
     2949                    }
     2950
     2951#if DEBUG_MEMC_WRITE
     2952                    if(m_debug)
     2953                        std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
     2954                            << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
     2955                            << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
     2956                            << " / data = " << m_cmd_write_data_fifo.read()
     2957                            << " / pktid = " << m_cmd_write_pktid_fifo.read()
     2958                            << std::endl;
     2959#endif
     2960                    break;
     2961                }
     2962
     2963                ////////////////
     2964            case WRITE_NEXT:  // copy next word of a write burst in local buffer
     2965                {
     2966                    if (not m_cmd_write_addr_fifo.rok()) break;
     2967
     2968                    // check that the next word is in the same cache line
     2969                    assert((m_nline[(addr_t)(r_write_address.read())] ==
     2970                                m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) &&
     2971                            "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
     2972
     2973                    size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     2974                    bool   is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC);
     2975
     2976                    // check that SC command has constant address
     2977                    assert((not is_sc or (index == r_write_word_index)) &&
     2978                            "MEMC ERROR in WRITE_NEXT state: "
     2979                            "the address must be constant on a SC command");
     2980
     2981                    // check that SC command has two flits
     2982                    assert((not is_sc or m_cmd_write_eop_fifo.read()) &&
     2983                            "MEMC ERROR in WRITE_NEXT state: "
     2984                            "invalid packet format for SC command");
     2985                    // consume a word in the FIFO & write it in the local buffer
     2986                    cmd_write_fifo_get  = true;
     2987
     2988                    r_write_be[index]   = m_cmd_write_be_fifo.read();
     2989                    r_write_data[index] = m_cmd_write_data_fifo.read();
     2990
     2991                    // the first flit of a SC command is the reservation key and
     2992                    // therefore it must not be counted as a data to write
     2993                    if (not is_sc)
     2994                    {
     2995                        r_write_word_count = r_write_word_count.read() + 1;
     2996                    }
     2997
     2998                    if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
     2999
     3000#if DEBUG_MEMC_WRITE
     3001                    if (m_debug)
     3002                        std::cout << "  <MEMC " << name()
     3003                            << " WRITE_NEXT> Write another word in local buffer"
     3004                            << std::endl;
     3005#endif
     3006                    break;
     3007                }
     3008
     3009                ////////////////////
     3010            case WRITE_DIR_REQ:
     3011                {
     3012                    // Get the lock to the directory
     3013                    // and access the llsc_global_table
     3014                    if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break;
     3015
     3016                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3017                    {
     3018                        // test address and key match of the SC command on the
     3019                        // LL/SC table without removing reservation. The reservation
     3020                        // will be erased after in this FSM.
     3021                        bool sc_success = m_llsc_table.check(r_write_address.read(),
     3022                                r_write_sc_key.read());
     3023
     3024                        r_write_sc_fail     = not sc_success;
     3025
     3026                        if (not sc_success) r_write_fsm = WRITE_RSP;
     3027                        else                r_write_fsm = WRITE_DIR_LOCK;
     3028                    }
     3029                    else
     3030                    {
     3031                        // write burst
     3032#define L2 soclib::common::uint32_log2
     3033                        addr_t min = r_write_address.read();
     3034                        addr_t max = r_write_address.read() +
     3035                            (r_write_word_count.read() << L2(vci_param_int::B));
     3036#undef L2
     3037
     3038                        m_llsc_table.sw(min, max);
     3039
     3040                        r_write_fsm = WRITE_DIR_LOCK;
     3041                    }
     3042
     3043#if DEBUG_MEMC_WRITE
     3044                    if(m_debug)
     3045                        std::cout << "  <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock "
     3046                            << std::endl;
     3047#endif
     3048                    break;
     3049                }
     3050
     3051                ////////////////////
     3052            case WRITE_DIR_LOCK:     // access directory to check hit/miss
     3053                {
     3054                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3055                            "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation");
     3056                    size_t  way = 0;
     3057                    DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
     3058
     3059                    if(entry.valid)    // hit
     3060                    {
     3061                        // copy directory entry in local buffer in case of hit
     3062                        r_write_is_cnt     = entry.is_cnt;
     3063                        r_write_lock       = entry.lock;
     3064                        r_write_tag        = entry.tag;
     3065                        r_write_copy       = entry.owner.srcid;
     3066                        r_write_copy_inst  = entry.owner.inst;
     3067                        r_write_count      = entry.count;
     3068                        r_write_ptr        = entry.ptr;
     3069                        r_write_way        = way;
     3070
     3071                        r_write_coherent   = entry.cache_coherent;
     3072
     3073                        if (entry.cache_coherent or (entry.owner.srcid == r_write_srcid.read()) or (entry.count == 0)) // hit WT
     3074                        {
     3075                            if(entry.is_cnt && entry.count)
     3076                            {
     3077                                r_write_fsm = WRITE_BC_DIR_READ;
     3078                            }
     3079                            else
     3080                            {
     3081                                r_write_fsm = WRITE_DIR_HIT;
     3082                            }
     3083                        }
     3084                        else
     3085                        {
     3086                            if (r_write_to_cleanup_req.read())//inval already sent
     3087                            {
     3088                                r_write_fsm = WRITE_WAIT;
     3089                            }
     3090                            else // hit on a NCC line with a different owner
     3091                            {
     3092                                r_write_fsm = WRITE_IVT_LOCK_HIT_WB;
     3093                                //            if(r_write_pktid.read() == TYPE_SC)
     3094                                //            {
     3095                                //              r_write_sc_fail = true;
     3096                                //            }
     3097                            }
     3098                        }
     3099                    }
     3100                    else  // miss
     3101                    {
     3102                        r_write_fsm = WRITE_MISS_IVT_LOCK;
     3103                    }
     3104
     3105#if DEBUG_MEMC_WRITE
     3106                    if(m_debug)
     3107                    {
     3108                        std::cout << "  <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: "
     3109                            << " address = " << std::hex << r_write_address.read()
     3110                            << " / hit = " << std::dec << entry.valid
     3111                            << " / count = " << entry.count
     3112                            << " / is_cnt = " << entry.is_cnt ;
     3113                        if((r_write_pktid.read() & 0x7) == TYPE_SC)
     3114                            std::cout << " / SC access" << std::endl;
     3115                        else
     3116                            std::cout << " / SW access" << std::endl;
     3117                    }
     3118#endif
     3119                    break;
     3120                }
     3121                ////////////////////
     3122            case WRITE_IVT_LOCK_HIT_WB:
     3123                {
     3124                    if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     3125                    {
     3126
     3127                        size_t index = 0;
     3128                        bool   match_inval;
     3129                        addr_t nline = m_nline[(addr_t)(r_write_address.read())];
     3130
     3131                        //std::cout << "WRITE on NCC on line" << std::hex << nline << std::dec << std::endl;
     3132                        //if there is a matched updt req, we should wait until it is over. Because
     3133                        //we need the lastest updt data.
     3134                        match_inval = m_ivt.search_inval(nline, index);
     3135
     3136                        assert ((r_write_count.read() == 1) and "NCC to CC req without copy");
     3137                        if(!match_inval and !r_write_to_cc_send_req.read())
     3138                        {
     3139                            r_write_to_cc_send_req = true;
     3140                            r_write_to_cc_send_dest = r_write_copy;
     3141                            r_write_to_cc_send_nline = nline;
     3142                            r_write_to_cleanup_req = true;
     3143                            r_write_to_cleanup_nline = nline;
     3144
     3145                            m_ivt.set(false,  // it's an inval transaction
     3146                                    false,     // it's not a broadcast
     3147                                    true,      // it needs no read response
     3148                                    false,     // no acknowledge required
     3149                                    m_cmd_write_srcid_fifo.read(), //never read, used for debug
     3150                                    m_cmd_write_trdid_fifo.read(), //never read, used for debug
     3151                                    m_cmd_write_pktid_fifo.read(), //never read, used for debug
     3152                                    nline,
     3153                                    0x1, //Expect only one answer
     3154                                    index);
     3155                        }
     3156                        r_write_fsm = WRITE_WAIT;
     3157#if DEBUG_MEMC_WRITE
     3158                        if(m_debug)
     3159                        {
     3160                            std::cout << "  <MEMC " << name() << " WRITE_IVT_LOCK_HIT_WB> get access to the UPT: "
     3161                                << " Inval requested =  " << (!match_inval and !r_write_to_cc_send_req.read())
     3162                                << std::endl;
     3163                        }
     3164#endif
     3165                    }
     3166#if DEBUG_MEMC_WRITE
     3167                    if(m_debug)
     3168                    {
     3169                        std::cout << "  <MEMC " << name() << " WRITE_IVT_LOCK_HIT_WB> failed to access to the UPT: "
     3170                            << std::endl;
     3171                    }
     3172#endif
     3173                    break;
     3174                }
     3175
     3176                ///////////////////
     3177            case WRITE_DIR_HIT:
     3178                {
     3179                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3180                            "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation");
     3181
     3182                    // update the cache directory
     3183                    // update directory with Dirty bit
     3184                    DirectoryEntry entry;
     3185                    entry.valid          = true;
     3186                    entry.cache_coherent = r_write_coherent.read();
     3187                    entry.dirty          = true;
     3188                    entry.tag            = r_write_tag.read();
     3189                    entry.is_cnt         = r_write_is_cnt.read();
     3190                    entry.lock           = r_write_lock.read();
     3191                    entry.owner.srcid    = r_write_copy.read();
     3192                    entry.owner.inst     = r_write_copy_inst.read();
     3193                    entry.count          = r_write_count.read();
     3194                    entry.ptr            = r_write_ptr.read();
     3195
     3196                    size_t set           = m_y[(addr_t)(r_write_address.read())];
     3197                    size_t way           = r_write_way.read();
     3198
     3199                    // update directory
     3200                    m_cache_directory.write(set, way, entry);
     3201
     3202                    // owner is true when the  the first registered copy is the writer itself
     3203                    bool owner = (((r_write_copy.read() == r_write_srcid.read())
     3204                                ) and not r_write_copy_inst.read());
     3205
     3206                    // no_update is true when there is no need for coherence transaction
     3207                    bool no_update = ( (r_write_count.read() == 0) or
     3208                            (owner and (r_write_count.read() == 1) and
     3209                             ((r_write_pktid.read() & 0x7) != TYPE_SC)));
     3210
     3211                    // write data in the cache if no coherence transaction
     3212                    if(no_update)
     3213                    {
     3214                        // SC command but zero copies
     3215                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3216                        {
     3217                            m_llsc_table.sc(r_write_address.read(),
     3218                                    r_write_sc_key.read());
     3219                        }
     3220
     3221                        for(size_t word=0 ; word<m_words ; word++)
     3222                        {
     3223                            m_cache_data.write(way, set, word, r_write_data[word].read(), r_write_be[word].read());
     3224
     3225                        }
     3226                    }
     3227
     3228                    if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC))
     3229                    {
     3230                        r_write_count = r_write_count.read() - 1;
     3231                    }
     3232
     3233                    if(no_update)
     3234                        // Write transaction completed
     3235                    {
     3236                        r_write_fsm = WRITE_RSP;
     3237                    }
     3238                    else
     3239                        // coherence update required
     3240                    {
     3241                        if(!r_write_to_cc_send_multi_req.read() and
     3242                                !r_write_to_cc_send_brdcast_req.read())
     3243                        {
     3244                            r_write_fsm = WRITE_UPT_LOCK;
     3245                        }
     3246                        else
     3247                        {
     3248                            r_write_fsm = WRITE_WAIT;
     3249                        }
     3250                    }
     3251
     3252#if DEBUG_MEMC_WRITE
     3253                    if(m_debug)
     3254                    {
     3255                        if(no_update)
     3256                        {
     3257                            std::cout << "  <MEMC " << name()
     3258                                << " WRITE_DIR_HIT> Write into cache / No coherence transaction"
     3259                                << std::endl;
     3260                        }
     3261                        else
     3262                        {
     3263                            std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
     3264                                << " is_cnt = " << r_write_is_cnt.read()
     3265                                << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
     3266                            if(owner) std::cout << "       ... but the first copy is the writer" << std::endl;
     3267                        }
     3268                    }
     3269#endif
     3270                    break;
     3271                }
     3272                ////////////////////
     3273            case WRITE_UPT_LOCK:  // Try to register the update request in UPT
     3274                {
     3275                    if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
     3276                    {
     3277                        bool        wok        = false;
     3278                        size_t      index      = 0;
     3279                        size_t      srcid      = r_write_srcid.read();
     3280                        size_t      trdid      = r_write_trdid.read();
     3281                        size_t      pktid      = r_write_pktid.read();
     3282                        addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
     3283                        size_t      nb_copies  = r_write_count.read();
     3284                        size_t      set        = m_y[(addr_t)(r_write_address.read())];
     3285                        size_t      way        = r_write_way.read();
     3286
     3287
     3288                        wok = m_upt.set(true,  // it's an update transaction
     3289                                false, // it's not a broadcast
     3290                                true,  // response required
     3291                                false, // no acknowledge required
     3292                                srcid,   
     3293                                trdid,
     3294                                pktid,
     3295                                nline,
     3296                                nb_copies,
     3297                                index);
     3298                        if(wok)       // write data in cache
     3299                        {
     3300
     3301                            if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3302                            {
     3303                                m_llsc_table.sc(r_write_address.read(),
     3304                                        r_write_sc_key.read());
     3305                            }
     3306
     3307                            for(size_t word=0 ; word<m_words ; word++)
     3308                            {
     3309                                m_cache_data.write(way,
     3310                                        set,
     3311                                        word,
     3312                                        r_write_data[word].read(),
     3313                                        r_write_be[word].read());
     3314
     3315                            }
     3316                        }
     3317
     3318#if DEBUG_MEMC_WRITE
     3319                        if(m_debug and wok)
     3320                        {
     3321                            if(wok)
     3322                            {
     3323                                std::cout << "  <MEMC " << name()
     3324                                    << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
     3325                                    << " nb_copies = " << r_write_count.read() << std::endl;
     3326                            }
     3327                        }
     3328#endif
     3329                        r_write_upt_index = index;
     3330                        //  releases the lock protecting UPT and the DIR if no entry...
     3331                        if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
     3332                        else    r_write_fsm = WRITE_WAIT;
     3333                        m_cpt_write_fsm_n_upt_lock++;
     3334                    }
     3335
     3336                    m_cpt_write_fsm_upt_lock++;
     3337
     3338                    break;
     3339                }
     3340
     3341                /////////////////////////
     3342            case WRITE_UPT_HEAP_LOCK:   // get access to heap
     3343                {
     3344                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE)
     3345                    {
     3346
     3347#if DEBUG_MEMC_WRITE
     3348                        if(m_debug)
     3349                            std::cout << "  <MEMC " << name()
     3350                                << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
     3351#endif
     3352                        r_write_fsm = WRITE_UPT_REQ;
     3353                        m_cpt_write_fsm_n_heap_lock++;
     3354                    }
     3355
     3356                    m_cpt_write_fsm_heap_lock++;
     3357
     3358                    break;
     3359                }
     3360
     3361                //////////////////
     3362            case WRITE_UPT_REQ:    // prepare the coherence transaction for the CC_SEND FSM
     3363                // and write the first copy in the FIFO
     3364                // send the request if only one copy
     3365                {
     3366                    assert(not r_write_to_cc_send_multi_req.read()   and
     3367                            not r_write_to_cc_send_brdcast_req.read() and
     3368                            "Error in VCI_MEM_CACHE : pending multicast or broadcast\n"
     3369                            "transaction in WRITE_UPT_REQ state"
     3370                          );
     3371
     3372
     3373                    r_write_to_cc_send_brdcast_req  = false;
     3374                    r_write_to_cc_send_trdid        = r_write_upt_index.read();
     3375                    r_write_to_cc_send_nline        = m_nline[(addr_t)(r_write_address.read())];
     3376                    r_write_to_cc_send_index        = r_write_word_index.read();
     3377                    r_write_to_cc_send_count        = r_write_word_count.read();
     3378
     3379                    for(size_t i=0; i<m_words ; i++) r_write_to_cc_send_be[i]=r_write_be[i].read();
     3380
     3381                    size_t min = r_write_word_index.read();
     3382                    size_t max = r_write_word_index.read() + r_write_word_count.read();
     3383                    for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
     3384
     3385                    if ((r_write_copy.read() != r_write_srcid.read()) or
     3386                            ((r_write_pktid.read() & 0x7) == TYPE_SC)      or
     3387                            r_write_copy_inst.read())
     3388                    {
     3389                        // put the first srcid in the fifo
     3390                        write_to_cc_send_fifo_put     = true;
     3391                        write_to_cc_send_fifo_inst    = r_write_copy_inst.read();
     3392                        write_to_cc_send_fifo_srcid   = r_write_copy.read();
     3393                        if(r_write_count.read() == 1)
     3394                        {
     3395                            r_write_fsm = WRITE_IDLE;
     3396                            r_write_to_cc_send_multi_req = true;
     3397                        }
     3398                        else
     3399                        {
     3400                            r_write_fsm = WRITE_UPT_NEXT;
     3401                            r_write_to_dec = false;
     3402
     3403                        }
     3404                    }
     3405                    else
     3406                    {
     3407                        r_write_fsm = WRITE_UPT_NEXT;
     3408                        r_write_to_dec = false;
     3409                    }
     3410
     3411#if DEBUG_MEMC_WRITE
     3412                    if(m_debug)
     3413                    {
     3414                        std::cout
     3415                            << "  <MEMC "    << name()
     3416                            << " WRITE_UPT_REQ> Post first request to CC_SEND FSM"
     3417                            << " / srcid = " << std::dec << r_write_copy.read()
     3418                            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3419
     3420                        if(r_write_count.read() == 1)
     3421                            std::cout << "         ... and this is the last" << std::endl;
     3422                    }
     3423#endif
     3424                    break;
     3425                }
     3426
     3427                ///////////////////
     3428            case WRITE_UPT_NEXT:
     3429                {
     3430                    // continue the multi-update request to CC_SEND fsm
     3431                    // when there is copies in the heap.
     3432                    // if one copy in the heap is the writer itself
     3433                    // the corresponding SRCID should not be written in the fifo,
     3434                    // but the UPT counter must be decremented.
     3435                    // As this decrement is done in the WRITE_UPT_DEC state,
     3436                    // after the last copy has been found, the decrement request
     3437                    // must be  registered in the r_write_to_dec flip-flop.
     3438
     3439                    HeapEntry entry = m_heap.read(r_write_ptr.read());
     3440
     3441                    bool dec_upt_counter;
     3442
     3443                    // put the next srcid in the fifo
     3444                    if ((entry.owner.srcid != r_write_srcid.read()) or
     3445                            ((r_write_pktid.read() & 0x7) == TYPE_SC)    or
     3446                            entry.owner.inst)
     3447                    {
     3448                        dec_upt_counter                = false;
     3449                        write_to_cc_send_fifo_put      = true;
     3450                        write_to_cc_send_fifo_inst     = entry.owner.inst;
     3451                        write_to_cc_send_fifo_srcid    = entry.owner.srcid;
     3452
     3453#if DEBUG_MEMC_WRITE
     3454                        if(m_debug)
     3455                        {
     3456                            std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM"
     3457                                << " / heap_index = " << std::dec << r_write_ptr.read()
     3458                                << " / srcid = " << std::dec << r_write_copy.read()
     3459                                << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3460                            if(entry.next == r_write_ptr.read())
     3461                                std::cout << "        ... and this is the last" << std::endl;
     3462                        }
     3463#endif
     3464                    }
     3465                    else                                // the UPT counter must be decremented
     3466                    {
     3467                        dec_upt_counter = true;
     3468
     3469#if DEBUG_MEMC_WRITE
     3470                        if(m_debug)
     3471                        {
     3472                            std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer"
     3473                                << " / heap_index = " << std::dec << r_write_ptr.read()
     3474                                << " / srcid = " << std::dec << r_write_copy.read()
     3475                                << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3476                            if(entry.next == r_write_ptr.read())
     3477                                std::cout << "        ... and this is the last" << std::endl;
     3478                        }
     3479#endif
     3480                    }
     3481
     3482                    // register the possible UPT decrement request
     3483                    r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
     3484
     3485                    if(not m_write_to_cc_send_inst_fifo.wok())
     3486                    {
     3487                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
     3488                            << "The write_to_cc_send_fifo should not be full" << std::endl
     3489                            << "as the depth should be larger than the max number of copies" << std::endl;
     3490                        exit(0);
     3491                    }
     3492
     3493                    r_write_ptr = entry.next;
     3494
     3495                    if(entry.next == r_write_ptr.read())    // last copy
     3496                    {
     3497                        r_write_to_cc_send_multi_req = true;
     3498                        if(r_write_to_dec.read() or dec_upt_counter)  r_write_fsm = WRITE_UPT_DEC;
     3499                        else                                          r_write_fsm = WRITE_IDLE;
     3500                    }
     3501                    break;
     3502                }
     3503
     3504                //////////////////
     3505            case WRITE_UPT_DEC:
     3506                {
     3507                    // If the initial writer has a copy, it should not
     3508                    // receive an update request, but the counter in the
     3509                    // update table must be decremented by the MULTI_ACK FSM.
     3510
     3511                    if(!r_write_to_multi_ack_req.read())
     3512                    {
     3513                        r_write_to_multi_ack_req = true;
     3514                        r_write_to_multi_ack_upt_index = r_write_upt_index.read();
     3515                        r_write_fsm = WRITE_IDLE;
     3516                    }
     3517                    break;
     3518                }
     3519
     3520                ///////////////
     3521            case WRITE_RSP:
     3522                {
     3523                    // Post a request to TGT_RSP FSM to acknowledge the write
     3524                    // In order to increase the Write requests throughput,
     3525                    // we don't wait to return in the IDLE state to consume
     3526                    // a new request in the write FIFO
     3527
     3528                    if (not r_write_to_tgt_rsp_req.read())
     3529                    {
     3530                        // post the request to TGT_RSP_FSM
     3531                        r_write_to_tgt_rsp_req     = true;
     3532                        r_write_to_tgt_rsp_srcid   = r_write_srcid.read();
     3533                        r_write_to_tgt_rsp_trdid   = r_write_trdid.read();
     3534                        r_write_to_tgt_rsp_pktid   = r_write_pktid.read();
     3535                        r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read();
     3536
     3537                        // try to get a new write request from the FIFO
     3538                        if (not m_cmd_write_addr_fifo.rok())
     3539                        {
     3540                            r_write_fsm = WRITE_IDLE;
     3541                        }
     3542                        else
     3543                        {
     3544                            // consume a word in the FIFO & write it in the local buffer
     3545                            cmd_write_fifo_get  = true;
     3546                            size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     3547
     3548                            r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     3549                            r_write_word_index  = index;
     3550                            r_write_word_count  = 0;
     3551                            r_write_data[index] = m_cmd_write_data_fifo.read();
     3552                            r_write_srcid       = m_cmd_write_srcid_fifo.read();
     3553                            r_write_trdid       = m_cmd_write_trdid_fifo.read();
     3554                            r_write_pktid       = m_cmd_write_pktid_fifo.read();
     3555
     3556                            // if SC command, get the SC key
     3557                            if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     3558                            {
     3559                                assert( not m_cmd_write_eop_fifo.read() &&
     3560                                        "MEMC ERROR in WRITE_RSP state: "
     3561                                        "invalid packet format for SC command");
     3562
     3563                                r_write_sc_key = m_cmd_write_data_fifo.read();
     3564                            }
     3565
     3566                            // initialize the be field for all words
     3567                            for(size_t word=0 ; word<m_words ; word++)
     3568                            {
     3569                                if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     3570                                else              r_write_be[word] = 0x0;
     3571                            }
     3572
     3573                            if( m_cmd_write_eop_fifo.read())
     3574                            {
     3575                                r_write_fsm = WRITE_DIR_REQ;
     3576                            }
     3577                            else
     3578                            {
     3579                                r_write_fsm = WRITE_NEXT;
     3580                            }
     3581                        }
     3582
     3583#if DEBUG_MEMC_WRITE
     3584                        if(m_debug)
     3585                        {
     3586                            std::cout << "  <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM"
     3587                                << " : rsrcid = " << std::hex << r_write_srcid.read()
     3588                                << " : rpktid = " << std::hex << r_write_pktid.read()
     3589                                << " : sc_fail= " << std::hex << r_write_sc_fail.read()
     3590                                << std::endl;
     3591                            if(m_cmd_write_addr_fifo.rok())
     3592                            {
     3593                                std::cout << "                    New Write request: "
     3594                                    << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
     3595                                    << " / address = " << m_cmd_write_addr_fifo.read()
     3596                                    << " / data = " << m_cmd_write_data_fifo.read()
     3597                                    << " / pktid = " << m_cmd_write_pktid_fifo.read()
     3598                                    << std::endl;
     3599                            }
     3600                        }
     3601#endif
     3602                    }
     3603                    break;
     3604                }
     3605                ///////////////////////// RWT
     3606            case WRITE_MISS_IVT_LOCK:
     3607                {
     3608                    if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     3609                    {
     3610                        size_t index;
     3611                        if(m_ivt.search_inval(m_nline[(addr_t)(r_write_address.read())], index))
     3612                        {
     3613                            r_write_fsm = WRITE_WAIT;
     3614                        }
     3615                        else
     3616                        {
     3617                            r_write_fsm = WRITE_MISS_TRT_LOCK;
     3618                        }
     3619                    }
     3620                    break;
     3621                }
     3622
     3623                /////////////////////////
     3624            case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table
     3625                {
     3626                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3627                    {
     3628
     3629#if DEBUG_MEMC_WRITE
     3630                        if(m_debug)
     3631                            std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
     3632#endif
     3633                        size_t  hit_index = 0;
     3634                        size_t  wok_index = 0;
     3635                        addr_t  addr  = (addr_t) r_write_address.read();
     3636                        bool    hit_read  = m_trt.hit_read(m_nline[addr], hit_index);
     3637                        bool    hit_write = m_trt.hit_write(m_nline[addr]);
     3638                        bool    wok       = not m_trt.full(wok_index);
     3639
     3640                        // wait an empty entry in TRT
     3641                        if(not hit_read and (not wok or hit_write))
     3642                        {
     3643                            r_write_fsm       = WRITE_WAIT;
     3644                            m_cpt_trt_full++;
     3645
     3646                            break;
     3647                        }
     3648
     3649                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3650                        {
     3651                            m_llsc_table.sc(r_write_address.read(),
     3652                                    r_write_sc_key.read());
     3653                        }
     3654
     3655                        // register the modified data in TRT
     3656                        if (hit_read)
     3657                        {
     3658                            r_write_trt_index = hit_index;
     3659                            r_write_fsm       = WRITE_MISS_TRT_DATA;
     3660                            m_cpt_write_miss++;
     3661                            break;
     3662                        }
     3663                        // set a new entry in TRT
     3664                        if (wok and not hit_write)
     3665                        {
     3666                            r_write_trt_index = wok_index;
     3667                            r_write_fsm       = WRITE_MISS_TRT_SET;
     3668                            m_cpt_write_miss++;
     3669                            break;
     3670                        }
     3671
     3672                        assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached");
     3673                    }
     3674                    break;
     3675                }
     3676
     3677                ////////////////
     3678            case WRITE_WAIT:  // release the locks protecting the shared ressources
     3679                {
     3680
     3681#if DEBUG_MEMC_WRITE
     3682                    if(m_debug)
     3683                        std::cout << "  <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl;
     3684#endif
     3685                    r_write_fsm = WRITE_DIR_REQ;
     3686                    break;
     3687                }
     3688
     3689                ////////////////////////
     3690            case WRITE_MISS_TRT_SET:  // register a new transaction in TRT (Write Buffer)
     3691                {
     3692                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3693                    {
     3694                        std::vector<be_t>   be_vector;
     3695                        std::vector<data_t> data_vector;
     3696                        be_vector.clear();
     3697                        data_vector.clear();
     3698                        for(size_t i=0; i<m_words; i++)
     3699                        {
     3700                            be_vector.push_back(r_write_be[i]);
     3701                            data_vector.push_back(r_write_data[i]);
     3702                        }
     3703                        m_trt.set(r_write_trt_index.read(),
     3704                                true,     // read request to XRAM
     3705                                m_nline[(addr_t)(r_write_address.read())],
     3706                                r_write_srcid.read(),
     3707                                r_write_trdid.read(),
     3708                                r_write_pktid.read(),
     3709                                false,      // not a processor read
     3710                                0,        // not a single word
     3711                                0,            // word index
     3712                                be_vector,
     3713                                data_vector);
     3714                        r_write_fsm = WRITE_MISS_XRAM_REQ;
     3715
     3716#if DEBUG_MEMC_WRITE
     3717                        if(m_debug)
     3718                            std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
     3719#endif
     3720                    }
     3721                    break;
     3722                }
     3723
     3724                /////////////////////////
     3725            case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer)
     3726                {
     3727                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3728                    {
     3729                        std::vector<be_t> be_vector;
     3730                        std::vector<data_t> data_vector;
     3731                        be_vector.clear();
     3732                        data_vector.clear();
     3733                        for(size_t i=0; i<m_words; i++)
     3734                        {
     3735                            be_vector.push_back(r_write_be[i]);
     3736                            data_vector.push_back(r_write_data[i]);
     3737                        }
     3738                        m_trt.write_data_mask(r_write_trt_index.read(),
     3739                                be_vector,
     3740                                data_vector);
     3741                        r_write_fsm = WRITE_RSP;
     3742
     3743#if DEBUG_MEMC_WRITE
     3744                        if(m_debug)
     3745                            std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
     3746#endif
     3747                    }
     3748                    break;
     3749                }
     3750
     3751                /////////////////////////
     3752            case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
     3753                {
     3754                    if(not r_write_to_ixr_cmd_req.read())
     3755                    {
     3756                        r_write_to_ixr_cmd_req   = true;
     3757                        r_write_to_ixr_cmd_index = r_write_trt_index.read();
     3758                        r_write_fsm              = WRITE_RSP;
     3759
     3760#if DEBUG_MEMC_WRITE
     3761                        if(m_debug)
     3762                            std::cout << "  <MEMC " << name()
     3763                                << " WRITE_MISS_XRAM_REQ> Post a GET request to the"
     3764                                << " IXR_CMD FSM" << std::endl;
     3765#endif
     3766                    }
     3767                    break;
     3768                }
     3769
     3770                ///////////////////////
     3771            case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
     3772                // the cache line must be erased in mem-cache, and written
     3773                // into XRAM.
     3774                {
     3775                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3776                            "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
     3777
     3778                    m_cpt_write_broadcast++;
     3779
     3780                    // write enable signal for data buffer.
     3781                    r_write_bc_data_we = true;
     3782
     3783                    r_write_fsm = WRITE_BC_TRT_LOCK;
     3784
     3785#if DEBUG_MEMC_WRITE
     3786                    if (m_debug)
     3787                        std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
     3788                            << " Read the cache to complete local buffer" << std::endl;
     3789#endif
     3790                    break;
     3791                }
     3792                ///////////////////////
     3793            case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
     3794                {
     3795                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3796                            "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
     3797
     3798                    // We read the cache and complete the buffer. As the DATA cache uses a
     3799                    // synchronous RAM, the read DATA request has been performed in the
     3800                    // WRITE_BC_DIR_READ state but the data is available in this state.
     3801                    if (r_write_bc_data_we.read())
     3802                    {
     3803                        size_t set  = m_y[(addr_t)(r_write_address.read())];
     3804                        size_t way  = r_write_way.read();
     3805                        for(size_t word=0 ; word<m_words ; word++)
     3806                        {
     3807                            data_t mask = 0;
     3808                            if(r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
     3809                            if(r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
     3810                            if(r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
     3811                            if(r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
     3812
     3813                            // complete only if mask is not null (for energy consumption)
     3814                            r_write_data[word] =
     3815                                (r_write_data[word].read()         &  mask) |
     3816                                (m_cache_data.read(way, set, word) & ~mask);
     3817                        }
     3818#if DEBUG_MEMC_WRITE
     3819                        if(m_debug)
     3820                            std::cout
     3821                                << "  <MEMC "  << name()
     3822                                << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl;
     3823#endif
     3824                    }
     3825
     3826                    if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE)
     3827                    {
     3828                        // if we loop in this state, the data does not need to be
     3829                        // rewritten (for energy consuption)
     3830                        r_write_bc_data_we = false;
     3831                        break;
     3832                    }
     3833
     3834                    size_t wok_index = 0;
     3835                    bool wok = not m_trt.full(wok_index);
     3836                    if(wok)       // set a new entry in TRT
     3837                    {
     3838                        r_write_trt_index = wok_index;
     3839                        r_write_fsm       = WRITE_BC_IVT_LOCK;
     3840                    }
     3841                    else  // wait an empty entry in TRT
     3842                    {
     3843                        r_write_fsm       = WRITE_WAIT;
     3844                    }
     3845
     3846#if DEBUG_MEMC_WRITE
     3847                    if(m_debug)
     3848                        std::cout << "  <MEMC "  << name()
     3849                            << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok
     3850                            << " / index = " << wok_index << std::endl;
     3851#endif
     3852
     3853                    m_cpt_write_fsm_trt_lock++;
     3854
     3855                    break;
     3856                }
     3857
     3858                //////////////////////
     3859            case WRITE_BC_IVT_LOCK:      // register BC transaction in IVT
     3860                {
     3861                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3862                            "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation");
     3863
     3864                    assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     3865                            "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation");
     3866
     3867                    if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     3868                    {
     3869                        bool        wok       = false;
     3870                        size_t      index     = 0;
     3871                        size_t      srcid     = r_write_srcid.read();
     3872                        size_t      trdid     = r_write_trdid.read();
     3873                        size_t      pktid     = r_write_pktid.read();
     3874                        addr_t      nline     = m_nline[(addr_t)(r_write_address.read())];
     3875                        size_t      nb_copies = r_write_count.read();
     3876
     3877                        wok = m_ivt.set(false,  // it's an inval transaction
     3878                                true,   // it's a broadcast
     3879                                true,   // response required
     3880                                false,  // no acknowledge required
     3881                                srcid,
     3882                                trdid,