Changeset 543 for branches/ODCCP


Ignore:
Timestamp:
Oct 4, 2013, 11:10:51 AM (9 years ago)
Author:
haoliu
Message:

ODCCP vci_mem_cache.cpp cosmetic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

    r541 r543  
    6161namespace soclib { namespace caba {
    6262
    63 const char *tgt_cmd_fsm_str[] =
    64 {
    65   "TGT_CMD_IDLE",
    66   "TGT_CMD_ERROR",
    67   "TGT_CMD_READ",
    68   "TGT_CMD_WRITE",
    69   "TGT_CMD_CAS",
    70   "TGT_CMD_CONFIG"
    71 };
    72 const char *tgt_rsp_fsm_str[] =
    73 {
    74   "TGT_RSP_CONFIG_IDLE",
    75   "TGT_RSP_TGT_CMD_IDLE",
    76   "TGT_RSP_READ_IDLE",
    77   "TGT_RSP_WRITE_IDLE",
    78   "TGT_RSP_CAS_IDLE",
    79   "TGT_RSP_XRAM_IDLE",
    80   "TGT_RSP_MULTI_ACK_IDLE",
    81   "TGT_RSP_CLEANUP_IDLE",
    82   "TGT_RSP_CONFIG",
    83   "TGT_RSP_TGT_CMD",
    84   "TGT_RSP_READ",
    85   "TGT_RSP_WRITE",
    86   "TGT_RSP_CAS",
    87   "TGT_RSP_XRAM",
    88   "TGT_RSP_MULTI_ACK",
    89   "TGT_RSP_CLEANUP"
    90 };
    91 const char *cc_receive_fsm_str[] =
    92 {
    93   "CC_RECEIVE_IDLE",
    94   "CC_RECEIVE_CLEANUP",
    95   "CC_RECEIVE_CLEANUP_EOP",
    96   "CC_RECEIVE_MULTI_ACK"
    97 };
    98 const char *cc_send_fsm_str[] =
    99 {
    100   "CC_SEND_CONFIG_IDLE",
    101   "CC_SEND_XRAM_RSP_IDLE",
    102   "CC_SEND_WRITE_IDLE",
    103   "CC_SEND_CAS_IDLE",
    104   "CC_SEND_CONFIG_INVAL_HEADER",
    105   "CC_SEND_CONFIG_INVAL_NLINE",
    106   "CC_SEND_CONFIG_BRDCAST_HEADER",
    107   "CC_SEND_CONFIG_BRDCAST_NLINE",
    108   "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
    109   "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
    110   "CC_SEND_XRAM_RSP_INVAL_HEADER",
    111   "CC_SEND_XRAM_RSP_INVAL_NLINE",
    112   "CC_SEND_WRITE_BRDCAST_HEADER",
    113   "CC_SEND_WRITE_BRDCAST_NLINE",
    114   "CC_SEND_WRITE_UPDT_HEADER",
    115   "CC_SEND_WRITE_UPDT_NLINE",
    116   "CC_SEND_WRITE_UPDT_DATA",
    117   "CC_SEND_CAS_BRDCAST_HEADER",
    118   "CC_SEND_CAS_BRDCAST_NLINE",
    119   "CC_SEND_CAS_UPDT_HEADER",
    120   "CC_SEND_CAS_UPDT_NLINE",
    121   "CC_SEND_CAS_UPDT_DATA",
    122   "CC_SEND_CAS_UPDT_DATA_HIGH"
    123 };
    124 const char *multi_ack_fsm_str[] =
    125 {
    126   "MULTI_ACK_IDLE",
    127   "MULTI_ACK_UPT_LOCK",
    128   "MULTI_ACK_UPT_CLEAR",
    129   "MULTI_ACK_WRITE_RSP"
    130 };
    131 const char *config_fsm_str[] =
    132 {
    133   "CONFIG_IDLE",
    134   "CONFIG_LOOP",
    135   "CONFIG_WAIT",
    136   "CONFIG_RSP",
    137   "CONFIG_DIR_REQ",
    138   "CONFIG_DIR_ACCESS",
    139   "CONFIG_IVT_LOCK",
    140   "CONFIG_BC_SEND",
    141   "CONFIG_INVAL_SEND",
    142   "CONFIG_HEAP_REQ",
    143   "CONFIG_HEAP_SCAN",
    144   "CONFIG_HEAP_LAST",
    145   "CONFIG_TRT_LOCK",
    146   "CONFIG_TRT_SET",
    147   "CONFIG_PUT_REQ"
    148 };
    149 const char *read_fsm_str[] =
    150 {
    151   "READ_IDLE",
    152   "READ_DIR_REQ",
    153   "READ_DIR_LOCK",
    154   "READ_DIR_HIT",
    155   "READ_HEAP_REQ",
    156   "READ_HEAP_LOCK",
    157   "READ_HEAP_WRITE",
    158   "READ_HEAP_ERASE",
    159   "READ_HEAP_LAST",
    160   "READ_RSP",
    161   "READ_TRT_LOCK",
    162   "READ_TRT_SET",
    163   "READ_TRT_REQ"
    164 };
    165 const char *write_fsm_str[] =
    166 {
    167   "WRITE_IDLE",
    168   "WRITE_NEXT",
    169   "WRITE_DIR_REQ",
    170   "WRITE_DIR_LOCK",
    171   "WRITE_DIR_HIT",
    172   "WRITE_UPT_LOCK",
    173   "WRITE_UPT_HEAP_LOCK",
    174   "WRITE_UPT_REQ",
    175   "WRITE_UPT_NEXT",
    176   "WRITE_UPT_DEC",
    177   "WRITE_RSP",
    178   "WRITE_MISS_TRT_LOCK",
    179   "WRITE_MISS_TRT_DATA",
    180   "WRITE_MISS_TRT_SET",
    181   "WRITE_MISS_XRAM_REQ",
    182   "WRITE_BC_DIR_READ",
    183   "WRITE_BC_TRT_LOCK",
    184   "WRITE_BC_IVT_LOCK",
    185   "WRITE_BC_DIR_INVAL",
    186   "WRITE_BC_CC_SEND",
    187   "WRITE_BC_XRAM_REQ",
    188   "WRITE_WAIT"
    189 };
    190 const char *ixr_rsp_fsm_str[] =
    191 {
    192   "IXR_RSP_IDLE",
    193   "IXR_RSP_ACK",
    194   "IXR_RSP_TRT_ERASE",
    195   "IXR_RSP_TRT_READ"
    196 };
    197 const char *xram_rsp_fsm_str[] =
    198 {
    199   "XRAM_RSP_IDLE",
    200   "XRAM_RSP_TRT_COPY",
    201   "XRAM_RSP_TRT_DIRTY",
    202   "XRAM_RSP_DIR_LOCK",
    203   "XRAM_RSP_DIR_UPDT",
    204   "XRAM_RSP_DIR_RSP",
    205   "XRAM_RSP_IVT_LOCK",
    206   "XRAM_RSP_INVAL_WAIT",
    207   "XRAM_RSP_INVAL",
    208   "XRAM_RSP_WRITE_DIRTY",
    209   "XRAM_RSP_HEAP_REQ",
    210   "XRAM_RSP_HEAP_ERASE",
    211   "XRAM_RSP_HEAP_LAST",
    212   "XRAM_RSP_ERROR_ERASE",
    213   "XRAM_RSP_ERROR_RSP"
    214 };
    215 const char *ixr_cmd_fsm_str[] =
    216 {
    217   "IXR_CMD_READ_IDLE",
    218   "IXR_CMD_WRITE_IDLE",
    219   "IXR_CMD_CAS_IDLE",
    220   "IXR_CMD_XRAM_IDLE",
    221   "IXR_CMD_CLEANUP_IDLE",
    222   "IXR_CMD_CONFIG_IDLE",
    223   "IXR_CMD_READ_TRT",
    224   "IXR_CMD_WRITE_TRT",
    225   "IXR_CMD_CAS_TRT",
    226   "IXR_CMD_XRAM_TRT",
    227   "IXR_CMD_CLEANUP_TRT",
    228   "IXR_CMD_CONFIG_TRT",
    229   "IXR_CMD_READ_SEND",
    230   "IXR_CMD_WRITE_SEND",
    231   "IXR_CMD_CAS_SEND",
    232   "IXR_CMD_XRAM_SEND",
    233   "IXR_CMD_CLEANUP_DATA_SEND",
    234   "IXR_CMD_CONFIG_SEND"
    235 };
    236 const char *cas_fsm_str[] =
    237 {
    238   "CAS_IDLE",
    239   "CAS_DIR_REQ",
    240   "CAS_DIR_LOCK",
    241   "CAS_DIR_HIT_READ",
    242   "CAS_DIR_HIT_COMPARE",
    243   "CAS_DIR_HIT_WRITE",
    244   "CAS_UPT_LOCK",
    245   "CAS_UPT_HEAP_LOCK",
    246   "CAS_UPT_REQ",
    247   "CAS_UPT_NEXT",
    248   "CAS_BC_TRT_LOCK",
    249   "CAS_BC_IVT_LOCK",
    250   "CAS_BC_DIR_INVAL",
    251   "CAS_BC_CC_SEND",
    252   "CAS_BC_XRAM_REQ",
    253   "CAS_RSP_FAIL",
    254   "CAS_RSP_SUCCESS",
    255   "CAS_MISS_TRT_LOCK",
    256   "CAS_MISS_TRT_SET",
    257   "CAS_MISS_XRAM_REQ",
    258   "CAS_WAIT"
    259 };
    260 const char *cleanup_fsm_str[] =
    261 {
    262   "CLEANUP_IDLE",
    263   "CLEANUP_GET_NLINE",
    264   "CLEANUP_GET_DATA",
    265   "CLEANUP_DIR_REQ",
    266   "CLEANUP_DIR_LOCK",
    267   "CLEANUP_DIR_WRITE",
    268   "CLEANUP_HEAP_REQ",
    269   "CLEANUP_HEAP_LOCK",
    270   "CLEANUP_HEAP_SEARCH",
    271   "CLEANUP_HEAP_CLEAN",
    272   "CLEANUP_HEAP_FREE",
    273   "CLEANUP_IVT_LOCK",
    274   "CLEANUP_IVT_DECREMENT",
    275   "CLEANUP_IVT_CLEAR",
    276   "CLEANUP_WRITE_RSP",
    277   "CLEANUP_IXR_REQ",
    278   "CLEANUP_WAIT",
    279   "CLEANUP_SEND_CLACK"
    280 };
    281 const char *alloc_dir_fsm_str[] =
    282 {
    283   "ALLOC_DIR_RESET",
    284   "ALLOC_DIR_CONFIG",
    285   "ALLOC_DIR_READ",
    286   "ALLOC_DIR_WRITE",
    287   "ALLOC_DIR_CAS",
    288   "ALLOC_DIR_CLEANUP",
    289   "ALLOC_DIR_XRAM_RSP"
    290 };
    291 const char *alloc_trt_fsm_str[] =
    292 {
    293   "ALLOC_TRT_READ",
    294   "ALLOC_TRT_WRITE",
    295   "ALLOC_TRT_CAS",
    296   "ALLOC_TRT_XRAM_RSP",
    297   "ALLOC_TRT_IXR_RSP",
    298   "ALLOC_TRT_CLEANUP",
    299   "ALLOC_TRT_IXR_CMD",
    300   "ALLOC_TRT_CONFIG"
    301 };
    302 const char *alloc_upt_fsm_str[] =
    303 {
    304   "ALLOC_UPT_WRITE",
    305   "ALLOC_UPT_CAS",
    306   "ALLOC_UPT_MULTI_ACK"
    307 };
    308 const char *alloc_ivt_fsm_str[] =
    309 {
    310   "ALLOC_IVT_WRITE",
    311   "ALLOC_IVT_XRAM_RSP",
    312   "ALLOC_IVT_CLEANUP",
    313   "ALLOC_IVT_CAS",
    314   "ALLOC_IVT_CONFIG"
    315 };
    316 const char *alloc_heap_fsm_str[] =
    317 {
    318   "ALLOC_HEAP_RESET",
    319   "ALLOC_HEAP_READ",
    320   "ALLOC_HEAP_WRITE",
    321   "ALLOC_HEAP_CAS",
    322   "ALLOC_HEAP_CLEANUP",
    323   "ALLOC_HEAP_XRAM_RSP",
    324   "ALLOC_HEAP_CONFIG"
    325 };
     63    const char *tgt_cmd_fsm_str[] =
     64    {
     65        "TGT_CMD_IDLE",
     66        "TGT_CMD_ERROR",
     67        "TGT_CMD_READ",
     68        "TGT_CMD_WRITE",
     69        "TGT_CMD_CAS",
     70        "TGT_CMD_CONFIG"
     71    };
     72    const char *tgt_rsp_fsm_str[] =
     73    {
     74        "TGT_RSP_CONFIG_IDLE",
     75        "TGT_RSP_TGT_CMD_IDLE",
     76        "TGT_RSP_READ_IDLE",
     77        "TGT_RSP_WRITE_IDLE",
     78        "TGT_RSP_CAS_IDLE",
     79        "TGT_RSP_XRAM_IDLE",
     80        "TGT_RSP_MULTI_ACK_IDLE",
     81        "TGT_RSP_CLEANUP_IDLE",
     82        "TGT_RSP_CONFIG",
     83        "TGT_RSP_TGT_CMD",
     84        "TGT_RSP_READ",
     85        "TGT_RSP_WRITE",
     86        "TGT_RSP_CAS",
     87        "TGT_RSP_XRAM",
     88        "TGT_RSP_MULTI_ACK",
     89        "TGT_RSP_CLEANUP"
     90    };
     91    const char *cc_receive_fsm_str[] =
     92    {
     93        "CC_RECEIVE_IDLE",
     94        "CC_RECEIVE_CLEANUP",
     95        "CC_RECEIVE_CLEANUP_EOP",
     96        "CC_RECEIVE_MULTI_ACK"
     97    };
     98    const char *cc_send_fsm_str[] =
     99    {
     100        "CC_SEND_CONFIG_IDLE",
     101        "CC_SEND_XRAM_RSP_IDLE",
     102        "CC_SEND_WRITE_IDLE",
     103        "CC_SEND_CAS_IDLE",
     104        "CC_SEND_CONFIG_INVAL_HEADER",
     105        "CC_SEND_CONFIG_INVAL_NLINE",
     106        "CC_SEND_CONFIG_BRDCAST_HEADER",
     107        "CC_SEND_CONFIG_BRDCAST_NLINE",
     108        "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
     109        "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
     110        "CC_SEND_XRAM_RSP_INVAL_HEADER",
     111        "CC_SEND_XRAM_RSP_INVAL_NLINE",
     112        "CC_SEND_WRITE_BRDCAST_HEADER",
     113        "CC_SEND_WRITE_BRDCAST_NLINE",
     114        "CC_SEND_WRITE_UPDT_HEADER",
     115        "CC_SEND_WRITE_UPDT_NLINE",
     116        "CC_SEND_WRITE_UPDT_DATA",
     117        "CC_SEND_CAS_BRDCAST_HEADER",
     118        "CC_SEND_CAS_BRDCAST_NLINE",
     119        "CC_SEND_CAS_UPDT_HEADER",
     120        "CC_SEND_CAS_UPDT_NLINE",
     121        "CC_SEND_CAS_UPDT_DATA",
     122        "CC_SEND_CAS_UPDT_DATA_HIGH"
     123    };
     124    const char *multi_ack_fsm_str[] =
     125    {
     126        "MULTI_ACK_IDLE",
     127        "MULTI_ACK_UPT_LOCK",
     128        "MULTI_ACK_UPT_CLEAR",
     129        "MULTI_ACK_WRITE_RSP"
     130    };
     131    const char *config_fsm_str[] =
     132    {
     133        "CONFIG_IDLE",
     134        "CONFIG_LOOP",
     135        "CONFIG_WAIT",
     136        "CONFIG_RSP",
     137        "CONFIG_DIR_REQ",
     138        "CONFIG_DIR_ACCESS",
     139        "CONFIG_IVT_LOCK",
     140        "CONFIG_BC_SEND",
     141        "CONFIG_INVAL_SEND",
     142        "CONFIG_HEAP_REQ",
     143        "CONFIG_HEAP_SCAN",
     144        "CONFIG_HEAP_LAST",
     145        "CONFIG_TRT_LOCK",
     146        "CONFIG_TRT_SET",
     147        "CONFIG_PUT_REQ"
     148    };
     149    const char *read_fsm_str[] =
     150    {
     151        "READ_IDLE",
     152        "READ_DIR_REQ",
     153        "READ_DIR_LOCK",
     154        "READ_DIR_HIT",
     155        "READ_HEAP_REQ",
     156        "READ_HEAP_LOCK",
     157        "READ_HEAP_WRITE",
     158        "READ_HEAP_ERASE",
     159        "READ_HEAP_LAST",
     160        "READ_RSP",
     161        "READ_TRT_LOCK",
     162        "READ_TRT_SET",
     163        "READ_TRT_REQ"
     164    };
     165    const char *write_fsm_str[] =
     166    {
     167        "WRITE_IDLE",
     168        "WRITE_NEXT",
     169        "WRITE_DIR_REQ",
     170        "WRITE_DIR_LOCK",
     171        "WRITE_DIR_HIT",
     172        "WRITE_UPT_LOCK",
     173        "WRITE_UPT_HEAP_LOCK",
     174        "WRITE_UPT_REQ",
     175        "WRITE_UPT_NEXT",
     176        "WRITE_UPT_DEC",
     177        "WRITE_RSP",
     178        "WRITE_MISS_TRT_LOCK",
     179        "WRITE_MISS_TRT_DATA",
     180        "WRITE_MISS_TRT_SET",
     181        "WRITE_MISS_XRAM_REQ",
     182        "WRITE_BC_DIR_READ",
     183        "WRITE_BC_TRT_LOCK",
     184        "WRITE_BC_IVT_LOCK",
     185        "WRITE_BC_DIR_INVAL",
     186        "WRITE_BC_CC_SEND",
     187        "WRITE_BC_XRAM_REQ",
     188        "WRITE_WAIT"
     189    };
     190    const char *ixr_rsp_fsm_str[] =
     191    {
     192        "IXR_RSP_IDLE",
     193        "IXR_RSP_ACK",
     194        "IXR_RSP_TRT_ERASE",
     195        "IXR_RSP_TRT_READ"
     196    };
     197    const char *xram_rsp_fsm_str[] =
     198    {
     199        "XRAM_RSP_IDLE",
     200        "XRAM_RSP_TRT_COPY",
     201        "XRAM_RSP_TRT_DIRTY",
     202        "XRAM_RSP_DIR_LOCK",
     203        "XRAM_RSP_DIR_UPDT",
     204        "XRAM_RSP_DIR_RSP",
     205        "XRAM_RSP_IVT_LOCK",
     206        "XRAM_RSP_INVAL_WAIT",
     207        "XRAM_RSP_INVAL",
     208        "XRAM_RSP_WRITE_DIRTY",
     209        "XRAM_RSP_HEAP_REQ",
     210        "XRAM_RSP_HEAP_ERASE",
     211        "XRAM_RSP_HEAP_LAST",
     212        "XRAM_RSP_ERROR_ERASE",
     213        "XRAM_RSP_ERROR_RSP"
     214    };
     215    const char *ixr_cmd_fsm_str[] =
     216    {
     217        "IXR_CMD_READ_IDLE",
     218        "IXR_CMD_WRITE_IDLE",
     219        "IXR_CMD_CAS_IDLE",
     220        "IXR_CMD_XRAM_IDLE",
     221        "IXR_CMD_CLEANUP_IDLE",
     222        "IXR_CMD_CONFIG_IDLE",
     223        "IXR_CMD_READ_TRT",
     224        "IXR_CMD_WRITE_TRT",
     225        "IXR_CMD_CAS_TRT",
     226        "IXR_CMD_XRAM_TRT",
     227        "IXR_CMD_CLEANUP_TRT",
     228        "IXR_CMD_CONFIG_TRT",
     229        "IXR_CMD_READ_SEND",
     230        "IXR_CMD_WRITE_SEND",
     231        "IXR_CMD_CAS_SEND",
     232        "IXR_CMD_XRAM_SEND",
     233        "IXR_CMD_CLEANUP_DATA_SEND",
     234        "IXR_CMD_CONFIG_SEND"
     235    };
     236    const char *cas_fsm_str[] =
     237    {
     238        "CAS_IDLE",
     239        "CAS_DIR_REQ",
     240        "CAS_DIR_LOCK",
     241        "CAS_DIR_HIT_READ",
     242        "CAS_DIR_HIT_COMPARE",
     243        "CAS_DIR_HIT_WRITE",
     244        "CAS_UPT_LOCK",
     245        "CAS_UPT_HEAP_LOCK",
     246        "CAS_UPT_REQ",
     247        "CAS_UPT_NEXT",
     248        "CAS_BC_TRT_LOCK",
     249        "CAS_BC_IVT_LOCK",
     250        "CAS_BC_DIR_INVAL",
     251        "CAS_BC_CC_SEND",
     252        "CAS_BC_XRAM_REQ",
     253        "CAS_RSP_FAIL",
     254        "CAS_RSP_SUCCESS",
     255        "CAS_MISS_TRT_LOCK",
     256        "CAS_MISS_TRT_SET",
     257        "CAS_MISS_XRAM_REQ",
     258        "CAS_WAIT"
     259    };
     260    const char *cleanup_fsm_str[] =
     261    {
     262        "CLEANUP_IDLE",
     263        "CLEANUP_GET_NLINE",
     264        "CLEANUP_GET_DATA",
     265        "CLEANUP_DIR_REQ",
     266        "CLEANUP_DIR_LOCK",
     267        "CLEANUP_DIR_WRITE",
     268        "CLEANUP_HEAP_REQ",
     269        "CLEANUP_HEAP_LOCK",
     270        "CLEANUP_HEAP_SEARCH",
     271        "CLEANUP_HEAP_CLEAN",
     272        "CLEANUP_HEAP_FREE",
     273        "CLEANUP_IVT_LOCK",
     274        "CLEANUP_IVT_DECREMENT",
     275        "CLEANUP_IVT_CLEAR",
     276        "CLEANUP_WRITE_RSP",
     277        "CLEANUP_IXR_REQ",
     278        "CLEANUP_WAIT",
     279        "CLEANUP_SEND_CLACK"
     280    };
     281    const char *alloc_dir_fsm_str[] =
     282    {
     283        "ALLOC_DIR_RESET",
     284        "ALLOC_DIR_CONFIG",
     285        "ALLOC_DIR_READ",
     286        "ALLOC_DIR_WRITE",
     287        "ALLOC_DIR_CAS",
     288        "ALLOC_DIR_CLEANUP",
     289        "ALLOC_DIR_XRAM_RSP"
     290    };
     291    const char *alloc_trt_fsm_str[] =
     292    {
     293        "ALLOC_TRT_READ",
     294        "ALLOC_TRT_WRITE",
     295        "ALLOC_TRT_CAS",
     296        "ALLOC_TRT_XRAM_RSP",
     297        "ALLOC_TRT_IXR_RSP",
     298        "ALLOC_TRT_CLEANUP",
     299        "ALLOC_TRT_IXR_CMD",
     300        "ALLOC_TRT_CONFIG"
     301    };
     302    const char *alloc_upt_fsm_str[] =
     303    {
     304        "ALLOC_UPT_WRITE",
     305        "ALLOC_UPT_CAS",
     306        "ALLOC_UPT_MULTI_ACK"
     307    };
     308    const char *alloc_ivt_fsm_str[] =
     309    {
     310        "ALLOC_IVT_WRITE",
     311        "ALLOC_IVT_XRAM_RSP",
     312        "ALLOC_IVT_CLEANUP",
     313        "ALLOC_IVT_CAS",
     314        "ALLOC_IVT_CONFIG"
     315    };
     316    const char *alloc_heap_fsm_str[] =
     317    {
     318        "ALLOC_HEAP_RESET",
     319        "ALLOC_HEAP_READ",
     320        "ALLOC_HEAP_WRITE",
     321        "ALLOC_HEAP_CAS",
     322        "ALLOC_HEAP_CLEANUP",
     323        "ALLOC_HEAP_XRAM_RSP",
     324        "ALLOC_HEAP_CONFIG"
     325    };
    326326
    327327#define tmpl(x) \
    328   template<typename vci_param_int, \
    329            typename vci_param_ext, \
    330            size_t dspin_in_width,  \
    331            size_t dspin_out_width> x \
    332   VciMemCache<vci_param_int, vci_param_ext, dspin_in_width, dspin_out_width>
    333 
    334 using namespace soclib::common;
    335 
    336 ////////////////////////////////
    337 //  Constructor
    338 ////////////////////////////////
    339 
    340 tmpl(/**/) ::VciMemCache(
    341   sc_module_name      name,
    342   const MappingTable  &mtp,              // mapping table for direct network
    343   const MappingTable  &mtx,              // mapping table for external network
    344   const IntTab        &srcid_x,          // global index on external network
    345   const IntTab        &tgtid_d,          // global index on direct network
    346   const size_t        cc_global_id,      // global index on cc network
    347   const size_t        nways,             // number of ways per set
    348   const size_t        nsets,             // number of associative sets
    349   const size_t        nwords,            // number of words in cache line
    350   const size_t        max_copies,        // max number of copies in heap
    351   const size_t        heap_size,         // number of heap entries
    352   const size_t        trt_lines,         // number of TRT entries
    353   const size_t        upt_lines,         // number of UPT entries
    354   const size_t        ivt_lines,         // number of IVT entries
    355   const size_t        debug_start_cycle,
    356   const bool          debug_ok)
    357 
    358   : soclib::caba::BaseModule(name),
    359 
    360     //m_monitor_ok(false),
    361    
    362     p_clk( "p_clk" ),
    363     p_resetn( "p_resetn" ),
    364     p_vci_tgt( "p_vci_tgt" ),
    365     p_vci_ixr( "p_vci_ixr" ),
    366     p_dspin_p2m( "p_dspin_p2m" ),
    367     p_dspin_m2p( "p_dspin_m2p" ),
    368     p_dspin_clack( "p_dspin_clack" ),
    369 
    370     m_seglist( mtp.getSegmentList(tgtid_d) ),
    371     m_nseg( 0 ),
    372     m_srcid_x( mtx.indexForId(srcid_x) ),
    373     m_initiators( 1 << vci_param_int::S ),
    374     m_heap_size( heap_size ),
    375     m_ways( nways ),
    376     m_sets( nsets ),
    377     m_words( nwords ),
    378     m_cc_global_id( cc_global_id ),
    379     m_debug_start_cycle( debug_start_cycle ),
    380     m_debug_ok( debug_ok ),
    381     m_trt_lines(trt_lines),
    382     m_trt(this->name(), trt_lines, nwords),
    383     m_upt_lines(upt_lines),
    384     m_upt(upt_lines),
    385     m_ivt(ivt_lines),
    386     m_cache_directory(nways, nsets, nwords, vci_param_int::N),
    387     m_cache_data(nways, nsets, nwords),
    388     m_heap(m_heap_size),
    389     m_max_copies( max_copies ),
    390     m_llsc_table(),
     328    template<typename vci_param_int, \
     329    typename vci_param_ext, \
     330    size_t dspin_in_width,  \
     331    size_t dspin_out_width> x \
     332    VciMemCache<vci_param_int, vci_param_ext, dspin_in_width, dspin_out_width>
     333
     334    using namespace soclib::common;
     335
     336    ////////////////////////////////
     337    //  Constructor
     338    ////////////////////////////////
     339
     340    tmpl(/**/) ::VciMemCache(
     341            sc_module_name      name,
     342            const MappingTable  &mtp,              // mapping table for direct network
     343            const MappingTable  &mtx,              // mapping table for external network
     344            const IntTab        &srcid_x,          // global index on external network
     345            const IntTab        &tgtid_d,          // global index on direct network
     346            const size_t        cc_global_id,      // global index on cc network
     347            const size_t        nways,             // number of ways per set
     348            const size_t        nsets,             // number of associative sets
     349            const size_t        nwords,            // number of words in cache line
     350            const size_t        max_copies,        // max number of copies in heap
     351            const size_t        heap_size,         // number of heap entries
     352            const size_t        trt_lines,         // number of TRT entries
     353            const size_t        upt_lines,         // number of UPT entries
     354            const size_t        ivt_lines,         // number of IVT entries
     355            const size_t        debug_start_cycle,
     356            const bool          debug_ok)
     357
     358        : soclib::caba::BaseModule(name),
     359
     360        //m_monitor_ok(false),
     361
     362        p_clk( "p_clk" ),
     363        p_resetn( "p_resetn" ),
     364        p_vci_tgt( "p_vci_tgt" ),
     365        p_vci_ixr( "p_vci_ixr" ),
     366        p_dspin_p2m( "p_dspin_p2m" ),
     367        p_dspin_m2p( "p_dspin_m2p" ),
     368        p_dspin_clack( "p_dspin_clack" ),
     369
     370        m_seglist( mtp.getSegmentList(tgtid_d) ),
     371        m_nseg( 0 ),
     372        m_srcid_x( mtx.indexForId(srcid_x) ),
     373        m_initiators( 1 << vci_param_int::S ),
     374        m_heap_size( heap_size ),
     375        m_ways( nways ),
     376        m_sets( nsets ),
     377        m_words( nwords ),
     378        m_cc_global_id( cc_global_id ),
     379        m_debug_start_cycle( debug_start_cycle ),
     380        m_debug_ok( debug_ok ),
     381        m_trt_lines(trt_lines),
     382        m_trt(this->name(), trt_lines, nwords),
     383        m_upt_lines(upt_lines),
     384        m_upt(upt_lines),
     385        m_ivt(ivt_lines),
     386        m_cache_directory(nways, nsets, nwords, vci_param_int::N),
     387        m_cache_data(nways, nsets, nwords),
     388        m_heap(m_heap_size),
     389        m_max_copies( max_copies ),
     390        m_llsc_table(),
    391391
    392392#define L2 soclib::common::uint32_log2
    393     m_x(L2(m_words), 2),
    394     m_y(L2(m_sets), L2(m_words) + 2),
    395     m_z(vci_param_int::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
    396     m_nline(vci_param_int::N - L2(m_words) - 2, L2(m_words) + 2),
     393        m_x(L2(m_words), 2),
     394        m_y(L2(m_sets), L2(m_words) + 2),
     395        m_z(vci_param_int::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
     396        m_nline(vci_param_int::N - L2(m_words) - 2, L2(m_words) + 2),
    397397#undef L2
    398398
    399     // XMIN(5 bits) / XMAX(5 bits) / YMIN(5 bits) / YMAX(5 bits)
    400     //   0b00000    /   0b11111    /   0b00000    /   0b11111
    401     m_broadcast_boundaries(0x7C1F),
    402 
    403 
    404     //  FIFOs
    405     m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
    406     m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
    407     m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
    408     m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
    409     m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
    410 
    411     m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
    412     m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
    413     m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
    414     m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
    415     m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
    416     m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
    417     m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
    418 
    419     m_cmd_cas_addr_fifo("m_cmd_cas_addr_fifo",4),
    420     m_cmd_cas_eop_fifo("m_cmd_cas_eop_fifo",4),
    421     m_cmd_cas_srcid_fifo("m_cmd_cas_srcid_fifo",4),
    422     m_cmd_cas_trdid_fifo("m_cmd_cas_trdid_fifo",4),
    423     m_cmd_cas_pktid_fifo("m_cmd_cas_pktid_fifo",4),
    424     m_cmd_cas_wdata_fifo("m_cmd_cas_wdata_fifo",4),
    425 
    426     m_cc_receive_to_cleanup_fifo("m_cc_receive_to_cleanup_fifo", 4),
    427     m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
    428 
    429     r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    430 
    431     r_config_fsm( "r_config_fsm" ),
    432 
    433     m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ),
    434     m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ),
    435 
    436     r_read_fsm( "r_read_fsm" ),
    437 
    438     r_write_fsm( "r_write_fsm" ),
    439 
    440     m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
    441     m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
    442 
    443     r_multi_ack_fsm("r_multi_ack_fsm"),
    444 
    445     r_cleanup_fsm("r_cleanup_fsm"),
    446 
    447     r_cas_fsm("r_cas_fsm"),
    448 
    449     m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
    450     m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
    451 
    452     r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
    453     r_xram_rsp_fsm("r_xram_rsp_fsm"),
    454 
    455     m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
    456     m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
    457 
    458     r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
    459 
    460     r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
    461 
    462     r_cc_send_fsm("r_cc_send_fsm"),
    463     r_cc_receive_fsm("r_cc_receive_fsm"),
    464 
    465     r_alloc_dir_fsm("r_alloc_dir_fsm"),
    466     r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"),
    467     r_alloc_trt_fsm("r_alloc_trt_fsm"),
    468     r_alloc_upt_fsm("r_alloc_upt_fsm"),
    469     r_alloc_ivt_fsm("r_alloc_ivt_fsm"),
    470     r_alloc_heap_fsm("r_alloc_heap_fsm"),
    471     r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
    472 {
    473     std::cout << "  - Building VciMemCache : " << name << std::endl;
    474 
    475     assert(IS_POW_OF_2(nsets));
    476     assert(IS_POW_OF_2(nwords));
    477     assert(IS_POW_OF_2(nways));
    478     assert(nsets);
    479     assert(nwords);
    480     assert(nways);
    481 
    482     // check Transaction table size
    483     assert((uint32_log2(trt_lines) <= vci_param_ext::T) and
    484     "MEMC ERROR : Need more bits for VCI TRDID field");
    485 
    486     // check internal and external data width
    487     assert( (vci_param_int::B == 4 ) and
    488     "MEMC ERROR : VCI internal data width must be 32 bits");
    489 
    490     assert( (vci_param_ext::B == 8) and
    491     "MEMC ERROR : VCI external data width must be 64 bits");
    492 
    493     // Check coherence between internal & external addresses
    494     assert( (vci_param_int::N == vci_param_ext::N) and
    495     "MEMC ERROR : VCI internal & external addresses must have the same width");
    496 
    497     // Get the segments associated to the MemCache
    498     std::list<soclib::common::Segment>::iterator seg;
    499     size_t i = 0;
    500 
    501     for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++)
     399        // XMIN(5 bits) / XMAX(5 bits) / YMIN(5 bits) / YMAX(5 bits)
     400        //   0b00000    /   0b11111    /   0b00000    /   0b11111
     401        m_broadcast_boundaries(0x7C1F),
     402
     403
     404        //  FIFOs
     405        m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
     406        m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
     407        m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
     408        m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
     409        m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
     410
     411        m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
     412        m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
     413        m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
     414        m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
     415        m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
     416        m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
     417        m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
     418
     419        m_cmd_cas_addr_fifo("m_cmd_cas_addr_fifo",4),
     420        m_cmd_cas_eop_fifo("m_cmd_cas_eop_fifo",4),
     421        m_cmd_cas_srcid_fifo("m_cmd_cas_srcid_fifo",4),
     422        m_cmd_cas_trdid_fifo("m_cmd_cas_trdid_fifo",4),
     423        m_cmd_cas_pktid_fifo("m_cmd_cas_pktid_fifo",4),
     424        m_cmd_cas_wdata_fifo("m_cmd_cas_wdata_fifo",4),
     425
     426        m_cc_receive_to_cleanup_fifo("m_cc_receive_to_cleanup_fifo", 4),
     427        m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
     428
     429        r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
     430
     431        r_config_fsm( "r_config_fsm" ),
     432
     433        m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ),
     434        m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ),
     435
     436        r_read_fsm( "r_read_fsm" ),
     437
     438        r_write_fsm( "r_write_fsm" ),
     439
     440        m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
     441        m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
     442
     443        r_multi_ack_fsm("r_multi_ack_fsm"),
     444
     445        r_cleanup_fsm("r_cleanup_fsm"),
     446
     447        r_cas_fsm("r_cas_fsm"),
     448
     449        m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
     450        m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
     451
     452        r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
     453        r_xram_rsp_fsm("r_xram_rsp_fsm"),
     454
     455        m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
     456        m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
     457
     458        r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
     459
     460        r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
     461
     462        r_cc_send_fsm("r_cc_send_fsm"),
     463        r_cc_receive_fsm("r_cc_receive_fsm"),
     464
     465        r_alloc_dir_fsm("r_alloc_dir_fsm"),
     466        r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"),
     467        r_alloc_trt_fsm("r_alloc_trt_fsm"),
     468        r_alloc_upt_fsm("r_alloc_upt_fsm"),
     469        r_alloc_ivt_fsm("r_alloc_ivt_fsm"),
     470        r_alloc_heap_fsm("r_alloc_heap_fsm"),
     471        r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
     472        {
     473            std::cout << "  - Building VciMemCache : " << name << std::endl;
     474
     475            assert(IS_POW_OF_2(nsets));
     476            assert(IS_POW_OF_2(nwords));
     477            assert(IS_POW_OF_2(nways));
     478            assert(nsets);
     479            assert(nwords);
     480            assert(nways);
     481
     482            // check Transaction table size
     483            assert((uint32_log2(trt_lines) <= vci_param_ext::T) and
     484                    "MEMC ERROR : Need more bits for VCI TRDID field");
     485
     486            // check internal and external data width
     487            assert( (vci_param_int::B == 4 ) and
     488                    "MEMC ERROR : VCI internal data width must be 32 bits");
     489
     490            assert( (vci_param_ext::B == 8) and
     491                    "MEMC ERROR : VCI external data width must be 64 bits");
     492
     493            // Check coherence between internal & external addresses
     494            assert( (vci_param_int::N == vci_param_ext::N) and
     495                    "MEMC ERROR : VCI internal & external addresses must have the same width");
     496
     497            // Get the segments associated to the MemCache
     498            std::list<soclib::common::Segment>::iterator seg;
     499            size_t i = 0;
     500
     501            for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++)
     502            {
     503                std::cout << "    => segment " << seg->name()
     504                    << " / base = " << std::hex << seg->baseAddress()
     505                    << " / size = " << seg->size() << std::endl;
     506                m_nseg++;
     507            }
     508
     509            m_seg = new soclib::common::Segment*[m_nseg];
     510
     511            for(seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++)
     512            {
     513                if ( seg->special() ) m_seg_config = i;
     514                m_seg[i] = & (*seg);
     515                i++;
     516            }
     517
     518            // Allocation for IXR_RSP FSM
     519            r_ixr_rsp_to_xram_rsp_rok  = new sc_signal<bool>[m_trt_lines];
     520            //r_ixr_rsp_to_xram_rsp_no_coherent  = new sc_signal<bool>[m_trt_lines];
     521
     522            // Allocation for XRAM_RSP FSM
     523            r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
     524            r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
     525
     526            // Allocation for READ FSM
     527            r_read_data                = new sc_signal<data_t>[nwords];
     528            r_read_to_tgt_rsp_data     = new sc_signal<data_t>[nwords];
     529
     530            // Allocation for WRITE FSM
     531            r_write_data               = new sc_signal<data_t>[nwords];
     532            r_write_be                 = new sc_signal<be_t>[nwords];
     533            r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
     534            r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
     535
     536            // Allocation for CAS FSM
     537            r_cas_data                 = new sc_signal<data_t>[nwords];
     538            r_cas_rdata                = new sc_signal<data_t>[2];
     539
     540            // Allocation for ODCCP
     541            r_cleanup_data             = new sc_signal<data_t>[nwords];
     542            r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
     543
     544            // Allocation for IXR_CMD FSM
     545            r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
     546
     547            // Allocation for debug
     548            m_debug_previous_data      = new data_t[nwords];
     549            m_debug_data               = new data_t[nwords];
     550
     551            SC_METHOD(transition);
     552            dont_initialize();
     553            sensitive << p_clk.pos();
     554
     555            SC_METHOD(genMoore);
     556            dont_initialize();
     557            sensitive << p_clk.neg();
     558        } // end constructor
     559
     560
     561    /////////////////////////////////////////////////////
     562    tmpl(void) ::cache_monitor(addr_t addr)
     563        /////////////////////////////////////////////////////
    502564    {
    503         std::cout << "    => segment " << seg->name()
    504                   << " / base = " << std::hex << seg->baseAddress()
    505                   << " / size = " << seg->size() << std::endl;
    506         m_nseg++;
    507     }
    508 
    509     m_seg = new soclib::common::Segment*[m_nseg];
    510 
    511     for(seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++)
    512     {
    513         if ( seg->special() ) m_seg_config = i;
    514         m_seg[i] = & (*seg);
    515         i++;
    516     }
    517 
    518     // Allocation for IXR_RSP FSM
    519     r_ixr_rsp_to_xram_rsp_rok  = new sc_signal<bool>[m_trt_lines];
    520     //r_ixr_rsp_to_xram_rsp_no_coherent  = new sc_signal<bool>[m_trt_lines];
    521 
    522     // Allocation for XRAM_RSP FSM
    523     r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
    524     r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
    525 
    526     // Allocation for READ FSM
    527     r_read_data                = new sc_signal<data_t>[nwords];
    528     r_read_to_tgt_rsp_data     = new sc_signal<data_t>[nwords];
    529 
    530     // Allocation for WRITE FSM
    531     r_write_data               = new sc_signal<data_t>[nwords];
    532     r_write_be                 = new sc_signal<be_t>[nwords];
    533     r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
    534     r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
    535 
    536     // Allocation for CAS FSM
    537     r_cas_data                 = new sc_signal<data_t>[nwords];
    538     r_cas_rdata                = new sc_signal<data_t>[2];
    539 
    540     // Allocation for ODCCP
    541     r_cleanup_data             = new sc_signal<data_t>[nwords];
    542     r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
    543 
    544     // Allocation for IXR_CMD FSM
    545     r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
    546 
    547     // Allocation for debug
    548     m_debug_previous_data      = new data_t[nwords];
    549     m_debug_data               = new data_t[nwords];
    550 
    551     SC_METHOD(transition);
    552     dont_initialize();
    553     sensitive << p_clk.pos();
    554 
    555     SC_METHOD(genMoore);
    556     dont_initialize();
    557     sensitive << p_clk.neg();
    558 } // end constructor
    559 
    560 
    561 /////////////////////////////////////////////////////
    562 tmpl(void) ::cache_monitor(addr_t addr)
    563 /////////////////////////////////////////////////////
    564 {
    565     size_t way = 0;
    566     size_t set = 0;
    567     DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
    568 
    569     // read data and compute data_change
    570     bool data_change = false;
    571     if ( entry.valid )
    572     {
    573         for ( size_t word = 0 ; word<m_words ; word++ )
     565        size_t way = 0;
     566        size_t set = 0;
     567        DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
     568
     569        // read data and compute data_change
     570        bool data_change = false;
     571        if ( entry.valid )
    574572        {
    575             m_debug_data[word] = m_cache_data.read(way, set, word);
    576             if ( m_debug_previous_valid and
    577                  (m_debug_data[word] != m_debug_previous_data[word]) )
     573            for ( size_t word = 0 ; word<m_words ; word++ )
    578574            {
    579                 data_change = true;
     575                m_debug_data[word] = m_cache_data.read(way, set, word);
     576                if ( m_debug_previous_valid and
     577                        (m_debug_data[word] != m_debug_previous_data[word]) )
     578                {
     579                    data_change = true;
     580                }
    580581            }
    581582        }
     583
     584        // print values if any change
     585        if ( (entry.valid != m_debug_previous_valid) or
     586                (entry.valid and (entry.count != m_debug_previous_count)) or
     587                (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change )
     588        {
     589            std::cout << "Monitor MEMC " << name()
     590                << " at cycle " << std::dec << m_cpt_cycles
     591                << " for address " << std::hex << addr
     592                << " / VAL = " << std::dec << entry.valid
     593                << " / WAY = " << way
     594                << " / COUNT = " << entry.count
     595                << " / DIRTY = " << entry.dirty
     596                << " / DATA_CHANGE = " << data_change
     597                << std::endl;
     598            std::cout << std::hex << "     /0:" << m_debug_data[0]
     599                << "/1:" << m_debug_data[1]
     600                << "/2:" << m_debug_data[2]
     601                << "/3:" << m_debug_data[3]
     602                << "/4:" << m_debug_data[4]
     603                << "/5:" << m_debug_data[5]
     604                << "/6:" << m_debug_data[6]
     605                << "/7:" << m_debug_data[7]
     606                << "/8:" << m_debug_data[8]
     607                << "/9:" << m_debug_data[9]
     608                << "/A:" << m_debug_data[10]
     609                << "/B:" << m_debug_data[11]
     610                << "/C:" << m_debug_data[12]
     611                << "/D:" << m_debug_data[13]
     612                << "/E:" << m_debug_data[14]
     613                << "/F:" << m_debug_data[15]
     614                << std::endl;
     615        }
     616
     617        // register values
     618        m_debug_previous_count = entry.count;
     619        m_debug_previous_valid = entry.valid;
     620        m_debug_previous_dirty = entry.dirty;
     621        for( size_t word=0 ; word<m_words ; word++ )
     622            m_debug_previous_data[word] = m_debug_data[word];
    582623    }
    583    
    584     // print values if any change
    585     if ( (entry.valid != m_debug_previous_valid) or
    586          (entry.valid and (entry.count != m_debug_previous_count)) or
    587          (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change )
     624
     625    //////////////////////////////////////////////////
     626    tmpl(void) ::print_trace()
     627        //////////////////////////////////////////////////
    588628    {
    589         std::cout << "Monitor MEMC " << name()
    590                   << " at cycle " << std::dec << m_cpt_cycles
    591                   << " for address " << std::hex << addr
    592                   << " / VAL = " << std::dec << entry.valid
    593                   << " / WAY = " << way
    594                   << " / COUNT = " << entry.count
    595                   << " / DIRTY = " << entry.dirty
    596                   << " / DATA_CHANGE = " << data_change
    597                   << std::endl;
    598         std::cout << std::hex << "     /0:" << m_debug_data[0]
    599                   << "/1:" << m_debug_data[1]
    600                   << "/2:" << m_debug_data[2]
    601                   << "/3:" << m_debug_data[3]
    602                   << "/4:" << m_debug_data[4]
    603                   << "/5:" << m_debug_data[5]
    604                   << "/6:" << m_debug_data[6]
    605                   << "/7:" << m_debug_data[7]
    606                   << "/8:" << m_debug_data[8]
    607                   << "/9:" << m_debug_data[9]
    608                   << "/A:" << m_debug_data[10]
    609                   << "/B:" << m_debug_data[11]
    610                   << "/C:" << m_debug_data[12]
    611                   << "/D:" << m_debug_data[13]
    612                   << "/E:" << m_debug_data[14]
    613                   << "/F:" << m_debug_data[15]
    614                   << std::endl;
    615     }
    616 
    617     // register values
    618     m_debug_previous_count = entry.count;
    619     m_debug_previous_valid = entry.valid;
    620     m_debug_previous_dirty = entry.dirty;
    621     for( size_t word=0 ; word<m_words ; word++ )
    622         m_debug_previous_data[word] = m_debug_data[word];
    623 }
    624 
    625 //////////////////////////////////////////////////
    626 tmpl(void) ::print_trace()
    627 //////////////////////////////////////////////////
    628 {
    629   std::cout << "MEMC " << name() << std::endl;
    630   std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]
     629        std::cout << "MEMC " << name() << std::endl;
     630        std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]
    631631            << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]
    632632            << " | " << read_fsm_str[r_read_fsm.read()]
     
    635635            << " | " << config_fsm_str[r_config_fsm.read()]
    636636            << " | " << cleanup_fsm_str[r_cleanup_fsm.read()] << std::endl;
    637   std::cout << "  "  << cc_send_fsm_str[r_cc_send_fsm.read()]
     637        std::cout << "  "  << cc_send_fsm_str[r_cc_send_fsm.read()]
    638638            << " | " << cc_receive_fsm_str[r_cc_receive_fsm.read()]
    639639            << " | " << multi_ack_fsm_str[r_multi_ack_fsm.read()]
     
    641641            << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]
    642642            << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm.read()] << std::endl;
    643   std::cout << "  "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]
     643        std::cout << "  "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]
    644644            << " | " << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]
    645645            << " | " << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]
    646646            << " | " << alloc_ivt_fsm_str[r_alloc_ivt_fsm.read()]
    647647            << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
    648 }
    649 
    650 /////////////////////////////////////////
    651 tmpl(void) ::clear_stats()
    652 /////////////////////////////////////////
    653 {
    654     m_cpt_cycles                  = 0;
    655     m_cpt_read                    = 0;
    656     m_cpt_read_miss               = 0;
    657     m_cpt_write                   = 0;
    658     m_cpt_write_miss              = 0;
    659     m_cpt_write_cells             = 0;
    660     m_cpt_write_dirty             = 0;
    661     m_cpt_update                  = 0;
    662     m_cpt_update_mult             = 0;
    663     m_cpt_inval_brdcast           = 0;
    664     m_cpt_inval                   = 0;
    665     m_cpt_inval_mult              = 0;
    666     m_cpt_cleanup                 = 0;
    667     m_cpt_cleanup_data            = 0;
    668     m_cpt_ll                      = 0;
    669     m_cpt_sc                      = 0;
    670     m_cpt_cas                     = 0;
    671     m_cpt_trt_full                = 0;
    672     m_cpt_trt_rb                  = 0;
    673     m_cpt_dir_unused              = 0;
    674     m_cpt_ivt_unused              = 0;
    675     m_cpt_heap_unused             = 0;
    676     m_cpt_trt_unused              = 0;
    677     m_cpt_read_fsm_n_dir_lock     = 0;
    678     m_cpt_read_fsm_dir_lock       = 0;
    679     m_cpt_read_fsm_dir_used       = 0;
    680     m_cpt_read_fsm_trt_lock       = 0;
    681     m_cpt_read_fsm_heap_lock      = 0;
    682     m_cpt_write_fsm_dir_lock      = 0;
    683     m_cpt_write_fsm_n_dir_lock    = 0;
    684     m_cpt_write_fsm_upt_lock      = 0;
    685     m_cpt_write_fsm_heap_lock     = 0;
    686     m_cpt_write_fsm_dir_used      = 0;
    687     m_cpt_write_fsm_trt_lock      = 0;
    688     m_cpt_cas_fsm_n_dir_lock      = 0;
    689     m_cpt_cas_fsm_dir_lock        = 0;
    690     m_cpt_cas_fsm_upt_lock        = 0;
    691     m_cpt_cas_fsm_heap_lock       = 0;
    692     m_cpt_cas_fsm_trt_lock        = 0;
    693     m_cpt_cas_fsm_dir_used        = 0;
    694     m_cpt_xram_rsp_fsm_n_dir_lock = 0;
    695     m_cpt_xram_rsp_fsm_dir_lock   = 0;
    696     m_cpt_xram_rsp_fsm_trt_lock   = 0;
    697     m_cpt_xram_rsp_fsm_upt_lock   = 0;
    698     m_cpt_xram_rsp_fsm_heap_lock  = 0;
    699     m_cpt_xram_rsp_fsm_dir_used   = 0;
    700     m_cpt_cleanup_fsm_dir_lock    = 0;
    701     m_cpt_cleanup_fsm_n_dir_lock  = 0;
    702     m_cpt_cleanup_fsm_heap_lock   = 0;
    703     m_cpt_cleanup_fsm_upt_lock    = 0;
    704     m_cpt_cleanup_fsm_dir_used    = 0;
    705     m_cpt_ixr_fsm_trt_lock        = 0;
    706     m_cpt_multi_ack_fsm_upt_lock  = 0;
    707 }
    708 /////////////////////////////////////////
    709 tmpl(void) ::print_stats()
    710 /////////////////////////////////////////
    711 {
    712   std::cout << "----------------------------------" << std::dec << std::endl;
    713   std::cout
    714       << "MEM_CACHE " << name() << " / Time = " << m_cpt_cycles << std::endl
    715       << "- READ RATE                              = " << (double) m_cpt_read/m_cpt_cycles << std::endl
    716       << "- READ TOTAL                             = " << m_cpt_read << std::endl
    717       << "- READ MISS RATE                         = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
    718       << "- WRITE RATE                             = " << (double) m_cpt_write/m_cpt_cycles << std::endl
    719       << "- WRITE TOTAL                            = " << m_cpt_write << std::endl
    720       << "- WRITE MISS RATE                        = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
    721       << "- WRITE BURST LENGTH                     = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
    722       << "- WRITE BURST TOTAL                      = " << m_cpt_write_cells << std::endl
    723       << "- REQUESTS TRT FULL                      = " << m_cpt_trt_full << std::endl
    724       << "- READ TRT BLOKED HIT                    = " << m_cpt_trt_rb << std::endl
    725       << "- UPDATE RATE                            = " << (double) m_cpt_update/m_cpt_cycles << std::endl
    726       << "- UPDATE ARITY                           = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
    727       << "- INVAL MULTICAST RATE                   = " << (double)(m_cpt_inval-m_cpt_inval_brdcast) /m_cpt_cycles << std::endl
    728       << "- INVAL MULTICAST ARITY                  = " << (double) m_cpt_inval_mult/ (m_cpt_inval-m_cpt_inval_brdcast) << std::endl
    729       << "- INVAL BROADCAST RATE                   = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
    730       << "- SAVE DIRTY RATE                        = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
    731       << "- CLEANUP RATE                           = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
    732       << "- CLEANUP TOTAL                          = " << (double) m_cpt_cleanup << std::endl
    733       << "- CLEANUP WITH DATA RATE                 = " << (double) m_cpt_cleanup_data/m_cpt_cycles << std::endl
    734       << "- CLEANUP WITH DATA TOTAL                = " << (double) m_cpt_cleanup_data << std::endl
    735       << "- LL RATE                                = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
    736       << "- SC RATE                                = " << (double) m_cpt_sc/m_cpt_cycles << std::endl
    737       << "- CAS RATE                               = " << (double) m_cpt_cas/m_cpt_cycles << std::endl << std::endl;
    738 
    739      /* << "- WAIT DIR LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_dir_lock/m_cpt_read_fsm_n_dir_lock << std::endl
    740       << "- NB CYCLES IN DIR LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_dir_used/m_cpt_read_fsm_n_dir_lock << std::endl
    741       << "- WAIT DIR LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_dir_lock/m_cpt_write_fsm_n_dir_lock << std::endl
    742       << "- NB CYCLES IN DIR LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_dir_used/m_cpt_write_fsm_n_dir_lock << std::endl
    743       << "- WAIT DIR LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_dir_lock/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
    744       << "- 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
    745       << "- WAIT DIR LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_dir_lock/m_cpt_cleanup_fsm_n_dir_lock << std::endl
    746       << "- NB CYCLES IN DIR LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_dir_used/m_cpt_cleanup_fsm_n_dir_lock << std::endl
    747       << "- WAIT DIR LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_dir_lock/m_cpt_cas_fsm_n_dir_lock << std::endl
    748       << "- NB CYCLES IN LOCK in CAS_FSM           = " << (double) m_cpt_cas_fsm_dir_used/m_cpt_cas_fsm_n_dir_lock << std::endl
    749       << "- DIR UNUSED RATE                        = " << (double) m_cpt_dir_unused/m_cpt_cycles << std::endl << std::endl
    750      
    751       << "- WAIT TRT LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_trt_lock/m_cpt_read_fsm_n_trt_lock << std::endl
    752       << "- NB CYCLES IN TRT LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_trt_used/m_cpt_read_fsm_n_trt_lock << std::endl
    753       << "- WAIT TRT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_trt_lock/m_cpt_write_fsm_n_trt_lock << std::endl
    754       << "- NB CYCLES IN TRT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_trt_used/m_cpt_write_fsm_n_trt_lock << std::endl
    755       << "- WAIT TRT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_trt_lock/m_cpt_cas_fsm_n_trt_lock << std::endl
    756       << "- NB CYCLES IN TRT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_trt_used/m_cpt_cas_fsm_n_trt_lock << std::endl
    757       << "- WAIT TRT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_trt_lock/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
    758       << "- 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
    759       << "- WAIT TRT LOCK in IXR_FSM               = " << (double) m_cpt_ixr_fsm_trt_lock/m_cpt_ixr_fsm_n_trt_lock << std::endl
    760       << "- NB CYCLES IN TRT LOCK in IXR_FSM       = " << (double) m_cpt_ixr_fsm_trt_used/m_cpt_ixr_fsm_n_trt_lock << std::endl
    761       << "- TRT UNUSED RATE                        = " << (double) m_cpt_trt_unused/m_cpt_cycles << std::endl << std::endl
    762      
    763       << "- WAIT UPT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_upt_lock/m_cpt_write_fsm_n_upt_lock << std::endl
    764       << "- NB CYCLES IN UPT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_upt_used/m_cpt_write_fsm_n_upt_lock << std::endl
    765       << "- WAIT UPT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_upt_lock/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
    766       << "- 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
    767       << "- WAIT UPT LOCK in MULTIACK_FSM          = " << (double) m_cpt_multi_ack_fsm_upt_lock/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
    768       << "- 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
    769       << "- WAIT UPT LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_upt_lock/m_cpt_cleanup_fsm_n_upt_lock << std::endl
    770       << "- NB CYCLES IN UPT LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_upt_used/m_cpt_cleanup_fsm_n_upt_lock << std::endl
    771       << "- WAIT UPT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_upt_lock/m_cpt_cas_fsm_n_upt_lock << std::endl
    772       << "- NB CYCLES IN UPT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_upt_used/m_cpt_cas_fsm_n_upt_lock << std::endl
    773       << "- IVT UNUSED RATE                        = " << (double) m_cpt_ivt_unused/m_cpt_cycles << std::endl << std::endl
    774      
    775       << "- WAIT HEAP LOCK in READ_FSM             = " << (double) m_cpt_read_fsm_heap_lock/m_cpt_read_fsm_n_heap_lock << std::endl
    776       << "- NB CYCLES IN HEAP LOCK in READ_FSM     = " << (double) m_cpt_read_fsm_heap_used/m_cpt_read_fsm_n_heap_lock << std::endl
    777       << "- WAIT HEAP LOCK in WRITE_FSM            = " << (double) m_cpt_write_fsm_heap_lock/m_cpt_write_fsm_n_heap_lock << std::endl
    778       << "- NB CYCLES IN HEAP LOCK in WRITE_FSM    = " << (double) m_cpt_write_fsm_heap_used/m_cpt_write_fsm_n_heap_lock << std::endl
    779       << "- WAIT HEAP LOCK in XRAM_FSM             = " << (double) m_cpt_xram_rsp_fsm_heap_lock/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
    780       << "- 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
    781       << "- WAIT HEAP LOCK in CLEANUP_FSM          = " << (double) m_cpt_cleanup_fsm_heap_lock/m_cpt_cleanup_fsm_n_heap_lock << std::endl
    782       << "- NB CYCLES IN HEAP LOCK in CLEANUP_FSM  = " << (double) m_cpt_cleanup_fsm_heap_used/m_cpt_cleanup_fsm_n_heap_lock << std::endl
    783       << "- WAIT HEAP LOCK in CAS_FSM              = " << (double) m_cpt_cas_fsm_heap_lock/m_cpt_cas_fsm_n_heap_lock << std::endl
    784       << "- NB CYCLES IN HEAP LOCK in CAS_FSM      = " << (double) m_cpt_cas_fsm_heap_used/m_cpt_cas_fsm_n_heap_lock << std::endl
    785       << "- HEAP UNUSED RATE                       = " << (double) m_cpt_heap_unused/m_cpt_cycles << std::endl;*/
    786 }
    787 
    788 /////////////////////////////////
    789 tmpl(/**/) ::~VciMemCache()
    790 /////////////////////////////////
    791 {
    792   delete [] r_ixr_rsp_to_xram_rsp_rok;
    793   //delete [] r_ixr_rsp_to_xram_rsp_no_coherent;
    794 
    795   delete [] r_xram_rsp_victim_data;
    796   delete [] r_xram_rsp_to_tgt_rsp_data;
    797 
    798   delete [] r_read_data;
    799   delete [] r_read_to_tgt_rsp_data;
    800 
    801   delete [] r_write_data;
    802   delete [] r_write_be;
    803   delete [] r_write_to_cc_send_data;
    804 
    805   delete [] r_cleanup_data;
    806   delete [] r_ixr_cmd_data;
    807   delete [] r_cleanup_to_ixr_cmd_data;
    808 }
    809 
    810 //////////////////////////////////
    811 tmpl(void) ::transition()
    812 //////////////////////////////////
    813 {
    814   using soclib::common::uint32_log2;
    815 
    816   // RESET
    817   if(! p_resetn.read())
    818   {
    819 
    820     // Initializing FSMs
    821     r_tgt_cmd_fsm    = TGT_CMD_IDLE;
    822     r_config_fsm     = CONFIG_IDLE;
    823     r_tgt_rsp_fsm    = TGT_RSP_TGT_CMD_IDLE;
    824     r_cc_send_fsm    = CC_SEND_XRAM_RSP_IDLE;
    825     r_cc_receive_fsm = CC_RECEIVE_IDLE;
    826     r_multi_ack_fsm  = MULTI_ACK_IDLE;
    827     r_read_fsm       = READ_IDLE;
    828     r_write_fsm      = WRITE_IDLE;
    829     r_cas_fsm        = CAS_IDLE;
    830     r_cleanup_fsm    = CLEANUP_IDLE;
    831     r_alloc_dir_fsm  = ALLOC_DIR_RESET;
    832     r_alloc_heap_fsm = ALLOC_HEAP_RESET;
    833     r_alloc_trt_fsm  = ALLOC_TRT_READ;
    834     r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
    835     r_alloc_ivt_fsm  = ALLOC_IVT_XRAM_RSP;
    836     r_ixr_rsp_fsm    = IXR_RSP_IDLE;
    837     r_xram_rsp_fsm   = XRAM_RSP_IDLE;
    838     r_ixr_cmd_fsm    = IXR_CMD_READ_IDLE;
    839 
    840     m_debug                = false;
    841     m_debug_previous_valid = false;
    842     m_debug_previous_dirty = false;
    843     m_debug_previous_count = 0;
    844 
    845     //  Initializing Tables
    846     m_trt.init();
    847     m_upt.init();
    848     m_ivt.init();
    849     m_llsc_table.init();
    850 
    851     // initializing FIFOs and communication Buffers
    852 
    853     m_cmd_read_addr_fifo.init();
    854     m_cmd_read_length_fifo.init();
    855     m_cmd_read_srcid_fifo.init();
    856     m_cmd_read_trdid_fifo.init();
    857     m_cmd_read_pktid_fifo.init();
    858 
    859     m_cmd_write_addr_fifo.init();
    860     m_cmd_write_eop_fifo.init();
    861     m_cmd_write_srcid_fifo.init();
    862     m_cmd_write_trdid_fifo.init();
    863     m_cmd_write_pktid_fifo.init();
    864     m_cmd_write_data_fifo.init();
    865 
    866     m_cmd_cas_addr_fifo.init()  ;
    867     m_cmd_cas_srcid_fifo.init() ;
    868     m_cmd_cas_trdid_fifo.init() ;
    869     m_cmd_cas_pktid_fifo.init() ;
    870     m_cmd_cas_wdata_fifo.init() ;
    871     m_cmd_cas_eop_fifo.init()   ;
    872 
    873     r_config_cmd  = MEMC_CMD_NOP;
    874     r_config_lock = false;
    875 
    876     m_config_to_cc_send_inst_fifo.init();
    877     m_config_to_cc_send_srcid_fifo.init();
    878 
    879     r_tgt_cmd_to_tgt_rsp_req = false;
    880 
    881     r_read_to_tgt_rsp_req = false;
    882     r_read_to_ixr_cmd_req = false;
    883 
    884     r_write_to_tgt_rsp_req          = false;
    885     r_write_to_ixr_cmd_req          = false;
    886     r_write_to_cc_send_multi_req    = false;
    887     r_write_to_cc_send_brdcast_req  = false;
    888     r_write_to_multi_ack_req        = false;
    889 
    890     m_write_to_cc_send_inst_fifo.init();
    891     m_write_to_cc_send_srcid_fifo.init();
    892 
    893     r_cleanup_to_tgt_rsp_req      = false;
    894 
    895     m_cc_receive_to_cleanup_fifo.init();
    896 
    897     r_multi_ack_to_tgt_rsp_req    = false;
    898 
    899     m_cc_receive_to_multi_ack_fifo.init();
    900 
    901     r_cas_to_tgt_rsp_req          = false;
    902     r_cas_cpt                     = 0    ;
    903     r_cas_lfsr                    = -1   ;
    904     r_cas_to_ixr_cmd_req          = false;
    905     r_cas_to_cc_send_multi_req    = false;
    906     r_cas_to_cc_send_brdcast_req  = false;
    907 
    908     m_cas_to_cc_send_inst_fifo.init();
    909     m_cas_to_cc_send_srcid_fifo.init();
    910 
    911     for(size_t i=0; i<m_trt_lines ; i++)
     648    }
     649
     650    /////////////////////////////////////////
     651    tmpl(void) ::clear_stats()
     652        /////////////////////////////////////////
    912653    {
    913       r_ixr_rsp_to_xram_rsp_rok[i] = false;
    914       //r_ixr_rsp_to_xram_rsp_no_coherent[i] = false;
     654        m_cpt_cycles                  = 0;
     655        m_cpt_read                    = 0;
     656        m_cpt_read_miss               = 0;
     657        m_cpt_write                   = 0;
     658        m_cpt_write_miss              = 0;
     659        m_cpt_write_cells             = 0;
     660        m_cpt_write_dirty             = 0;
     661        m_cpt_update                  = 0;
     662        m_cpt_update_mult             = 0;
     663        m_cpt_inval_brdcast           = 0;
     664        m_cpt_inval                   = 0;
     665        m_cpt_inval_mult              = 0;
     666        m_cpt_cleanup                 = 0;
     667        m_cpt_cleanup_data            = 0;
     668        m_cpt_ll                      = 0;
     669        m_cpt_sc                      = 0;
     670        m_cpt_cas                     = 0;
     671        m_cpt_trt_full                = 0;
     672        m_cpt_trt_rb                  = 0;
     673        m_cpt_dir_unused              = 0;
     674        m_cpt_ivt_unused              = 0;
     675        m_cpt_heap_unused             = 0;
     676        m_cpt_trt_unused              = 0;
     677        m_cpt_read_fsm_n_dir_lock     = 0;
     678        m_cpt_read_fsm_dir_lock       = 0;
     679        m_cpt_read_fsm_dir_used       = 0;
     680        m_cpt_read_fsm_trt_lock       = 0;
     681        m_cpt_read_fsm_heap_lock      = 0;
     682        m_cpt_write_fsm_dir_lock      = 0;
     683        m_cpt_write_fsm_n_dir_lock    = 0;
     684        m_cpt_write_fsm_upt_lock      = 0;
     685        m_cpt_write_fsm_heap_lock     = 0;
     686        m_cpt_write_fsm_dir_used      = 0;
     687        m_cpt_write_fsm_trt_lock      = 0;
     688        m_cpt_cas_fsm_n_dir_lock      = 0;
     689        m_cpt_cas_fsm_dir_lock        = 0;
     690        m_cpt_cas_fsm_upt_lock        = 0;
     691        m_cpt_cas_fsm_heap_lock       = 0;
     692        m_cpt_cas_fsm_trt_lock        = 0;
     693        m_cpt_cas_fsm_dir_used        = 0;
     694        m_cpt_xram_rsp_fsm_n_dir_lock = 0;
     695        m_cpt_xram_rsp_fsm_dir_lock   = 0;
     696        m_cpt_xram_rsp_fsm_trt_lock   = 0;
     697        m_cpt_xram_rsp_fsm_upt_lock   = 0;
     698        m_cpt_xram_rsp_fsm_heap_lock  = 0;
     699        m_cpt_xram_rsp_fsm_dir_used   = 0;
     700        m_cpt_cleanup_fsm_dir_lock    = 0;
     701        m_cpt_cleanup_fsm_n_dir_lock  = 0;
     702        m_cpt_cleanup_fsm_heap_lock   = 0;
     703        m_cpt_cleanup_fsm_upt_lock    = 0;
     704        m_cpt_cleanup_fsm_dir_used    = 0;
     705        m_cpt_ixr_fsm_trt_lock        = 0;
     706        m_cpt_multi_ack_fsm_upt_lock  = 0;
    915707    }
    916 
    917     r_xram_rsp_to_tgt_rsp_req          = false;
    918     r_xram_rsp_to_cc_send_multi_req   = false;
    919     r_xram_rsp_to_cc_send_brdcast_req = false;
    920     r_xram_rsp_to_ixr_cmd_req          = false;
    921     r_xram_rsp_trt_index               = 0;
    922 
    923     m_xram_rsp_to_cc_send_inst_fifo.init();
    924     m_xram_rsp_to_cc_send_srcid_fifo.init();
    925 
    926     r_alloc_dir_reset_cpt  = 0;
    927     r_alloc_heap_reset_cpt = 0;
    928 
    929     r_tgt_rsp_key_sent  = false;
    930 
    931     // ODCCP
    932     r_cleanup_data_index       = 0;
    933     r_cleanup_trdid            = 0;
    934     r_cleanup_pktid            = 0;
    935     r_cleanup_contains_data    = false;
    936     r_cleanup_to_ixr_cmd_req   = false;
    937     //r_cleanup_to_ixr_cmd_l1_dirty_ncc = false;
    938     //r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
    939     r_cleanup_to_ixr_cmd_srcid = 0;
    940     r_cleanup_to_ixr_cmd_index = 0;
    941     r_cleanup_to_ixr_cmd_pktid = 0;
    942     r_cleanup_to_ixr_cmd_nline = 0;
    943     for (size_t word = 0; word < m_words; word ++)
     708    /////////////////////////////////////////
     709    tmpl(void) ::print_stats()
     710        /////////////////////////////////////////
    944711    {
    945       r_cleanup_to_ixr_cmd_data[word] = 0;
    946       r_cleanup_data[word] = 0;
    947       r_ixr_cmd_wdata[word] = 0;
     712        std::cout << "----------------------------------" << std::dec << std::endl;
     713        std::cout
     714            << "MEM_CACHE " << name() << " / Time = " << m_cpt_cycles << std::endl
     715            << "- READ RATE                              = " << (double) m_cpt_read/m_cpt_cycles << std::endl
     716            << "- READ TOTAL                             = " << m_cpt_read << std::endl
     717            << "- READ MISS RATE                         = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
     718            << "- WRITE RATE                             = " << (double) m_cpt_write/m_cpt_cycles << std::endl
     719            << "- WRITE TOTAL                            = " << m_cpt_write << std::endl
     720            << "- WRITE MISS RATE                        = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
     721            << "- WRITE BURST LENGTH                     = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
     722            << "- WRITE BURST TOTAL                      = " << m_cpt_write_cells << std::endl
     723            << "- REQUESTS TRT FULL                      = " << m_cpt_trt_full << std::endl
     724            << "- READ TRT BLOKED HIT                    = " << m_cpt_trt_rb << std::endl
     725            << "- UPDATE RATE                            = " << (double) m_cpt_update/m_cpt_cycles << std::endl
     726            << "- UPDATE ARITY                           = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
     727            << "- INVAL MULTICAST RATE                   = " << (double)(m_cpt_inval-m_cpt_inval_brdcast) /m_cpt_cycles << std::endl
     728            << "- INVAL MULTICAST ARITY                  = " << (double) m_cpt_inval_mult/ (m_cpt_inval-m_cpt_inval_brdcast) << std::endl
     729            << "- INVAL BROADCAST RATE                   = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
     730            << "- SAVE DIRTY RATE                        = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
     731            << "- CLEANUP RATE                           = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
     732            << "- CLEANUP TOTAL                          = " << (double) m_cpt_cleanup << std::endl
     733            << "- CLEANUP WITH DATA RATE                 = " << (double) m_cpt_cleanup_data/m_cpt_cycles << std::endl
     734            << "- CLEANUP WITH DATA TOTAL                = " << (double) m_cpt_cleanup_data << std::endl
     735            << "- LL RATE                                = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
     736            << "- SC RATE                                = " << (double) m_cpt_sc/m_cpt_cycles << std::endl
     737            << "- CAS RATE                               = " << (double) m_cpt_cas/m_cpt_cycles << std::endl << std::endl;
     738
     739        /* << "- WAIT DIR LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_dir_lock/m_cpt_read_fsm_n_dir_lock << std::endl
     740           << "- NB CYCLES IN DIR LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_dir_used/m_cpt_read_fsm_n_dir_lock << std::endl
     741           << "- WAIT DIR LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_dir_lock/m_cpt_write_fsm_n_dir_lock << std::endl
     742           << "- NB CYCLES IN DIR LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_dir_used/m_cpt_write_fsm_n_dir_lock << std::endl
     743           << "- WAIT DIR LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_dir_lock/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
     744           << "- 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
     745           << "- WAIT DIR LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_dir_lock/m_cpt_cleanup_fsm_n_dir_lock << std::endl
     746           << "- NB CYCLES IN DIR LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_dir_used/m_cpt_cleanup_fsm_n_dir_lock << std::endl
     747           << "- WAIT DIR LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_dir_lock/m_cpt_cas_fsm_n_dir_lock << std::endl
     748           << "- NB CYCLES IN LOCK in CAS_FSM           = " << (double) m_cpt_cas_fsm_dir_used/m_cpt_cas_fsm_n_dir_lock << std::endl
     749           << "- DIR UNUSED RATE                        = " << (double) m_cpt_dir_unused/m_cpt_cycles << std::endl << std::endl
     750
     751           << "- WAIT TRT LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_trt_lock/m_cpt_read_fsm_n_trt_lock << std::endl
     752           << "- NB CYCLES IN TRT LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_trt_used/m_cpt_read_fsm_n_trt_lock << std::endl
     753           << "- WAIT TRT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_trt_lock/m_cpt_write_fsm_n_trt_lock << std::endl
     754           << "- NB CYCLES IN TRT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_trt_used/m_cpt_write_fsm_n_trt_lock << std::endl
     755           << "- WAIT TRT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_trt_lock/m_cpt_cas_fsm_n_trt_lock << std::endl
     756           << "- NB CYCLES IN TRT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_trt_used/m_cpt_cas_fsm_n_trt_lock << std::endl
     757           << "- WAIT TRT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_trt_lock/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
     758           << "- 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
     759           << "- WAIT TRT LOCK in IXR_FSM               = " << (double) m_cpt_ixr_fsm_trt_lock/m_cpt_ixr_fsm_n_trt_lock << std::endl
     760           << "- NB CYCLES IN TRT LOCK in IXR_FSM       = " << (double) m_cpt_ixr_fsm_trt_used/m_cpt_ixr_fsm_n_trt_lock << std::endl
     761           << "- TRT UNUSED RATE                        = " << (double) m_cpt_trt_unused/m_cpt_cycles << std::endl << std::endl
     762
     763           << "- WAIT UPT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_upt_lock/m_cpt_write_fsm_n_upt_lock << std::endl
     764           << "- NB CYCLES IN UPT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_upt_used/m_cpt_write_fsm_n_upt_lock << std::endl
     765           << "- WAIT UPT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_upt_lock/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
     766           << "- 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
     767           << "- WAIT UPT LOCK in MULTIACK_FSM          = " << (double) m_cpt_multi_ack_fsm_upt_lock/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
     768           << "- 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
     769           << "- WAIT UPT LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_upt_lock/m_cpt_cleanup_fsm_n_upt_lock << std::endl
     770           << "- NB CYCLES IN UPT LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_upt_used/m_cpt_cleanup_fsm_n_upt_lock << std::endl
     771           << "- WAIT UPT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_upt_lock/m_cpt_cas_fsm_n_upt_lock << std::endl
     772           << "- NB CYCLES IN UPT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_upt_used/m_cpt_cas_fsm_n_upt_lock << std::endl
     773           << "- IVT UNUSED RATE                        = " << (double) m_cpt_ivt_unused/m_cpt_cycles << std::endl << std::endl
     774
     775           << "- WAIT HEAP LOCK in READ_FSM             = " << (double) m_cpt_read_fsm_heap_lock/m_cpt_read_fsm_n_heap_lock << std::endl
     776           << "- NB CYCLES IN HEAP LOCK in READ_FSM     = " << (double) m_cpt_read_fsm_heap_used/m_cpt_read_fsm_n_heap_lock << std::endl
     777           << "- WAIT HEAP LOCK in WRITE_FSM            = " << (double) m_cpt_write_fsm_heap_lock/m_cpt_write_fsm_n_heap_lock << std::endl
     778           << "- NB CYCLES IN HEAP LOCK in WRITE_FSM    = " << (double) m_cpt_write_fsm_heap_used/m_cpt_write_fsm_n_heap_lock << std::endl
     779           << "- WAIT HEAP LOCK in XRAM_FSM             = " << (double) m_cpt_xram_rsp_fsm_heap_lock/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
     780           << "- 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
     781           << "- WAIT HEAP LOCK in CLEANUP_FSM          = " << (double) m_cpt_cleanup_fsm_heap_lock/m_cpt_cleanup_fsm_n_heap_lock << std::endl
     782           << "- NB CYCLES IN HEAP LOCK in CLEANUP_FSM  = " << (double) m_cpt_cleanup_fsm_heap_used/m_cpt_cleanup_fsm_n_heap_lock << std::endl
     783           << "- WAIT HEAP LOCK in CAS_FSM              = " << (double) m_cpt_cas_fsm_heap_lock/m_cpt_cas_fsm_n_heap_lock << std::endl
     784           << "- NB CYCLES IN HEAP LOCK in CAS_FSM      = " << (double) m_cpt_cas_fsm_heap_used/m_cpt_cas_fsm_n_heap_lock << std::endl
     785           << "- HEAP UNUSED RATE                       = " << (double) m_cpt_heap_unused/m_cpt_cycles << std::endl;*/
    948786    }
    949787
    950 
    951     // Activity counters
    952     m_cpt_cycles                  = 0;
    953     m_cpt_read                    = 0;
    954     m_cpt_read_miss               = 0;
    955     m_cpt_write                   = 0;
    956     m_cpt_write_miss              = 0;
    957     m_cpt_write_cells             = 0;
    958     m_cpt_write_dirty             = 0;
    959     m_cpt_update                  = 0;
    960     m_cpt_update_mult             = 0;
    961     m_cpt_inval_brdcast           = 0;
    962     m_cpt_inval                   = 0;
    963     m_cpt_inval_mult              = 0;
    964     m_cpt_cleanup                 = 0;
    965     m_cpt_cleanup_data            = 0;
    966     m_cpt_ll                      = 0;
    967     m_cpt_sc                      = 0;
    968     m_cpt_cas                     = 0;
    969     m_cpt_trt_full                = 0;
    970     m_cpt_trt_rb                  = 0;
    971     m_cpt_dir_unused              = 0;
    972     m_cpt_ivt_unused              = 0;
    973     m_cpt_heap_unused             = 0;
    974     m_cpt_trt_unused              = 0;
    975     m_cpt_read_fsm_n_dir_lock     = 0;
    976     m_cpt_read_fsm_dir_lock       = 0;
    977     m_cpt_read_fsm_dir_used       = 0;
    978     m_cpt_read_fsm_trt_lock       = 0;
    979     m_cpt_read_fsm_heap_lock      = 0;
    980     m_cpt_write_fsm_dir_lock      = 0;
    981     m_cpt_write_fsm_n_dir_lock    = 0;
    982     m_cpt_write_fsm_upt_lock      = 0;
    983     m_cpt_write_fsm_heap_lock     = 0;
    984     m_cpt_write_fsm_dir_used      = 0;
    985     m_cpt_write_fsm_trt_lock      = 0;
    986     m_cpt_cas_fsm_n_dir_lock      = 0;
    987     m_cpt_cas_fsm_dir_lock        = 0;
    988     m_cpt_cas_fsm_upt_lock        = 0;
    989     m_cpt_cas_fsm_heap_lock       = 0;
    990     m_cpt_cas_fsm_trt_lock        = 0;
    991     m_cpt_cas_fsm_dir_used        = 0;
    992     m_cpt_xram_rsp_fsm_n_dir_lock = 0;
    993     m_cpt_xram_rsp_fsm_dir_lock   = 0;
    994     m_cpt_xram_rsp_fsm_trt_lock   = 0;
    995     m_cpt_xram_rsp_fsm_upt_lock   = 0;
    996     m_cpt_xram_rsp_fsm_heap_lock  = 0;
    997     m_cpt_xram_rsp_fsm_dir_used   = 0;
    998     m_cpt_cleanup_fsm_dir_lock    = 0;
    999     m_cpt_cleanup_fsm_n_dir_lock  = 0;
    1000     m_cpt_cleanup_fsm_heap_lock   = 0;
    1001     m_cpt_cleanup_fsm_upt_lock    = 0;
    1002     m_cpt_cleanup_fsm_dir_used    = 0;
    1003     m_cpt_ixr_fsm_trt_lock        = 0;
    1004     m_cpt_multi_ack_fsm_upt_lock  = 0;
    1005 
    1006     return;
    1007   }
    1008 
    1009   bool    cmd_read_fifo_put = false;
    1010   bool    cmd_read_fifo_get = false;
    1011 
    1012   bool    cmd_write_fifo_put = false;
    1013   bool    cmd_write_fifo_get = false;
    1014 
    1015   bool    cmd_cas_fifo_put = false;
    1016   bool    cmd_cas_fifo_get = false;
    1017 
    1018   bool    cc_receive_to_cleanup_fifo_get = false;
    1019   bool    cc_receive_to_cleanup_fifo_put = false;
    1020 
    1021   bool    cc_receive_to_multi_ack_fifo_get = false;
    1022   bool    cc_receive_to_multi_ack_fifo_put = false;
    1023 
    1024   bool    write_to_cc_send_fifo_put   = false;
    1025   bool    write_to_cc_send_fifo_get   = false;
    1026   bool    write_to_cc_send_fifo_inst  = false;
    1027   size_t  write_to_cc_send_fifo_srcid = 0;
    1028 
    1029   bool    xram_rsp_to_cc_send_fifo_put   = false;
    1030   bool    xram_rsp_to_cc_send_fifo_get   = false;
    1031   bool    xram_rsp_to_cc_send_fifo_inst  = false;
    1032   size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
    1033 
    1034   bool    config_to_cc_send_fifo_put   = false;
    1035   bool    config_to_cc_send_fifo_get   = false;
    1036   bool    config_to_cc_send_fifo_inst  = false;
    1037   size_t  config_to_cc_send_fifo_srcid = 0;
    1038 
    1039   bool    cas_to_cc_send_fifo_put   = false;
    1040   bool    cas_to_cc_send_fifo_get   = false;
    1041   bool    cas_to_cc_send_fifo_inst  = false;
    1042   size_t  cas_to_cc_send_fifo_srcid = 0;
    1043 
    1044   m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     788    /////////////////////////////////
     789    tmpl(/**/) ::~VciMemCache()
     790        /////////////////////////////////
     791    {
     792        delete [] r_ixr_rsp_to_xram_rsp_rok;
     793        //delete [] r_ixr_rsp_to_xram_rsp_no_coherent;
     794
     795        delete [] r_xram_rsp_victim_data;
     796        delete [] r_xram_rsp_to_tgt_rsp_data;
     797
     798        delete [] r_read_data;
     799        delete [] r_read_to_tgt_rsp_data;
     800
     801        delete [] r_write_data;
     802        delete [] r_write_be;
     803        delete [] r_write_to_cc_send_data;
     804
     805        delete [] r_cleanup_data;
     806        delete [] r_ixr_cmd_data;
     807        delete [] r_cleanup_to_ixr_cmd_data;
     808    }
     809
     810    //////////////////////////////////
     811    tmpl(void) ::transition()
     812        //////////////////////////////////
     813    {
     814        using soclib::common::uint32_log2;
     815
     816        // RESET
     817        if(! p_resetn.read())
     818        {
     819
     820            // Initializing FSMs
     821            r_tgt_cmd_fsm    = TGT_CMD_IDLE;
     822            r_config_fsm     = CONFIG_IDLE;
     823            r_tgt_rsp_fsm    = TGT_RSP_TGT_CMD_IDLE;
     824            r_cc_send_fsm    = CC_SEND_XRAM_RSP_IDLE;
     825            r_cc_receive_fsm = CC_RECEIVE_IDLE;
     826            r_multi_ack_fsm  = MULTI_ACK_IDLE;
     827            r_read_fsm       = READ_IDLE;
     828            r_write_fsm      = WRITE_IDLE;
     829            r_cas_fsm        = CAS_IDLE;
     830            r_cleanup_fsm    = CLEANUP_IDLE;
     831            r_alloc_dir_fsm  = ALLOC_DIR_RESET;
     832            r_alloc_heap_fsm = ALLOC_HEAP_RESET;
     833            r_alloc_trt_fsm  = ALLOC_TRT_READ;
     834            r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
     835            r_alloc_ivt_fsm  = ALLOC_IVT_XRAM_RSP;
     836            r_ixr_rsp_fsm    = IXR_RSP_IDLE;
     837            r_xram_rsp_fsm   = XRAM_RSP_IDLE;
     838            r_ixr_cmd_fsm    = IXR_CMD_READ_IDLE;
     839
     840            m_debug                = false;
     841            m_debug_previous_valid = false;
     842            m_debug_previous_dirty = false;
     843            m_debug_previous_count = 0;
     844
     845            //  Initializing Tables
     846            m_trt.init();
     847            m_upt.init();
     848            m_ivt.init();
     849            m_llsc_table.init();
     850
     851            // initializing FIFOs and communication Buffers
     852
     853            m_cmd_read_addr_fifo.init();
     854            m_cmd_read_length_fifo.init();
     855            m_cmd_read_srcid_fifo.init();
     856            m_cmd_read_trdid_fifo.init();
     857            m_cmd_read_pktid_fifo.init();
     858
     859            m_cmd_write_addr_fifo.init();
     860            m_cmd_write_eop_fifo.init();
     861            m_cmd_write_srcid_fifo.init();
     862            m_cmd_write_trdid_fifo.init();
     863            m_cmd_write_pktid_fifo.init();
     864            m_cmd_write_data_fifo.init();
     865
     866            m_cmd_cas_addr_fifo.init()  ;
     867            m_cmd_cas_srcid_fifo.init() ;
     868            m_cmd_cas_trdid_fifo.init() ;
     869            m_cmd_cas_pktid_fifo.init() ;
     870            m_cmd_cas_wdata_fifo.init() ;
     871            m_cmd_cas_eop_fifo.init()   ;
     872
     873            r_config_cmd  = MEMC_CMD_NOP;
     874            r_config_lock = false;
     875
     876            m_config_to_cc_send_inst_fifo.init();
     877            m_config_to_cc_send_srcid_fifo.init();
     878
     879            r_tgt_cmd_to_tgt_rsp_req = false;
     880
     881            r_read_to_tgt_rsp_req = false;
     882            r_read_to_ixr_cmd_req = false;
     883
     884            r_write_to_tgt_rsp_req          = false;
     885            r_write_to_ixr_cmd_req          = false;
     886            r_write_to_cc_send_multi_req    = false;
     887            r_write_to_cc_send_brdcast_req  = false;
     888            r_write_to_multi_ack_req        = false;
     889
     890            m_write_to_cc_send_inst_fifo.init();
     891            m_write_to_cc_send_srcid_fifo.init();
     892
     893            r_cleanup_to_tgt_rsp_req      = false;
     894
     895            m_cc_receive_to_cleanup_fifo.init();
     896
     897            r_multi_ack_to_tgt_rsp_req    = false;
     898
     899            m_cc_receive_to_multi_ack_fifo.init();
     900
     901            r_cas_to_tgt_rsp_req          = false;
     902            r_cas_cpt                     = 0    ;
     903            r_cas_lfsr                    = -1   ;
     904            r_cas_to_ixr_cmd_req          = false;
     905            r_cas_to_cc_send_multi_req    = false;
     906            r_cas_to_cc_send_brdcast_req  = false;
     907
     908            m_cas_to_cc_send_inst_fifo.init();
     909            m_cas_to_cc_send_srcid_fifo.init();
     910
     911            for(size_t i=0; i<m_trt_lines ; i++)
     912            {
     913                r_ixr_rsp_to_xram_rsp_rok[i] = false;
     914                //r_ixr_rsp_to_xram_rsp_no_coherent[i] = false;
     915            }
     916
     917            r_xram_rsp_to_tgt_rsp_req          = false;
     918            r_xram_rsp_to_cc_send_multi_req   = false;
     919            r_xram_rsp_to_cc_send_brdcast_req = false;
     920            r_xram_rsp_to_ixr_cmd_req          = false;
     921            r_xram_rsp_trt_index               = 0;
     922
     923            m_xram_rsp_to_cc_send_inst_fifo.init();
     924            m_xram_rsp_to_cc_send_srcid_fifo.init();
     925
     926            r_alloc_dir_reset_cpt  = 0;
     927            r_alloc_heap_reset_cpt = 0;
     928
     929            r_tgt_rsp_key_sent  = false;
     930
     931            // ODCCP
     932            r_cleanup_data_index       = 0;
     933            r_cleanup_trdid            = 0;
     934            r_cleanup_pktid            = 0;
     935            r_cleanup_contains_data    = false;
     936            r_cleanup_to_ixr_cmd_req   = false;
     937            //r_cleanup_to_ixr_cmd_l1_dirty_ncc = false;
     938            //r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
     939            r_cleanup_to_ixr_cmd_srcid = 0;
     940            r_cleanup_to_ixr_cmd_index = 0;
     941            r_cleanup_to_ixr_cmd_pktid = 0;
     942            r_cleanup_to_ixr_cmd_nline = 0;
     943            for (size_t word = 0; word < m_words; word ++)
     944            {
     945                r_cleanup_to_ixr_cmd_data[word] = 0;
     946                r_cleanup_data[word] = 0;
     947                r_ixr_cmd_wdata[word] = 0;
     948            }
     949
     950
     951            // Activity counters
     952            m_cpt_cycles                  = 0;
     953            m_cpt_read                    = 0;
     954            m_cpt_read_miss               = 0;
     955            m_cpt_write                   = 0;
     956            m_cpt_write_miss              = 0;
     957            m_cpt_write_cells             = 0;
     958            m_cpt_write_dirty             = 0;
     959            m_cpt_update                  = 0;
     960            m_cpt_update_mult             = 0;
     961            m_cpt_inval_brdcast           = 0;
     962            m_cpt_inval                   = 0;
     963            m_cpt_inval_mult              = 0;
     964            m_cpt_cleanup                 = 0;
     965            m_cpt_cleanup_data            = 0;
     966            m_cpt_ll                      = 0;
     967            m_cpt_sc                      = 0;
     968            m_cpt_cas                     = 0;
     969            m_cpt_trt_full                = 0;
     970            m_cpt_trt_rb                  = 0;
     971            m_cpt_dir_unused              = 0;
     972            m_cpt_ivt_unused              = 0;
     973            m_cpt_heap_unused             = 0;
     974            m_cpt_trt_unused              = 0;
     975            m_cpt_read_fsm_n_dir_lock     = 0;
     976            m_cpt_read_fsm_dir_lock       = 0;
     977            m_cpt_read_fsm_dir_used       = 0;
     978            m_cpt_read_fsm_trt_lock       = 0;
     979            m_cpt_read_fsm_heap_lock      = 0;
     980            m_cpt_write_fsm_dir_lock      = 0;
     981            m_cpt_write_fsm_n_dir_lock    = 0;
     982            m_cpt_write_fsm_upt_lock      = 0;
     983            m_cpt_write_fsm_heap_lock     = 0;
     984            m_cpt_write_fsm_dir_used      = 0;
     985            m_cpt_write_fsm_trt_lock      = 0;
     986            m_cpt_cas_fsm_n_dir_lock      = 0;
     987            m_cpt_cas_fsm_dir_lock        = 0;
     988            m_cpt_cas_fsm_upt_lock        = 0;
     989            m_cpt_cas_fsm_heap_lock       = 0;
     990            m_cpt_cas_fsm_trt_lock        = 0;
     991            m_cpt_cas_fsm_dir_used        = 0;
     992            m_cpt_xram_rsp_fsm_n_dir_lock = 0;
     993            m_cpt_xram_rsp_fsm_dir_lock   = 0;
     994            m_cpt_xram_rsp_fsm_trt_lock   = 0;
     995            m_cpt_xram_rsp_fsm_upt_lock   = 0;
     996            m_cpt_xram_rsp_fsm_heap_lock  = 0;
     997            m_cpt_xram_rsp_fsm_dir_used   = 0;
     998            m_cpt_cleanup_fsm_dir_lock    = 0;
     999            m_cpt_cleanup_fsm_n_dir_lock  = 0;
     1000            m_cpt_cleanup_fsm_heap_lock   = 0;
     1001            m_cpt_cleanup_fsm_upt_lock    = 0;
     1002            m_cpt_cleanup_fsm_dir_used    = 0;
     1003            m_cpt_ixr_fsm_trt_lock        = 0;
     1004            m_cpt_multi_ack_fsm_upt_lock  = 0;
     1005
     1006            return;
     1007        }
     1008
     1009        bool    cmd_read_fifo_put = false;
     1010        bool    cmd_read_fifo_get = false;
     1011
     1012        bool    cmd_write_fifo_put = false;
     1013        bool    cmd_write_fifo_get = false;
     1014
     1015        bool    cmd_cas_fifo_put = false;
     1016        bool    cmd_cas_fifo_get = false;
     1017
     1018        bool    cc_receive_to_cleanup_fifo_get = false;
     1019        bool    cc_receive_to_cleanup_fifo_put = false;
     1020
     1021        bool    cc_receive_to_multi_ack_fifo_get = false;
     1022        bool    cc_receive_to_multi_ack_fifo_put = false;
     1023
     1024        bool    write_to_cc_send_fifo_put   = false;
     1025        bool    write_to_cc_send_fifo_get   = false;
     1026        bool    write_to_cc_send_fifo_inst  = false;
     1027        size_t  write_to_cc_send_fifo_srcid = 0;
     1028
     1029        bool    xram_rsp_to_cc_send_fifo_put   = false;
     1030        bool    xram_rsp_to_cc_send_fifo_get   = false;
     1031        bool    xram_rsp_to_cc_send_fifo_inst  = false;
     1032        size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
     1033
     1034        bool    config_to_cc_send_fifo_put   = false;
     1035        bool    config_to_cc_send_fifo_get   = false;
     1036        bool    config_to_cc_send_fifo_inst  = false;
     1037        size_t  config_to_cc_send_fifo_srcid = 0;
     1038
     1039        bool    cas_to_cc_send_fifo_put   = false;
     1040        bool    cas_to_cc_send_fifo_get   = false;
     1041        bool    cas_to_cc_send_fifo_inst  = false;
     1042        size_t  cas_to_cc_send_fifo_srcid = 0;
     1043
     1044        m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    10451045
    10461046#if DEBUG_MEMC_GLOBAL
    1047 if(m_debug)
    1048 {
    1049     std::cout
    1050         << "---------------------------------------------"           << std::dec << std::endl
    1051         << "MEM_CACHE "            << name()
    1052         << " ; Time = "            << m_cpt_cycles                                << std::endl
    1053         << " - TGT_CMD FSM    = "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]       << std::endl
    1054         << " - TGT_RSP FSM    = "  << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]       << std::endl
    1055         << " - CC_SEND FSM  = "    << cc_send_fsm_str[r_cc_send_fsm.read()]       << std::endl
    1056         << " - CC_RECEIVE FSM  = " << cc_receive_fsm_str[r_cc_receive_fsm.read()] << std::endl
    1057         << " - MULTI_ACK FSM  = "  << multi_ack_fsm_str[r_multi_ack_fsm.read()]   << std::endl
    1058         << " - READ FSM       = "  << read_fsm_str[r_read_fsm.read()]             << std::endl
    1059         << " - WRITE FSM      = "  << write_fsm_str[r_write_fsm.read()]           << std::endl
    1060         << " - CAS FSM        = "  << cas_fsm_str[r_cas_fsm.read()]               << std::endl
    1061         << " - CLEANUP FSM    = "  << cleanup_fsm_str[r_cleanup_fsm.read()]       << std::endl
    1062         << " - IXR_CMD FSM    = "  << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()]       << std::endl
    1063         << " - IXR_RSP FSM    = "  << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]       << std::endl
    1064         << " - XRAM_RSP FSM   = "  << xram_rsp_fsm_str[r_xram_rsp_fsm.read()]     << std::endl
    1065         << " - ALLOC_DIR FSM  = "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]   << std::endl
    1066         << " - ALLOC_TRT FSM  = "  << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]   << std::endl
    1067         << " - ALLOC_UPT FSM  = "  << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]   << std::endl
    1068         << " - ALLOC_HEAP FSM = "  << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
    1069 }
    1070 #endif
    1071 
    1072   ////////////////////////////////////////////////////////////////////////////////////
    1073   //    TGT_CMD FSM
    1074   ////////////////////////////////////////////////////////////////////////////////////
    1075   // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors,
    1076   // and dispatch these commands to the proper FSM through dedicated FIFOs.
    1077   //
    1078   // There are 5 types of commands accepted in the XRAM segment:
    1079   // - READ   : A READ request has a length of 1 VCI flit. It can be a single word
    1080   //            or an entire cache line, depending on the PLEN value => READ FSM
    1081   // - WRITE  : A WRITE request has a maximum length of 16 flits, and can only
    1082   //            concern words in a same line => WRITE FSM
    1083   // - CAS    : A CAS request has a length of 2 flits or 4 flits => CAS FSM
    1084   // - LL     : An LL request has a length of 1 flit => READ FSM
    1085   // - SC     : An SC request has a length of 2 flits. First flit contains the
    1086   //            acces key, second flit the data to write => WRITE FSM.
    1087   //
    1088   // The READ/WRITE commands accepted in the configuration segment are targeting
    1089   // configuration or status registers. They must contain one single flit.
    1090   // - For almost all addressable registers, the response is returned immediately.
    1091   // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
    1092   ////////////////////////////////////////////////////////////////////////////////////
    1093 
    1094 //std::cout << std::endl << "tgt_cmd_fsm" << std::endl;
    1095 
    1096   switch(r_tgt_cmd_fsm.read())
    1097   {
    1098     //////////////////
    1099     case TGT_CMD_IDLE:     // waiting a VCI command (RAM or CONFIG)
    1100     if(p_vci_tgt.cmdval)
    1101     {
     1047        if(m_debug)
     1048        {
     1049            std::cout
     1050                << "---------------------------------------------"           << std::dec << std::endl
     1051                << "MEM_CACHE "            << name()
     1052                << " ; Time = "            << m_cpt_cycles                                << std::endl
     1053                << " - TGT_CMD FSM    = "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()]       << std::endl
     1054                << " - TGT_RSP FSM    = "  << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()]       << std::endl
     1055                << " - CC_SEND FSM  = "    << cc_send_fsm_str[r_cc_send_fsm.read()]       << std::endl
     1056                << " - CC_RECEIVE FSM  = " << cc_receive_fsm_str[r_cc_receive_fsm.read()] << std::endl
     1057                << " - MULTI_ACK FSM  = "  << multi_ack_fsm_str[r_multi_ack_fsm.read()]   << std::endl
     1058                << " - READ FSM       = "  << read_fsm_str[r_read_fsm.read()]             << std::endl
     1059                << " - WRITE FSM      = "  << write_fsm_str[r_write_fsm.read()]           << std::endl
     1060                << " - CAS FSM        = "  << cas_fsm_str[r_cas_fsm.read()]               << std::endl
     1061                << " - CLEANUP FSM    = "  << cleanup_fsm_str[r_cleanup_fsm.read()]       << std::endl
     1062                << " - IXR_CMD FSM    = "  << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()]       << std::endl
     1063                << " - IXR_RSP FSM    = "  << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]       << std::endl
     1064                << " - XRAM_RSP FSM   = "  << xram_rsp_fsm_str[r_xram_rsp_fsm.read()]     << std::endl
     1065                << " - ALLOC_DIR FSM  = "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]   << std::endl
     1066                << " - ALLOC_TRT FSM  = "  << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]   << std::endl
     1067                << " - ALLOC_UPT FSM  = "  << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]   << std::endl
     1068                << " - ALLOC_HEAP FSM = "  << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
     1069        }
     1070#endif
     1071
     1072        ////////////////////////////////////////////////////////////////////////////////////
     1073        //    TGT_CMD FSM
     1074        ////////////////////////////////////////////////////////////////////////////////////
     1075        // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors,
     1076        // and dispatch these commands to the proper FSM through dedicated FIFOs.
     1077        //
     1078        // There are 5 types of commands accepted in the XRAM segment:
     1079        // - READ   : A READ request has a length of 1 VCI flit. It can be a single word
     1080        //            or an entire cache line, depending on the PLEN value => READ FSM
     1081        // - WRITE  : A WRITE request has a maximum length of 16 flits, and can only
     1082        //            concern words in a same line => WRITE FSM
     1083        // - CAS    : A CAS request has a length of 2 flits or 4 flits => CAS FSM
     1084        // - LL     : An LL request has a length of 1 flit => READ FSM
     1085        // - SC     : An SC request has a length of 2 flits. First flit contains the
     1086        //            acces key, second flit the data to write => WRITE FSM.
     1087        //
     1088        // The READ/WRITE commands accepted in the configuration segment are targeting
     1089        // configuration or status registers. They must contain one single flit.
     1090        // - For almost all addressable registers, the response is returned immediately.
     1091        // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
     1092        ////////////////////////////////////////////////////////////////////////////////////
     1093
     1094        //std::cout << std::endl << "tgt_cmd_fsm" << std::endl;
     1095
     1096        switch(r_tgt_cmd_fsm.read())
     1097        {
     1098            //////////////////
     1099            case TGT_CMD_IDLE:     // waiting a VCI command (RAM or CONFIG)
     1100                if(p_vci_tgt.cmdval)
     1101                {
    11021102
    11031103#if DEBUG_MEMC_TGT_CMD
    1104 if(m_debug)
    1105 std::cout << "  <MEMC " << name()
    1106           << " TGT_CMD_IDLE> Receive command from srcid "
    1107           << std::hex << p_vci_tgt.srcid.read()
    1108           << " / address " << std::hex << p_vci_tgt.address.read() << std::endl;
    1109 #endif
    1110         // checking segmentation violation
    1111         addr_t      address  = p_vci_tgt.address.read();
    1112         uint32_t    plen     = p_vci_tgt.plen.read();
    1113         bool        found    = false;
    1114         bool        config   = false;
    1115 
    1116         // register arguments for response (segmentation violation or config)
    1117         r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
    1118         r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
    1119         r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
    1120 
    1121         for(size_t seg_id = 0 ; (seg_id < m_nseg) and not found ; seg_id++)
     1104                    if(m_debug)
     1105                        std::cout << "  <MEMC " << name()
     1106                            << " TGT_CMD_IDLE> Receive command from srcid "
     1107                            << std::hex << p_vci_tgt.srcid.read()
     1108                            << " / address " << std::hex << p_vci_tgt.address.read() << std::endl;
     1109#endif
     1110                    // checking segmentation violation
     1111                    addr_t      address  = p_vci_tgt.address.read();
     1112                    uint32_t    plen     = p_vci_tgt.plen.read();
     1113                    bool        found    = false;
     1114                    bool        config   = false;
     1115
     1116                    // register arguments for response (segmentation violation or config)
     1117                    r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
     1118                    r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
     1119                    r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
     1120
     1121                    for(size_t seg_id = 0 ; (seg_id < m_nseg) and not found ; seg_id++)
     1122                    {
     1123                        if( m_seg[seg_id]->contains(address) and
     1124                                m_seg[seg_id]->contains(address + plen - vci_param_int::B) )
     1125                        {
     1126                            found = true;
     1127                            if ( m_seg[seg_id]->special() ) config = true;
     1128                        }
     1129                    }
     1130
     1131                    if ( not found )                /////////// out of segment error
     1132                    {
     1133                        r_tgt_cmd_fsm   = TGT_CMD_ERROR;
     1134                    }
     1135                    else if ( config )              /////////// configuration command
     1136                    {
     1137                        if ( not p_vci_tgt.eop.read() ) r_tgt_cmd_fsm = TGT_CMD_ERROR;
     1138                        else                            r_tgt_cmd_fsm = TGT_CMD_CONFIG;
     1139                    }
     1140                    else                            //////////// memory access
     1141                    {
     1142                        if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ )
     1143                        {
     1144                            // check that the pktid is either :
     1145                            // TYPE_READ_DATA_UNC
     1146                            // TYPE_READ_DATA_MISS
     1147                            // TYPE_READ_INS_UNC
     1148                            // TYPE_READ_INS_MISS
     1149                            // ==> bit2 must be zero with the TSAR encoding
     1150                            // ==> mask = 0b0100 = 0x4
     1151                            assert( ((p_vci_tgt.pktid.read() & 0x4) == 0x0) and
     1152                                    "The type specified in the pktid field is incompatible with the READ CMD");
     1153                            r_tgt_cmd_fsm = TGT_CMD_READ;
     1154                        }
     1155                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)
     1156                        {
     1157                            // check that the pktid is TYPE_WRITE
     1158                            // ==> TYPE_WRITE = X100 with the TSAR encoding
     1159                            // ==> mask = 0b0111 = 0x7
     1160                            assert(((p_vci_tgt.pktid.read() & 0x7) == 0x4) and
     1161                                    "The type specified in the pktid field is incompatible with the WRITE CMD");
     1162                            r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1163                        }
     1164                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ)
     1165                        {
     1166                            // check that the pktid is TYPE_LL
     1167                            // ==> TYPE_LL = X110 with the TSAR encoding
     1168                            // ==> mask = 0b0111 = 0x7
     1169                            assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) and
     1170                                    "The type specified in the pktid field is incompatible with the LL CMD");
     1171                            r_tgt_cmd_fsm = TGT_CMD_READ;
     1172                        }
     1173                        else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)
     1174                        {
     1175                            // check that the pktid is either :
     1176                            // TYPE_CAS
     1177                            // TYPE_SC
     1178                            // ==> TYPE_CAS = X101 with the TSAR encoding
     1179                            // ==> TYPE_SC  = X111 with the TSAR encoding
     1180                            // ==> mask = 0b0101 = 0x5
     1181                            assert(((p_vci_tgt.pktid.read() & 0x5) == 0x5) and
     1182                                    "The type specified in the pktid field is incompatible with the NOP CMD");
     1183
     1184                            if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS;
     1185                            else                                           r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1186                        }
     1187                        else
     1188                        {
     1189                            r_tgt_cmd_fsm = TGT_CMD_ERROR;
     1190                        }
     1191                    }
     1192                }
     1193                break;
     1194
     1195                ///////////////////
     1196            case TGT_CMD_ERROR:  // response error must be sent
     1197
     1198                // wait if pending request
     1199                if(r_tgt_cmd_to_tgt_rsp_req.read()) break;
     1200
     1201                // consume all the command packet flits before sending response error
     1202                if ( p_vci_tgt.cmdval and p_vci_tgt.eop )
     1203                {
     1204                    r_tgt_cmd_to_tgt_rsp_req   = true;
     1205                    r_tgt_cmd_to_tgt_rsp_error = 1;
     1206                    r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1207
     1208#if DEBUG_MEMC_TGT_CMD
     1209                    if(m_debug)
     1210                        std::cout << "  <MEMC " << name()
     1211                            << " TGT_CMD_ERROR> Segmentation violation:"
     1212                            << " address = " << std::hex << p_vci_tgt.address.read()
     1213                            << " / srcid = " << p_vci_tgt.srcid.read()
     1214                            << " / trdid = " << p_vci_tgt.trdid.read()
     1215                            << " / pktid = " << p_vci_tgt.pktid.read()
     1216                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1217#endif
     1218
     1219                }
     1220                break;
     1221
     1222                ////////////////////
     1223            case TGT_CMD_CONFIG:    // execute config request and return response
     1224                {
     1225                    addr_t   seg_base = m_seg[m_seg_config]->baseAddress();
     1226                    addr_t   address  = p_vci_tgt.address.read();
     1227                    size_t   cell     = (address - seg_base)/vci_param_int::B;
     1228
     1229                    bool     need_rsp;
     1230                    size_t   error; 
     1231                    uint32_t rdata = 0;         // default value
     1232                    uint32_t wdata = p_vci_tgt.wdata.read();
     1233
     1234                    if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
     1235                            and (cell == MEMC_LOCK) )
     1236                    {
     1237                        rdata            = (uint32_t)r_config_lock.read();
     1238                        need_rsp         = true;
     1239                        error            = 0;
     1240                        r_config_lock    = true;
     1241                        if ( rdata == 0 )
     1242                        {
     1243                            r_tgt_cmd_srcid = p_vci_tgt.srcid.read();
     1244                            r_tgt_cmd_trdid = p_vci_tgt.trdid.read();
     1245                            r_tgt_cmd_pktid = p_vci_tgt.pktid.read();
     1246                        }
     1247                    }
     1248                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
     1249                            and (cell == MEMC_LOCK)
     1250                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1251                    {
     1252                        need_rsp         = true;
     1253                        error            = 0;
     1254                        r_config_lock    = false;
     1255                    }
     1256                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
     1257                            and (cell == MEMC_ADDR_LO)
     1258                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1259                    {
     1260                        assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
     1261                                "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
     1262
     1263                        need_rsp         = true;
     1264                        error            = 0;
     1265                        r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
     1266                            (addr_t)p_vci_tgt.wdata.read();
     1267                    }
     1268                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
     1269                            and (cell == MEMC_ADDR_HI)
     1270                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1271
     1272                    {
     1273                        need_rsp         = true;
     1274                        error            = 0;
     1275                        r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
     1276                            ((addr_t)p_vci_tgt.wdata.read())<<32;
     1277                    }
     1278                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
     1279                            and (cell == MEMC_BUF_LENGTH)
     1280                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1281                    {
     1282                        need_rsp         = true;
     1283                        error            = 0;
     1284                        size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2));
     1285                        if ( r_config_address.read()%(m_words*4) ) lines++;
     1286                        r_config_cmd_lines  = lines;
     1287                        r_config_rsp_lines  = lines;
     1288                    }
     1289                    else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
     1290                            and (cell == MEMC_CMD_TYPE)
     1291                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1292                    {
     1293                        need_rsp         = false;
     1294                        error            = 0;
     1295                        r_config_cmd     = p_vci_tgt.wdata.read();
     1296
     1297                        // prepare delayed response from CONFIG FSM
     1298                        r_config_srcid   = p_vci_tgt.srcid.read();
     1299                        r_config_trdid   = p_vci_tgt.trdid.read();
     1300                        r_config_pktid   = p_vci_tgt.pktid.read();
     1301                    }
     1302                    else
     1303                    {
     1304                        need_rsp         = true;
     1305                        error            = 1;
     1306                    }
     1307
     1308                    if ( need_rsp )
     1309                    {
     1310                        // blocked if previous pending request to TGT_RSP FSM
     1311                        if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break;
     1312
     1313                        r_tgt_cmd_to_tgt_rsp_req   = true;
     1314                        r_tgt_cmd_to_tgt_rsp_error = error;
     1315                        r_tgt_cmd_to_tgt_rsp_rdata = rdata;
     1316                        r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1317                    }
     1318                    else
     1319                    {
     1320                        r_tgt_cmd_fsm              = TGT_CMD_IDLE;
     1321                    }
     1322
     1323#if DEBUG_MEMC_TGT_CMD
     1324                    if(m_debug)
     1325                        std::cout << "  <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:"
     1326                            << " address = " << std::hex << p_vci_tgt.address.read()
     1327                            << " / wdata = " << p_vci_tgt.wdata.read()
     1328                            << " / need_rsp = " << need_rsp
     1329                            << " / error = " << error << std::endl;
     1330#endif
     1331                    break;
     1332                }
     1333                //////////////////
     1334            case TGT_CMD_READ:    // Push a read request into read fifo
     1335
     1336                // check that the read does not cross a cache line limit.
     1337                if ( ((m_x[(addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) and
     1338                        (p_vci_tgt.cmd.read() != vci_param_int::CMD_LOCKED_READ))
     1339                {
     1340                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1341                        << " illegal address/plen for VCI read command" << std::endl;
     1342                    exit(0);
     1343                }
     1344                // check single flit
     1345                if(!p_vci_tgt.eop.read())
     1346                {
     1347                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1348                        << " read command packet must contain one single flit" << std::endl;
     1349                    exit(0);
     1350                }
     1351                // check plen for LL
     1352                if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and
     1353                        (p_vci_tgt.plen.read() != 8) )
     1354                {
     1355                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     1356                        << " ll command packets must have a plen of 8" << std::endl;
     1357                    exit(0);
     1358                }
     1359
     1360                if ( p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok() )
     1361                {
     1362
     1363#if DEBUG_MEMC_TGT_CMD
     1364                    if(m_debug)
     1365                        std::cout << "  <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:"
     1366                            << " address = " << std::hex << p_vci_tgt.address.read()
     1367                            << " / srcid = " << p_vci_tgt.srcid.read()
     1368                            << " / trdid = " << p_vci_tgt.trdid.read()
     1369                            << " / pktid = " << p_vci_tgt.pktid.read()
     1370                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1371#endif
     1372                    cmd_read_fifo_put = true;
     1373                    if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) m_cpt_ll++;
     1374                    else                                                       m_cpt_read++;
     1375                    r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1376                }
     1377                break;
     1378
     1379                ///////////////////
     1380            case TGT_CMD_WRITE:
     1381                if(p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok())
     1382                {
     1383
     1384#if DEBUG_MEMC_TGT_CMD
     1385                    if(m_debug)
     1386                        std::cout << "  <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:"
     1387                            << " address = " << std::hex << p_vci_tgt.address.read()
     1388                            << " / srcid = " << p_vci_tgt.srcid.read()
     1389                            << " / trdid = " << p_vci_tgt.trdid.read()
     1390                            << " / pktid = " << p_vci_tgt.pktid.read()
     1391                            << " / wdata = " << p_vci_tgt.wdata.read()
     1392                            << " / be = " << p_vci_tgt.be.read()
     1393                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1394#endif
     1395                    cmd_write_fifo_put = true;
     1396                    if(p_vci_tgt.eop)  r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1397                }
     1398                break;
     1399
     1400                /////////////////
     1401            case TGT_CMD_CAS:
     1402                if((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16))
     1403                {
     1404                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state"
     1405                        << "illegal format for CAS command " << std::endl;
     1406                    exit(0);
     1407                }
     1408
     1409                if(p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok())
     1410                {
     1411
     1412#if DEBUG_MEMC_TGT_CMD
     1413                    if(m_debug)
     1414                        std::cout << "  <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:"
     1415                            << " address = " << std::hex << p_vci_tgt.address.read()
     1416                            << " srcid = " << p_vci_tgt.srcid.read()
     1417                            << " trdid = " << p_vci_tgt.trdid.read()
     1418                            << " pktid = " << p_vci_tgt.pktid.read()
     1419                            << " wdata = " << p_vci_tgt.wdata.read()
     1420                            << " be = " << p_vci_tgt.be.read()
     1421                            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1422#endif
     1423                    cmd_cas_fifo_put = true;
     1424                    if(p_vci_tgt.eop) r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1425                }
     1426                break;
     1427        } // end switch tgt_cmd_fsm
     1428
     1429        /////////////////////////////////////////////////////////////////////////
     1430        //    MULTI_ACK FSM
     1431        /////////////////////////////////////////////////////////////////////////
     1432        // This FSM controls the response to the multicast update requests sent
     1433        // by the memory cache to the L1 caches and update the UPT.
     1434        //
     1435        // - The FSM decrements the proper entry in UPT,
     1436        //   and clear the UPT entry when all responses have been received.
     1437        // - If required, it sends a request to the TGT_RSP FSM to complete
     1438        //   a pending  write transaction.
     1439        //
     1440        // All those multi-ack packets are one flit packet.
     1441        // The index in the UPT is defined in the TRDID field.
     1442        ////////////////////////////////////////////////////////////////////////
     1443
     1444        //std::cout << std::endl << "multi_ack_fsm" << std::endl;
     1445
     1446        switch(r_multi_ack_fsm.read())
    11221447        {
    1123             if( m_seg[seg_id]->contains(address) and
    1124                 m_seg[seg_id]->contains(address + plen - vci_param_int::B) )
    1125             {
    1126                 found = true;
    1127                 if ( m_seg[seg_id]->special() ) config = true;
    1128             }
    1129         }
    1130 
    1131         if ( not found )                /////////// out of segment error
     1448            ////////////////////
     1449            case MULTI_ACK_IDLE:
     1450                {
     1451                    bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok();
     1452
     1453                    // No CC_RECEIVE FSM request and no WRITE FSM request
     1454                    if( not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read())
     1455                        break;
     1456
     1457                    uint8_t updt_index;
     1458
     1459                    // handling WRITE FSM request to decrement update table response
     1460                    // counter if no CC_RECEIVE FSM request
     1461                    if(not multi_ack_fifo_rok)
     1462                    {
     1463                        updt_index               = r_write_to_multi_ack_upt_index.read();
     1464                        r_write_to_multi_ack_req = false;
     1465                    }
     1466                    // Handling CC_RECEIVE FSM request
     1467                    else
     1468                    {
     1469                        uint64_t flit = m_cc_receive_to_multi_ack_fifo.read();
     1470                        updt_index    = DspinDhccpParam::dspin_get(flit,
     1471                                DspinDhccpParam::MULTI_ACK_UPDT_INDEX);
     1472
     1473                        cc_receive_to_multi_ack_fifo_get = true;
     1474                    }
     1475
     1476                    assert((updt_index < m_upt.size()) and
     1477                            "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : "
     1478                            "index too large for UPT");
     1479
     1480                    r_multi_ack_upt_index = updt_index;
     1481                    r_multi_ack_fsm       = MULTI_ACK_UPT_LOCK;
     1482
     1483#if DEBUG_MEMC_MULTI_ACK
     1484                    if(m_debug)
     1485                    {
     1486                        if (multi_ack_fifo_rok)
     1487                        {
     1488                            std::cout << "  <MEMC " << name()
     1489                                << " MULTI_ACK_IDLE> Response for UPT entry "
     1490                                << (size_t)updt_index << std::endl;
     1491                        }
     1492                        else
     1493                        {
     1494                            std::cout << "  <MEMC " << name()
     1495                                << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry "
     1496                                << updt_index << std::endl;
     1497                        }
     1498                    }
     1499#endif
     1500                    break;
     1501                }
     1502
     1503                ////////////////////////
     1504            case MULTI_ACK_UPT_LOCK:
     1505                {
     1506                    m_cpt_multi_ack_fsm_upt_lock++;
     1507                    // get lock to the UPDATE table
     1508                    if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)  break;
     1509
     1510                    // decrement the number of expected responses
     1511                    size_t count = 0;
     1512                    bool valid   = m_upt.decrement(r_multi_ack_upt_index.read(), count);
     1513
     1514
     1515                    if(not valid)
     1516                    {
     1517                        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1518                            << " MULTI_ACK_UPT_LOCK state" << std::endl
     1519                            << "unsuccessful access to decrement the UPT" << std::endl;
     1520                        exit(0);
     1521                    }
     1522
     1523                    if(count == 0)
     1524                    {
     1525                        r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR;
     1526                    }
     1527                    else
     1528                    {
     1529                        r_multi_ack_fsm = MULTI_ACK_IDLE;
     1530                    }
     1531
     1532#if DEBUG_MEMC_MULTI_ACK
     1533                    if(m_debug)
     1534                        std::cout << "  <MEMC " << name()
     1535                            << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:"
     1536                            << " entry = "       << r_multi_ack_upt_index.read()
     1537                            << " / rsp_count = " << std::dec << count << std::endl;
     1538                    m_cpt_multi_ack_fsm_n_upt_lock++;
     1539#endif
     1540                    break;
     1541                }
     1542
     1543                /////////////////////////
     1544            case MULTI_ACK_UPT_CLEAR:   // Clear UPT entry / Test if rsp or ack required
     1545                {
     1546                    if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)
     1547                    {
     1548                        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1549                            << " MULTI_ACK_UPT_CLEAR state"
     1550                            << " bad UPT allocation" << std::endl;
     1551                        exit(0);
     1552                    }
     1553
     1554                    r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read());
     1555                    r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read());
     1556                    r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read());
     1557                    r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
     1558                    bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
     1559
     1560                    // clear the UPT entry
     1561                    m_upt.clear(r_multi_ack_upt_index.read());
     1562
     1563                    if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
     1564                    else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
     1565
     1566#if DEBUG_MEMC_MULTI_ACK
     1567                    if(m_debug)
     1568                        std::cout <<  "  <MEMC " << name()
     1569                            << " MULTI_ACK_UPT_CLEAR> Clear UPT entry "
     1570                            << std::dec << r_multi_ack_upt_index.read() << std::endl;
     1571#endif
     1572                    break;
     1573                }
     1574                /////////////////////////
     1575            case MULTI_ACK_WRITE_RSP:     // Post a response request to TGT_RSP FSM
     1576                // Wait if pending request
     1577                {
     1578                    if ( r_multi_ack_to_tgt_rsp_req.read() ) break;
     1579
     1580                    r_multi_ack_to_tgt_rsp_req   = true;
     1581                    r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read();
     1582                    r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read();
     1583                    r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read();
     1584                    r_multi_ack_fsm              = MULTI_ACK_IDLE;
     1585
     1586#if DEBUG_MEMC_MULTI_ACK
     1587                    if(m_debug)
     1588                        std::cout << "  <MEMC " << name() << " MULTI_ACK_WRITE_RSP>"
     1589                            << " Request TGT_RSP FSM to send a response to srcid "
     1590                            << std::hex << r_multi_ack_srcid.read() << std::endl;
     1591#endif
     1592                    break;
     1593                }
     1594        } // end switch r_multi_ack_fsm
     1595
     1596        ////////////////////////////////////////////////////////////////////////////////////
     1597        //    CONFIG FSM
     1598        ////////////////////////////////////////////////////////////////////////////////////
     1599        // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC).
     1600        // The target buffer can have any size, and there is one single command for
     1601        // all cache lines covered by the target buffer.
     1602        //
     1603        // An INVAL or SYNC configuration operation is defined by the following registers:
     1604        // - bool      r_config_cmd        : INVAL / SYNC / NOP
     1605        // - uint64_t  r_config_address    : buffer base address
     1606        // - uint32_t  r_config_cmd_lines  : number of lines to be handled
     1607        // - uint32_t  r_config_rsp_lines  : number of lines not completed
     1608        //
     1609        // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
     1610        // all cache lines covered by the buffer. The various lines of a given buffer
     1611        // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
     1612        // the command for line (n+1). It decrements the r_config_cmd_lines counter until
     1613        // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
     1614        //
     1615        // - INVAL request:
     1616        //   For each line, it access to the DIR.
     1617        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1618        //   In case of hit, with no copies in L1 caches, the line is invalidated and
     1619        //   a response is requested to TGT_RSP FSM.
     1620        //   If there is copies, a multi-inval, or a broadcast-inval coherence transaction
     1621        //   is launched and registered in UPT. The multi-inval transaction completion
     1622        //   is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter.
     1623        //   The CONFIG INVAL response is sent only when the last line has been invalidated.
     1624        //   TODO : The target buffer address must be aligned on a cache line boundary.
     1625        //   This constraint can be released, but it requires to make 2 PUT transactions
     1626        //   for the first and the last line...
     1627        //
     1628        // - SYNC request:
     1629        //   For each line, it access to the DIR.
     1630        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1631        //   In case of hit, a PUT transaction is registered in TRT and a request is sent
     1632        //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
     1633        //   when a PUT response is received.
     1634        //   The CONFIG SYNC response is sent only when the last PUT response is received.
     1635        //
     1636        // From the software point of view, a configuration request is a sequence
     1637        // of 6 atomic accesses in an uncached segment. A dedicated lock is used
     1638        // to handle only one configuration command at a given time:
     1639        // - Read  MEMC_LOCK       : Get the lock
     1640        // - Write MEMC_ADDR_LO    : Set the buffer address LSB
     1641        // - Write MEMC_ADDR_HI    : Set the buffer address MSB
     1642        // - Write MEMC_BUF_LENGTH : set buffer length (bytes)
     1643        // - Write MEMC_CMD_TYPE   : launch the actual operation
     1644        // - WRITE MEMC_LOCK       : release the lock
     1645        ////////////////////////////////////////////////////////////////////////////////////
     1646
     1647        //std::cout << std::endl << "config_fsm" << std::endl;
     1648
     1649        switch( r_config_fsm.read() )
    11321650        {
    1133             r_tgt_cmd_fsm   = TGT_CMD_ERROR;
    1134         }
    1135         else if ( config )              /////////// configuration command
     1651            /////////////////
     1652            case CONFIG_IDLE:  // waiting a config request
     1653                {
     1654                    if ( r_config_cmd.read() != MEMC_CMD_NOP ) 
     1655                    {
     1656                        r_config_fsm    = CONFIG_LOOP;
     1657
     1658#if DEBUG_MEMC_CONFIG
     1659                        if(m_debug)
     1660                            std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
     1661                                << " / address = " << std::hex << r_config_address.read()
     1662                                << " / lines = " << std::dec << r_config_cmd_lines.read()
     1663                                << " / type = " << r_config_cmd.read() << std::endl;
     1664#endif
     1665                    }
     1666                    break;
     1667                }
     1668                /////////////////
     1669            case CONFIG_LOOP:   // test if last line to be handled
     1670                {
     1671                    if ( r_config_cmd_lines.read() == 0 )
     1672                    {
     1673                        r_config_cmd = MEMC_CMD_NOP;
     1674                        r_config_fsm = CONFIG_WAIT;
     1675                    }
     1676                    else
     1677                    {
     1678                        r_config_fsm = CONFIG_DIR_REQ;
     1679                    }
     1680
     1681#if DEBUG_MEMC_CONFIG
     1682                    if(m_debug)
     1683                        std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
     1684                            << " / address = " << std::hex << r_config_address.read()   
     1685                            << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
     1686                            << " / command = " << r_config_cmd.read() << std::endl;
     1687#endif
     1688                    break;
     1689                }
     1690                /////////////////
     1691            case CONFIG_WAIT:   // wait completion (last response)
     1692                {
     1693                    if ( r_config_rsp_lines.read() == 0 )  // last response received
     1694                    {
     1695                        r_config_fsm = CONFIG_RSP;
     1696                    }
     1697
     1698#if DEBUG_MEMC_CONFIG
     1699                    if(m_debug)
     1700                        std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
     1701                            << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     1702#endif
     1703                    break;
     1704                }
     1705                ////////////////
     1706            case CONFIG_RSP:  // request TGT_RSP FSM to return response
     1707                {
     1708                    if ( not r_config_to_tgt_rsp_req.read() )
     1709                    {
     1710                        r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
     1711                        r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
     1712                        r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
     1713                        r_config_to_tgt_rsp_error  = false;
     1714                        r_config_to_tgt_rsp_req    = true;
     1715                        r_config_fsm               = CONFIG_IDLE;
     1716
     1717#if DEBUG_MEMC_CONFIG
     1718                        if(m_debug)
     1719                            std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
     1720                                << " error = " << r_config_to_tgt_rsp_error.read()
     1721                                << " / rsrcid = " << std::hex << r_config_srcid.read()
     1722                                << " / rtrdid = " << std::hex << r_config_trdid.read()
     1723                                << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     1724#endif
     1725                    }
     1726                    break;
     1727
     1728                }
     1729                ////////////////////
     1730            case CONFIG_DIR_REQ:  // Request directory lock
     1731                {
     1732                    if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
     1733                    {
     1734                        r_config_fsm = CONFIG_DIR_ACCESS;
     1735                    }
     1736
     1737#if DEBUG_MEMC_CONFIG
     1738                    if(m_debug)
     1739                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
     1740                            << " Request DIR access" << std::endl;
     1741#endif
     1742                    break;
     1743                }
     1744                ///////////////////////
     1745            case CONFIG_DIR_ACCESS:   // Access directory and decode config command
     1746                {
     1747                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1748                            "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
     1749
     1750                    size_t way = 0;
     1751                    DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
     1752
     1753                    if ( entry.valid and                            // hit & inval command
     1754                            (r_config_cmd.read() == MEMC_CMD_INVAL) )
     1755                    {
     1756                        r_config_dir_way        = way;
     1757                        r_config_dir_copy_inst  = entry.owner.inst;
     1758                        r_config_dir_copy_srcid = entry.owner.srcid;
     1759                        r_config_dir_is_cnt     = entry.is_cnt;
     1760                        r_config_dir_lock       = entry.lock;
     1761                        r_config_dir_count      = entry.count;
     1762                        r_config_dir_ptr        = entry.ptr;
     1763
     1764                        r_config_fsm    = CONFIG_IVT_LOCK;
     1765                    }
     1766                    else if ( entry.valid and                       // hit & sync command
     1767                            entry.dirty and
     1768                            (r_config_cmd.read() == MEMC_CMD_SYNC) )
     1769                    {
     1770                        r_config_fsm  = CONFIG_TRT_LOCK;
     1771                    }
     1772                    else                                            // miss : return to LOOP
     1773                    {
     1774                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1775                        r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     1776                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1777                        r_config_address   = r_config_address.read() + (m_words<<2);
     1778                        r_config_fsm       = CONFIG_LOOP;
     1779                    }
     1780
     1781#if DEBUG_MEMC_CONFIG
     1782                    if(m_debug)
     1783                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
     1784                            << " address = " << std::hex << r_config_address.read()
     1785                            << " / hit = " << std::dec << entry.valid
     1786                            << " / dirty = " << entry.dirty
     1787                            << " / count = " << entry.count
     1788                            << " / is_cnt = " << entry.is_cnt << std::endl;
     1789#endif
     1790                    break;
     1791                }
     1792                /////////////////////
     1793            case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
     1794                // to a dirty cache line
     1795                // keep DIR lock, and try to get TRT lock
     1796                // return to LOOP state if TRT full
     1797                // reset dirty bit in DIR and register a PUT
     1798                // trabsaction in TRT if not full.
     1799                {
     1800                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1801                            "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
     1802
     1803                    if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
     1804                    {
     1805                        size_t index = 0;
     1806                        bool   wok   = not m_trt.full(index);
     1807
     1808                        if ( not wok )
     1809                        {
     1810                            r_config_fsm = CONFIG_LOOP;
     1811                        }
     1812                        else
     1813                        {
     1814                            size_t          way = r_config_dir_way.read();
     1815                            size_t          set = m_y[r_config_address.read()];
     1816
     1817                            // reset dirty bit in DIR
     1818                            DirectoryEntry  entry;
     1819                            entry.valid       = true;
     1820                            entry.dirty       = false;
     1821                            entry.tag         = m_z[r_config_address.read()];
     1822                            entry.is_cnt      = r_config_dir_is_cnt.read();
     1823                            entry.lock        = r_config_dir_lock.read();
     1824                            entry.ptr         = r_config_dir_ptr.read();
     1825                            entry.count       = r_config_dir_count.read();
     1826                            entry.owner.inst  = r_config_dir_copy_inst.read();
     1827                            entry.owner.srcid = r_config_dir_copy_srcid.read();
     1828                            m_cache_directory.write( set,
     1829                                    way,
     1830                                    entry );
     1831
     1832                            r_config_trt_index = index;
     1833                            r_config_fsm       = CONFIG_TRT_SET;
     1834                        }
     1835
     1836#if DEBUG_MEMC_CONFIG
     1837                        if(m_debug)
     1838                            std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
     1839                                << " wok = " << std::dec << wok
     1840                                << " index = " << index << std::endl;
     1841#endif
     1842                    }
     1843                    break;
     1844                }
     1845                ////////////////////
     1846            case CONFIG_TRT_SET:       // read data in cache
     1847                // and post a PUT request in TRT
     1848                {
     1849                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1850                            "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
     1851
     1852                    assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
     1853                            "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
     1854
     1855                    // read data into cache
     1856                    size_t          way = r_config_dir_way.read();
     1857                    size_t          set = m_y[r_config_address.read()];
     1858
     1859                    sc_signal<data_t> config_data[16];
     1860                    m_cache_data.read_line( way,
     1861                            set,
     1862                            config_data );
     1863
     1864                    // post a PUT request in TRT
     1865                    std::vector<data_t> data_vector;
     1866                    data_vector.clear();
     1867                    for(size_t i=0; i<m_words; i++) data_vector.push_back(config_data[i].read());
     1868                    m_trt.set( r_config_trt_index.read(),
     1869                            false,                               // PUT
     1870                            m_nline[r_config_address.read()],    // nline
     1871                            0,                                   // srcid:       unused
     1872                            0,                                   // trdid:       unused
     1873                            0,                                   // pktid:       unused
     1874                            false,                               // not proc_read
     1875                            0,                                   // read_length: unused
     1876                            0,                                   // word_index:  unused
     1877                            std::vector<be_t>(m_words,0xF),                         
     1878                            data_vector);
     1879
     1880#if DEBUG_MEMC_CONFIG
     1881                    if(m_debug)
     1882                        std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
     1883                            << " address = " << std::hex << r_config_address.read()
     1884                            << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     1885#endif
     1886                    break;
     1887                }
     1888                ////////////////////
     1889            case CONFIG_PUT_REQ:       // PUT request to IXR_CMD_FSM
     1890                {
     1891                    if ( not r_config_to_ixr_cmd_req.read() )
     1892                    {
     1893                        r_config_to_ixr_cmd_req   = true;
     1894                        r_config_to_ixr_cmd_index = r_config_trt_index.read();
     1895
     1896                        // prepare next iteration
     1897                        r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     1898                        r_config_address                = r_config_address.read() + (m_words<<2);
     1899                        r_config_fsm                    = CONFIG_LOOP;
     1900
     1901#if DEBUG_MEMC_CONFIG
     1902                        if(m_debug)
     1903                            std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> PUT request to IXR_CMD_FSM"
     1904                                << " / address = " << std::hex << r_config_address.read() << std::endl;
     1905#endif
     1906                    }
     1907                    break;
     1908                }
     1909                /////////////////////
     1910            case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
     1911                // Keep DIR lock and Try to get IVT lock.
     1912                // Return to LOOP state if IVT full.
     1913                // Register inval in IVT, and invalidate the
     1914                // directory if IVT not full.
     1915                {
     1916                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1917                            "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
     1918
     1919                    if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
     1920                    {
     1921                        size_t set        = m_y[(addr_t)(r_config_address.read())];
     1922                        size_t way        = r_config_dir_way.read();
     1923
     1924                        if ( r_config_dir_count.read() == 0 )     // inval DIR and return to LOOP
     1925                        {
     1926                            m_cache_directory.inval( way, set );
     1927                            r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
     1928                            r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
     1929                            r_config_address    = r_config_address.read() + (m_words<<2);
     1930                            r_config_fsm        = CONFIG_LOOP;
     1931
     1932#if DEBUG_MEMC_CONFIG
     1933                            if(m_debug)
     1934                                std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     1935                                    << " No copies in L1 : inval DIR entry"  << std::endl;
     1936#endif
     1937                        }
     1938                        else    // try to register inval in IVT
     1939                        {
     1940                            bool        wok       = false;
     1941                            size_t      index     = 0;
     1942                            bool        broadcast = r_config_dir_is_cnt.read();
     1943                            size_t      srcid     = r_config_srcid.read();
     1944                            size_t      trdid     = r_config_trdid.read();
     1945                            size_t      pktid     = r_config_pktid.read();
     1946                            addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
     1947                            size_t      nb_copies = r_config_dir_count.read();
     1948
     1949                            wok = m_ivt.set(false,       // it's an inval transaction
     1950                                    broadcast,   
     1951                                    false,       // no response required
     1952                                    true,        // acknowledge required
     1953                                    srcid,
     1954                                    trdid,
     1955                                    pktid,
     1956                                    nline,
     1957                                    nb_copies,
     1958                                    index);
     1959
     1960                            if ( wok )  // IVT success => inval DIR slot
     1961                            {
     1962                                m_cache_directory.inval( way, set );
     1963                                r_config_ivt_index = index;
     1964                                if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
     1965                                else              r_config_fsm = CONFIG_INVAL_SEND;
     1966
     1967#if DEBUG_MEMC_CONFIG
     1968                                if(m_debug)
     1969                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     1970                                        << " Inval DIR entry and register inval in IVT"
     1971                                        << " / index = " << std::dec << index
     1972                                        << " / broadcast = " << broadcast << std::endl;
     1973#endif
     1974                            }
     1975                            else       // IVT full => release both DIR and IVT locks
     1976                            {
     1977                                r_config_fsm = CONFIG_LOOP;
     1978
     1979#if DEBUG_MEMC_CONFIG
     1980                                if(m_debug)
     1981                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     1982                                        << " IVT full : release DIR & IVT locks and retry" << std::endl;
     1983#endif
     1984                            }
     1985                        }
     1986                    }
     1987                    break;
     1988                }
     1989                ////////////////////
     1990            case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
     1991                {
     1992                    if( not r_config_to_cc_send_multi_req.read() and
     1993                            not r_config_to_cc_send_brdcast_req.read() )
     1994                    {
     1995                        // post bc inval request
     1996                        r_config_to_cc_send_multi_req   = false;
     1997                        r_config_to_cc_send_brdcast_req = true;
     1998                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
     1999                        r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.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_BC_SEND>"
     2009                                << " Post a broadcast inval request to CC_SEND FSM"
     2010                                << " / address = " << r_config_address.read() <<std::endl;
     2011#endif
     2012                    }
     2013                    break;
     2014                }
     2015                ///////////////////////
     2016            case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
     2017                {
     2018                    if( not r_config_to_cc_send_multi_req.read() and
     2019                            not r_config_to_cc_send_brdcast_req.read() )
     2020                    {
     2021                        // post multi inval request
     2022                        r_config_to_cc_send_multi_req   = true;
     2023                        r_config_to_cc_send_brdcast_req = false;
     2024                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
     2025                        r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
     2026
     2027                        // post data into FIFO
     2028                        config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
     2029                        config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
     2030                        config_to_cc_send_fifo_put      = true;
     2031
     2032                        if ( r_config_dir_count.read() == 1 )  // one copy
     2033                        {
     2034                            // prepare next iteration
     2035                            r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2036                            r_config_address            = r_config_address.read() + (m_words<<2);
     2037                            r_config_fsm                = CONFIG_LOOP;
     2038                        }
     2039                        else                                   // several copies
     2040                        {
     2041                            r_config_fsm = CONFIG_HEAP_REQ;
     2042                        }
     2043
     2044#if DEBUG_MEMC_CONFIG
     2045                        if(m_debug)
     2046                            std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
     2047                                << " Post multi inval request to CC_SEND FSM"
     2048                                << " / address = " << std::hex << r_config_address.read()
     2049                                << " / copy = " << r_config_dir_copy_srcid.read()
     2050                                << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
     2051#endif
     2052                    }
     2053                    break;
     2054                }
     2055                /////////////////////
     2056            case CONFIG_HEAP_REQ:  // Try to get access to Heap
     2057                {
     2058                    if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
     2059                    {
     2060                        r_config_fsm       = CONFIG_HEAP_SCAN;
     2061                        r_config_heap_next = r_config_dir_ptr.read();
     2062                    }
     2063
     2064#if DEBUG_MEMC_CONFIG
     2065                    if(m_debug)
     2066                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
     2067                            << " Requesting HEAP lock" << std::endl;
     2068#endif
     2069                    break;
     2070                }
     2071                //////////////////////
     2072            case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
     2073                {
     2074                    HeapEntry entry = m_heap.read( r_config_heap_next.read() );
     2075                    bool last_copy  = (entry.next == r_config_heap_next.read());
     2076
     2077                    config_to_cc_send_fifo_srcid = entry.owner.srcid;
     2078                    config_to_cc_send_fifo_inst  = entry.owner.inst;
     2079                    // config_to_cc_send_fifo_last  = last_copy;
     2080                    config_to_cc_send_fifo_put   = true;
     2081
     2082                    if ( m_config_to_cc_send_inst_fifo.wok() ) // inval request accepted
     2083                    {
     2084                        r_config_heap_next = entry.next;
     2085                        if ( last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
     2086                    }
     2087
     2088#if DEBUG_MEMC_CONFIG
     2089                    if(m_debug)
     2090                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
     2091                            << " Post multi inval request to CC_SEND FSM"
     2092                            << " / address = " << std::hex << r_config_address.read()
     2093                            << " / copy = " << entry.owner.srcid
     2094                            << " / inst = " << std::dec << entry.owner.inst << std::endl;
     2095#endif
     2096                    break;
     2097                }
     2098                //////////////////////
     2099            case CONFIG_HEAP_LAST:      // HEAP housekeeping
     2100                {
     2101                    size_t free_pointer = m_heap.next_free_ptr();
     2102                    HeapEntry last_entry;
     2103                    last_entry.owner.srcid = 0;
     2104                    last_entry.owner.inst  = false;
     2105
     2106                    if ( m_heap.is_full() )
     2107                    {
     2108                        last_entry.next = r_config_dir_ptr.read();
     2109                        m_heap.unset_full();
     2110                    }
     2111                    else
     2112                    {
     2113                        last_entry.next = free_pointer;
     2114                    }
     2115
     2116                    m_heap.write_free_ptr( r_config_dir_ptr.read() );
     2117                    m_heap.write( r_config_heap_next.read(), last_entry );
     2118
     2119                    // prepare next iteration
     2120                    r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2121                    r_config_address            = r_config_address.read() + (m_words<<2);
     2122                    r_config_fsm                = CONFIG_LOOP;
     2123
     2124#if DEBUG_MEMC_CONFIG
     2125                    if(m_debug)
     2126                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
     2127                            << " Heap housekeeping" << std::endl;
     2128#endif
     2129                    break;
     2130                }
     2131        }  // end switch r_config_fsm
     2132
     2133        ////////////////////////////////////////////////////////////////////////////////////
     2134        //    READ FSM
     2135        ////////////////////////////////////////////////////////////////////////////////////
     2136        // The READ FSM controls the VCI read  and ll requests.
     2137        // It takes the lock protecting the cache directory to check the cache line status:
     2138        // - In case of HIT
     2139        //   The fsm copies the data (one line, or one single word)
     2140        //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
     2141        //   The requesting initiator is registered in the cache directory.
     2142        //   If the number of copy is larger than 1, the new copy is registered
     2143        //   in the HEAP.
     2144        //   If the number of copy is larger than the threshold, the HEAP is cleared,
     2145        //   and the corresponding line switches to the counter mode.
     2146        // - In case of MISS
     2147        //   The READ fsm takes the lock protecting the transaction tab.
     2148        //   If a read transaction to the XRAM for this line already exists,
     2149        //   or if the transaction tab is full, the fsm is stalled.
     2150        //   If a TRT entry is free, the READ request is registered in TRT,
     2151        //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
     2152        //   The READ FSM returns in the IDLE state as the read transaction will be
     2153        //   completed when the missing line will be received.
     2154        ////////////////////////////////////////////////////////////////////////////////////
     2155
     2156        //std::cout << std::endl << "read_fsm" << std::endl;
     2157
     2158        switch(r_read_fsm.read())
    11362159        {
    1137             if ( not p_vci_tgt.eop.read() ) r_tgt_cmd_fsm = TGT_CMD_ERROR;
    1138             else                            r_tgt_cmd_fsm = TGT_CMD_CONFIG;
    1139         }
    1140         else                            //////////// memory access
    1141         {
    1142             if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ )
    1143             {
    1144                 // check that the pktid is either :
    1145                 // TYPE_READ_DATA_UNC
    1146                 // TYPE_READ_DATA_MISS
    1147                 // TYPE_READ_INS_UNC
    1148                 // TYPE_READ_INS_MISS
    1149                 // ==> bit2 must be zero with the TSAR encoding
    1150                 // ==> mask = 0b0100 = 0x4
    1151                 assert( ((p_vci_tgt.pktid.read() & 0x4) == 0x0) and
    1152                 "The type specified in the pktid field is incompatible with the READ CMD");
    1153                 r_tgt_cmd_fsm = TGT_CMD_READ;
    1154             }
    1155             else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)
    1156             {
    1157                 // check that the pktid is TYPE_WRITE
    1158                 // ==> TYPE_WRITE = X100 with the TSAR encoding
    1159                 // ==> mask = 0b0111 = 0x7
    1160                 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x4) and
    1161                 "The type specified in the pktid field is incompatible with the WRITE CMD");
    1162                 r_tgt_cmd_fsm = TGT_CMD_WRITE;
    1163             }
    1164             else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ)
    1165             {
    1166                 // check that the pktid is TYPE_LL
    1167                 // ==> TYPE_LL = X110 with the TSAR encoding
    1168                 // ==> mask = 0b0111 = 0x7
    1169                 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) and
    1170                 "The type specified in the pktid field is incompatible with the LL CMD");
    1171                 r_tgt_cmd_fsm = TGT_CMD_READ;
    1172             }
    1173             else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)
    1174             {
    1175                 // check that the pktid is either :
    1176                 // TYPE_CAS
    1177                 // TYPE_SC
    1178                 // ==> TYPE_CAS = X101 with the TSAR encoding
    1179                 // ==> TYPE_SC  = X111 with the TSAR encoding
    1180                 // ==> mask = 0b0101 = 0x5
    1181                 assert(((p_vci_tgt.pktid.read() & 0x5) == 0x5) and
    1182                 "The type specified in the pktid field is incompatible with the NOP CMD");
    1183 
    1184                 if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS;
    1185                 else                                           r_tgt_cmd_fsm = TGT_CMD_WRITE;
    1186             }
    1187             else
    1188             {
    1189                 r_tgt_cmd_fsm = TGT_CMD_ERROR;
    1190             }
    1191         }
    1192     }
    1193     break;
    1194 
    1195     ///////////////////
    1196     case TGT_CMD_ERROR:  // response error must be sent
    1197 
    1198     // wait if pending request
    1199     if(r_tgt_cmd_to_tgt_rsp_req.read()) break;
    1200 
    1201     // consume all the command packet flits before sending response error
    1202     if ( p_vci_tgt.cmdval and p_vci_tgt.eop )
    1203     {
    1204         r_tgt_cmd_to_tgt_rsp_req   = true;
    1205         r_tgt_cmd_to_tgt_rsp_error = 1;
    1206         r_tgt_cmd_fsm              = TGT_CMD_IDLE;
    1207 
    1208 #if DEBUG_MEMC_TGT_CMD
    1209 if(m_debug)
    1210   std::cout << "  <MEMC " << name()
    1211     << " TGT_CMD_ERROR> Segmentation violation:"
    1212     << " address = " << std::hex << p_vci_tgt.address.read()
    1213     << " / srcid = " << p_vci_tgt.srcid.read()
    1214     << " / trdid = " << p_vci_tgt.trdid.read()
    1215     << " / pktid = " << p_vci_tgt.pktid.read()
    1216     << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    1217 #endif
    1218 
    1219     }
    1220     break;
    1221 
    1222     ////////////////////
    1223     case TGT_CMD_CONFIG:    // execute config request and return response
    1224     {
    1225         addr_t   seg_base = m_seg[m_seg_config]->baseAddress();
    1226         addr_t   address  = p_vci_tgt.address.read();
    1227         size_t   cell     = (address - seg_base)/vci_param_int::B;
    1228      
    1229         bool     need_rsp;
    1230         size_t   error; 
    1231         uint32_t rdata = 0;         // default value
    1232         uint32_t wdata = p_vci_tgt.wdata.read();
    1233 
    1234         if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
    1235              and (cell == MEMC_LOCK) )
    1236         {
    1237             rdata            = (uint32_t)r_config_lock.read();
    1238             need_rsp         = true;
    1239             error            = 0;
    1240             r_config_lock    = true;
    1241             if ( rdata == 0 )
    1242             {
    1243                 r_tgt_cmd_srcid = p_vci_tgt.srcid.read();
    1244                 r_tgt_cmd_trdid = p_vci_tgt.trdid.read();
    1245                 r_tgt_cmd_pktid = p_vci_tgt.pktid.read();
    1246             }
    1247         }
    1248         else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
    1249                    and (cell == MEMC_LOCK)
    1250                    and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    1251         {
    1252             need_rsp         = true;
    1253             error            = 0;
    1254             r_config_lock    = false;
    1255         }
    1256         else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
    1257                    and (cell == MEMC_ADDR_LO)
    1258                    and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    1259         {
    1260             assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
    1261             "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
    1262 
    1263             need_rsp         = true;
    1264             error            = 0;
    1265             r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
    1266                                (addr_t)p_vci_tgt.wdata.read();
    1267         }
    1268         else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
    1269                    and (cell == MEMC_ADDR_HI)
    1270                    and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    1271 
    1272         {
    1273             need_rsp         = true;
    1274             error            = 0;
    1275             r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
    1276                                ((addr_t)p_vci_tgt.wdata.read())<<32;
    1277         }
    1278         else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
    1279                    and (cell == MEMC_BUF_LENGTH)
    1280                    and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    1281         {
    1282             need_rsp         = true;
    1283             error            = 0;
    1284             size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2));
    1285             if ( r_config_address.read()%(m_words*4) ) lines++;
    1286             r_config_cmd_lines  = lines;
    1287             r_config_rsp_lines  = lines;
    1288         }
    1289         else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
    1290                    and (cell == MEMC_CMD_TYPE)
    1291                    and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    1292         {
    1293             need_rsp         = false;
    1294             error            = 0;
    1295             r_config_cmd     = p_vci_tgt.wdata.read();
    1296 
    1297             // prepare delayed response from CONFIG FSM
    1298             r_config_srcid   = p_vci_tgt.srcid.read();
    1299             r_config_trdid   = p_vci_tgt.trdid.read();
    1300             r_config_pktid   = p_vci_tgt.pktid.read();
    1301         }
    1302         else
    1303         {
    1304             need_rsp         = true;
    1305             error            = 1;
    1306         }
    1307 
    1308         if ( need_rsp )
    1309         {
    1310             // blocked if previous pending request to TGT_RSP FSM
    1311             if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break;
    1312 
    1313             r_tgt_cmd_to_tgt_rsp_req   = true;
    1314             r_tgt_cmd_to_tgt_rsp_error = error;
    1315             r_tgt_cmd_to_tgt_rsp_rdata = rdata;
    1316             r_tgt_cmd_fsm              = TGT_CMD_IDLE;
    1317         }
    1318         else
    1319         {
    1320             r_tgt_cmd_fsm              = TGT_CMD_IDLE;
    1321         }
    1322 
    1323 #if DEBUG_MEMC_TGT_CMD
    1324 if(m_debug)
    1325 std::cout << "  <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:"
    1326           << " address = " << std::hex << p_vci_tgt.address.read()
    1327           << " / wdata = " << p_vci_tgt.wdata.read()
    1328           << " / need_rsp = " << need_rsp
    1329           << " / error = " << error << std::endl;
    1330 #endif
    1331         break;
    1332     }
    1333     //////////////////
    1334     case TGT_CMD_READ:    // Push a read request into read fifo
    1335 
    1336     // check that the read does not cross a cache line limit.
    1337     if ( ((m_x[(addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) and
    1338           (p_vci_tgt.cmd.read() != vci_param_int::CMD_LOCKED_READ))
    1339     {
    1340         std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
    1341                   << " illegal address/plen for VCI read command" << std::endl;
    1342         exit(0);
    1343     }
    1344     // check single flit
    1345     if(!p_vci_tgt.eop.read())
    1346     {
    1347         std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
    1348                   << " read command packet must contain one single flit" << std::endl;
    1349         exit(0);
    1350     }
    1351     // check plen for LL
    1352     if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and
    1353          (p_vci_tgt.plen.read() != 8) )
    1354     {
    1355         std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
    1356                   << " ll command packets must have a plen of 8" << std::endl;
    1357         exit(0);
    1358     }
    1359 
    1360     if ( p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok() )
    1361     {
    1362 
    1363 #if DEBUG_MEMC_TGT_CMD
    1364 if(m_debug)
    1365 std::cout << "  <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:"
    1366           << " address = " << std::hex << p_vci_tgt.address.read()
    1367           << " / srcid = " << p_vci_tgt.srcid.read()
    1368           << " / trdid = " << p_vci_tgt.trdid.read()
    1369           << " / pktid = " << p_vci_tgt.pktid.read()
    1370           << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    1371 #endif
    1372         cmd_read_fifo_put = true;
    1373         if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) m_cpt_ll++;
    1374         else                                                       m_cpt_read++;
    1375         r_tgt_cmd_fsm = TGT_CMD_IDLE;
    1376     }
    1377     break;
    1378 
    1379     ///////////////////
    1380     case TGT_CMD_WRITE:
    1381     if(p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok())
    1382     {
    1383 
    1384 #if DEBUG_MEMC_TGT_CMD
    1385 if(m_debug)
    1386 std::cout << "  <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:"
    1387           << " address = " << std::hex << p_vci_tgt.address.read()
    1388           << " / srcid = " << p_vci_tgt.srcid.read()
    1389           << " / trdid = " << p_vci_tgt.trdid.read()
    1390           << " / pktid = " << p_vci_tgt.pktid.read()
    1391           << " / wdata = " << p_vci_tgt.wdata.read()
    1392           << " / be = " << p_vci_tgt.be.read()
    1393           << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    1394 #endif
    1395         cmd_write_fifo_put = true;
    1396         if(p_vci_tgt.eop)  r_tgt_cmd_fsm = TGT_CMD_IDLE;
    1397     }
    1398     break;
    1399 
    1400     /////////////////
    1401     case TGT_CMD_CAS:
    1402     if((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16))
    1403     {
    1404         std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state"
    1405                   << "illegal format for CAS command " << std::endl;
    1406         exit(0);
    1407     }
    1408 
    1409     if(p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok())
    1410     {
    1411 
    1412 #if DEBUG_MEMC_TGT_CMD
    1413 if(m_debug)
    1414 std::cout << "  <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:"
    1415           << " address = " << std::hex << p_vci_tgt.address.read()
    1416           << " srcid = " << p_vci_tgt.srcid.read()
    1417           << " trdid = " << p_vci_tgt.trdid.read()
    1418           << " pktid = " << p_vci_tgt.pktid.read()
    1419           << " wdata = " << p_vci_tgt.wdata.read()
    1420           << " be = " << p_vci_tgt.be.read()
    1421           << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    1422 #endif
    1423         cmd_cas_fifo_put = true;
    1424         if(p_vci_tgt.eop) r_tgt_cmd_fsm = TGT_CMD_IDLE;
    1425     }
    1426     break;
    1427   } // end switch tgt_cmd_fsm
    1428 
    1429   /////////////////////////////////////////////////////////////////////////
    1430   //    MULTI_ACK FSM
    1431   /////////////////////////////////////////////////////////////////////////
    1432   // This FSM controls the response to the multicast update requests sent
    1433   // by the memory cache to the L1 caches and update the UPT.
    1434   //
    1435   // - The FSM decrements the proper entry in UPT,
    1436   //   and clear the UPT entry when all responses have been received.
    1437   // - If required, it sends a request to the TGT_RSP FSM to complete
    1438   //   a pending  write transaction.
    1439   //
    1440   // All those multi-ack packets are one flit packet.
    1441   // The index in the UPT is defined in the TRDID field.
    1442   ////////////////////////////////////////////////////////////////////////
    1443 
    1444 //std::cout << std::endl << "multi_ack_fsm" << std::endl;
    1445 
    1446   switch(r_multi_ack_fsm.read())
    1447   {
    1448     ////////////////////
    1449     case MULTI_ACK_IDLE:
    1450     {
    1451         bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok();
    1452 
    1453         // No CC_RECEIVE FSM request and no WRITE FSM request
    1454         if( not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read())
    1455           break;
    1456 
    1457         uint8_t updt_index;
    1458 
    1459         // handling WRITE FSM request to decrement update table response
    1460         // counter if no CC_RECEIVE FSM request
    1461         if(not multi_ack_fifo_rok)
    1462         {
    1463           updt_index               = r_write_to_multi_ack_upt_index.read();
    1464           r_write_to_multi_ack_req = false;
    1465         }
    1466         // Handling CC_RECEIVE FSM request
    1467         else
    1468         {
    1469           uint64_t flit = m_cc_receive_to_multi_ack_fifo.read();
    1470           updt_index    = DspinDhccpParam::dspin_get(flit,
    1471                             DspinDhccpParam::MULTI_ACK_UPDT_INDEX);
    1472 
    1473           cc_receive_to_multi_ack_fifo_get = true;
    1474         }
    1475 
    1476         assert((updt_index < m_upt.size()) and
    1477                "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : "
    1478                "index too large for UPT");
    1479 
    1480         r_multi_ack_upt_index = updt_index;
    1481         r_multi_ack_fsm       = MULTI_ACK_UPT_LOCK;
    1482 
    1483 #if DEBUG_MEMC_MULTI_ACK
    1484 if(m_debug)
    1485 {
    1486     if (multi_ack_fifo_rok)
    1487     {
    1488         std::cout << "  <MEMC " << name()
    1489                   << " MULTI_ACK_IDLE> Response for UPT entry "
    1490                   << (size_t)updt_index << std::endl;
    1491     }
    1492     else
    1493     {
    1494         std::cout << "  <MEMC " << name()
    1495                   << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry "
    1496                   << updt_index << std::endl;
    1497     }
    1498 }
    1499 #endif
    1500         break;
    1501       }
    1502 
    1503     ////////////////////////
    1504     case MULTI_ACK_UPT_LOCK:
    1505     {
    1506         m_cpt_multi_ack_fsm_upt_lock++;
    1507         // get lock to the UPDATE table
    1508         if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)  break;
    1509 
    1510         // decrement the number of expected responses
    1511         size_t count = 0;
    1512         bool valid   = m_upt.decrement(r_multi_ack_upt_index.read(), count);
    1513 
    1514 
    1515         if(not valid)
    1516         {
    1517             std::cout << "VCI_MEM_CACHE ERROR " << name()
    1518                       << " MULTI_ACK_UPT_LOCK state" << std::endl
    1519                       << "unsuccessful access to decrement the UPT" << std::endl;
    1520             exit(0);
    1521         }
    1522 
    1523         if(count == 0)
    1524         {
    1525           r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR;
    1526         }
    1527         else
    1528         {
    1529           r_multi_ack_fsm = MULTI_ACK_IDLE;
    1530         }
    1531 
    1532 #if DEBUG_MEMC_MULTI_ACK
    1533 if(m_debug)
    1534 std::cout << "  <MEMC " << name()
    1535           << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:"
    1536           << " entry = "       << r_multi_ack_upt_index.read()
    1537           << " / rsp_count = " << std::dec << count << std::endl;
    1538         m_cpt_multi_ack_fsm_n_upt_lock++;
    1539 #endif
    1540         break;
    1541     }
    1542 
    1543     /////////////////////////
    1544     case MULTI_ACK_UPT_CLEAR:   // Clear UPT entry / Test if rsp or ack required
    1545     {
    1546         if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)
    1547         {
    1548             std::cout << "VCI_MEM_CACHE ERROR " << name()
    1549                       << " MULTI_ACK_UPT_CLEAR state"
    1550                       << " bad UPT allocation" << std::endl;
    1551             exit(0);
    1552         }
    1553 
    1554         r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read());
    1555         r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read());
    1556         r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read());
    1557         r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
    1558         bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
    1559 
    1560         // clear the UPT entry
    1561         m_upt.clear(r_multi_ack_upt_index.read());
    1562 
    1563         if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
    1564         else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
    1565 
    1566 #if DEBUG_MEMC_MULTI_ACK
    1567 if(m_debug)
    1568 std::cout <<  "  <MEMC " << name()
    1569           << " MULTI_ACK_UPT_CLEAR> Clear UPT entry "
    1570           << std::dec << r_multi_ack_upt_index.read() << std::endl;
    1571 #endif
    1572         break;
    1573     }
    1574     /////////////////////////
    1575     case MULTI_ACK_WRITE_RSP:     // Post a response request to TGT_RSP FSM
    1576                                   // Wait if pending request
    1577     {
    1578         if ( r_multi_ack_to_tgt_rsp_req.read() ) break;
    1579 
    1580         r_multi_ack_to_tgt_rsp_req   = true;
    1581         r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read();
    1582         r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read();
    1583         r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read();
    1584         r_multi_ack_fsm              = MULTI_ACK_IDLE;
    1585 
    1586 #if DEBUG_MEMC_MULTI_ACK
    1587 if(m_debug)
    1588 std::cout << "  <MEMC " << name() << " MULTI_ACK_WRITE_RSP>"
    1589           << " Request TGT_RSP FSM to send a response to srcid "
    1590           << std::hex << r_multi_ack_srcid.read() << std::endl;
    1591 #endif
    1592         break;
    1593     }
    1594   } // end switch r_multi_ack_fsm
    1595 
    1596   ////////////////////////////////////////////////////////////////////////////////////
    1597   //    CONFIG FSM
    1598   ////////////////////////////////////////////////////////////////////////////////////
    1599   // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC).
    1600   // The target buffer can have any size, and there is one single command for
    1601   // all cache lines covered by the target buffer.
    1602   //
    1603   // An INVAL or SYNC configuration operation is defined by the following registers:
    1604   // - bool      r_config_cmd        : INVAL / SYNC / NOP
    1605   // - uint64_t  r_config_address    : buffer base address
    1606   // - uint32_t  r_config_cmd_lines  : number of lines to be handled
    1607   // - uint32_t  r_config_rsp_lines  : number of lines not completed
    1608   //
    1609   // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
    1610   // all cache lines covered by the buffer. The various lines of a given buffer
    1611   // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
    1612   // the command for line (n+1). It decrements the r_config_cmd_lines counter until
    1613   // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
    1614   //
    1615   // - INVAL request:
    1616   //   For each line, it access to the DIR.
    1617   //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    1618   //   In case of hit, with no copies in L1 caches, the line is invalidated and
    1619   //   a response is requested to TGT_RSP FSM.
    1620   //   If there is copies, a multi-inval, or a broadcast-inval coherence transaction
    1621   //   is launched and registered in UPT. The multi-inval transaction completion
    1622   //   is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter.
    1623   //   The CONFIG INVAL response is sent only when the last line has been invalidated.
    1624   //   TODO : The target buffer address must be aligned on a cache line boundary.
    1625   //   This constraint can be released, but it requires to make 2 PUT transactions
    1626   //   for the first and the last line...
    1627   //
    1628   // - SYNC request:
    1629   //   For each line, it access to the DIR.
    1630   //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    1631   //   In case of hit, a PUT transaction is registered in TRT and a request is sent
    1632   //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
    1633   //   when a PUT response is received.
    1634   //   The CONFIG SYNC response is sent only when the last PUT response is received.
    1635   //
    1636   // From the software point of view, a configuration request is a sequence
    1637   // of 6 atomic accesses in an uncached segment. A dedicated lock is used
    1638   // to handle only one configuration command at a given time:
    1639   // - Read  MEMC_LOCK       : Get the lock
    1640   // - Write MEMC_ADDR_LO    : Set the buffer address LSB
    1641   // - Write MEMC_ADDR_HI    : Set the buffer address MSB
    1642   // - Write MEMC_BUF_LENGTH : set buffer length (bytes)
    1643   // - Write MEMC_CMD_TYPE   : launch the actual operation
    1644   // - WRITE MEMC_LOCK       : release the lock
    1645   ////////////////////////////////////////////////////////////////////////////////////
    1646 
    1647 //std::cout << std::endl << "config_fsm" << std::endl;
    1648 
    1649   switch( r_config_fsm.read() )
    1650   {
    1651       /////////////////
    1652       case CONFIG_IDLE:  // waiting a config request
    1653       {
    1654           if ( r_config_cmd.read() != MEMC_CMD_NOP ) 
    1655           {
    1656               r_config_fsm    = CONFIG_LOOP;
    1657 
    1658 #if DEBUG_MEMC_CONFIG
    1659 if(m_debug)
    1660 std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
    1661           << " / address = " << std::hex << r_config_address.read()
    1662           << " / lines = " << std::dec << r_config_cmd_lines.read()
    1663           << " / type = " << r_config_cmd.read() << std::endl;
    1664 #endif
    1665           }
    1666           break;
    1667       }
    1668       /////////////////
    1669       case CONFIG_LOOP:   // test if last line to be handled
    1670       {
    1671           if ( r_config_cmd_lines.read() == 0 )
    1672           {
    1673               r_config_cmd = MEMC_CMD_NOP;
    1674               r_config_fsm = CONFIG_WAIT;
    1675           }
    1676           else
    1677           {
    1678               r_config_fsm = CONFIG_DIR_REQ;
    1679           }
    1680 
    1681 #if DEBUG_MEMC_CONFIG
    1682 if(m_debug)
    1683 std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
    1684           << " / address = " << std::hex << r_config_address.read()   
    1685           << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
    1686           << " / command = " << r_config_cmd.read() << std::endl;
    1687 #endif
    1688           break;
    1689       }
    1690       /////////////////
    1691       case CONFIG_WAIT:   // wait completion (last response)
    1692       {
    1693           if ( r_config_rsp_lines.read() == 0 )  // last response received
    1694           {
    1695               r_config_fsm = CONFIG_RSP;
    1696           }
    1697 
    1698 #if DEBUG_MEMC_CONFIG
    1699 if(m_debug)
    1700 std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
    1701           << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
    1702 #endif
    1703           break;
    1704       }
    1705       ////////////////
    1706       case CONFIG_RSP:  // request TGT_RSP FSM to return response
    1707       {
    1708           if ( not r_config_to_tgt_rsp_req.read() )
    1709           {
    1710               r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
    1711               r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
    1712               r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
    1713               r_config_to_tgt_rsp_error  = false;
    1714               r_config_to_tgt_rsp_req    = true;
    1715               r_config_fsm               = CONFIG_IDLE;
    1716 
    1717 #if DEBUG_MEMC_CONFIG
    1718 if(m_debug)
    1719 std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
    1720           << " error = " << r_config_to_tgt_rsp_error.read()
    1721           << " / rsrcid = " << std::hex << r_config_srcid.read()
    1722           << " / rtrdid = " << std::hex << r_config_trdid.read()
    1723           << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
    1724 #endif
    1725           }
    1726           break;
    1727 
    1728       }
    1729       ////////////////////
    1730       case CONFIG_DIR_REQ:  // Request directory lock
    1731       {
    1732           if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
    1733           {
    1734               r_config_fsm = CONFIG_DIR_ACCESS;
    1735           }
    1736 
    1737 #if DEBUG_MEMC_CONFIG
    1738 if(m_debug)
    1739 std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
    1740           << " Request DIR access" << std::endl;
    1741 #endif
    1742           break;
    1743       }
    1744       ///////////////////////
    1745       case CONFIG_DIR_ACCESS:   // Access directory and decode config command
    1746       {
    1747           assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    1748           "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
    1749 
    1750           size_t way = 0;
    1751           DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
    1752 
    1753           if ( entry.valid and                            // hit & inval command
    1754                (r_config_cmd.read() == MEMC_CMD_INVAL) )
    1755           {
    1756               r_config_dir_way        = way;
    1757               r_config_dir_copy_inst  = entry.owner.inst;
    1758               r_config_dir_copy_srcid = entry.owner.srcid;
    1759               r_config_dir_is_cnt     = entry.is_cnt;
    1760               r_config_dir_lock       = entry.lock;
    1761               r_config_dir_count      = entry.count;
    1762               r_config_dir_ptr        = entry.ptr;
    1763 
    1764               r_config_fsm    = CONFIG_IVT_LOCK;
    1765           }
    1766           else if ( entry.valid and                       // hit & sync command
    1767                     entry.dirty and
    1768                     (r_config_cmd.read() == MEMC_CMD_SYNC) )
    1769           {
    1770               r_config_fsm  = CONFIG_TRT_LOCK;
    1771           }
    1772           else                                            // miss : return to LOOP
    1773           {
    1774               r_config_cmd_lines = r_config_cmd_lines.read() - 1;
    1775               r_config_rsp_lines = r_config_rsp_lines.read() - 1;
    1776               r_config_cmd_lines = r_config_cmd_lines.read() - 1;
    1777               r_config_address   = r_config_address.read() + (m_words<<2);
    1778               r_config_fsm       = CONFIG_LOOP;
    1779           }
    1780 
    1781 #if DEBUG_MEMC_CONFIG
    1782 if(m_debug)
    1783 std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
    1784           << " address = " << std::hex << r_config_address.read()
    1785           << " / hit = " << std::dec << entry.valid
    1786           << " / dirty = " << entry.dirty
    1787           << " / count = " << entry.count
    1788           << " / is_cnt = " << entry.is_cnt << std::endl;
    1789 #endif
    1790           break;
    1791       }
    1792       /////////////////////
    1793       case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
    1794                                  // to a dirty cache line
    1795                                  // keep DIR lock, and try to get TRT lock
    1796                                  // return to LOOP state if TRT full
    1797                                  // reset dirty bit in DIR and register a PUT
    1798                                  // trabsaction in TRT if not full.
    1799       {
    1800           assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    1801           "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
    1802 
    1803           if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
    1804           {
    1805               size_t index = 0;
    1806               bool   wok   = not m_trt.full(index);
    1807 
    1808               if ( not wok )
    1809               {
    1810                   r_config_fsm = CONFIG_LOOP;
    1811               }
    1812               else
    1813               {
    1814                   size_t          way = r_config_dir_way.read();
    1815                   size_t          set = m_y[r_config_address.read()];
    1816 
    1817                   // reset dirty bit in DIR
    1818                   DirectoryEntry  entry;
    1819                   entry.valid       = true;
    1820                   entry.dirty       = false;
    1821                   entry.tag         = m_z[r_config_address.read()];
    1822                   entry.is_cnt      = r_config_dir_is_cnt.read();
    1823                   entry.lock        = r_config_dir_lock.read();
    1824                   entry.ptr         = r_config_dir_ptr.read();
    1825                   entry.count       = r_config_dir_count.read();
    1826                   entry.owner.inst  = r_config_dir_copy_inst.read();
    1827                   entry.owner.srcid = r_config_dir_copy_srcid.read();
    1828                   m_cache_directory.write( set,
    1829                                            way,
    1830                                            entry );
    1831 
    1832                   r_config_trt_index = index;
    1833                   r_config_fsm       = CONFIG_TRT_SET;
    1834               }
    1835 
    1836 #if DEBUG_MEMC_CONFIG
    1837 if(m_debug)
    1838 std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
    1839           << " wok = " << std::dec << wok
    1840           << " index = " << index << std::endl;
    1841 #endif
    1842           }
    1843           break;
    1844       }
    1845       ////////////////////
    1846       case CONFIG_TRT_SET:       // read data in cache
    1847                                  // and post a PUT request in TRT
    1848       {
    1849           assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    1850           "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
    1851 
    1852           assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
    1853           "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
    1854 
    1855           // read data into cache
    1856           size_t          way = r_config_dir_way.read();
    1857           size_t          set = m_y[r_config_address.read()];
    1858 
    1859           sc_signal<data_t> config_data[16];
    1860           m_cache_data.read_line( way,
    1861                                   set,
    1862                                   config_data );
    1863            
    1864           // post a PUT request in TRT
    1865           std::vector<data_t> data_vector;
    1866           data_vector.clear();
    1867           for(size_t i=0; i<m_words; i++) data_vector.push_back(config_data[i].read());
    1868           m_trt.set( r_config_trt_index.read(),
    1869                      false,                               // PUT
    1870                      m_nline[r_config_address.read()],    // nline
    1871                      0,                                   // srcid:       unused
    1872                      0,                                   // trdid:       unused
    1873                      0,                                   // pktid:       unused
    1874                      false,                               // not proc_read
    1875                      0,                                   // read_length: unused
    1876                      0,                                   // word_index:  unused
    1877                      std::vector<be_t>(m_words,0xF),                         
    1878                      data_vector);
    1879 
    1880 #if DEBUG_MEMC_CONFIG
    1881 if(m_debug)
    1882 std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
    1883           << " address = " << std::hex << r_config_address.read()
    1884           << " index = " << std::dec << r_config_trt_index.read() << std::endl;
    1885 #endif
    1886           break;
    1887       }
    1888       ////////////////////
    1889       case CONFIG_PUT_REQ:       // PUT request to IXR_CMD_FSM
    1890       {
    1891           if ( not r_config_to_ixr_cmd_req.read() )
    1892           {
    1893               r_config_to_ixr_cmd_req   = true;
    1894               r_config_to_ixr_cmd_index = r_config_trt_index.read();
    1895 
    1896               // prepare next iteration
    1897               r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
    1898               r_config_address                = r_config_address.read() + (m_words<<2);
    1899               r_config_fsm                    = CONFIG_LOOP;
    1900 
    1901 #if DEBUG_MEMC_CONFIG
    1902 if(m_debug)
    1903 std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> PUT request to IXR_CMD_FSM"
    1904           << " / address = " << std::hex << r_config_address.read() << std::endl;
    1905 #endif
    1906           }
    1907           break;
    1908       }
    1909       /////////////////////
    1910       case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
    1911                              // Keep DIR lock and Try to get IVT lock.
    1912                              // Return to LOOP state if IVT full.
    1913                              // Register inval in IVT, and invalidate the
    1914                              // directory if IVT not full.
    1915       {
    1916           assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    1917           "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
    1918 
    1919           if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
    1920           {
    1921               size_t set        = m_y[(addr_t)(r_config_address.read())];
    1922               size_t way        = r_config_dir_way.read();
    1923 
    1924               if ( r_config_dir_count.read() == 0 )     // inval DIR and return to LOOP
    1925               {
    1926                   m_cache_directory.inval( way, set );
    1927                   r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
    1928                   r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
    1929                   r_config_address    = r_config_address.read() + (m_words<<2);
    1930                   r_config_fsm        = CONFIG_LOOP;
    1931 
    1932 #if DEBUG_MEMC_CONFIG
    1933 if(m_debug)
    1934 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    1935           << " No copies in L1 : inval DIR entry"  << std::endl;
    1936 #endif
    1937               }
    1938               else    // try to register inval in IVT
    1939               {
    1940                   bool        wok       = false;
    1941                   size_t      index     = 0;
    1942                   bool        broadcast = r_config_dir_is_cnt.read();
    1943                   size_t      srcid     = r_config_srcid.read();
    1944                   size_t      trdid     = r_config_trdid.read();
    1945                   size_t      pktid     = r_config_pktid.read();
    1946                   addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
    1947                   size_t      nb_copies = r_config_dir_count.read();
    1948 
    1949                   wok = m_ivt.set(false,       // it's an inval transaction
    1950                                   broadcast,   
    1951                                   false,       // no response required
    1952                                   true,        // acknowledge required
    1953                                   srcid,
    1954                                   trdid,
    1955                                   pktid,
    1956                                   nline,
    1957                                   nb_copies,
    1958                                   index);
    1959 
    1960                   if ( wok )  // IVT success => inval DIR slot
    1961                   {
    1962                       m_cache_directory.inval( way, set );
    1963                       r_config_ivt_index = index;
    1964                       if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
    1965                       else              r_config_fsm = CONFIG_INVAL_SEND;
    1966 
    1967 #if DEBUG_MEMC_CONFIG
    1968 if(m_debug)
    1969 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    1970           << " Inval DIR entry and register inval in IVT"
    1971           << " / index = " << std::dec << index
    1972           << " / broadcast = " << broadcast << std::endl;
    1973 #endif
    1974                   }
    1975                   else       // IVT full => release both DIR and IVT locks
    1976                   {
    1977                       r_config_fsm = CONFIG_LOOP;
    1978 
    1979 #if DEBUG_MEMC_CONFIG
    1980 if(m_debug)
    1981 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    1982           << " IVT full : release DIR & IVT locks and retry" << std::endl;
    1983 #endif
    1984                   }
    1985               }
    1986           }
    1987           break;
    1988       }
    1989       ////////////////////
    1990       case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
    1991       {
    1992           if( not r_config_to_cc_send_multi_req.read() and
    1993               not r_config_to_cc_send_brdcast_req.read() )
    1994           {
    1995               // post bc inval request
    1996               r_config_to_cc_send_multi_req   = false;
    1997               r_config_to_cc_send_brdcast_req = true;
    1998               r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    1999               r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.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_BC_SEND>"
    2009           << " Post a broadcast inval request to CC_SEND FSM"
    2010           << " / address = " << r_config_address.read() <<std::endl;
    2011 #endif
    2012           }
    2013           break;
    2014       }
    2015       ///////////////////////
    2016       case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
    2017       {
    2018           if( not r_config_to_cc_send_multi_req.read() and
    2019               not r_config_to_cc_send_brdcast_req.read() )
    2020           {
    2021               // post multi inval request
    2022               r_config_to_cc_send_multi_req   = true;
    2023               r_config_to_cc_send_brdcast_req = false;
    2024               r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    2025               r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
    2026 
    2027               // post data into FIFO
    2028               config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
    2029               config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
    2030               config_to_cc_send_fifo_put      = true;
    2031 
    2032               if ( r_config_dir_count.read() == 1 )  // one copy
    2033               {
    2034                   // prepare next iteration
    2035                   r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
    2036                   r_config_address            = r_config_address.read() + (m_words<<2);
    2037                   r_config_fsm                = CONFIG_LOOP;
    2038               }
    2039               else                                   // several copies
    2040               {
    2041                   r_config_fsm = CONFIG_HEAP_REQ;
    2042               }
    2043 
    2044 #if DEBUG_MEMC_CONFIG
    2045 if(m_debug)
    2046 std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
    2047           << " Post multi inval request to CC_SEND FSM"
    2048           << " / address = " << std::hex << r_config_address.read()
    2049           << " / copy = " << r_config_dir_copy_srcid.read()
    2050           << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
    2051 #endif
    2052           }
    2053           break;
    2054       }
    2055       /////////////////////
    2056       case CONFIG_HEAP_REQ:  // Try to get access to Heap
    2057       {
    2058           if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
    2059           {
    2060               r_config_fsm       = CONFIG_HEAP_SCAN;
    2061               r_config_heap_next = r_config_dir_ptr.read();
    2062           }
    2063 
    2064 #if DEBUG_MEMC_CONFIG
    2065 if(m_debug)
    2066 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
    2067           << " Requesting HEAP lock" << std::endl;
    2068 #endif
    2069           break;
    2070       }
    2071       //////////////////////
    2072       case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
    2073       {
    2074           HeapEntry entry = m_heap.read( r_config_heap_next.read() );
    2075           bool last_copy  = (entry.next == r_config_heap_next.read());
    2076 
    2077           config_to_cc_send_fifo_srcid = entry.owner.srcid;
    2078           config_to_cc_send_fifo_inst  = entry.owner.inst;
    2079           // config_to_cc_send_fifo_last  = last_copy;
    2080           config_to_cc_send_fifo_put   = true;
    2081 
    2082           if ( m_config_to_cc_send_inst_fifo.wok() ) // inval request accepted
    2083           {
    2084               r_config_heap_next = entry.next;
    2085               if ( last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
    2086           }
    2087          
    2088 #if DEBUG_MEMC_CONFIG
    2089 if(m_debug)
    2090 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
    2091           << " Post multi inval request to CC_SEND FSM"
    2092           << " / address = " << std::hex << r_config_address.read()
    2093           << " / copy = " << entry.owner.srcid
    2094           << " / inst = " << std::dec << entry.owner.inst << std::endl;
    2095 #endif
    2096           break;
    2097       }
    2098       //////////////////////
    2099       case CONFIG_HEAP_LAST:      // HEAP housekeeping
    2100       {
    2101           size_t free_pointer = m_heap.next_free_ptr();
    2102           HeapEntry last_entry;
    2103           last_entry.owner.srcid = 0;
    2104           last_entry.owner.inst  = false;
    2105 
    2106           if ( m_heap.is_full() )
    2107           {
    2108               last_entry.next = r_config_dir_ptr.read();
    2109               m_heap.unset_full();
    2110           }
    2111           else
    2112           {
    2113               last_entry.next = free_pointer;
    2114           }
    2115 
    2116           m_heap.write_free_ptr( r_config_dir_ptr.read() );
    2117           m_heap.write( r_config_heap_next.read(), last_entry );
    2118 
    2119           // prepare next iteration
    2120           r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
    2121           r_config_address            = r_config_address.read() + (m_words<<2);
    2122           r_config_fsm                = CONFIG_LOOP;
    2123 
    2124 #if DEBUG_MEMC_CONFIG
    2125 if(m_debug)
    2126 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
    2127           << " Heap housekeeping" << std::endl;
    2128 #endif
    2129           break;
    2130       }
    2131   }  // end switch r_config_fsm
    2132 
    2133   ////////////////////////////////////////////////////////////////////////////////////
    2134   //    READ FSM
    2135   ////////////////////////////////////////////////////////////////////////////////////
    2136   // The READ FSM controls the VCI read  and ll requests.
    2137   // It takes the lock protecting the cache directory to check the cache line status:
    2138   // - In case of HIT
    2139   //   The fsm copies the data (one line, or one single word)
    2140   //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
    2141   //   The requesting initiator is registered in the cache directory.
    2142   //   If the number of copy is larger than 1, the new copy is registered
    2143   //   in the HEAP.
    2144   //   If the number of copy is larger than the threshold, the HEAP is cleared,
    2145   //   and the corresponding line switches to the counter mode.
    2146   // - In case of MISS
    2147   //   The READ fsm takes the lock protecting the transaction tab.
    2148   //   If a read transaction to the XRAM for this line already exists,
    2149   //   or if the transaction tab is full, the fsm is stalled.
    2150   //   If a TRT entry is free, the READ request is registered in TRT,
    2151   //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
    2152   //   The READ FSM returns in the IDLE state as the read transaction will be
    2153   //   completed when the missing line will be received.
    2154   ////////////////////////////////////////////////////////////////////////////////////
    2155 
    2156 //std::cout << std::endl << "read_fsm" << std::endl;
    2157 
    2158   switch(r_read_fsm.read())
    2159   {
    2160     ///////////////
    2161     case READ_IDLE:  // waiting a read request
    2162     {
    2163         if(m_cmd_read_addr_fifo.rok())
    2164         {
     2160            ///////////////
     2161            case READ_IDLE:  // waiting a read request
     2162                {
     2163                    if(m_cmd_read_addr_fifo.rok())
     2164                    {
    21652165
    21662166#if DEBUG_MEMC_READ
    2167 if(m_debug)
    2168 std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
    2169           << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
    2170           << " / srcid = " << m_cmd_read_srcid_fifo.read()
    2171           << " / trdid = " << m_cmd_read_trdid_fifo.read()
    2172           << " / pktid = " << m_cmd_read_pktid_fifo.read()
    2173           << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    2174 #endif
    2175             r_read_fsm = READ_DIR_REQ;
    2176         }
    2177         break;
    2178     }
    2179     //////////////////
    2180     case READ_DIR_REQ:  // Get the lock to the directory
    2181     {
    2182       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    2183       {
    2184         r_read_fsm = READ_DIR_LOCK;
    2185         m_cpt_read_fsm_n_dir_lock++;
    2186       }
     2167                        if(m_debug)
     2168                            std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
     2169                                << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
     2170                                << " / srcid = " << m_cmd_read_srcid_fifo.read()
     2171                                << " / trdid = " << m_cmd_read_trdid_fifo.read()
     2172                                << " / pktid = " << m_cmd_read_pktid_fifo.read()
     2173                                << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2174#endif
     2175                        r_read_fsm = READ_DIR_REQ;
     2176                    }
     2177                    break;
     2178                }
     2179                //////////////////
     2180            case READ_DIR_REQ:  // Get the lock to the directory
     2181                {
     2182                    if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
     2183                    {
     2184                        r_read_fsm = READ_DIR_LOCK;
     2185                        m_cpt_read_fsm_n_dir_lock++;
     2186                    }
    21872187
    21882188#if DEBUG_MEMC_READ
    2189 if(m_debug)
    2190 std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
    2191 #endif
    2192 
    2193       m_cpt_read_fsm_dir_lock++;
    2194 
    2195       break;
    2196     }
    2197 
    2198     ///////////////////
    2199     case READ_DIR_LOCK:  // check directory for hit / miss
    2200     {
    2201         assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
    2202         "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
    2203 
    2204         size_t way = 0;
    2205         DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
    2206 
    2207         // access the global table ONLY when we have an LL cmd
    2208         if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)   
    2209         {
    2210             r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
    2211         }
    2212         r_read_is_cnt     = entry.is_cnt;
    2213         r_read_dirty      = entry.dirty;
    2214         r_read_lock       = entry.lock;
    2215         r_read_tag        = entry.tag;
    2216         r_read_way        = way;
    2217         r_read_count      = entry.count;
    2218         r_read_copy       = entry.owner.srcid;
    2219         r_read_copy_inst  = entry.owner.inst;
    2220         r_read_ptr        = entry.ptr; // pointer to the heap
    2221 
    2222         // check if this is a cached read, this means pktid is either
    2223         // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    2224         // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2225         bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
    2226         if(entry.valid)    // hit
    2227         {
    2228             // test if we need to register a new copy in the heap
    2229             if(entry.is_cnt or (entry.count == 0) or !cached_read)
    2230             {
    2231                 r_read_fsm = READ_DIR_HIT;
    2232             }
    2233             else
    2234             {
    2235                 r_read_fsm = READ_HEAP_REQ;
    2236             }
    2237         }
    2238         else      // miss
    2239         {
    2240             r_read_fsm = READ_TRT_LOCK;
    2241         }
     2189                    if(m_debug)
     2190                        std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
     2191#endif
     2192
     2193                    m_cpt_read_fsm_dir_lock++;
     2194
     2195                    break;
     2196                }
     2197
     2198                ///////////////////
     2199            case READ_DIR_LOCK:  // check directory for hit / miss
     2200                {
     2201                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2202                            "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
     2203
     2204                    size_t way = 0;
     2205                    DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2206
     2207                    // access the global table ONLY when we have an LL cmd
     2208                    if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)   
     2209                    {
     2210                        r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     2211                    }
     2212                    r_read_is_cnt     = entry.is_cnt;
     2213                    r_read_dirty      = entry.dirty;
     2214                    r_read_lock       = entry.lock;
     2215                    r_read_tag        = entry.tag;
     2216                    r_read_way        = way;
     2217                    r_read_count      = entry.count;
     2218                    r_read_copy       = entry.owner.srcid;
     2219                    r_read_copy_inst  = entry.owner.inst;
     2220                    r_read_ptr        = entry.ptr; // pointer to the heap
     2221
     2222                    // check if this is a cached read, this means pktid is either
     2223                    // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2224                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2225                    bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
     2226                    if(entry.valid)    // hit
     2227                    {
     2228                        // test if we need to register a new copy in the heap
     2229                        if(entry.is_cnt or (entry.count == 0) or !cached_read)
     2230                        {
     2231                            r_read_fsm = READ_DIR_HIT;
     2232                        }
     2233                        else
     2234                        {
     2235                            r_read_fsm = READ_HEAP_REQ;
     2236                        }
     2237                    }
     2238                    else      // miss
     2239                    {
     2240                        r_read_fsm = READ_TRT_LOCK;
     2241                    }
    22422242
    22432243#if DEBUG_MEMC_READ
    2244 if(m_debug)
    2245 {
    2246 std::cout << "  <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: "
    2247           << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    2248           << " / hit = " << std::dec << entry.valid
    2249           << " / count = " <<std::dec << entry.count
    2250           << " / is_cnt = " << entry.is_cnt;
    2251 if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl;
    2252 else                                                std::cout << std::endl;
    2253 }
    2254 #endif
    2255         break;
    2256     }
    2257     //////////////////
    2258     case READ_DIR_HIT:    //  read data in cache & update the directory
    2259                           //  we enter this state in 3 cases:
    2260                           //  - the read request is uncachable
    2261                           //  - the cache line is in counter mode
    2262                           //  - the cache line is valid but not replicated
    2263 
    2264     {
    2265         assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
    2266         "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
    2267 
    2268         // check if this is an instruction read, this means pktid is either
    2269         // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
    2270         // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2271         bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    2272         // check if this is a cached read, this means pktid is either
    2273         // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    2274         // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2275         bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
    2276         bool is_cnt       = r_read_is_cnt.read();
    2277 
    2278         // read data in the cache
    2279         size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
    2280         size_t way        = r_read_way.read();
    2281 
    2282         m_cache_data.read_line(way, set, r_read_data);
    2283 
    2284         // update the cache directory
    2285         DirectoryEntry entry;
    2286         entry.valid    = true;
    2287         entry.is_cnt   = is_cnt;
    2288         entry.dirty    = r_read_dirty.read();
    2289         entry.tag      = r_read_tag.read();
    2290         entry.lock     = r_read_lock.read();
    2291         entry.ptr      = r_read_ptr.read();
    2292 
    2293         /*ODCCP*/ // if pktid = 0x9 that means read on no coherent line
    2294         if(m_cmd_read_pktid_fifo.read() == 0x9){
    2295           entry.coherent = false;
    2296         }
    2297         else{
    2298           entry.coherent = true;
    2299         }
    2300        
    2301         if(cached_read)   // Cached read => we must update the copies
    2302         {
    2303             if(!is_cnt)  // Not counter mode
    2304             {
    2305                 entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2306                 entry.owner.inst     = inst_read;
    2307                 entry.count          = r_read_count.read() + 1;
    2308             }
    2309             else  // Counter mode
    2310             {
    2311                 entry.owner.srcid    = 0;
    2312                 entry.owner.inst     = false;
    2313                 entry.count          = r_read_count.read() + 1;
    2314             }
    2315         }
    2316         else            // Uncached read
    2317         {
    2318             entry.owner.srcid     = r_read_copy.read();
    2319             entry.owner.inst      = r_read_copy_inst.read();
    2320             entry.count           = r_read_count.read();
    2321         }
     2244                    if(m_debug)
     2245                    {
     2246                        std::cout << "  <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: "
     2247                            << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     2248                            << " / hit = " << std::dec << entry.valid
     2249                            << " / count = " <<std::dec << entry.count
     2250                            << " / is_cnt = " << entry.is_cnt;
     2251                        if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl;
     2252                        else                                                std::cout << std::endl;
     2253                    }
     2254#endif
     2255                    break;
     2256                }
     2257                //////////////////
     2258            case READ_DIR_HIT:    //  read data in cache & update the directory
     2259                //  we enter this state in 3 cases:
     2260                //  - the read request is uncachable
     2261                //  - the cache line is in counter mode
     2262                //  - the cache line is valid but not replicated
     2263
     2264                {
     2265                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2266                            "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
     2267
     2268                    // check if this is an instruction read, this means pktid is either
     2269                    // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     2270                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2271                    bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2272                    // check if this is a cached read, this means pktid is either
     2273                    // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2274                    // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2275                    bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
     2276                    bool is_cnt       = r_read_is_cnt.read();
     2277
     2278                    // read data in the cache
     2279                    size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
     2280                    size_t way        = r_read_way.read();
     2281
     2282                    m_cache_data.read_line(way, set, r_read_data);
     2283
     2284                    // update the cache directory
     2285                    DirectoryEntry entry;
     2286                    entry.valid    = true;
     2287                    entry.is_cnt   = is_cnt;
     2288                    entry.dirty    = r_read_dirty.read();
     2289                    entry.tag      = r_read_tag.read();
     2290                    entry.lock     = r_read_lock.read();
     2291                    entry.ptr      = r_read_ptr.read();
     2292
     2293                    /*ODCCP*/ // if pktid = 0x9 that means read on no coherent line
     2294                    if(m_cmd_read_pktid_fifo.read() == 0x9){
     2295                        entry.coherent = false;
     2296                    }
     2297                    else{
     2298                        entry.coherent = true;
     2299                    }
     2300
     2301                    if(cached_read)   // Cached read => we must update the copies
     2302                    {
     2303                        if(!is_cnt)  // Not counter mode
     2304                        {
     2305                            entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2306                            entry.owner.inst     = inst_read;
     2307                            entry.count          = r_read_count.read() + 1;
     2308                        }
     2309                        else  // Counter mode
     2310                        {
     2311                            entry.owner.srcid    = 0;
     2312                            entry.owner.inst     = false;
     2313                            entry.count          = r_read_count.read() + 1;
     2314                        }
     2315                    }
     2316                    else            // Uncached read
     2317                    {
     2318                        entry.owner.srcid     = r_read_copy.read();
     2319                        entry.owner.inst      = r_read_copy_inst.read();
     2320                        entry.count           = r_read_count.read();
     2321                    }
    23222322
    23232323#if DEBUG_MEMC_READ
    2324 if(m_debug)
    2325 std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
    2326           << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
    2327           << " / set = " << std::dec << set
    2328           << " / way = " << way
    2329           << " / owner_id = " << std::hex << entry.owner.srcid
    2330           << " / owner_ins = " << std::dec << entry.owner.inst
    2331           << " / count = " << entry.count
    2332           << " / is_cnt = " << entry.is_cnt << std::endl;
    2333 #endif
    2334           /*if(m_monitor_ok)
    2335           {
    2336             char buf[80];
    2337             snprintf(buf, 80, "READ_DIR_HIT srcid %d, ins %d",
    2338                      (int)m_cmd_read_srcid_fifo.read(),
    2339                      (int)((m_cmd_read_pktid_fifo.read()&0x2)!=0));
    2340             check_monitor(m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    2341           }*/
    2342         m_cache_directory.write(set, way, entry);
    2343         r_read_fsm    = READ_RSP;
    2344         break;
    2345     }
    2346     ///////////////////
    2347     case READ_HEAP_REQ:    // Get the lock to the HEAP directory
    2348     {
    2349       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2350       {
    2351         r_read_fsm = READ_HEAP_LOCK;
    2352         m_cpt_read_fsm_n_heap_lock++;
    2353       }
     2324                    if(m_debug)
     2325                        std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
     2326                            << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
     2327                            << " / set = " << std::dec << set
     2328                            << " / way = " << way
     2329                            << " / owner_id = " << std::hex << entry.owner.srcid
     2330                            << " / owner_ins = " << std::dec << entry.owner.inst
     2331                            << " / count = " << entry.count
     2332                            << " / is_cnt = " << entry.is_cnt << std::endl;
     2333#endif
     2334                    /*if(m_monitor_ok)
     2335                      {
     2336                      char buf[80];
     2337                      snprintf(buf, 80, "READ_DIR_HIT srcid %d, ins %d",
     2338                      (int)m_cmd_read_srcid_fifo.read(),
     2339                      (int)((m_cmd_read_pktid_fifo.read()&0x2)!=0));
     2340                      check_monitor(m_cmd_read_addr_fifo.read(), r_read_data[0], true);
     2341                      }*/
     2342                    m_cache_directory.write(set, way, entry);
     2343                    r_read_fsm    = READ_RSP;
     2344                    break;
     2345                }
     2346                ///////////////////
     2347            case READ_HEAP_REQ:    // Get the lock to the HEAP directory
     2348                {
     2349                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2350                    {
     2351                        r_read_fsm = READ_HEAP_LOCK;
     2352                        m_cpt_read_fsm_n_heap_lock++;
     2353                    }
    23542354
    23552355#if DEBUG_MEMC_READ
    2356 if(m_debug)
    2357 std::cout << "  <MEMC " << name() << " READ_HEAP_REQ>"
    2358           << " Requesting HEAP lock " << std::endl;
    2359 #endif
    2360 
    2361       m_cpt_read_fsm_heap_lock++;
    2362 
    2363       break;
    2364     }
    2365 
    2366     ////////////////////
    2367     case READ_HEAP_LOCK:   // read data in cache, update the directory
    2368                            // and prepare the HEAP update
    2369     {
    2370       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2371       {
    2372         // enter counter mode when we reach the limit of copies or the heap is full
    2373         bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full();
    2374 
    2375         // read data in the cache
    2376         size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
    2377         size_t way = r_read_way.read();
    2378 
    2379         m_cache_data.read_line(way, set, r_read_data);
    2380 
    2381         // update the cache directory
    2382         DirectoryEntry entry;
    2383         entry.valid  = true;
    2384         entry.is_cnt = go_cnt;
    2385         entry.dirty  = r_read_dirty.read();
    2386         entry.tag    = r_read_tag.read();
    2387         entry.lock   = r_read_lock.read();
    2388         entry.count  = r_read_count.read() + 1;
    2389 
    2390         if(not go_cnt)         // Not entering counter mode
    2391         {
    2392           entry.owner.srcid    = r_read_copy.read();
    2393           entry.owner.inst     = r_read_copy_inst.read();
    2394           entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
    2395         }
    2396         else                // Entering Counter mode
    2397         {
    2398           entry.owner.srcid    = 0;
    2399           entry.owner.inst     = false;
    2400           entry.ptr            = 0;
    2401         }
    2402 
    2403         m_cache_directory.write(set, way, entry);
    2404 
    2405         // prepare the heap update (add an entry, or clear the linked list)
    2406         if(not go_cnt)      // not switching to counter mode
    2407         {
    2408           // We test if the next free entry in the heap is the last
    2409           HeapEntry heap_entry = m_heap.next_free_entry();
    2410           r_read_next_ptr      = heap_entry.next;
    2411           r_read_last_free     = (heap_entry.next == m_heap.next_free_ptr());
    2412 
    2413           r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
    2414         }
    2415         else            // switching to counter mode
    2416         {
    2417           if(r_read_count.read() >1)              // heap must be cleared
    2418           {
    2419             HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    2420             r_read_next_ptr      = m_heap.next_free_ptr();
    2421             m_heap.write_free_ptr(r_read_ptr.read());
    2422 
    2423             if(next_entry.next == r_read_ptr.read())    // last entry
    2424             {
    2425               r_read_fsm = READ_HEAP_LAST;    // erase the entry
    2426             }
    2427             else                                        // not the last entry
    2428             {
    2429               r_read_ptr = next_entry.next;
    2430               r_read_fsm = READ_HEAP_ERASE;   // erase the list
    2431             }
    2432           }
    2433           else  // the heap is not used / nothing to do
    2434           {
    2435             r_read_fsm = READ_RSP;
    2436           }
    2437         }
     2356                    if(m_debug)
     2357                        std::cout << "  <MEMC " << name() << " READ_HEAP_REQ>"
     2358                            << " Requesting HEAP lock " << std::endl;
     2359#endif
     2360
     2361                    m_cpt_read_fsm_heap_lock++;
     2362
     2363                    break;
     2364                }
     2365
     2366                ////////////////////
     2367            case READ_HEAP_LOCK:   // read data in cache, update the directory
     2368                // and prepare the HEAP update
     2369                {
     2370                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2371                    {
     2372                        // enter counter mode when we reach the limit of copies or the heap is full
     2373                        bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full();
     2374
     2375                        // read data in the cache
     2376                        size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
     2377                        size_t way = r_read_way.read();
     2378
     2379                        m_cache_data.read_line(way, set, r_read_data);
     2380
     2381                        // update the cache directory
     2382                        DirectoryEntry entry;
     2383                        entry.valid  = true;
     2384                        entry.is_cnt = go_cnt;
     2385                        entry.dirty  = r_read_dirty.read();
     2386                        entry.tag    = r_read_tag.read();
     2387                        entry.lock   = r_read_lock.read();
     2388                        entry.count  = r_read_count.read() + 1;
     2389
     2390                        if(not go_cnt)         // Not entering counter mode
     2391                        {
     2392                            entry.owner.srcid    = r_read_copy.read();
     2393                            entry.owner.inst     = r_read_copy_inst.read();
     2394                            entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
     2395                        }
     2396                        else                // Entering Counter mode
     2397                        {
     2398                            entry.owner.srcid    = 0;
     2399                            entry.owner.inst     = false;
     2400                            entry.ptr            = 0;
     2401                        }
     2402
     2403                        m_cache_directory.write(set, way, entry);
     2404
     2405                        // prepare the heap update (add an entry, or clear the linked list)
     2406                        if(not go_cnt)      // not switching to counter mode
     2407                        {
     2408                            // We test if the next free entry in the heap is the last
     2409                            HeapEntry heap_entry = m_heap.next_free_entry();
     2410                            r_read_next_ptr      = heap_entry.next;
     2411                            r_read_last_free     = (heap_entry.next == m_heap.next_free_ptr());
     2412
     2413                            r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
     2414                        }
     2415                        else            // switching to counter mode
     2416                        {
     2417                            if(r_read_count.read() >1)              // heap must be cleared
     2418                            {
     2419                                HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2420                                r_read_next_ptr      = m_heap.next_free_ptr();
     2421                                m_heap.write_free_ptr(r_read_ptr.read());
     2422
     2423                                if(next_entry.next == r_read_ptr.read())    // last entry
     2424                                {
     2425                                    r_read_fsm = READ_HEAP_LAST;    // erase the entry
     2426                                }
     2427                                else                                        // not the last entry
     2428                                {
     2429                                    r_read_ptr = next_entry.next;
     2430                                    r_read_fsm = READ_HEAP_ERASE;   // erase the list
     2431                                }
     2432                            }
     2433                            else  // the heap is not used / nothing to do
     2434                            {
     2435                                r_read_fsm = READ_RSP;
     2436                            }
     2437                        }
    24382438
    24392439#if DEBUG_MEMC_READ
    2440 if(m_debug)
    2441 std::cout << "  <MEMC " << name() << " READ_HEAP_LOCK> Update directory:"
    2442           << " tag = " << std::hex << entry.tag
    2443           << " set = " << std::dec << set
    2444           << " way = " << way
    2445           << " count = " << entry.count
    2446           << " is_cnt = " << entry.is_cnt << std::endl;
    2447 #endif
    2448       }
    2449       else
    2450       {
    2451         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK"
    2452                   << "Bad HEAP allocation"   << std::endl;
    2453         exit(0);
    2454       }
    2455       break;
    2456     }
    2457     /////////////////////
    2458     case READ_HEAP_WRITE:       // add an entry in the heap
    2459     {
    2460       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2461       {
    2462         HeapEntry heap_entry;
    2463         heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2464         heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    2465 
    2466         if(r_read_count.read() == 1)  // creation of a new linked list
    2467         {
    2468           heap_entry.next         = m_heap.next_free_ptr();
    2469         }
    2470         else                         // head insertion in existing list
    2471         {
    2472           heap_entry.next         = r_read_ptr.read();
    2473         }
    2474         m_heap.write_free_entry(heap_entry);
    2475         m_heap.write_free_ptr(r_read_next_ptr.read());
    2476         if(r_read_last_free.read())  m_heap.set_full();
    2477 
    2478         r_read_fsm = READ_RSP;
     2440                        if(m_debug)
     2441                            std::cout << "  <MEMC " << name() << " READ_HEAP_LOCK> Update directory:"
     2442                                << " tag = " << std::hex << entry.tag
     2443                                << " set = " << std::dec << set
     2444                                << " way = " << way
     2445                                << " count = " << entry.count
     2446                                << " is_cnt = " << entry.is_cnt << std::endl;
     2447#endif
     2448                    }
     2449                    else
     2450                    {
     2451                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK"
     2452                            << "Bad HEAP allocation"   << std::endl;
     2453                        exit(0);
     2454                    }
     2455                    break;
     2456                }
     2457                /////////////////////
     2458            case READ_HEAP_WRITE:       // add an entry in the heap
     2459                {
     2460                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2461                    {
     2462                        HeapEntry heap_entry;
     2463                        heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2464                        heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2465
     2466                        if(r_read_count.read() == 1)  // creation of a new linked list
     2467                        {
     2468                            heap_entry.next         = m_heap.next_free_ptr();
     2469                        }
     2470                        else                         // head insertion in existing list
     2471                        {
     2472                            heap_entry.next         = r_read_ptr.read();
     2473                        }
     2474                        m_heap.write_free_entry(heap_entry);
     2475                        m_heap.write_free_ptr(r_read_next_ptr.read());
     2476                        if(r_read_last_free.read())  m_heap.set_full();
     2477
     2478                        r_read_fsm = READ_RSP;
    24792479
    24802480#if DEBUG_MEMC_READ
    2481 if(m_debug)
    2482 std::cout << "  <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:"
    2483           << " owner_id = " << std::hex << heap_entry.owner.srcid
    2484           << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl;
    2485 #endif
    2486       }
    2487       else
    2488       {
    2489         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE"
    2490                   << "Bad HEAP allocation" << std::endl;
    2491         exit(0);
    2492       }
    2493       break;
    2494     }
    2495     /////////////////////
    2496     case READ_HEAP_ERASE:
    2497     {
    2498       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2499       {
    2500         HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    2501         if(next_entry.next == r_read_ptr.read())
    2502         {
    2503           r_read_fsm = READ_HEAP_LAST;
    2504         }
    2505         else
    2506         {
    2507           r_read_ptr = next_entry.next;
    2508           r_read_fsm = READ_HEAP_ERASE;
    2509         }
    2510       }
    2511       else
    2512       {
    2513         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE"
    2514                   << "Bad HEAP allocation" << std::endl;
    2515         exit(0);
    2516       }
    2517       break;
    2518     }
    2519 
    2520     ////////////////////
    2521     case READ_HEAP_LAST:
    2522     {
    2523       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2524       {
    2525         HeapEntry last_entry;
    2526         last_entry.owner.srcid    = 0;
    2527         last_entry.owner.inst     = false;
    2528 
    2529         if(m_heap.is_full())
    2530         {
    2531           last_entry.next       = r_read_ptr.read();
    2532           m_heap.unset_full();
    2533         }
    2534         else
    2535         {
    2536           last_entry.next       = r_read_next_ptr.read();
    2537         }
    2538         m_heap.write(r_read_ptr.read(),last_entry);
    2539         r_read_fsm = READ_RSP;
    2540       }
    2541       else
    2542       {
    2543         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST"
    2544                   << "Bad HEAP allocation" << std::endl;
    2545         exit(0);
    2546       }
    2547       break;
    2548     }
    2549     //////////////
    2550     case READ_RSP:    //  request the TGT_RSP FSM to return data
    2551     {
    2552         if(!r_read_to_tgt_rsp_req)
    2553         {
    2554             for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
    2555             r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
    2556             r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
    2557             r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
    2558             r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    2559             r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    2560             r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
    2561             cmd_read_fifo_get        = true;
    2562             r_read_to_tgt_rsp_req    = true;
    2563             r_read_fsm               = READ_IDLE;
     2481                        if(m_debug)
     2482                            std::cout << "  <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:"
     2483                                << " owner_id = " << std::hex << heap_entry.owner.srcid
     2484                                << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl;
     2485#endif
     2486                    }
     2487                    else
     2488                    {
     2489                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE"
     2490                            << "Bad HEAP allocation" << std::endl;
     2491                        exit(0);
     2492                    }
     2493                    break;
     2494                }
     2495                /////////////////////
     2496            case READ_HEAP_ERASE:
     2497                {
     2498                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2499                    {
     2500                        HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2501                        if(next_entry.next == r_read_ptr.read())
     2502                        {
     2503                            r_read_fsm = READ_HEAP_LAST;
     2504                        }
     2505                        else
     2506                        {
     2507                            r_read_ptr = next_entry.next;
     2508                            r_read_fsm = READ_HEAP_ERASE;
     2509                        }
     2510                    }
     2511                    else
     2512                    {
     2513                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE"
     2514                            << "Bad HEAP allocation" << std::endl;
     2515                        exit(0);
     2516                    }
     2517                    break;
     2518                }
     2519
     2520                ////////////////////
     2521            case READ_HEAP_LAST:
     2522                {
     2523                    if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2524                    {
     2525                        HeapEntry last_entry;
     2526                        last_entry.owner.srcid    = 0;
     2527                        last_entry.owner.inst     = false;
     2528
     2529                        if(m_heap.is_full())
     2530                        {
     2531                            last_entry.next       = r_read_ptr.read();
     2532                            m_heap.unset_full();
     2533                        }
     2534                        else
     2535                        {
     2536                            last_entry.next       = r_read_next_ptr.read();
     2537                        }
     2538                        m_heap.write(r_read_ptr.read(),last_entry);
     2539                        r_read_fsm = READ_RSP;
     2540                    }
     2541                    else
     2542                    {
     2543                        std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST"
     2544                            << "Bad HEAP allocation" << std::endl;
     2545                        exit(0);
     2546                    }
     2547                    break;
     2548                }
     2549                //////////////
     2550            case READ_RSP:    //  request the TGT_RSP FSM to return data
     2551                {
     2552                    if(!r_read_to_tgt_rsp_req)
     2553                    {
     2554                        for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
     2555                        r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2556                        r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     2557                        r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     2558                        r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     2559                        r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
     2560                        r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     2561                        cmd_read_fifo_get        = true;
     2562                        r_read_to_tgt_rsp_req    = true;
     2563                        r_read_fsm               = READ_IDLE;
    25642564
    25652565#if DEBUG_MEMC_READ
    2566 if(m_debug)
    2567 std::cout << "  <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:"
    2568           << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
    2569           << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
    2570           << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    2571 #endif
    2572         }
    2573         break;
    2574     }
    2575     ///////////////////
    2576     case READ_TRT_LOCK: // read miss : check the Transaction Table
    2577     {
    2578       if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2579       {
    2580         size_t      index     = 0;
    2581         size_t      index_write = 0;
    2582         addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
    2583         bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
     2566                        if(m_debug)
     2567                            std::cout << "  <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:"
     2568                                << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
     2569                                << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     2570                                << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2571#endif
     2572                    }
     2573                    break;
     2574                }
     2575                ///////////////////
     2576            case READ_TRT_LOCK: // read miss : check the Transaction Table
     2577                {
     2578                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2579                    {
     2580                        size_t      index     = 0;
     2581                        size_t      index_write = 0;
     2582                        addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
     2583                        bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
    25842584#if ODCCP_NON_INCLUSIVE
    2585         bool        hit_write = (m_trt.hit_write(m_nline[addr], &index_write) or
     2585                        bool        hit_write = (m_trt.hit_write(m_nline[addr], &index_write) or
    25862586                                ((r_cleanup_to_ixr_cmd_nline.read() == m_nline[addr]) and r_cleanup_to_ixr_cmd_req.read()));
    25872587#else
    2588         bool        hit_write = m_trt.hit_write(m_nline[addr], &index_write);
    2589 #endif
    2590         bool        wok       = !m_trt.full(index);
    2591 
    2592         if(hit_read or !wok or hit_write)    // missing line already requested or no space
     2588                        bool        hit_write = m_trt.hit_write(m_nline[addr], &index_write);
     2589#endif
     2590                        bool        wok       = !m_trt.full(index);
     2591
     2592                        if(hit_read or !wok or hit_write)    // missing line already requested or no space
     2593                        {
     2594                            if(!wok)                    m_cpt_trt_full++;
     2595                            if(hit_read or hit_write)   m_cpt_trt_rb++;
     2596                            r_read_fsm = READ_IDLE;
     2597                        }
     2598                        else                  // missing line is requested to the XRAM
     2599                        {
     2600                            m_cpt_read_miss++;
     2601                            r_read_trt_index = index;
     2602                            r_read_fsm       = READ_TRT_SET;
     2603                        }
     2604
     2605#if DEBUG_MEMC_READ
     2606                        if(m_debug)
     2607                            std::cout << "  <MEMC " << name() << " READ_TRT_LOCK> Check TRT:"
     2608                                << " hit_read = " << hit_read
     2609                                << " / hit_write = " << hit_write
     2610                                << " / Index = " << index_write
     2611                                << " / full = " << !wok << std::endl;
     2612                        m_cpt_read_fsm_n_trt_lock++;
     2613#endif
     2614                    }
     2615
     2616                    m_cpt_read_fsm_trt_lock++;
     2617
     2618                    break;
     2619                }
     2620                //////////////////
     2621            case READ_TRT_SET:      // register get transaction in TRT
     2622                {
     2623                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2624                    {
     2625                        m_trt.set( r_read_trt_index.read(),
     2626                                true,      // GET
     2627                                m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
     2628                                m_cmd_read_srcid_fifo.read(),
     2629                                m_cmd_read_trdid_fifo.read(),
     2630                                m_cmd_read_pktid_fifo.read(),
     2631                                true,      // proc read
     2632                                m_cmd_read_length_fifo.read(),
     2633                                m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
     2634                                std::vector<be_t> (m_words,0),
     2635                                std::vector<data_t> (m_words,0),
     2636                                r_read_ll_key.read() );
     2637#if DEBUG_MEMC_READ
     2638                        if(m_debug)
     2639                            std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
     2640                                << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     2641                                << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
     2642#endif
     2643                        r_read_fsm = READ_TRT_REQ;
     2644                    }
     2645                    break;
     2646                }
     2647
     2648                //////////////////
     2649            case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
     2650                {
     2651                    if(not r_read_to_ixr_cmd_req)
     2652                    {
     2653                        cmd_read_fifo_get       = true;
     2654                        r_read_to_ixr_cmd_req   = true;
     2655                        r_read_to_ixr_cmd_index = r_read_trt_index.read();
     2656                        r_read_fsm              = READ_IDLE;
     2657
     2658#if DEBUG_MEMC_READ
     2659                        if(m_debug)
     2660                            std::cout << "  <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address "
     2661                                << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
     2662#endif
     2663                    }
     2664                    break;
     2665                }
     2666        } // end switch read_fsm
     2667
     2668        ///////////////////////////////////////////////////////////////////////////////////
     2669        //    WRITE FSM
     2670        ///////////////////////////////////////////////////////////////////////////////////
     2671        // The WRITE FSM handles the write bursts and sc requests sent by the processors.
     2672        // All addresses in a burst must be in the same cache line.
     2673        // A complete write burst is consumed in the FIFO & copied to a local buffer.
     2674        // Then the FSM takes the lock protecting the cache directory, to check
     2675        // if the line is in the cache.
     2676        //
     2677        // - In case of HIT, the cache is updated.
     2678        //   If there is no other copy, an acknowledge response is immediately
     2679        //   returned to the writing processor.
     2680        //   If the data is cached by other processors, a coherence transaction must
     2681        //   be launched (sc requests always require a coherence transaction):
     2682        //   It is a multicast update if the line is not in counter mode: the processor
     2683        //   takes the lock protecting the Update Table (UPT) to register this transaction.
     2684        //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
     2685        //   a multi-update request to all owners of the line (but the writer),
     2686        //   through the CC_SEND FSM. In case of coherence transaction, the WRITE FSM
     2687        //   does not respond to the writing processor, as this response will be sent by
     2688        //   the MULTI_ACK FSM when all update responses have been received.
     2689        //   It is a broadcast invalidate if the line is in counter mode: The line
     2690        //   should be erased in memory cache, and written in XRAM with a PUT transaction,
     2691        //   after registration in TRT.
     2692        //
     2693        // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
     2694        //   table (TRT). If a read transaction to the XRAM for this line already exists,
     2695        //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
     2696        //   the WRITE FSM register a new transaction in TRT, and sends a GET request
     2697        //   to the XRAM. If the TRT is full, it releases the lock, and waits.
     2698        //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
     2699        /////////////////////////////////////////////////////////////////////////////////////
     2700
     2701        //std::cout << std::endl << "write_fsm" << std::endl;
     2702
     2703        switch(r_write_fsm.read())
    25932704        {
    2594           if(!wok)                    m_cpt_trt_full++;
    2595           if(hit_read or hit_write)   m_cpt_trt_rb++;
    2596           r_read_fsm = READ_IDLE;
    2597         }
    2598         else                  // missing line is requested to the XRAM
    2599         {
    2600           m_cpt_read_miss++;
    2601           r_read_trt_index = index;
    2602           r_read_fsm       = READ_TRT_SET;
    2603         }
    2604 
    2605 #if DEBUG_MEMC_READ
    2606 if(m_debug)
    2607 std::cout << "  <MEMC " << name() << " READ_TRT_LOCK> Check TRT:"
    2608           << " hit_read = " << hit_read
    2609           << " / hit_write = " << hit_write
    2610           << " / Index = " << index_write
    2611           << " / full = " << !wok << std::endl;
    2612         m_cpt_read_fsm_n_trt_lock++;
    2613 #endif
    2614       }
    2615 
    2616       m_cpt_read_fsm_trt_lock++;
    2617 
    2618       break;
    2619     }
    2620     //////////////////
    2621     case READ_TRT_SET:      // register get transaction in TRT
    2622     {
    2623         if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2624         {
    2625             m_trt.set( r_read_trt_index.read(),
    2626                        true,      // GET
    2627                        m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
    2628                        m_cmd_read_srcid_fifo.read(),
    2629                        m_cmd_read_trdid_fifo.read(),
    2630                        m_cmd_read_pktid_fifo.read(),
    2631                        true,      // proc read
    2632                        m_cmd_read_length_fifo.read(),
    2633                        m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
    2634                        std::vector<be_t> (m_words,0),
    2635                        std::vector<data_t> (m_words,0),
    2636                        r_read_ll_key.read() );
    2637 #if DEBUG_MEMC_READ
    2638 if(m_debug)
    2639 std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
    2640           << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    2641           << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
    2642 #endif
    2643             r_read_fsm = READ_TRT_REQ;
    2644         }
    2645         break;
    2646     }
    2647 
    2648     //////////////////
    2649     case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
    2650     {
    2651         if(not r_read_to_ixr_cmd_req)
    2652         {
    2653             cmd_read_fifo_get       = true;
    2654             r_read_to_ixr_cmd_req   = true;
    2655             r_read_to_ixr_cmd_index = r_read_trt_index.read();
    2656             r_read_fsm              = READ_IDLE;
    2657 
    2658 #if DEBUG_MEMC_READ
    2659 if(m_debug)
    2660 std::cout << "  <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address "
    2661           << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
    2662 #endif
    2663         }
    2664         break;
    2665     }
    2666   } // end switch read_fsm
    2667 
    2668   ///////////////////////////////////////////////////////////////////////////////////
    2669   //    WRITE FSM
    2670   ///////////////////////////////////////////////////////////////////////////////////
    2671   // The WRITE FSM handles the write bursts and sc requests sent by the processors.
    2672   // All addresses in a burst must be in the same cache line.
    2673   // A complete write burst is consumed in the FIFO & copied to a local buffer.
    2674   // Then the FSM takes the lock protecting the cache directory, to check
    2675   // if the line is in the cache.
    2676   //
    2677   // - In case of HIT, the cache is updated.
    2678   //   If there is no other copy, an acknowledge response is immediately
    2679   //   returned to the writing processor.
    2680   //   If the data is cached by other processors, a coherence transaction must
    2681   //   be launched (sc requests always require a coherence transaction):
    2682   //   It is a multicast update if the line is not in counter mode: the processor
    2683   //   takes the lock protecting the Update Table (UPT) to register this transaction.
    2684   //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
    2685   //   a multi-update request to all owners of the line (but the writer),
    2686   //   through the CC_SEND FSM. In case of coherence transaction, the WRITE FSM
    2687   //   does not respond to the writing processor, as this response will be sent by
    2688   //   the MULTI_ACK FSM when all update responses have been received.
    2689   //   It is a broadcast invalidate if the line is in counter mode: The line
    2690   //   should be erased in memory cache, and written in XRAM with a PUT transaction,
    2691   //   after registration in TRT.
    2692   //
    2693   // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
    2694   //   table (TRT). If a read transaction to the XRAM for this line already exists,
    2695   //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
    2696   //   the WRITE FSM register a new transaction in TRT, and sends a GET request
    2697   //   to the XRAM. If the TRT is full, it releases the lock, and waits.
    2698   //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
    2699   /////////////////////////////////////////////////////////////////////////////////////
    2700 
    2701 //std::cout << std::endl << "write_fsm" << std::endl;
    2702 
    2703   switch(r_write_fsm.read())
    2704   {
    2705     ////////////////
    2706     case WRITE_IDLE:  // copy first word of a write burst in local buffer
    2707     {
    2708         if(m_cmd_write_addr_fifo.rok())
    2709         {
    2710             if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
    2711             {
    2712                 m_cpt_sc++;
    2713             }
    2714             else
    2715             {
    2716                 m_cpt_write++;
    2717                 m_cpt_write_cells++;
    2718             }
    2719 
    2720             // consume a word in the FIFO & write it in the local buffer
    2721             cmd_write_fifo_get  = true;
    2722             size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
    2723 
    2724             r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
    2725             r_write_word_index  = index;
    2726             r_write_word_count  = 1;
    2727             r_write_data[index] = m_cmd_write_data_fifo.read();
    2728             r_write_srcid       = m_cmd_write_srcid_fifo.read();
    2729             r_write_trdid       = m_cmd_write_trdid_fifo.read();
    2730             r_write_pktid       = m_cmd_write_pktid_fifo.read();
    2731             r_write_pending_sc  = false;
    2732 
    2733             // initialize the be field for all words
    2734             for(size_t word=0 ; word<m_words ; word++)
    2735             {
    2736                 if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    2737                 else              r_write_be[word] = 0x0;
    2738             }
    2739 
    2740             if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
    2741             {
    2742                 r_write_fsm = WRITE_DIR_REQ;
    2743             }
    2744             else
    2745             {
    2746                 r_write_fsm = WRITE_NEXT;
    2747             }
     2705            ////////////////
     2706            case WRITE_IDLE:  // copy first word of a write burst in local buffer
     2707                {
     2708                    if(m_cmd_write_addr_fifo.rok())
     2709                    {
     2710                        if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     2711                        {
     2712                            m_cpt_sc++;
     2713                        }
     2714                        else
     2715                        {
     2716                            m_cpt_write++;
     2717                            m_cpt_write_cells++;
     2718                        }
     2719
     2720                        // consume a word in the FIFO & write it in the local buffer
     2721                        cmd_write_fifo_get  = true;
     2722                        size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     2723
     2724                        r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     2725                        r_write_word_index  = index;
     2726                        r_write_word_count  = 1;
     2727                        r_write_data[index] = m_cmd_write_data_fifo.read();
     2728                        r_write_srcid       = m_cmd_write_srcid_fifo.read();
     2729                        r_write_trdid       = m_cmd_write_trdid_fifo.read();
     2730                        r_write_pktid       = m_cmd_write_pktid_fifo.read();
     2731                        r_write_pending_sc  = false;
     2732
     2733                        // initialize the be field for all words
     2734                        for(size_t word=0 ; word<m_words ; word++)
     2735                        {
     2736                            if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     2737                            else              r_write_be[word] = 0x0;
     2738                        }
     2739
     2740                        if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
     2741                        {
     2742                            r_write_fsm = WRITE_DIR_REQ;
     2743                        }
     2744                        else
     2745                        {
     2746                            r_write_fsm = WRITE_NEXT;
     2747                        }
    27482748
    27492749#if DEBUG_MEMC_WRITE
    2750 if(m_debug)
    2751 std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
    2752           << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
    2753           << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
    2754           << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    2755 #endif
    2756         }
    2757         break;
    2758     }
    2759     ////////////////
    2760     case WRITE_NEXT:  // copy next word of a write burst in local buffer
    2761     {
    2762         if(m_cmd_write_addr_fifo.rok())
    2763         {
     2750                        if(m_debug)
     2751                            std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
     2752                                << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
     2753                                << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
     2754                                << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
     2755#endif
     2756                    }
     2757                    break;
     2758                }
     2759                ////////////////
     2760            case WRITE_NEXT:  // copy next word of a write burst in local buffer
     2761                {
     2762                    if(m_cmd_write_addr_fifo.rok())
     2763                    {
    27642764
    27652765#if DEBUG_MEMC_WRITE
    2766 if(m_debug)
    2767 std::cout << "  <MEMC " << name()
    2768           << " WRITE_NEXT> Write another word in local buffer"
    2769           << std::endl;
    2770 #endif
    2771             m_cpt_write_cells++;
    2772 
    2773             // check that the next word is in the same cache line
    2774             assert( (m_nline[(addr_t)(r_write_address.read())] ==
    2775                      m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and
    2776             "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
    2777 
    2778             // consume a word in the FIFO & write it in the local buffer
    2779             cmd_write_fifo_get  = true;
    2780             size_t index        = r_write_word_index.read() + r_write_word_count.read();
    2781 
    2782             r_write_be[index]   = m_cmd_write_be_fifo.read();
    2783             r_write_data[index] = m_cmd_write_data_fifo.read();
    2784             r_write_word_count  = r_write_word_count.read() + 1;
    2785 
    2786             if(m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
    2787         }
    2788         break;
    2789     }
    2790     ///////////////////
    2791     case WRITE_DIR_REQ:    // Get the lock to the directory
    2792                            // and access the llsc_global_table
    2793     {
    2794         if( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
    2795         {
    2796             if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())