Changeset 273 for trunk


Ignore:
Timestamp:
Nov 28, 2012, 11:51:48 AM (12 years ago)
Author:
cfuguet
Message:

Modificating the VCI Memory Cache to align the VHDL and the SOCLIB models.
The primary modification consists to add a state DIR_REQ or HEAP_REQ, in all
FSMs using these two structures.

In these states a FSM take the lock of the DIRECTORY or HEAP, respectively,
and at the end of the cycle sends the READ request. Is in the next cycle,
when the response of the READ is obtained.

With this modifications, the behavior of a Synchonous RAM is emulated.

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

Legend:

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

    r20 r273  
    66
    77Module('caba:vci_mem_cache_v4',
    8        classname = 'soclib::caba::VciMemCacheV4',
    9        tmpl_parameters = [parameter.Module('vci_param', default = 'caba:vci_param'),],
    10        header_files = ['../source/include/vci_mem_cache_v4.h',
    11                        '../source/include/xram_transaction_v4.h',
    12                        '../source/include/mem_cache_directory_v4.h',
    13                        '../source/include/update_tab_v4.h',],
    14        implementation_files = ['../source/src/vci_mem_cache_v4.cpp',],
    15        uses = [Uses('caba:base_module'),
    16                Uses('common:loader'),
    17                Uses('common:mapping_table'),
    18                Uses('caba:generic_fifo'),
    19                ],
    20        ports = [Port('caba:vci_target', 'p_vci_tgt'),
    21                 Port('caba:vci_target','p_vci_tgt_cleanup'),
    22                 Port('caba:vci_initiator','p_vci_ini'),
    23                 Port('caba:vci_initiator','p_vci_ixr'),
    24                 Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
    25                 Port('caba:clock_in', 'p_clk', auto = 'clock'),],
    26        instance_parameters = [
    27                 parameter.Module('mtp', 'common:mapping_table'),
    28                 parameter.Module('mtc', 'common:mapping_table'),
    29                 parameter.Module('mtx', 'common:mapping_table'),
    30                 parameter.IntTab('vci_ixr_index'),
    31                 parameter.IntTab('vci_ini_index'),
    32                 parameter.IntTab('vci_tgt_index'),
    33                 parameter.IntTab('vci_tgt_index_cleanup'),
    34     parameter.Int('nways'),
    35                 parameter.Int('nsets'),
    36                 parameter.Int('nwords'),
    37                 parameter.Int('heap_size'),
    38                 ],
    39        extensions = [
    40           'dsx:get_ident='
    41           'vci_ini_index:p_vci_ini:mtc,'
    42           'vci_tgt_index_cleanup:p_vci_tgt_cleanup:mtc,'
    43           'vci_tgt_index:p_vci_tgt:mtp,'
    44           'vci_ixr_index:p_vci_ixr:mtx',
    45                 'dsx:addressable=vci_tgt_index,vci_tgt_index_cleanup',
    46        ],
     8        classname = 'soclib::caba::VciMemCacheV4',
     9
     10        tmpl_parameters = [ parameter.Module('vci_param', default = 'caba:vci_param') ],
     11
     12        header_files = [
     13            '../source/include/vci_mem_cache_v4.h',
     14            '../source/include/xram_transaction_v4.h',
     15            '../source/include/mem_cache_directory_v4.h',
     16            '../source/include/update_tab_v4.h'
     17        ],
     18
     19        implementation_files = [ '../source/src/vci_mem_cache_v4.cpp' ],
     20
     21        uses = [
     22            Uses('caba:base_module'),
     23            Uses('common:loader'),
     24            Uses('common:mapping_table'),
     25            Uses('caba:generic_fifo'),
     26        ],
     27
     28        ports = [
     29            Port( 'caba:vci_target'   , 'p_vci_tgt' ),
     30            Port( 'caba:vci_target'   , 'p_vci_tgt_cleanup' ),
     31            Port( 'caba:vci_initiator', 'p_vci_ini' ),
     32            Port( 'caba:vci_initiator', 'p_vci_ixr' ),
     33            Port( 'caba:bit_in'       , 'p_resetn'  , auto = 'resetn' ),
     34            Port( 'caba:clock_in'     , 'p_clk'     , auto = 'clock'  ),
     35        ],
     36
     37        instance_parameters = [
     38            parameter.Module( 'mtp', 'common:mapping_table' ),
     39            parameter.Module( 'mtc', 'common:mapping_table' ),
     40            parameter.Module( 'mtx', 'common:mapping_table' ),
     41            parameter.IntTab( 'vci_ixr_index' ),
     42            parameter.IntTab( 'vci_ini_index' ),
     43            parameter.IntTab( 'vci_tgt_index' ),
     44            parameter.IntTab( 'vci_tgt_index_cleanup '),
     45            parameter.Int   ( 'nways' ),
     46            parameter.Int   ( 'nsets' ),
     47            parameter.Int   ( 'nwords' ),
     48            parameter.Int   ( 'heap_size' ),
     49        ],
     50
     51        extensions = [
     52            'dsx:get_ident='
     53            'vci_ini_index:p_vci_ini:mtc,'
     54            'vci_tgt_index_cleanup:p_vci_tgt_cleanup:mtc,'
     55            'vci_tgt_index:p_vci_tgt:mtp,'
     56            'vci_ixr_index:p_vci_ixr:mtx',
     57            'dsx:addressable=vci_tgt_index,vci_tgt_index_cleanup',
     58        ],
    4759)
  • trunk/modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h

    r245 r273  
    2626 *
    2727 * Maintainers: alain eric.guthmuller@polytechnique.edu
    28  */
    29 /*
     28 *              cesar.fuguet-tortolero@lip6.fr
    3029 *
    3130 * Modifications done by Christophe Choichillon on the 7/04/2009:
     
    3332 * - Adding a new VCI target port for the CLEANUP network
    3433 * - Adding new state in the ALLOC_UPT_FSM : ALLOC_UPT_CLEANUP
    35  * 
     34 *
    3635 * Modifications to do :
    3736 * - Adding new variables used by the CLEANUP FSM
     
    5857#include "update_tab_v4.h"
    5958
    60 #define TRANSACTION_TAB_LINES   4               // Number of lines in the transaction tab
    61 #define UPDATE_TAB_LINES        4               // Number of lines in the update tab
     59#define TRANSACTION_TAB_LINES 4 // Number of lines in the transaction tab
     60#define UPDATE_TAB_LINES      4 // Number of lines in the update tab
    6261
    6362namespace soclib {  namespace caba {
     
    8180        TGT_CMD_READ,
    8281        TGT_CMD_WRITE,
    83         TGT_CMD_ATOMIC,
     82        TGT_CMD_ATOMIC
    8483      };
    8584
     
    9796        TGT_RSP_XRAM,
    9897        TGT_RSP_INIT,
    99         TGT_RSP_CLEANUP,
     98        TGT_RSP_CLEANUP
    10099      };
    101100
     
    115114        INIT_CMD_SC_UPDT_INDEX,
    116115        INIT_CMD_SC_UPDT_DATA,
    117         INIT_CMD_SC_UPDT_DATA_HIGH,
     116        INIT_CMD_SC_UPDT_DATA_HIGH
    118117      };
    119118
     
    123122        INIT_RSP_UPT_LOCK,
    124123        INIT_RSP_UPT_CLEAR,
    125         INIT_RSP_END,
     124        INIT_RSP_END
    126125      };
    127126
     
    129128      enum read_fsm_state_e{
    130129        READ_IDLE,
     130        READ_DIR_REQ,
    131131        READ_DIR_LOCK,
    132132        READ_DIR_HIT,
     133        READ_HEAP_REQ,
    133134        READ_HEAP_LOCK,
    134135        READ_HEAP_WRITE,
     
    138139        READ_TRT_LOCK,
    139140        READ_TRT_SET,
    140         READ_TRT_REQ,
     141        READ_TRT_REQ
    141142      };
    142143
     
    145146        WRITE_IDLE,
    146147        WRITE_NEXT,
     148        WRITE_DIR_REQ,
    147149        WRITE_DIR_LOCK,
    148150        WRITE_DIR_READ,
     
    163165        WRITE_BC_CC_SEND,
    164166        WRITE_BC_XRAM_REQ,
    165         WRITE_WAIT,
     167        WRITE_WAIT
    166168      };
    167169
     
    171173        IXR_RSP_ACK,
    172174        IXR_RSP_TRT_ERASE,
    173         IXR_RSP_TRT_READ,
     175        IXR_RSP_TRT_READ
    174176      };
    175177
     
    186188        XRAM_RSP_INVAL,
    187189        XRAM_RSP_WRITE_DIRTY,
     190        XRAM_RSP_HEAP_REQ,
    188191        XRAM_RSP_HEAP_ERASE,
    189192        XRAM_RSP_HEAP_LAST,
    190193        XRAM_RSP_ERROR_ERASE,
    191         XRAM_RSP_ERROR_RSP,
     194        XRAM_RSP_ERROR_RSP
    192195      };
    193196
     
    201204        IXR_CMD_WRITE_NLINE,
    202205        IXR_CMD_SC_NLINE,
    203         IXR_CMD_XRAM_DATA,
     206        IXR_CMD_XRAM_DATA
    204207      };
    205208
     
    207210      enum sc_fsm_state_e{
    208211        SC_IDLE,
     212        SC_DIR_REQ,
    209213        SC_DIR_LOCK,
    210214        SC_DIR_HIT_READ,
     
    224228        SC_MISS_TRT_SET,
    225229        SC_MISS_XRAM_REQ,
    226         SC_WAIT,
     230        SC_WAIT
    227231      };
    228232
     
    230234      enum cleanup_fsm_state_e{
    231235        CLEANUP_IDLE,
     236        CLEANUP_DIR_REQ,
    232237        CLEANUP_DIR_LOCK,
    233238        CLEANUP_DIR_WRITE,
     239        CLEANUP_HEAP_REQ,
    234240        CLEANUP_HEAP_LOCK,
    235241        CLEANUP_HEAP_SEARCH,
     
    239245        CLEANUP_UPT_WRITE,
    240246        CLEANUP_WRITE_RSP,
    241         CLEANUP_RSP,
     247        CLEANUP_RSP
    242248      };
    243249
    244250      /* States of the ALLOC_DIR fsm */
    245251      enum alloc_dir_fsm_state_e{
     252        ALLOC_DIR_RESET,
    246253        ALLOC_DIR_READ,
    247254        ALLOC_DIR_WRITE,
    248255        ALLOC_DIR_SC,
    249256        ALLOC_DIR_CLEANUP,
    250         ALLOC_DIR_XRAM_RSP,
     257        ALLOC_DIR_XRAM_RSP
    251258      };
    252259
     
    257264        ALLOC_TRT_SC,
    258265        ALLOC_TRT_XRAM_RSP,
    259         ALLOC_TRT_IXR_RSP,
     266        ALLOC_TRT_IXR_RSP
    260267      };
    261268
     
    266273        ALLOC_UPT_INIT_RSP,
    267274        ALLOC_UPT_CLEANUP,
    268         ALLOC_UPT_SC,
     275        ALLOC_UPT_SC
    269276      };
    270277
    271278      /* States of the ALLOC_HEAP fsm */
    272279      enum alloc_heap_fsm_state_e{
     280        ALLOC_HEAP_RESET,
    273281        ALLOC_HEAP_READ,
    274282        ALLOC_HEAP_WRITE,
    275283        ALLOC_HEAP_SC,
    276284        ALLOC_HEAP_CLEANUP,
    277         ALLOC_HEAP_XRAM_RSP,
     285        ALLOC_HEAP_XRAM_RSP
    278286      };
    279287
     
    301309
    302310      // instrumentation counters
    303       uint32_t     m_cpt_cycles;            // Counter of cycles
    304       uint32_t     m_cpt_read;              // Number of READ transactions
    305       uint32_t     m_cpt_read_miss;         // Number of MISS READ
    306       uint32_t     m_cpt_write;             // Number of WRITE transactions
    307       uint32_t     m_cpt_write_miss;        // Number of MISS WRITE
    308       uint32_t     m_cpt_write_cells;       // Cumulated length for WRITE transactions
    309       uint32_t     m_cpt_write_dirty;       // Cumulated length for WRITE transactions
    310       uint32_t     m_cpt_update;            // Number of UPDATE transactions
    311       uint32_t     m_cpt_trt_rb;            // Read blocked by a hit in trt
    312       uint32_t     m_cpt_trt_full;          // Transaction blocked due to a full trt
    313       uint32_t     m_cpt_update_mult;       // Number of targets for UPDATE
    314       uint32_t     m_cpt_inval;             // Number of INVAL  transactions
    315       uint32_t     m_cpt_inval_mult;        // Number of targets for INVAL 
    316       uint32_t     m_cpt_inval_brdcast;     // Number of BROADCAST INVAL 
    317       uint32_t     m_cpt_cleanup;           // Number of CLEANUP transactions
    318       uint32_t     m_cpt_ll;                // Number of LL transactions
    319       uint32_t     m_cpt_sc;                // Number of SC transactions
     311      uint32_t     m_cpt_cycles;        // Counter of cycles
     312      uint32_t     m_cpt_read;          // Number of READ transactions
     313      uint32_t     m_cpt_read_miss;     // Number of MISS READ
     314      uint32_t     m_cpt_write;         // Number of WRITE transactions
     315      uint32_t     m_cpt_write_miss;    // Number of MISS WRITE
     316      uint32_t     m_cpt_write_cells;   // Cumulated length for WRITE transactions
     317      uint32_t     m_cpt_write_dirty;   // Cumulated length for WRITE transactions
     318      uint32_t     m_cpt_update;        // Number of UPDATE transactions
     319      uint32_t     m_cpt_trt_rb;        // Read blocked by a hit in trt
     320      uint32_t     m_cpt_trt_full;      // Transaction blocked due to a full trt
     321      uint32_t     m_cpt_update_mult;   // Number of targets for UPDATE
     322      uint32_t     m_cpt_inval;         // Number of INVAL  transactions
     323      uint32_t     m_cpt_inval_mult;    // Number of targets for INVAL
     324      uint32_t     m_cpt_inval_brdcast; // Number of BROADCAST INVAL
     325      uint32_t     m_cpt_cleanup;       // Number of CLEANUP transactions
     326      uint32_t     m_cpt_ll;            // Number of LL transactions
     327      uint32_t     m_cpt_sc;            // Number of SC transactions
    320328
    321329      size_t       m_prev_count;
     
    326334
    327335      public:
    328       sc_in<bool>                                               p_clk;
    329       sc_in<bool>                                               p_resetn;
    330       soclib::caba::VciTarget<vci_param>        p_vci_tgt;
    331       soclib::caba::VciTarget<vci_param>        p_vci_tgt_cleanup;
    332       soclib::caba::VciInitiator<vci_param>     p_vci_ini;     
    333       soclib::caba::VciInitiator<vci_param>     p_vci_ixr;
     336      sc_in<bool>                           p_clk;
     337      sc_in<bool>                           p_resetn;
     338      soclib::caba::VciTarget<vci_param>    p_vci_tgt;
     339      soclib::caba::VciTarget<vci_param>    p_vci_tgt_cleanup;
     340      soclib::caba::VciInitiator<vci_param> p_vci_ini;
     341      soclib::caba::VciInitiator<vci_param> p_vci_ixr;
    334342
    335343      VciMemCacheV4(
    336           sc_module_name name,                                // Instance Name 
     344          sc_module_name name,                                // Instance Name
    337345          const soclib::common::MappingTable &mtp,            // Mapping table for primary requets
    338346          const soclib::common::MappingTable &mtc,            // Mapping table for coherence requets
     
    342350          const soclib::common::IntTab &vci_tgt_index,        // VCI port to PROC (target)
    343351          const soclib::common::IntTab &vci_tgt_index_cleanup,// VCI port to PROC (target) for cleanup
    344           size_t nways,                                       // Number of ways per set 
     352          size_t nways,                                       // Number of ways per set
    345353          size_t nsets,                                       // Number of sets
    346354          size_t nwords,                                      // Number of words per line
     
    348356          size_t transaction_tab_lines=TRANSACTION_TAB_LINES, // Size of the TRT
    349357          size_t update_tab_lines=UPDATE_TAB_LINES,           // Size of the UPT
    350           size_t debug_start_cycle=0,                       
     358          size_t debug_start_cycle=0,
    351359          bool   debug_ok=false);
    352360
     
    366374
    367375      // Component attributes
    368       const size_t                              m_initiators;           // Number of initiators
    369       const size_t                              m_heap_size;            // Size of the heap
    370       const size_t                              m_ways;                 // Number of ways in a set
    371       const size_t                              m_sets;                 // Number of cache sets
    372       const size_t                              m_words;                        // Number of words in a line
    373       const size_t                              m_srcid_ixr;                // Srcid for requests to XRAM
    374       const size_t                              m_srcid_ini;                // Srcid for requests to processors
    375       std::list<soclib::common::Segment>        m_seglist;              // memory cached into the cache
    376       std::list<soclib::common::Segment>        m_cseglist;             // coherence segment for the cache
    377       vci_addr_t                                *m_coherence_table;     // address(srcid)
    378       uint32_t                                  m_transaction_tab_lines;
    379       TransactionTab                            m_transaction_tab;          // xram transaction table
    380       uint32_t                                  m_update_tab_lines;
    381       UpdateTab                                 m_update_tab;               // pending update & invalidate
    382       CacheDirectory                            m_cache_directory;          // data cache directory
    383       HeapDirectory                             m_heap;                 // heap for copies
    384 
    385       data_t                                    ***m_cache_data;            // data array[set][way][word]
     376      std::list<soclib::common::Segment> m_seglist;  // memory cached into the cache
     377      std::list<soclib::common::Segment> m_cseglist; // coherence segment for the cache
     378
     379      const size_t    m_initiators; // Number of initiators
     380      const size_t    m_heap_size;  // Size of the heap
     381      const size_t    m_ways;       // Number of ways in a set
     382      const size_t    m_sets;       // Number of cache sets
     383      const size_t    m_words;      // Number of words in a line
     384      const size_t    m_srcid_ixr;  // Srcid for requests to XRAM
     385      const size_t    m_srcid_ini;  // Srcid for requests to processors
     386
     387      uint32_t        m_transaction_tab_lines;
     388      TransactionTab  m_transaction_tab;  // xram transaction table
     389      uint32_t        m_update_tab_lines;
     390      UpdateTab       m_update_tab;       // pending update & invalidate
     391      CacheDirectory  m_cache_directory;  // data cache directory
     392      HeapDirectory   m_heap;             // heap for copies
     393
     394      data_t      *** m_cache_data;       // data array[set][way][word]
    386395
    387396      // adress masks
    388       const soclib::common::AddressMaskingTable<vci_addr_t>   m_x;
    389       const soclib::common::AddressMaskingTable<vci_addr_t>   m_y;
    390       const soclib::common::AddressMaskingTable<vci_addr_t>   m_z;
    391       const soclib::common::AddressMaskingTable<vci_addr_t>   m_nline;
     397      const soclib::common::AddressMaskingTable<vci_addr_t> m_x;
     398      const soclib::common::AddressMaskingTable<vci_addr_t> m_y;
     399      const soclib::common::AddressMaskingTable<vci_addr_t> m_z;
     400      const soclib::common::AddressMaskingTable<vci_addr_t> m_nline;
    392401
    393402      // broadcast address
    394       vci_addr_t                        m_broadcast_address;
     403      vci_addr_t m_broadcast_address;
    395404
    396405      //////////////////////////////////////////////////
    397406      // Others registers
    398407      //////////////////////////////////////////////////
    399       sc_signal<size_t>   r_copies_limit; // Limit of the number of copies for one line
    400       sc_signal<size_t>   xxx_count;
     408      sc_signal<size_t> r_copies_limit; // Limit of the number of copies for one line
     409      sc_signal<size_t> xxx_count;
    401410
    402411      //////////////////////////////////////////////////
     
    411420      GenericFifo<size_t>    m_cmd_read_pktid_fifo;
    412421
    413       // Fifo between TGT_CMD fsm and WRITE fsm   
     422      // Fifo between TGT_CMD fsm and WRITE fsm
    414423      GenericFifo<uint64_t>  m_cmd_write_addr_fifo;
    415424      GenericFifo<bool>      m_cmd_write_eop_fifo;
     
    418427      GenericFifo<size_t>    m_cmd_write_pktid_fifo;
    419428      GenericFifo<data_t>    m_cmd_write_data_fifo;
    420       GenericFifo<be_t>      m_cmd_write_be_fifo;
     429      GenericFifo<be_t>      m_cmd_write_be_fifo;
    421430
    422431      // Fifo between TGT_CMD fsm and SC fsm
     
    434443      soclib::common::Segment  **m_seg;
    435444      soclib::common::Segment  **m_cseg;
    436 
    437445      ///////////////////////////////////////////////////////
    438446      // Registers controlled by the READ fsm
    439447      ///////////////////////////////////////////////////////
    440448
    441       sc_signal<int>         r_read_fsm;        // FSM state
    442       sc_signal<size_t>      r_read_copy;       // Srcid of the first copy
    443       sc_signal<size_t>      r_read_copy_cache; // Srcid of the first copy
    444       sc_signal<bool>        r_read_copy_inst;  // Type of the first copy
    445       sc_signal<tag_t>       r_read_tag;            // cache line tag (in directory)
    446       sc_signal<bool>        r_read_is_cnt;         // is_cnt bit (in directory)
    447       sc_signal<bool>        r_read_lock;           // lock bit (in directory)
    448       sc_signal<bool>        r_read_dirty;          // dirty bit (in directory)
    449       sc_signal<size_t>      r_read_count;      // number of copies
    450       sc_signal<size_t>      r_read_ptr;        // pointer to the heap
    451       sc_signal<data_t>     *r_read_data;       // data (one cache line)
    452       sc_signal<size_t>      r_read_way;        // associative way (in cache)
    453       sc_signal<size_t>      r_read_trt_index;  // Transaction Table index
    454       sc_signal<size_t>      r_read_next_ptr;   // Next entry to point to
    455       sc_signal<bool>        r_read_last_free;  // Last free entry
    456 
    457       // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM)   
    458       sc_signal<bool>        r_read_to_ixr_cmd_req;     // valid request
    459       sc_signal<addr_t>      r_read_to_ixr_cmd_nline;   // cache line index
    460       sc_signal<size_t>      r_read_to_ixr_cmd_trdid;   // index in Transaction Table
     449      sc_signal<int>      r_read_fsm;        // FSM state
     450      sc_signal<size_t>   r_read_copy;       // Srcid of the first copy
     451      sc_signal<size_t>   r_read_copy_cache; // Srcid of the first copy
     452      sc_signal<bool>     r_read_copy_inst;  // Type of the first copy
     453      sc_signal<tag_t>    r_read_tag;        // cache line tag (in directory)
     454      sc_signal<bool>     r_read_is_cnt;     // is_cnt bit (in directory)
     455      sc_signal<bool>     r_read_lock;       // lock bit (in directory)
     456      sc_signal<bool>     r_read_dirty;      // dirty bit (in directory)
     457      sc_signal<size_t>   r_read_count;      // number of copies
     458      sc_signal<size_t>   r_read_ptr;        // pointer to the heap
     459      sc_signal<data_t> * r_read_data;       // data (one cache line)
     460      sc_signal<size_t>   r_read_way;        // associative way (in cache)
     461      sc_signal<size_t>   r_read_trt_index;  // Transaction Table index
     462      sc_signal<size_t>   r_read_next_ptr;   // Next entry to point to
     463      sc_signal<bool>     r_read_last_free;  // Last free entry
     464
     465      // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM)
     466      sc_signal<bool>     r_read_to_ixr_cmd_req;    // valid request
     467      sc_signal<addr_t>   r_read_to_ixr_cmd_nline;  // cache line index
     468      sc_signal<size_t>   r_read_to_ixr_cmd_trdid;  // index in Transaction Table
    461469
    462470      // Buffer between READ fsm and TGT_RSP fsm (send a hit read response to L1 cache)
    463       sc_signal<bool>      r_read_to_tgt_rsp_req;       // valid request
    464       sc_signal<size_t>    r_read_to_tgt_rsp_srcid;         // Transaction srcid
    465       sc_signal<size_t>    r_read_to_tgt_rsp_trdid;         // Transaction trdid
    466       sc_signal<size_t>    r_read_to_tgt_rsp_pktid;         // Transaction pktid
    467       sc_signal<data_t>   *r_read_to_tgt_rsp_data;          // data (one cache line)
    468       sc_signal<size_t>    r_read_to_tgt_rsp_word;      // first word of the response
    469       sc_signal<size_t>    r_read_to_tgt_rsp_length;    // length of the response
     471      sc_signal<bool>     r_read_to_tgt_rsp_req;    // valid request
     472      sc_signal<size_t>   r_read_to_tgt_rsp_srcid;  // Transaction srcid
     473      sc_signal<size_t>   r_read_to_tgt_rsp_trdid;  // Transaction trdid
     474      sc_signal<size_t>   r_read_to_tgt_rsp_pktid;  // Transaction pktid
     475      sc_signal<data_t> * r_read_to_tgt_rsp_data;   // data (one cache line)
     476      sc_signal<size_t>   r_read_to_tgt_rsp_word;   // first word of the response
     477      sc_signal<size_t>   r_read_to_tgt_rsp_length; // length of the response
    470478
    471479      ///////////////////////////////////////////////////////////////
     
    473481      ///////////////////////////////////////////////////////////////
    474482
    475       sc_signal<int>       r_write_fsm;             // FSM state
    476       sc_signal<addr_t>    r_write_address;         // first word address
    477       sc_signal<size_t>    r_write_word_index;      // first word index in line
    478       sc_signal<size_t>    r_write_word_count;      // number of words in line
    479       sc_signal<size_t>    r_write_srcid;           // transaction srcid
    480       sc_signal<size_t>    r_write_trdid;           // transaction trdid
    481       sc_signal<size_t>    r_write_pktid;           // transaction pktid
    482       sc_signal<data_t>   *r_write_data;            // data (one cache line)   
    483       sc_signal<be_t>     *r_write_be;              // one byte enable per word
    484       sc_signal<bool>      r_write_byte;            // (BE != 0X0) and (BE != 0xF)
    485       sc_signal<bool>      r_write_is_cnt;          // is_cnt bit (in directory)
    486       sc_signal<bool>      r_write_lock;            // lock bit (in directory)
    487       sc_signal<tag_t>     r_write_tag;             // cache line tag (in directory)
    488       sc_signal<size_t>    r_write_copy;            // first owner of the line
    489       sc_signal<size_t>    r_write_copy_cache;      // first owner of the line
    490       sc_signal<bool>      r_write_copy_inst;       // is this owner a ICache ?
    491       sc_signal<size_t>    r_write_count;           // number of copies
    492       sc_signal<size_t>    r_write_ptr;             // pointer to the heap
    493       sc_signal<size_t>    r_write_next_ptr;        // next pointer to the heap
    494       sc_signal<bool>      r_write_to_dec;          // need to decrement update counter
    495       sc_signal<size_t>    r_write_way;                 // way of the line
    496       sc_signal<size_t>    r_write_trt_index;       // index in Transaction Table
    497       sc_signal<size_t>    r_write_upt_index;       // index in Update Table
     483      sc_signal<int>      r_write_fsm;        // FSM state
     484      sc_signal<addr_t>   r_write_address;    // first word address
     485      sc_signal<size_t>   r_write_word_index; // first word index in line
     486      sc_signal<size_t>   r_write_word_count; // number of words in line
     487      sc_signal<size_t>   r_write_srcid;      // transaction srcid
     488      sc_signal<size_t>   r_write_trdid;      // transaction trdid
     489      sc_signal<size_t>   r_write_pktid;      // transaction pktid
     490      sc_signal<data_t> * r_write_data;       // data (one cache line)
     491      sc_signal<be_t>   * r_write_be;         // one byte enable per word
     492      sc_signal<bool>     r_write_byte;       // (BE != 0X0) and (BE != 0xF)
     493      sc_signal<bool>     r_write_is_cnt;     // is_cnt bit (in directory)
     494      sc_signal<bool>     r_write_lock;       // lock bit (in directory)
     495      sc_signal<tag_t>    r_write_tag;        // cache line tag (in directory)
     496      sc_signal<size_t>   r_write_copy;       // first owner of the line
     497      sc_signal<size_t>   r_write_copy_cache; // first owner of the line
     498      sc_signal<bool>     r_write_copy_inst;  // is this owner a ICache ?
     499      sc_signal<size_t>   r_write_count;      // number of copies
     500      sc_signal<size_t>   r_write_ptr;        // pointer to the heap
     501      sc_signal<size_t>   r_write_next_ptr;   // next pointer to the heap
     502      sc_signal<bool>     r_write_to_dec;     // need to decrement update counter
     503      sc_signal<size_t>   r_write_way;        // way of the line
     504      sc_signal<size_t>   r_write_trt_index;  // index in Transaction Table
     505      sc_signal<size_t>   r_write_upt_index;  // index in Update Table
    498506
    499507      // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
    500       sc_signal<bool>      r_write_to_tgt_rsp_req;              // valid request
    501       sc_signal<size_t>    r_write_to_tgt_rsp_srcid;    // transaction srcid
    502       sc_signal<size_t>    r_write_to_tgt_rsp_trdid;    // transaction trdid
    503       sc_signal<size_t>    r_write_to_tgt_rsp_pktid;    // transaction pktid
    504 
    505       // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 
    506       sc_signal<bool>      r_write_to_ixr_cmd_req;      // valid request
    507       sc_signal<bool>      r_write_to_ixr_cmd_write;    // write request
    508       sc_signal<addr_t>    r_write_to_ixr_cmd_nline;    // cache line index
    509       sc_signal<data_t>   *r_write_to_ixr_cmd_data;         // cache line data
    510       sc_signal<size_t>    r_write_to_ixr_cmd_trdid;    // index in Transaction Table
     508      sc_signal<bool>     r_write_to_tgt_rsp_req;   // valid request
     509      sc_signal<size_t>   r_write_to_tgt_rsp_srcid; // transaction srcid
     510      sc_signal<size_t>   r_write_to_tgt_rsp_trdid; // transaction trdid
     511      sc_signal<size_t>   r_write_to_tgt_rsp_pktid; // transaction pktid
     512
     513      // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM)
     514      sc_signal<bool>     r_write_to_ixr_cmd_req;   // valid request
     515      sc_signal<bool>     r_write_to_ixr_cmd_write; // write request
     516      sc_signal<addr_t>   r_write_to_ixr_cmd_nline; // cache line index
     517      sc_signal<data_t> * r_write_to_ixr_cmd_data;  // cache line data
     518      sc_signal<size_t>   r_write_to_ixr_cmd_trdid; // index in Transaction Table
    511519
    512520      // Buffer between WRITE fsm and INIT_CMD fsm (Update/Invalidate L1 caches)
    513       sc_signal<bool>      r_write_to_init_cmd_multi_req;   // valid multicast request
    514       sc_signal<bool>      r_write_to_init_cmd_brdcast_req; // valid brdcast request
    515       sc_signal<addr_t>    r_write_to_init_cmd_nline;       // cache line index
    516       sc_signal<size_t>    r_write_to_init_cmd_trdid;       // index in Update Table
    517       sc_signal<data_t>   *r_write_to_init_cmd_data;        // data (one cache line)
    518       sc_signal<be_t>     *r_write_to_init_cmd_be;              // word enable
    519       sc_signal<size_t>    r_write_to_init_cmd_count;       // number of words in line
    520       sc_signal<size_t>    r_write_to_init_cmd_index;       // index of first word in line
    521       GenericFifo<bool>    m_write_to_init_cmd_inst_fifo;   // fifo for the L1 type
    522       GenericFifo<size_t>  m_write_to_init_cmd_srcid_fifo;  // fifo for srcids
    523       GenericFifo<size_t>  m_write_to_init_cmd_cache_id_fifo; // fifo for srcids
     521      sc_signal<bool>     r_write_to_init_cmd_multi_req;     // valid multicast request
     522      sc_signal<bool>     r_write_to_init_cmd_brdcast_req;  // valid brdcast request
     523      sc_signal<addr_t>   r_write_to_init_cmd_nline;         // cache line index
     524      sc_signal<size_t>   r_write_to_init_cmd_trdid;         // index in Update Table
     525      sc_signal<data_t> * r_write_to_init_cmd_data;          // data (one cache line)
     526      sc_signal<be_t>   * r_write_to_init_cmd_be;            // word enable
     527      sc_signal<size_t>   r_write_to_init_cmd_count;         // number of words in line
     528      sc_signal<size_t>   r_write_to_init_cmd_index;         // index of first word in line
     529      GenericFifo<bool>   m_write_to_init_cmd_inst_fifo;     // fifo for the L1 type
     530      GenericFifo<size_t> m_write_to_init_cmd_srcid_fifo;    // fifo for srcids
     531      GenericFifo<size_t> m_write_to_init_cmd_cache_id_fifo; // fifo for srcids
    524532
    525533      // Buffer between WRITE fsm and INIT_RSP fsm (Decrement UPT entry)
    526       sc_signal<bool>      r_write_to_init_rsp_req;         // valid request
    527       sc_signal<size_t>    r_write_to_init_rsp_upt_index;  // index in update table
     534      sc_signal<bool>     r_write_to_init_rsp_req;       // valid request
     535      sc_signal<size_t>   r_write_to_init_rsp_upt_index; // index in update table
    528536
    529537      /////////////////////////////////////////////////////////
     
    531539      //////////////////////////////////////////////////////////
    532540
    533       sc_signal<int>       r_init_rsp_fsm;        // FSM state
    534       sc_signal<size_t>    r_init_rsp_upt_index; // index in the Update Table
    535       sc_signal<size_t>    r_init_rsp_srcid;      // pending write srcid     
    536       sc_signal<size_t>    r_init_rsp_trdid;      // pending write trdid     
    537       sc_signal<size_t>    r_init_rsp_pktid;      // pending write pktid     
    538       sc_signal<addr_t>    r_init_rsp_nline;      // pending write nline     
     541      sc_signal<int>      r_init_rsp_fsm;       // FSM state
     542      sc_signal<size_t>   r_init_rsp_upt_index; // index in the Update Table
     543      sc_signal<size_t>   r_init_rsp_srcid;     // pending write srcid
     544      sc_signal<size_t>   r_init_rsp_trdid;     // pending write trdid
     545      sc_signal<size_t>   r_init_rsp_pktid;     // pending write pktid
     546      sc_signal<addr_t>   r_init_rsp_nline;     // pending write nline
    539547
    540548      // Buffer between INIT_RSP fsm and TGT_RSP fsm (complete write/update transaction)
    541       sc_signal<bool>      r_init_rsp_to_tgt_rsp_req;           // valid request
    542       sc_signal<size_t>    r_init_rsp_to_tgt_rsp_srcid;         // Transaction srcid
    543       sc_signal<size_t>    r_init_rsp_to_tgt_rsp_trdid;         // Transaction trdid
    544       sc_signal<size_t>    r_init_rsp_to_tgt_rsp_pktid;         // Transaction pktid
     549      sc_signal<bool>     r_init_rsp_to_tgt_rsp_req;   // valid request
     550      sc_signal<size_t>   r_init_rsp_to_tgt_rsp_srcid; // Transaction srcid
     551      sc_signal<size_t>   r_init_rsp_to_tgt_rsp_trdid; // Transaction trdid
     552      sc_signal<size_t>   r_init_rsp_to_tgt_rsp_pktid; // Transaction pktid
    545553
    546554      ///////////////////////////////////////////////////////
     
    548556      ///////////////////////////////////////////////////////
    549557
    550       sc_signal<int>         r_cleanup_fsm;         // FSM state
    551       sc_signal<size_t>      r_cleanup_srcid;       // transaction srcid
    552       sc_signal<size_t>      r_cleanup_trdid;       // transaction trdid
    553       sc_signal<size_t>      r_cleanup_pktid;       // transaction pktid
    554       sc_signal<addr_t>      r_cleanup_nline;       // cache line index
    555 
    556       sc_signal<copy_t>      r_cleanup_copy;        // first copy
    557       sc_signal<copy_t>      r_cleanup_copy_cache;  // first copy
    558       sc_signal<size_t>      r_cleanup_copy_inst;   // type of the first copy
    559       sc_signal<copy_t>      r_cleanup_count;       // number of copies
    560       sc_signal<size_t>      r_cleanup_ptr;         // pointer to the heap
    561       sc_signal<size_t>      r_cleanup_prev_ptr;    // previous pointer to the heap
    562       sc_signal<size_t>      r_cleanup_prev_srcid;  // srcid of previous heap entry
    563       sc_signal<size_t>      r_cleanup_prev_cache_id; // srcid of previous heap entry
    564       sc_signal<bool>        r_cleanup_prev_inst;   // inst bit of previous heap entry
    565       sc_signal<size_t>      r_cleanup_next_ptr;    // next pointer to the heap
    566       sc_signal<tag_t>       r_cleanup_tag;             // cache line tag (in directory)
    567       sc_signal<bool>        r_cleanup_is_cnt;      // inst bit (in directory)
    568       sc_signal<bool>        r_cleanup_lock;        // lock bit (in directory)
    569       sc_signal<bool>        r_cleanup_dirty;       // dirty bit (in directory)
    570       sc_signal<size_t>      r_cleanup_way;             // associative way (in cache)
    571 
    572       sc_signal<size_t>      r_cleanup_write_srcid; // srcid of write response
    573       sc_signal<size_t>      r_cleanup_write_trdid; // trdid of write rsp
    574       sc_signal<size_t>      r_cleanup_write_pktid; // pktid of write rsp
    575       sc_signal<bool>        r_cleanup_need_rsp;    // needs a write rsp
    576 
    577       sc_signal<size_t>      r_cleanup_index;       // index of the INVAL line (in the UPT)
     558      sc_signal<int>      r_cleanup_fsm;           // FSM state
     559      sc_signal<size_t>   r_cleanup_srcid;         // transaction srcid
     560      sc_signal<size_t>   r_cleanup_trdid;         // transaction trdid
     561      sc_signal<size_t>   r_cleanup_pktid;         // transaction pktid
     562      sc_signal<addr_t>   r_cleanup_nline;         // cache line index
     563
     564      sc_signal<copy_t>   r_cleanup_copy;          // first copy
     565      sc_signal<copy_t>   r_cleanup_copy_cache;    // first copy
     566      sc_signal<size_t>   r_cleanup_copy_inst;     // type of the first copy
     567      sc_signal<copy_t>   r_cleanup_count;         // number of copies
     568      sc_signal<size_t>   r_cleanup_ptr;           // pointer to the heap
     569      sc_signal<size_t>   r_cleanup_prev_ptr;      // previous pointer to the heap
     570      sc_signal<size_t>   r_cleanup_prev_srcid;    // srcid of previous heap entry
     571      sc_signal<size_t>   r_cleanup_prev_cache_id; // srcid of previous heap entry
     572      sc_signal<bool>     r_cleanup_prev_inst;     // inst bit of previous heap entry
     573      sc_signal<size_t>   r_cleanup_next_ptr;      // next pointer to the heap
     574      sc_signal<tag_t>    r_cleanup_tag;           // cache line tag (in directory)
     575      sc_signal<bool>     r_cleanup_is_cnt;        // inst bit (in directory)
     576      sc_signal<bool>     r_cleanup_lock;          // lock bit (in directory)
     577      sc_signal<bool>     r_cleanup_dirty;         // dirty bit (in directory)
     578      sc_signal<size_t>   r_cleanup_way;           // associative way (in cache)
     579
     580      sc_signal<size_t>   r_cleanup_write_srcid;  // srcid of write response
     581      sc_signal<size_t>   r_cleanup_write_trdid;  // trdid of write rsp
     582      sc_signal<size_t>   r_cleanup_write_pktid;  // pktid of write rsp
     583      sc_signal<bool>     r_cleanup_need_rsp;      // needs a write rsp
     584
     585      sc_signal<size_t>   r_cleanup_index;         // index of the INVAL line (in the UPT)
    578586
    579587      // Buffer between CLEANUP fsm and TGT_RSP fsm (acknowledge a write command from L1)
    580       sc_signal<bool>      r_cleanup_to_tgt_rsp_req;    // valid request
    581       sc_signal<size_t>    r_cleanup_to_tgt_rsp_srcid; // transaction srcid
    582       sc_signal<size_t>    r_cleanup_to_tgt_rsp_trdid;  // transaction trdid
    583       sc_signal<size_t>    r_cleanup_to_tgt_rsp_pktid;  // transaction pktid
     588      sc_signal<bool>     r_cleanup_to_tgt_rsp_req;   // valid request
     589      sc_signal<size_t>   r_cleanup_to_tgt_rsp_srcid; // transaction srcid
     590      sc_signal<size_t>   r_cleanup_to_tgt_rsp_trdid; // transaction trdid
     591      sc_signal<size_t>   r_cleanup_to_tgt_rsp_pktid; // transaction pktid
    584592
    585593      ///////////////////////////////////////////////////////
     
    587595      ///////////////////////////////////////////////////////
    588596
    589       sc_signal<int>       r_sc_fsm;                        // FSM state
    590       sc_signal<data_t>    r_sc_wdata;                      // write data word
    591       sc_signal<data_t>    *r_sc_rdata;                     // read data word
    592       sc_signal<uint32_t>  r_sc_lfsr;                       // lfsr for random introducing
    593       sc_signal<size_t>    r_sc_cpt;                        // size of command
    594       sc_signal<copy_t>    r_sc_copy;                       // Srcid of the first copy
    595       sc_signal<copy_t>    r_sc_copy_cache;                // Srcid of the first copy
    596       sc_signal<bool>      r_sc_copy_inst;                      // Type of the first copy
    597       sc_signal<size_t>    r_sc_count;                      // number of copies
    598       sc_signal<size_t>    r_sc_ptr;                        // pointer to the heap
    599       sc_signal<size_t>    r_sc_next_ptr;                       // next pointer to the heap
    600       sc_signal<bool>      r_sc_is_cnt;                     // is_cnt bit (in directory)
    601       sc_signal<bool>      r_sc_dirty;                      // dirty bit (in directory)
    602       sc_signal<size_t>    r_sc_way;                            // way in directory
    603       sc_signal<size_t>    r_sc_set;                            // set in directory
    604       sc_signal<data_t>    r_sc_tag;                            // cache line tag (in directory)
    605       sc_signal<size_t>    r_sc_trt_index;                  // Transaction Table index
    606       sc_signal<size_t>    r_sc_upt_index;                  // Update Table index
    607 
    608       // Buffer between SC fsm and INIT_CMD fsm (XRAM read)     
    609       sc_signal<bool>      r_sc_to_ixr_cmd_req;             // valid request
    610       sc_signal<addr_t>    r_sc_to_ixr_cmd_nline;          // cache line index
    611       sc_signal<size_t>    r_sc_to_ixr_cmd_trdid;          // index in Transaction Table
    612       sc_signal<bool>      r_sc_to_ixr_cmd_write;          // write request
    613       sc_signal<data_t>   *r_sc_to_ixr_cmd_data;            // cache line data
     597      sc_signal<int>      r_sc_fsm;        // FSM state
     598      sc_signal<data_t>   r_sc_wdata;      // write data word
     599      sc_signal<data_t> * r_sc_rdata;      // read data word
     600      sc_signal<uint32_t> r_sc_lfsr;       // lfsr for random introducing
     601      sc_signal<size_t>   r_sc_cpt;        // size of command
     602      sc_signal<copy_t>   r_sc_copy;       // Srcid of the first copy
     603      sc_signal<copy_t>   r_sc_copy_cache; // Srcid of the first copy
     604      sc_signal<bool>     r_sc_copy_inst;  // Type of the first copy
     605      sc_signal<size_t>   r_sc_count;      // number of copies
     606      sc_signal<size_t>   r_sc_ptr;        // pointer to the heap
     607      sc_signal<size_t>   r_sc_next_ptr;   // next pointer to the heap
     608      sc_signal<bool>     r_sc_is_cnt;     // is_cnt bit (in directory)
     609      sc_signal<bool>     r_sc_dirty;      // dirty bit (in directory)
     610      sc_signal<size_t>   r_sc_way;        // way in directory
     611      sc_signal<size_t>   r_sc_set;        // set in directory
     612      sc_signal<data_t>   r_sc_tag;        // cache line tag (in directory)
     613      sc_signal<size_t>   r_sc_trt_index;  // Transaction Table index
     614      sc_signal<size_t>   r_sc_upt_index;  // Update Table index
     615
     616      // Buffer between SC fsm and INIT_CMD fsm (XRAM read)
     617      sc_signal<bool>     r_sc_to_ixr_cmd_req;   // valid request
     618      sc_signal<addr_t>   r_sc_to_ixr_cmd_nline; // cache line index
     619      sc_signal<size_t>   r_sc_to_ixr_cmd_trdid; // index in Transaction Table
     620      sc_signal<bool>     r_sc_to_ixr_cmd_write; // write request
     621      sc_signal<data_t> * r_sc_to_ixr_cmd_data;  // cache line data
    614622
    615623
    616624      // Buffer between SC fsm and TGT_RSP fsm
    617       sc_signal<bool>      r_sc_to_tgt_rsp_req;             // valid request
    618       sc_signal<data_t>    r_sc_to_tgt_rsp_data;            // read data word
    619       sc_signal<size_t>    r_sc_to_tgt_rsp_srcid;          // Transaction srcid
    620       sc_signal<size_t>    r_sc_to_tgt_rsp_trdid;          // Transaction trdid
    621       sc_signal<size_t>    r_sc_to_tgt_rsp_pktid;          // Transaction pktid
     625      sc_signal<bool>     r_sc_to_tgt_rsp_req;   // valid request
     626      sc_signal<data_t>   r_sc_to_tgt_rsp_data;  // read data word
     627      sc_signal<size_t>   r_sc_to_tgt_rsp_srcid; // Transaction srcid
     628      sc_signal<size_t>   r_sc_to_tgt_rsp_trdid; // Transaction trdid
     629      sc_signal<size_t>   r_sc_to_tgt_rsp_pktid; // Transaction pktid
    622630
    623631      // Buffer between SC fsm and INIT_CMD fsm (Update/Invalidate L1 caches)
    624       sc_signal<bool>      r_sc_to_init_cmd_multi_req;      // valid request
    625       sc_signal<bool>      r_sc_to_init_cmd_brdcast_req;    // brdcast request
    626       sc_signal<addr_t>    r_sc_to_init_cmd_nline;              // cache line index
    627       sc_signal<size_t>    r_sc_to_init_cmd_trdid;              // index in Update Table
    628       sc_signal<data_t>    r_sc_to_init_cmd_wdata;          // data (one word)
    629       sc_signal<bool>      r_sc_to_init_cmd_is_long;        // it is a 64 bits SC
    630       sc_signal<data_t>    r_sc_to_init_cmd_wdata_high;     // data high (one word)
    631       sc_signal<size_t>    r_sc_to_init_cmd_index;              // index of the word in line
    632       GenericFifo<bool>    m_sc_to_init_cmd_inst_fifo;      // fifo for the L1 type
    633       GenericFifo<size_t>  m_sc_to_init_cmd_srcid_fifo;     // fifo for srcids
    634       GenericFifo<size_t>  m_sc_to_init_cmd_cache_id_fifo; // fifo for srcids
     632      sc_signal<bool>     r_sc_to_init_cmd_multi_req;     // valid request
     633      sc_signal<bool>     r_sc_to_init_cmd_brdcast_req;   // brdcast request
     634      sc_signal<addr_t>   r_sc_to_init_cmd_nline;         // cache line index
     635      sc_signal<size_t>   r_sc_to_init_cmd_trdid;         // index in Update Table
     636      sc_signal<data_t>   r_sc_to_init_cmd_wdata;         // data (one word)
     637      sc_signal<bool>     r_sc_to_init_cmd_is_long;       // it is a 64 bits SC
     638      sc_signal<data_t>   r_sc_to_init_cmd_wdata_high;    // data high (one word)
     639      sc_signal<size_t>   r_sc_to_init_cmd_index;         // index of the word in line
     640      GenericFifo<bool>   m_sc_to_init_cmd_inst_fifo;     // fifo for the L1 type
     641      GenericFifo<size_t> m_sc_to_init_cmd_srcid_fifo;    // fifo for srcids
     642      GenericFifo<size_t> m_sc_to_init_cmd_cache_id_fifo; // fifo for srcids
    635643
    636644      // Buffer between SC fsm and INIT_RSP fsm (Decrement UPT entry)
    637       sc_signal<bool>      r_sc_to_init_rsp_req;            // valid request
    638       sc_signal<size_t>    r_sc_to_init_rsp_upt_index;      // index in update table
     645      sc_signal<bool>     r_sc_to_init_rsp_req;       // valid request
     646      sc_signal<size_t>   r_sc_to_init_rsp_upt_index; // index in update table
    639647
    640648      ////////////////////////////////////////////////////
     
    642650      ////////////////////////////////////////////////////
    643651
    644       sc_signal<int>       r_ixr_rsp_fsm;       // FSM state
    645       sc_signal<size_t>    r_ixr_rsp_trt_index; // TRT entry index
    646       sc_signal<size_t>    r_ixr_rsp_cpt;           // word counter
     652      sc_signal<int>      r_ixr_rsp_fsm;       // FSM state
     653      sc_signal<size_t>   r_ixr_rsp_trt_index; // TRT entry index
     654      sc_signal<size_t>   r_ixr_rsp_cpt;       // word counter
    647655
    648656      // Buffer between IXR_RSP fsm and XRAM_RSP fsm  (response from the XRAM)
    649       sc_signal<bool>     *r_ixr_rsp_to_xram_rsp_rok;   // A xram response is ready
     657      sc_signal<bool>   * r_ixr_rsp_to_xram_rsp_rok; // A xram response is ready
    650658
    651659      ////////////////////////////////////////////////////
     
    653661      ////////////////////////////////////////////////////
    654662
    655       sc_signal<int>       r_xram_rsp_fsm;                      // FSM state
    656       sc_signal<size_t>    r_xram_rsp_trt_index;            // TRT entry index
    657       TransactionTabEntry  r_xram_rsp_trt_buf;              // TRT entry local buffer
    658       sc_signal<bool>      r_xram_rsp_victim_inval;         // victim line invalidate
    659       sc_signal<bool>      r_xram_rsp_victim_is_cnt;    // victim line inst bit
    660       sc_signal<bool>      r_xram_rsp_victim_dirty;         // victim line dirty bit
    661       sc_signal<size_t>    r_xram_rsp_victim_way;           // victim line way
    662       sc_signal<size_t>    r_xram_rsp_victim_set;           // victim line set
    663       sc_signal<addr_t>    r_xram_rsp_victim_nline;     // victim line index
    664       sc_signal<copy_t>    r_xram_rsp_victim_copy;      // victim line first copy
    665       sc_signal<copy_t>    r_xram_rsp_victim_copy_cache;// victim line first copy
    666       sc_signal<bool>      r_xram_rsp_victim_copy_inst; // victim line type of first copy
    667       sc_signal<size_t>    r_xram_rsp_victim_count;         // victim line number of copies
    668       sc_signal<size_t>    r_xram_rsp_victim_ptr;       // victim line pointer to the heap
    669       sc_signal<data_t>   *r_xram_rsp_victim_data;          // victim line data
    670       sc_signal<size_t>    r_xram_rsp_upt_index;            // UPT entry index
    671       sc_signal<size_t>    r_xram_rsp_next_ptr;         // Next pointer to the heap
     663      sc_signal<int>      r_xram_rsp_fsm;               // FSM state
     664      sc_signal<size_t>   r_xram_rsp_trt_index;         // TRT entry index
     665      TransactionTabEntry r_xram_rsp_trt_buf;           // TRT entry local buffer
     666      sc_signal<bool>     r_xram_rsp_victim_inval;      // victim line invalidate
     667      sc_signal<bool>     r_xram_rsp_victim_is_cnt;     // victim line inst bit
     668      sc_signal<bool>     r_xram_rsp_victim_dirty;      // victim line dirty bit
     669      sc_signal<size_t>   r_xram_rsp_victim_way;        // victim line way
     670      sc_signal<size_t>   r_xram_rsp_victim_set;        // victim line set
     671      sc_signal<addr_t>   r_xram_rsp_victim_nline;      // victim line index
     672      sc_signal<copy_t>   r_xram_rsp_victim_copy;       // victim line first copy
     673      sc_signal<copy_t>   r_xram_rsp_victim_copy_cache; // victim line first copy
     674      sc_signal<bool>     r_xram_rsp_victim_copy_inst;  // victim line type of first copy
     675      sc_signal<size_t>   r_xram_rsp_victim_count;      // victim line number of copies
     676      sc_signal<size_t>   r_xram_rsp_victim_ptr;        // victim line pointer to the heap
     677      sc_signal<data_t> * r_xram_rsp_victim_data;       // victim line data
     678      sc_signal<size_t>   r_xram_rsp_upt_index;         // UPT entry index
     679      sc_signal<size_t>   r_xram_rsp_next_ptr;          // Next pointer to the heap
    672680
    673681      // Buffer between XRAM_RSP fsm and TGT_RSP fsm  (response to L1 cache)
    674       sc_signal<bool>      r_xram_rsp_to_tgt_rsp_req;   // Valid request
    675       sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_srcid; // Transaction srcid
    676       sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_trdid; // Transaction trdid
    677       sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_pktid; // Transaction pktid
    678       sc_signal<data_t>   *r_xram_rsp_to_tgt_rsp_data;  // data (one cache line)
    679       sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_word;  // first word index
    680       sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_length;// length of the response
    681       sc_signal<bool>      r_xram_rsp_to_tgt_rsp_rerror;// send error to requester
    682 
    683       // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches) 
    684       sc_signal<bool>       r_xram_rsp_to_init_cmd_multi_req;       // Valid request
    685       sc_signal<bool>       r_xram_rsp_to_init_cmd_brdcast_req;     // Broadcast request
    686       sc_signal<addr_t>     r_xram_rsp_to_init_cmd_nline;           // cache line index;
    687       sc_signal<size_t>     r_xram_rsp_to_init_cmd_trdid;           // index of UPT entry
    688       GenericFifo<bool>     m_xram_rsp_to_init_cmd_inst_fifo;       // fifo for the L1 type
    689       GenericFifo<size_t>   m_xram_rsp_to_init_cmd_srcid_fifo;      // fifo for srcids
    690       GenericFifo<size_t>   m_xram_rsp_to_init_cmd_cache_id_fifo;      // fifo for srcids
     682      sc_signal<bool>     r_xram_rsp_to_tgt_rsp_req;    // Valid request
     683      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_srcid;  // Transaction srcid
     684      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_trdid;  // Transaction trdid
     685      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_pktid;  // Transaction pktid
     686      sc_signal<data_t> * r_xram_rsp_to_tgt_rsp_data;   // data (one cache line)
     687      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_word;   // first word index
     688      sc_signal<size_t>   r_xram_rsp_to_tgt_rsp_length; // length of the response
     689      sc_signal<bool>     r_xram_rsp_to_tgt_rsp_rerror; // send error to requester
     690
     691      // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches)
     692      sc_signal<bool>     r_xram_rsp_to_init_cmd_multi_req;     // Valid request
     693      sc_signal<bool>     r_xram_rsp_to_init_cmd_brdcast_req;   // Broadcast request
     694      sc_signal<addr_t>   r_xram_rsp_to_init_cmd_nline;         // cache line index;
     695      sc_signal<size_t>   r_xram_rsp_to_init_cmd_trdid;         // index of UPT entry
     696      GenericFifo<bool>   m_xram_rsp_to_init_cmd_inst_fifo;     // fifo for the L1 type
     697      GenericFifo<size_t> m_xram_rsp_to_init_cmd_srcid_fifo;    // fifo for srcids
     698      GenericFifo<size_t> m_xram_rsp_to_init_cmd_cache_id_fifo; // fifo for srcids
    691699
    692700      // Buffer between XRAM_RSP fsm and IXR_CMD fsm (XRAM write)
    693       sc_signal<bool>      r_xram_rsp_to_ixr_cmd_req;   // Valid request
    694       sc_signal<addr_t>    r_xram_rsp_to_ixr_cmd_nline; // cache line index
    695       sc_signal<data_t>   *r_xram_rsp_to_ixr_cmd_data;  // cache line data
    696       sc_signal<size_t>    r_xram_rsp_to_ixr_cmd_trdid; // index in transaction table
     701      sc_signal<bool>     r_xram_rsp_to_ixr_cmd_req;   // Valid request
     702      sc_signal<addr_t>   r_xram_rsp_to_ixr_cmd_nline; // cache line index
     703      sc_signal<data_t> * r_xram_rsp_to_ixr_cmd_data;  // cache line data
     704      sc_signal<size_t>   r_xram_rsp_to_ixr_cmd_trdid; // index in transaction table
    697705
    698706      ////////////////////////////////////////////////////
     
    700708      ////////////////////////////////////////////////////
    701709
    702       sc_signal<int>       r_ixr_cmd_fsm;
    703       sc_signal<size_t>    r_ixr_cmd_cpt;
     710      sc_signal<int>      r_ixr_cmd_fsm;
     711      sc_signal<size_t>   r_ixr_cmd_cpt;
    704712
    705713      ////////////////////////////////////////////////////
     
    707715      ////////////////////////////////////////////////////
    708716
    709       sc_signal<int>       r_tgt_rsp_fsm;
    710       sc_signal<size_t>    r_tgt_rsp_cpt;
     717      sc_signal<int>      r_tgt_rsp_fsm;
     718      sc_signal<size_t>   r_tgt_rsp_cpt;
    711719
    712720      ////////////////////////////////////////////////////
     
    714722      ////////////////////////////////////////////////////
    715723
    716       sc_signal<int>      r_init_cmd_fsm;
     724      sc_signal<int>      r_init_cmd_fsm;
    717725      sc_signal<size_t>   r_init_cmd_cpt;
    718726      sc_signal<bool>     r_init_cmd_inst;
     
    722730      ////////////////////////////////////////////////////
    723731
    724       sc_signal<int>            r_alloc_dir_fsm;
     732      sc_signal<int>      r_alloc_dir_fsm;
     733      sc_signal<unsigned> r_alloc_dir_reset_cpt;
    725734
    726735      ////////////////////////////////////////////////////
     
    728737      ////////////////////////////////////////////////////
    729738
    730       sc_signal<int>            r_alloc_trt_fsm;
     739      sc_signal<int>      r_alloc_trt_fsm;
    731740
    732741      ////////////////////////////////////////////////////
     
    734743      ////////////////////////////////////////////////////
    735744
    736       sc_signal<int>            r_alloc_upt_fsm;
     745      sc_signal<int>      r_alloc_upt_fsm;
    737746
    738747      ////////////////////////////////////////////////////
     
    740749      ////////////////////////////////////////////////////
    741750
    742       sc_signal<int>            r_alloc_heap_fsm;
    743 
     751      sc_signal<int>      r_alloc_heap_fsm;
     752      sc_signal<unsigned> r_alloc_heap_reset_cpt;
    744753    }; // end class VciMemCacheV4
    745754
     
    755764// End:
    756765
    757 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
    758 
     766// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=2:softtabstop=2
     767
  • trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp

    r253 r273  
    11 /* -*- c++ -*-
    2  * File         : vci_mem_cache_v4.cpp
    3  * Date         : 30/10/2008
    4  * Copyright    : UPMC / LIP6
    5  * Authors      : Alain Greiner / Eric Guthmuller
     2 * File       : vci_mem_cache_v4.cpp
     3 * Date       : 30/10/2008
     4 * Copyright  : UPMC / LIP6
     5 * Authors    : Alain Greiner / Eric Guthmuller
    66 *
    77 * SOCLIB_LGPL_HEADER_BEGIN
     
    2626 *
    2727 * Maintainers: alain eric.guthmuller@polytechnique.edu
     28 *              cesar.fuguet-tortolero@lip6.fr
    2829 */
    2930
     
    3233//////   debug services   ///////////////////////////////////////////////////////
    3334// All debug messages are conditionned by two variables:
    34 // - compile time : DEBUG_MEMC_*** : defined below
    35 // - execution time : m_debug_***  : defined by constructor arguments
     35// - compile time   : DEBUG_MEMC_*** : defined below
     36// - execution time : m_debug_***    : defined by constructor arguments
    3637//    m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)
    3738/////////////////////////////////////////////////////////////////////////////////
    3839
    39 #define DEBUG_MEMC_GLOBAL       0       // synthetic trace of all FSMs
    40 #define DEBUG_MEMC_READ         1       // detailed trace of READ FSM
    41 #define DEBUG_MEMC_WRITE        1       // detailed trace of WRITE FSM 
    42 #define DEBUG_MEMC_SC           1       // detailed trace of SC FSM     
    43 #define DEBUG_MEMC_IXR_CMD      1       // detailed trace of IXR_RSP FSM
    44 #define DEBUG_MEMC_IXR_RSP      1       // detailed trace of IXR_RSP FSM
    45 #define DEBUG_MEMC_XRAM_RSP     1       // detailed trace of XRAM_RSP FSM       
    46 #define DEBUG_MEMC_INIT_CMD     1       // detailed trace of INIT_CMD FSM       
    47 #define DEBUG_MEMC_INIT_RSP     1       // detailed trace of INIT_RSP FSM       
    48 #define DEBUG_MEMC_TGT_CMD      1       // detailed trace of TGT_CMD FSM       
    49 #define DEBUG_MEMC_TGT_RSP      1       // detailed trace of TGT_RSP FSM       
    50 #define DEBUG_MEMC_CLEANUP      1       // detailed trace of CLEANUP FSM       
    51 
    52 #define RANDOMIZE_SC            1
     40#define DEBUG_MEMC_GLOBAL   0 // synthetic trace of all FSMs
     41#define DEBUG_MEMC_READ     1 // detailed trace of READ FSM
     42#define DEBUG_MEMC_WRITE    1 // detailed trace of WRITE FSM
     43#define DEBUG_MEMC_SC       1 // detailed trace of SC FSM
     44#define DEBUG_MEMC_IXR_CMD  1 // detailed trace of IXR_RSP FSM
     45#define DEBUG_MEMC_IXR_RSP  1 // detailed trace of IXR_RSP FSM
     46#define DEBUG_MEMC_XRAM_RSP 1 // detailed trace of XRAM_RSP FSM
     47#define DEBUG_MEMC_INIT_CMD 1 // detailed trace of INIT_CMD FSM
     48#define DEBUG_MEMC_INIT_RSP 1 // detailed trace of INIT_RSP FSM
     49#define DEBUG_MEMC_TGT_CMD  1 // detailed trace of TGT_CMD FSM
     50#define DEBUG_MEMC_TGT_RSP  1 // detailed trace of TGT_RSP FSM
     51#define DEBUG_MEMC_CLEANUP  1 // detailed trace of CLEANUP FSM
     52
     53#define RANDOMIZE_SC        1
    5354
    5455namespace soclib { namespace caba {
     
    5859    "TGT_CMD_READ",
    5960    "TGT_CMD_WRITE",
    60     "TGT_CMD_ATOMIC",
     61    "TGT_CMD_ATOMIC"
    6162  };
    6263  const char *tgt_rsp_fsm_str[] = {
     
    7273    "TGT_RSP_XRAM",
    7374    "TGT_RSP_INIT",
    74     "TGT_RSP_CLEANUP",
     75    "TGT_RSP_CLEANUP"
    7576  };
    7677  const char *init_cmd_fsm_str[] = {
     
    8889    "INIT_CMD_SC_UPDT_INDEX",
    8990    "INIT_CMD_SC_UPDT_DATA",
    90     "INIT_CMD_SC_UPDT_DATA_HIGH",
     91    "INIT_CMD_SC_UPDT_DATA_HIGH"
    9192  };
    9293  const char *init_rsp_fsm_str[] = {
     
    9495    "INIT_RSP_UPT_LOCK",
    9596    "INIT_RSP_UPT_CLEAR",
    96     "INIT_RSP_END",
     97    "INIT_RSP_END"
    9798  };
    9899  const char *read_fsm_str[] = {
    99100    "READ_IDLE",
     101    "READ_DIR_REQ",
    100102    "READ_DIR_LOCK",
    101103    "READ_DIR_HIT",
     104    "READ_HEAP_REQ",
    102105    "READ_HEAP_LOCK",
    103106    "READ_HEAP_WRITE",
     
    107110    "READ_TRT_LOCK",
    108111    "READ_TRT_SET",
    109     "READ_TRT_REQ",
     112    "READ_TRT_REQ"
    110113  };
    111114  const char *write_fsm_str[] = {
    112115    "WRITE_IDLE",
    113116    "WRITE_NEXT",
     117    "WRITE_DIR_REQ",
    114118    "WRITE_DIR_LOCK",
    115119    "WRITE_DIR_READ",
     
    130134    "WRITE_BC_CC_SEND",
    131135    "WRITE_BC_XRAM_REQ",
    132     "WRITE_WAIT",
     136    "WRITE_WAIT"
    133137  };
    134138  const char *ixr_rsp_fsm_str[] = {
     
    136140    "IXR_RSP_ACK",
    137141    "IXR_RSP_TRT_ERASE",
    138     "IXR_RSP_TRT_READ",
     142    "IXR_RSP_TRT_READ"
    139143  };
    140144  const char *xram_rsp_fsm_str[] = {
     
    149153    "XRAM_RSP_INVAL",
    150154    "XRAM_RSP_WRITE_DIRTY",
     155    "XRAM_RSP_HEAP_REQ",
    151156    "XRAM_RSP_HEAP_ERASE",
    152157    "XRAM_RSP_HEAP_LAST",
    153158    "XRAM_RSP_ERROR_ERASE",
    154     "XRAM_RSP_ERROR_RSP",
     159    "XRAM_RSP_ERROR_RSP"
    155160  };
    156161  const char *ixr_cmd_fsm_str[] = {
     
    162167    "IXR_CMD_WRITE_NLINE",
    163168    "IXR_CMD_SC_NLINE",
    164     "IXR_CMD_XRAM_DATA",
     169    "IXR_CMD_XRAM_DATA"
    165170  };
    166171  const char *sc_fsm_str[] = {
    167172    "SC_IDLE",
     173    "SC_DIR_REQ",
    168174    "SC_DIR_LOCK",
    169175    "SC_DIR_HIT_READ",
     
    183189    "SC_MISS_TRT_SET",
    184190    "SC_MISS_XRAM_REQ",
    185     "SC_WAIT",
     191    "SC_WAIT"
    186192  };
    187193  const char *cleanup_fsm_str[] = {
    188194    "CLEANUP_IDLE",
     195    "CLEANUP_DIR_REQ",
    189196    "CLEANUP_DIR_LOCK",
    190197    "CLEANUP_DIR_WRITE",
     198    "CLEANUP_HEAP_REQ",
    191199    "CLEANUP_HEAP_LOCK",
    192200    "CLEANUP_HEAP_SEARCH",
     
    196204    "CLEANUP_UPT_WRITE",
    197205    "CLEANUP_WRITE_RSP",
    198     "CLEANUP_RSP",
     206    "CLEANUP_RSP"
    199207  };
    200208  const char *alloc_dir_fsm_str[] = {
     209    "ALLOC_DIR_RESET",
    201210    "ALLOC_DIR_READ",
    202211    "ALLOC_DIR_WRITE",
    203212    "ALLOC_DIR_SC",
    204213    "ALLOC_DIR_CLEANUP",
    205     "ALLOC_DIR_XRAM_RSP",
     214    "ALLOC_DIR_XRAM_RSP"
    206215  };
    207216  const char *alloc_trt_fsm_str[] = {
     
    210219    "ALLOC_TRT_SC",
    211220    "ALLOC_TRT_XRAM_RSP",
    212     "ALLOC_TRT_IXR_RSP",
     221    "ALLOC_TRT_IXR_RSP"
    213222  };
    214223  const char *alloc_upt_fsm_str[] = {
     
    217226    "ALLOC_UPT_INIT_RSP",
    218227    "ALLOC_UPT_CLEANUP",
     228    "ALLOC_UPT_SC"
    219229  };
    220230  const char *alloc_heap_fsm_str[] = {
     231    "ALLOC_HEAP_RESET",
    221232    "ALLOC_HEAP_READ",
    222233    "ALLOC_HEAP_WRITE",
    223234    "ALLOC_HEAP_SC",
    224235    "ALLOC_HEAP_CLEANUP",
    225     "ALLOC_HEAP_XRAM_RSP",
     236    "ALLOC_HEAP_XRAM_RSP"
    226237  };
    227238
     
    231242
    232243  ////////////////////////////////
    233   //    Constructor
     244  //  Constructor
    234245  ////////////////////////////////
    235246
    236   tmpl(/**/)::VciMemCacheV4( 
     247  tmpl(/**/)::VciMemCacheV4(
    237248      sc_module_name name,
    238249      const soclib::common::MappingTable &mtp,
     
    243254      const soclib::common::IntTab &vci_tgt_index,
    244255      const soclib::common::IntTab &vci_tgt_index_cleanup,
    245       size_t nways,                                         // number of ways per set
    246       size_t nsets,                                         // number of cache sets
    247       size_t nwords,                                        // number of words in cache line
    248       size_t heap_size,                                     // number of heap entries
    249       size_t transaction_tab_lines,                         // number of TRT entries
    250       size_t update_tab_lines,                              // number of UPT entries
     256      size_t nways,                 // number of ways per set
     257      size_t nsets,                 // number of cache sets
     258      size_t nwords,                // number of words in cache line
     259      size_t heap_size,             // number of heap entries
     260      size_t transaction_tab_lines, // number of TRT entries
     261      size_t update_tab_lines,      // number of UPT entries
    251262      size_t debug_start_cycle,
    252263      bool   debug_ok)
     
    287298#undef L2
    288299
    289     //  FIFOs 
     300    //  FIFOs
    290301
    291302    m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
     
    311322
    312323    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    313    
    314     m_nseg(0), 
    315     m_ncseg(0), 
     324
     325    m_nseg(0),
     326    m_ncseg(0),
    316327
    317328    r_read_fsm("r_read_fsm"),
     
    352363
    353364    r_alloc_dir_fsm("r_alloc_dir_fsm"),
     365    r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"),
    354366    r_alloc_trt_fsm("r_alloc_trt_fsm"),
    355367    r_alloc_upt_fsm("r_alloc_upt_fsm"),
    356     r_alloc_heap_fsm("r_alloc_heap_fsm")
     368    r_alloc_heap_fsm("r_alloc_heap_fsm"),
     369    r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
    357370    {
    358371      assert(IS_POW_OF_2(nsets));
     
    370383      m_broadcast_address = 0x3 | (0x7C1F << (vci_param::N-20));
    371384
    372       // Get the segments associated to the MemCache 
     385      // Get the segments associated to the MemCache
    373386      std::list<soclib::common::Segment>::iterator seg;
    374387      size_t i;
     
    384397
    385398      i = 0;
    386       for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) { 
     399      for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) {
    387400        m_seg[i] = &(*seg);
    388401        i++;
     
    392405
    393406      i = 0;
    394       for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) { 
     407      for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) {
    395408          m_cseg[i] = &(*seg);
    396409          i++;
     
    407420          for ( size_t k=0; k<nwords; k++){
    408421            m_cache_data[i][j][k]=0;
    409           }     
     422          }
    410423        }
    411424      }
    412425
    413426      // Allocation for IXR_RSP FSM
    414       r_ixr_rsp_to_xram_rsp_rok     = new sc_signal<bool>[m_transaction_tab_lines];
     427      r_ixr_rsp_to_xram_rsp_rok   = new sc_signal<bool>[m_transaction_tab_lines];
    415428
    416429      // Allocation for XRAM_RSP FSM
    417       r_xram_rsp_victim_data        = new sc_signal<data_t>[nwords];
    418       r_xram_rsp_to_tgt_rsp_data    = new sc_signal<data_t>[nwords];
    419       r_xram_rsp_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
     430      r_xram_rsp_victim_data      = new sc_signal<data_t>[nwords];
     431      r_xram_rsp_to_tgt_rsp_data  = new sc_signal<data_t>[nwords];
     432      r_xram_rsp_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
    420433
    421434      // Allocation for READ FSM
    422       r_read_data                               = new sc_signal<data_t>[nwords];
    423       r_read_to_tgt_rsp_data            = new sc_signal<data_t>[nwords];
     435      r_read_data                 = new sc_signal<data_t>[nwords];
     436      r_read_to_tgt_rsp_data      = new sc_signal<data_t>[nwords];
    424437
    425438      // Allocation for WRITE FSM
    426       r_write_data                              = new sc_signal<data_t>[nwords];
    427       r_write_be                                = new sc_signal<be_t>[nwords];
    428       r_write_to_init_cmd_data          = new sc_signal<data_t>[nwords];
    429       r_write_to_init_cmd_be            = new sc_signal<be_t>[nwords];
    430       r_write_to_ixr_cmd_data       = new sc_signal<data_t>[nwords];
     439      r_write_data                = new sc_signal<data_t>[nwords];
     440      r_write_be                  = new sc_signal<be_t>[nwords];
     441      r_write_to_init_cmd_data    = new sc_signal<data_t>[nwords];
     442      r_write_to_init_cmd_be      = new sc_signal<be_t>[nwords];
     443      r_write_to_ixr_cmd_data     = new sc_signal<data_t>[nwords];
    431444
    432445      // Allocation for SC FSM
    433       r_sc_to_ixr_cmd_data              = new sc_signal<data_t>[nwords];
    434       r_sc_rdata                    = new sc_signal<data_t>[2];
     446      r_sc_to_ixr_cmd_data        = new sc_signal<data_t>[nwords];
     447      r_sc_rdata                  = new sc_signal<data_t>[2];
    435448
    436449
     
    471484    {
    472485        std::cout << " MEMC Write Monitor : " << buf << " Address = " << std::hex << addr
    473                   << " / Data = " << data << std::endl; 
     486                  << " / Data = " << data << std::endl;
    474487    }
    475488}
     
    480493{
    481494    DirectoryEntry entry = m_cache_directory.read_neutral(addr);
    482     if ( (entry.count != m_debug_previous_count) or 
     495    if ( (entry.count != m_debug_previous_count) or
    483496         (entry.valid != m_debug_previous_hit) )
    484497    {
     
    498511{
    499512    std::cout << "MEMC " << name() << std::endl;
    500     std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm] 
    501               << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] 
     513    std::cout << "  "  << tgt_cmd_fsm_str[r_tgt_cmd_fsm]
     514              << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm]
    502515              << " | " << read_fsm_str[r_read_fsm]
    503               << " | " << write_fsm_str[r_write_fsm] 
    504               << " | " << sc_fsm_str[r_sc_fsm] 
     516              << " | " << write_fsm_str[r_write_fsm]
     517              << " | " << sc_fsm_str[r_sc_fsm]
    505518              << " | " << cleanup_fsm_str[r_cleanup_fsm] << std::endl;
    506519    std::cout << "  "  << init_cmd_fsm_str[r_init_cmd_fsm]
    507               << " | " << init_rsp_fsm_str[r_init_rsp_fsm] 
    508               << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] 
     520              << " | " << init_rsp_fsm_str[r_init_rsp_fsm]
     521              << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm]
    509522              << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm]
    510523              << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl;
     
    515528/////////////////////////////////////////
    516529{
    517     std::cout << "----------------------------------" << std::dec << std::endl;
    518     std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl
    519               << "- READ RATE            = " << (double)m_cpt_read/m_cpt_cycles << std::endl
    520               << "- READ TOTAL           = " << m_cpt_read << std::endl
    521               << "- READ MISS RATE       = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
    522               << "- WRITE RATE           = " << (double)m_cpt_write/m_cpt_cycles << std::endl
    523               << "- WRITE TOTAL          = " << m_cpt_write << std::endl
    524               << "- WRITE MISS RATE      = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
    525               << "- WRITE BURST LENGTH   = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
    526               << "- WRITE BURST TOTAL    = " << m_cpt_write_cells << std::endl
    527               << "- REQUESTS TRT FULL    = " << m_cpt_trt_full << std::endl
    528               << "- READ TRT BLOKED HIT  = " << m_cpt_trt_rb << std::endl
    529               << "- UPDATE RATE          = " << (double)m_cpt_update/m_cpt_cycles << std::endl
    530               << "- UPDATE ARITY         = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
    531               << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
    532               << "- INVAL MULTICAST ARITY= " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
    533               << "- INVAL BROADCAST RATE = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
    534               << "- SAVE DIRTY RATE      = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
    535               << "- CLEANUP RATE         = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
    536               << "- LL RATE              = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
    537               << "- SC RATE              = " << (double)m_cpt_sc/m_cpt_cycles << std::endl;
     530  std::cout << "----------------------------------" << std::dec << std::endl;
     531  std::cout
     532    << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl
     533    << "- READ RATE            = " << (double) m_cpt_read/m_cpt_cycles << std::endl
     534    << "- READ TOTAL           = " << m_cpt_read << std::endl
     535    << "- READ MISS RATE       = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
     536    << "- WRITE RATE           = " << (double) m_cpt_write/m_cpt_cycles << std::endl
     537    << "- WRITE TOTAL          = " << m_cpt_write << std::endl
     538    << "- WRITE MISS RATE      = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
     539    << "- WRITE BURST LENGTH   = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
     540    << "- WRITE BURST TOTAL    = " << m_cpt_write_cells << std::endl
     541    << "- REQUESTS TRT FULL    = " << m_cpt_trt_full << std::endl
     542    << "- READ TRT BLOKED HIT  = " << m_cpt_trt_rb << std::endl
     543    << "- UPDATE RATE          = " << (double) m_cpt_update/m_cpt_cycles << std::endl
     544    << "- UPDATE ARITY         = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
     545    << "- INVAL MULTICAST RATE = " << (double) (m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
     546    << "- INVAL MULTICAST ARITY= " << (double) m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
     547    << "- INVAL BROADCAST RATE = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
     548    << "- SAVE DIRTY RATE      = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
     549    << "- CLEANUP RATE         = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
     550    << "- LL RATE              = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
     551    << "- SC RATE              = " << (double) m_cpt_sc/m_cpt_cycles << std::endl;
    538552}
    539553
     
    570584//////////////////////////////////
    571585{
    572     using soclib::common::uint32_log2;
    573 
    574     //  RESET         
    575     if ( ! p_resetn.read() ) {
    576 
    577       //    Initializing FSMs
    578       r_tgt_cmd_fsm     = TGT_CMD_IDLE;
    579       r_tgt_rsp_fsm     = TGT_RSP_READ_IDLE;
    580       r_init_cmd_fsm    = INIT_CMD_INVAL_IDLE;
    581       r_init_rsp_fsm    = INIT_RSP_IDLE;
    582       r_read_fsm            = READ_IDLE;
    583       r_write_fsm           = WRITE_IDLE;
    584       r_sc_fsm          = SC_IDLE;
    585       r_cleanup_fsm     = CLEANUP_IDLE;
    586       r_alloc_dir_fsm   = ALLOC_DIR_READ;
    587       r_alloc_heap_fsm  = ALLOC_HEAP_READ;
    588       r_alloc_trt_fsm   = ALLOC_TRT_READ;
    589       r_alloc_upt_fsm   = ALLOC_UPT_WRITE;
    590       r_ixr_rsp_fsm     = IXR_RSP_IDLE;
    591       r_xram_rsp_fsm    = XRAM_RSP_IDLE;
    592       r_ixr_cmd_fsm     = IXR_CMD_READ_IDLE;
    593 
    594       m_debug_global         = false;
    595       m_debug_tgt_cmd_fsm    = false;
    596       m_debug_tgt_rsp_fsm    = false;
    597       m_debug_init_cmd_fsm   = false;
    598       m_debug_init_rsp_fsm   = false;
    599       m_debug_read_fsm       = false;
    600       m_debug_write_fsm      = false;
    601       m_debug_sc_fsm         = false;
    602       m_debug_cleanup_fsm    = false;
    603       m_debug_ixr_cmd_fsm    = false;
    604       m_debug_ixr_rsp_fsm    = false;
    605       m_debug_xram_rsp_fsm   = false;
    606       m_debug_previous_hit   = false;
    607       m_debug_previous_count = 0;
    608 
    609       //  Initializing Tables
    610       m_cache_directory.init();
    611       m_transaction_tab.init();
    612       m_heap.init();
    613 
    614       // initializing FIFOs and communication Buffers
    615 
    616       m_cmd_read_addr_fifo.init();
    617       m_cmd_read_length_fifo.init();
    618       m_cmd_read_srcid_fifo.init();
    619       m_cmd_read_trdid_fifo.init();
    620       m_cmd_read_pktid_fifo.init();
    621 
    622       m_cmd_write_addr_fifo.init();
    623       m_cmd_write_eop_fifo.init();
    624       m_cmd_write_srcid_fifo.init();
    625       m_cmd_write_trdid_fifo.init();
    626       m_cmd_write_pktid_fifo.init();
    627       m_cmd_write_data_fifo.init();
    628 
    629       m_cmd_sc_addr_fifo.init();
    630       m_cmd_sc_srcid_fifo.init();
    631       m_cmd_sc_trdid_fifo.init();
    632       m_cmd_sc_pktid_fifo.init();
    633       m_cmd_sc_wdata_fifo.init();
    634       m_cmd_sc_eop_fifo.init();
    635 
    636       r_read_to_tgt_rsp_req                = false;
    637       r_read_to_ixr_cmd_req                 = false;
    638 
    639       r_write_to_tgt_rsp_req            = false;
    640       r_write_to_ixr_cmd_req            = false;
    641       r_write_to_init_cmd_multi_req        = false;
    642       r_write_to_init_cmd_brdcast_req   = false;
    643       r_write_to_init_rsp_req           = false;
    644       m_write_to_init_cmd_inst_fifo.init();
    645       m_write_to_init_cmd_srcid_fifo.init();
     586  using soclib::common::uint32_log2;
     587
     588  // RESET
     589  if ( ! p_resetn.read() ) {
     590
     591    // Initializing FSMs
     592    r_tgt_cmd_fsm    = TGT_CMD_IDLE;
     593    r_tgt_rsp_fsm    = TGT_RSP_READ_IDLE;
     594    r_init_cmd_fsm   = INIT_CMD_INVAL_IDLE;
     595    r_init_rsp_fsm   = INIT_RSP_IDLE;
     596    r_read_fsm       = READ_IDLE;
     597    r_write_fsm      = WRITE_IDLE;
     598    r_sc_fsm         = SC_IDLE;
     599    r_cleanup_fsm    = CLEANUP_IDLE;
     600    r_alloc_dir_fsm  = ALLOC_DIR_RESET;
     601    r_alloc_heap_fsm = ALLOC_HEAP_RESET;
     602    r_alloc_trt_fsm  = ALLOC_TRT_READ;
     603    r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
     604    r_ixr_rsp_fsm    = IXR_RSP_IDLE;
     605    r_xram_rsp_fsm   = XRAM_RSP_IDLE;
     606    r_ixr_cmd_fsm    = IXR_CMD_READ_IDLE;
     607
     608    m_debug_global         = false;
     609    m_debug_tgt_cmd_fsm    = false;
     610    m_debug_tgt_rsp_fsm    = false;
     611    m_debug_init_cmd_fsm   = false;
     612    m_debug_init_rsp_fsm   = false;
     613    m_debug_read_fsm       = false;
     614    m_debug_write_fsm      = false;
     615    m_debug_sc_fsm         = false;
     616    m_debug_cleanup_fsm    = false;
     617    m_debug_ixr_cmd_fsm    = false;
     618    m_debug_ixr_rsp_fsm    = false;
     619    m_debug_xram_rsp_fsm   = false;
     620    m_debug_previous_hit   = false;
     621    m_debug_previous_count = 0;
     622
     623    //  Initializing Tables
     624    m_transaction_tab.init();
     625    m_update_tab.init();
     626
     627    // initializing FIFOs and communication Buffers
     628
     629    m_cmd_read_addr_fifo.init();
     630    m_cmd_read_length_fifo.init();
     631    m_cmd_read_srcid_fifo.init();
     632    m_cmd_read_trdid_fifo.init();
     633    m_cmd_read_pktid_fifo.init();
     634
     635    m_cmd_write_addr_fifo.init();
     636    m_cmd_write_eop_fifo.init();
     637    m_cmd_write_srcid_fifo.init();
     638    m_cmd_write_trdid_fifo.init();
     639    m_cmd_write_pktid_fifo.init();
     640    m_cmd_write_data_fifo.init();
     641
     642    m_cmd_sc_addr_fifo.init();
     643    m_cmd_sc_srcid_fifo.init();
     644    m_cmd_sc_trdid_fifo.init();
     645    m_cmd_sc_pktid_fifo.init();
     646    m_cmd_sc_wdata_fifo.init();
     647    m_cmd_sc_eop_fifo.init();
     648
     649    r_read_to_tgt_rsp_req = false;
     650    r_read_to_ixr_cmd_req = false;
     651
     652    r_write_to_tgt_rsp_req          = false;
     653    r_write_to_ixr_cmd_req          = false;
     654    r_write_to_init_cmd_multi_req   = false;
     655    r_write_to_init_cmd_brdcast_req = false;
     656    r_write_to_init_rsp_req         = false;
     657
     658    m_write_to_init_cmd_inst_fifo.init();
     659    m_write_to_init_cmd_srcid_fifo.init();
    646660#if L1_MULTI_CACHE
    647       m_write_to_init_cmd_cache_id_fifo.init();
    648 #endif
    649 
    650       r_cleanup_to_tgt_rsp_req          = false;
    651 
    652       r_init_rsp_to_tgt_rsp_req         = false;
    653 
    654       r_sc_to_tgt_rsp_req                   = false;
    655       r_sc_cpt                          = 0;
    656       r_sc_lfsr                         = -1;
    657       r_sc_to_ixr_cmd_req                   = false;
    658       r_sc_to_init_cmd_multi_req            = false;
    659       r_sc_to_init_cmd_brdcast_req          = false;
    660       m_sc_to_init_cmd_inst_fifo.init();
    661       m_sc_to_init_cmd_srcid_fifo.init();
     661    m_write_to_init_cmd_cache_id_fifo.init();
     662#endif
     663
     664    r_cleanup_to_tgt_rsp_req     = false;
     665
     666    r_init_rsp_to_tgt_rsp_req    = false;
     667
     668    r_sc_to_tgt_rsp_req          = false;
     669    r_sc_cpt                     = 0;
     670    r_sc_lfsr                    = -1;
     671    r_sc_to_ixr_cmd_req          = false;
     672    r_sc_to_init_cmd_multi_req   = false;
     673    r_sc_to_init_cmd_brdcast_req = false;
     674
     675    m_sc_to_init_cmd_inst_fifo.init();
     676    m_sc_to_init_cmd_srcid_fifo.init();
    662677#if L1_MULTI_CACHE
    663       m_sc_to_init_cmd_cache_id_fifo.init();
    664 #endif
    665 
    666       for(size_t i=0; i<m_transaction_tab_lines ; i++){
    667         r_ixr_rsp_to_xram_rsp_rok[i] = false;
    668       }
    669 
    670       r_xram_rsp_to_tgt_rsp_req             = false;
    671       r_xram_rsp_to_init_cmd_multi_req      = false;
    672       r_xram_rsp_to_init_cmd_brdcast_req    = false;
    673       r_xram_rsp_to_ixr_cmd_req             = false;
    674       r_xram_rsp_trt_index                      = 0;
    675       m_xram_rsp_to_init_cmd_inst_fifo.init();
    676       m_xram_rsp_to_init_cmd_srcid_fifo.init();
     678    m_sc_to_init_cmd_cache_id_fifo.init();
     679#endif
     680
     681    for(size_t i=0; i<m_transaction_tab_lines ; i++){
     682      r_ixr_rsp_to_xram_rsp_rok[i] = false;
     683    }
     684
     685    r_xram_rsp_to_tgt_rsp_req          = false;
     686    r_xram_rsp_to_init_cmd_multi_req   = false;
     687    r_xram_rsp_to_init_cmd_brdcast_req = false;
     688    r_xram_rsp_to_ixr_cmd_req          = false;
     689    r_xram_rsp_trt_index               = 0;
     690
     691    m_xram_rsp_to_init_cmd_inst_fifo.init();
     692    m_xram_rsp_to_init_cmd_srcid_fifo.init();
    677693#if L1_MULTI_CACHE
    678       m_xram_rsp_to_init_cmd_cache_id_fifo.init();
    679 #endif
    680 
    681       r_ixr_cmd_cpt         = 0;
    682 
    683       r_copies_limit        = 3;
    684 
    685       // Activity counters
    686       m_cpt_cycles                  = 0;
    687       m_cpt_read                    = 0;
    688       m_cpt_read_miss       = 0;
    689       m_cpt_write                   = 0;
    690       m_cpt_write_miss      = 0;
    691       m_cpt_write_cells     = 0;
    692       m_cpt_write_dirty     = 0;
    693       m_cpt_update                  = 0;
    694       m_cpt_update_mult     = 0;
    695       m_cpt_inval_brdcast       = 0;
    696       m_cpt_inval                   = 0;
    697       m_cpt_inval_mult          = 0;
    698       m_cpt_cleanup                 = 0;
    699       m_cpt_ll                      = 0;
    700       m_cpt_sc                      = 0;
    701       m_cpt_trt_full        = 0;
    702       m_cpt_trt_rb          = 0;
    703 
    704       return;
    705     }
    706 
    707     bool    cmd_read_fifo_put = false;
    708     bool    cmd_read_fifo_get = false;
    709 
    710     bool    cmd_write_fifo_put = false;
    711     bool    cmd_write_fifo_get = false;
    712 
    713     bool    cmd_sc_fifo_put = false;
    714     bool    cmd_sc_fifo_get = false;
    715 
    716     bool    write_to_init_cmd_fifo_put      = false;
    717     bool    write_to_init_cmd_fifo_get      = false;
    718     bool    write_to_init_cmd_fifo_inst     = false;
    719     size_t  write_to_init_cmd_fifo_srcid    = 0;
     694    m_xram_rsp_to_init_cmd_cache_id_fifo.init();
     695#endif
     696
     697    r_ixr_cmd_cpt          = 0;
     698    r_alloc_dir_reset_cpt  = 0;
     699    r_alloc_heap_reset_cpt = 0;
     700
     701    r_copies_limit         = 3;
     702
     703    // Activity counters
     704    m_cpt_cycles        = 0;
     705    m_cpt_read          = 0;
     706    m_cpt_read_miss     = 0;
     707    m_cpt_write         = 0;
     708    m_cpt_write_miss    = 0;
     709    m_cpt_write_cells   = 0;
     710    m_cpt_write_dirty   = 0;
     711    m_cpt_update        = 0;
     712    m_cpt_update_mult   = 0;
     713    m_cpt_inval_brdcast = 0;
     714    m_cpt_inval         = 0;
     715    m_cpt_inval_mult    = 0;
     716    m_cpt_cleanup       = 0;
     717    m_cpt_ll            = 0;
     718    m_cpt_sc            = 0;
     719    m_cpt_trt_full      = 0;
     720    m_cpt_trt_rb        = 0;
     721
     722    return;
     723  }
     724
     725  bool    cmd_read_fifo_put = false;
     726  bool    cmd_read_fifo_get = false;
     727
     728  bool    cmd_write_fifo_put = false;
     729  bool    cmd_write_fifo_get = false;
     730
     731  bool    cmd_sc_fifo_put = false;
     732  bool    cmd_sc_fifo_get = false;
     733
     734  bool    write_to_init_cmd_fifo_put   = false;
     735  bool    write_to_init_cmd_fifo_get   = false;
     736  bool    write_to_init_cmd_fifo_inst  = false;
     737  size_t  write_to_init_cmd_fifo_srcid = 0;
    720738
    721739#if L1_MULTI_CACHE
    722     size_t  write_to_init_cmd_fifo_cache_id = 0;
    723 #endif
    724 
    725     bool    xram_rsp_to_init_cmd_fifo_put      = false;
    726     bool    xram_rsp_to_init_cmd_fifo_get      = false;
    727     bool    xram_rsp_to_init_cmd_fifo_inst     = false;
    728     size_t  xram_rsp_to_init_cmd_fifo_srcid    = 0;
     740  size_t  write_to_init_cmd_fifo_cache_id = 0;
     741#endif
     742
     743  bool    xram_rsp_to_init_cmd_fifo_put   = false;
     744  bool    xram_rsp_to_init_cmd_fifo_get   = false;
     745  bool    xram_rsp_to_init_cmd_fifo_inst  = false;
     746  size_t  xram_rsp_to_init_cmd_fifo_srcid = 0;
    729747
    730748#if L1_MULTI_CACHE
    731     size_t  xram_rsp_to_init_cmd_fifo_cache_id = 0;
    732 #endif
    733 
    734     bool    sc_to_init_cmd_fifo_put      = false;
    735     bool    sc_to_init_cmd_fifo_get      = false;
    736     bool    sc_to_init_cmd_fifo_inst     = false;
    737     size_t  sc_to_init_cmd_fifo_srcid    = 0;
     749  size_t  xram_rsp_to_init_cmd_fifo_cache_id = 0;
     750#endif
     751
     752  bool    sc_to_init_cmd_fifo_put   = false;
     753  bool    sc_to_init_cmd_fifo_get   = false;
     754  bool    sc_to_init_cmd_fifo_inst  = false;
     755  size_t  sc_to_init_cmd_fifo_srcid = 0;
    738756
    739757#if L1_MULTI_CACHE
    740     size_t  sc_to_init_cmd_fifo_cache_id = 0;
    741 #endif
    742 
    743 m_debug_global       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    744 m_debug_tgt_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    745 m_debug_tgt_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    746 m_debug_init_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    747 m_debug_init_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    748 m_debug_read_fsm     = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    749 m_debug_write_fsm    = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    750 m_debug_sc_fsm       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    751 m_debug_cleanup_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    752 m_debug_ixr_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    753 m_debug_ixr_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    754 m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
    755 
    756 
    757 #if DEBUG_MEMC_GLOBAL   
    758 if( m_debug_global )
    759 {
    760     std::cout << "---------------------------------------------" << std::dec << std::endl;
    761     std::cout << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
     758  size_t  sc_to_init_cmd_fifo_cache_id = 0;
     759#endif
     760
     761  m_debug_global       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     762  m_debug_tgt_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     763  m_debug_tgt_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     764  m_debug_init_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     765  m_debug_init_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     766  m_debug_read_fsm     = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     767  m_debug_write_fsm    = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     768  m_debug_sc_fsm       = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     769  m_debug_cleanup_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     770  m_debug_ixr_cmd_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     771  m_debug_ixr_rsp_fsm  = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     772  m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     773
     774#if DEBUG_MEMC_GLOBAL
     775  if( m_debug_global )
     776  {
     777    std::cout
     778      << "---------------------------------------------" << std::dec << std::endl
     779      << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
    762780      << " - TGT_CMD FSM    = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
    763781      << " - TGT_RSP FSM    = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
     
    775793      << " - ALLOC_UPT FSM  = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl
    776794      << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm] << std::endl;
    777 }
    778 #endif
    779 
    780     ////////////////////////////////////////////////////////////////////////////////////
    781     //          TGT_CMD FSM
    782     ////////////////////////////////////////////////////////////////////////////////////
    783     // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
    784     //
    785     // There is 3 types of accepted commands :
    786     // - READ    : a READ request has a length of 1 VCI cell. It can be a single word
    787     //             or an entire cache line, depending on the PLEN value.
    788     // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
    789     //             concern words in a same line.
    790     // - SC      : The SC request has a length of 2 cells or 4 cells.
    791     ////////////////////////////////////////////////////////////////////////////////////
    792 
    793     switch ( r_tgt_cmd_fsm.read() )
     795  }
     796#endif
     797
     798  ////////////////////////////////////////////////////////////////////////////////////
     799  //    TGT_CMD FSM
     800  ////////////////////////////////////////////////////////////////////////////////////
     801  // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
     802  //
     803  // There is 3 types of accepted commands :
     804  // - READ    : a READ request has a length of 1 VCI cell. It can be a single word
     805  //             or an entire cache line, depending on the PLEN value.
     806  // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
     807  //             concern words in a same line.
     808  // - SC      : The SC request has a length of 2 cells or 4 cells.
     809  ////////////////////////////////////////////////////////////////////////////////////
     810
     811  switch ( r_tgt_cmd_fsm.read() )
     812  {
     813    //////////////////
     814    case TGT_CMD_IDLE:
     815      if ( p_vci_tgt.cmdval )
     816      {
     817
     818#if DEBUG_MEMC_TGT_CMD
     819        if( m_debug_tgt_cmd_fsm )
     820        {
     821          std::cout
     822            << "  <MEMC " << name() << ".TGT_CMD_IDLE> Receive command from srcid "
     823            << std::dec << p_vci_tgt.srcid.read()
     824            << " / for address " << std::hex << p_vci_tgt.address.read() << std::endl;
     825        }
     826#endif
     827        // checking segmentation violation
     828        vci_addr_t  address = p_vci_tgt.address.read();
     829        uint32_t    plen    = p_vci_tgt.plen.read();
     830        bool found = false;
     831        for ( size_t seg_id = 0 ; seg_id < m_nseg ; seg_id++ )
     832        {
     833          if ( m_seg[seg_id]->contains(address) &&
     834              m_seg[seg_id]->contains(address + plen - vci_param::B) )
     835          {
     836            found = true;
     837          }
     838        }
     839        if ( not found )
     840        {
     841          std::cout << "VCI_MEM_CACHE ERROR " << name() << std::endl;
     842          std::cout
     843            << "Out of segment VCI address in TGT_CMD_IDLE state (address = "
     844            << std::hex << address << ", srcid = " << p_vci_tgt.srcid.read()
     845            << std::dec << ", cycle = " << m_cpt_cycles << ")" << std::endl;
     846          exit(0);
     847        }
     848
     849        if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ )
     850        {
     851          r_tgt_cmd_fsm = TGT_CMD_READ;
     852        }
     853        else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )
     854        {
     855          r_tgt_cmd_fsm = TGT_CMD_WRITE;
     856        }
     857        else if ( p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND )
     858        {
     859          r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
     860        }
     861        else
     862        {
     863          std::cout << "VCI_MEM_CACHE ERROR " << name()
     864            << " TGT_CMD_IDLE state" << std::endl;
     865          std::cout << " illegal VCI command type" << std::endl;
     866          exit(0);
     867        }
     868      }
     869      break;
     870
     871    //////////////////
     872    case TGT_CMD_READ:
     873      if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16)
     874      {
     875        std::cout
     876          << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     877          << std::endl;
     878        std::cout
     879          << " illegal address/plen combination for VCI read command" << std::endl;
     880        exit(0);
     881      }
     882      if ( !p_vci_tgt.eop.read() )
     883      {
     884        std::cout
     885          << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state"
     886          << std::endl;
     887        std::cout
     888          << " read command packets must contain one single flit"
     889          << std::endl;
     890        exit(0);
     891      }
     892
     893      if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() )
     894      {
     895
     896#if DEBUG_MEMC_TGT_CMD
     897        if( m_debug_tgt_cmd_fsm )
     898        {
     899          std::cout << "  <MEMC " << name() << ".TGT_CMD_READ> Push into read_fifo:"
     900            << " address = " << std::hex << p_vci_tgt.address.read()
     901            << " srcid = " << std::dec << p_vci_tgt.srcid.read()
     902            << " trdid = " << p_vci_tgt.trdid.read()
     903            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     904        }
     905#endif
     906        cmd_read_fifo_put = true;
     907        m_cpt_read++;
     908        r_tgt_cmd_fsm = TGT_CMD_IDLE;
     909      }
     910      break;
     911
     912    ///////////////////
     913    case TGT_CMD_WRITE:
     914      if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() )
     915      {
     916
     917#if DEBUG_MEMC_TGT_CMD
     918        if( m_debug_tgt_cmd_fsm )
     919        {
     920          std::cout << "  <MEMC " << name() << ".TGT_CMD_WRITE> Push into write_fifo:"
     921            << " address = " << std::hex << p_vci_tgt.address.read()
     922            << " srcid = " << std::dec << p_vci_tgt.srcid.read()
     923            << " trdid = " << p_vci_tgt.trdid.read()
     924            << " wdata = " << std::hex << p_vci_tgt.wdata.read()
     925            << " be = " << p_vci_tgt.be.read()
     926            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     927        }
     928#endif
     929        cmd_write_fifo_put = true;
     930        if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
     931      }
     932      break;
     933
     934    ////////////////////
     935    case TGT_CMD_ATOMIC:
     936      if ( (p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16) )
     937      {
     938        std::cout
     939          << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_ATOMIC state"
     940          << std::endl
     941          << "illegal format for sc command " << std::endl;
     942
     943        exit(0);
     944      }
     945
     946      if ( p_vci_tgt.cmdval && m_cmd_sc_addr_fifo.wok() )
     947      {
     948
     949#if DEBUG_MEMC_TGT_CMD
     950        if( m_debug_tgt_cmd_fsm )
     951        {
     952          std::cout << "  <MEMC " << name() << ".TGT_CMD_ATOMIC> Pushing command into cmd_sc_fifo:"
     953            << " address = " << std::hex << p_vci_tgt.address.read()
     954            << " srcid = " << std::dec << p_vci_tgt.srcid.read()
     955            << " trdid = " << p_vci_tgt.trdid.read()
     956            << " wdata = " << std::hex << p_vci_tgt.wdata.read()
     957            << " be = " << p_vci_tgt.be.read()
     958            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     959        }
     960#endif
     961        cmd_sc_fifo_put = true;
     962        if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE;
     963      }
     964      break;
     965  } // end switch tgt_cmd_fsm
     966
     967  /////////////////////////////////////////////////////////////////////////
     968  //    INIT_RSP FSM
     969  /////////////////////////////////////////////////////////////////////////
     970  // This FSM controls the response to the update or inval coherence
     971  // requests sent by the memory cache to the L1 caches and update the UPT.
     972  //
     973  // It can be update or inval requests initiated by the WRITE FSM,
     974  // or inval requests initiated by the XRAM_RSP FSM.
     975  // It can also be a direct request from the WRITE FSM.
     976  //
     977  // The FSM decrements the proper entry in UPT.
     978  // It sends a request to the TGT_RSP FSM to complete the pending
     979  // write transaction (acknowledge response to the writer processor),
     980  // and clear the UPT entry when all responses have been received.
     981  //
     982  // All those response packets are one word, compact
     983  // packets complying with the VCI advanced format.
     984  // The index in the Table is defined in the RTRDID field, and
     985  // the transaction type is defined in the UPT entry.
     986  /////////////////////////////////////////////////////////////////////
     987
     988  switch ( r_init_rsp_fsm.read() )
     989  {
     990    ///////////////////
     991    case INIT_RSP_IDLE:   // wait a response for a coherence transaction
     992      if ( p_vci_ini.rspval )
     993      {
     994
     995#if DEBUG_MEMC_INIT_RSP
     996        if( m_debug_init_rsp_fsm )
     997        {
     998          std::cout <<  "  <MEMC " << name() << ".INIT_RSP_IDLE> Response for UPT entry "
     999            << p_vci_ini.rtrdid.read() << std::endl;
     1000        }
     1001#endif
     1002        if ( p_vci_ini.rtrdid.read() >= m_update_tab.size() )
     1003        {
     1004          std::cout
     1005            << "VCI_MEM_CACHE ERROR " << name()
     1006            << " INIT_RSP_IDLE state" << std::endl
     1007            << "index too large for UPT: "
     1008            << " / rtrdid = " << std::dec << p_vci_ini.rtrdid.read()
     1009            << " / UPT size = " << std::dec << m_update_tab.size()
     1010            << std::endl;
     1011
     1012          exit(0);
     1013        }
     1014        if ( !p_vci_ini.reop.read() )
     1015        {
     1016          std::cout
     1017            << "VCI_MEM_CACHE ERROR " << name()
     1018            << " INIT_RSP_IDLE state" << std::endl
     1019            << "all coherence response packets must be one flit"
     1020            << std::endl;
     1021
     1022          exit(0);
     1023        }
     1024
     1025        r_init_rsp_upt_index = p_vci_ini.rtrdid.read();
     1026        r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
     1027      }
     1028      else if( r_write_to_init_rsp_req.read() )
     1029      {
     1030        r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read();
     1031        r_write_to_init_rsp_req = false;
     1032        r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
     1033      }
     1034      break;
     1035
     1036    ///////////////////////
     1037    case INIT_RSP_UPT_LOCK: // decrement the number of expected responses
     1038      if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
     1039      {
     1040        size_t count = 0;
     1041        bool valid   = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
     1042
     1043#if DEBUG_MEMC_INIT_RSP
     1044        if( m_debug_init_rsp_fsm )
     1045        {
     1046          std::cout << "  <MEMC " << name() << ".INIT_RSP_UPT_LOCK> Decrement the responses counter for UPT:"
     1047            << " entry = " << r_init_rsp_upt_index.read()
     1048            << " / rsp_count = " << std::dec << count << std::endl;
     1049        }
     1050#endif
     1051        if ( not valid )
     1052        {
     1053          std::cout << "VCI_MEM_CACHE ERROR " << name()
     1054            << " INIT_RSP_UPT_LOCK state" << std::endl
     1055            << "unsuccessful access to decrement the UPT" << std::endl;
     1056
     1057          exit(0);
     1058        }
     1059
     1060        if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
     1061        else              r_init_rsp_fsm = INIT_RSP_IDLE;
     1062      }
     1063      break;
     1064
     1065      ////////////////////////
     1066    case INIT_RSP_UPT_CLEAR:  // clear the UPT entry
     1067      if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
     1068      {
     1069        r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
     1070        r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
     1071        r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
     1072        r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
     1073        bool need_rsp    = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
     1074
     1075        if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
     1076        else            r_init_rsp_fsm = INIT_RSP_IDLE;
     1077
     1078        m_update_tab.clear(r_init_rsp_upt_index.read());
     1079
     1080#if DEBUG_MEMC_INIT_RSP
     1081        if ( m_debug_init_rsp_fsm )
     1082        {
     1083          std::cout <<  "  <MEMC " << name() << ".INIT_RSP_UPT_CLEAR> Clear UPT entry "
     1084            << r_init_rsp_upt_index.read() <<  std::endl;
     1085        }
     1086#endif
     1087      }
     1088      break;
     1089
     1090    //////////////////
     1091    case INIT_RSP_END:  // Post a request to TGT_RSP FSM
     1092      if ( !r_init_rsp_to_tgt_rsp_req )
     1093      {
     1094        r_init_rsp_to_tgt_rsp_req   = true;
     1095        r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
     1096        r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
     1097        r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
     1098        r_init_rsp_fsm = INIT_RSP_IDLE;
     1099
     1100#if DEBUG_MEMC_INIT_RSP
     1101        if ( m_debug_init_rsp_fsm )
     1102        {
     1103          std::cout
     1104            << "  <MEMC " << name()
     1105            << ".INIT_RSP_END> Request TGT_RSP FSM to send a response to srcid "
     1106            << r_init_rsp_srcid.read()
     1107            << std::endl;
     1108        }
     1109#endif
     1110      }
     1111      break;
     1112  } // end switch r_init_rsp_fsm
     1113
     1114  ////////////////////////////////////////////////////////////////////////////////////
     1115  //    READ FSM
     1116  ////////////////////////////////////////////////////////////////////////////////////
     1117  // The READ FSM controls the VCI read requests.
     1118  // It takes the lock protecting the cache directory to check the cache line status:
     1119  // - In case of HIT
     1120  //   The fsm copies the data (one line, or one single word)
     1121  //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
     1122  //   The requesting initiator is registered in the cache directory.
     1123  //   If the number of copy is larger than 1, the new copy is registered
     1124  //   in the HEAP.
     1125  //   If the number of copy is larger than the threshold, the HEAP is cleared,
     1126  //   and the corresponding line switches to the counter mode.
     1127  // - In case of MISS
     1128  //   The READ fsm takes the lock protecting the transaction tab.
     1129  //   If a read transaction to the XRAM for this line already exists,
     1130  //   or if the transaction tab is full, the fsm is stalled.
     1131  //   If a TRT entry is free, the READ request is registered in TRT,
     1132  //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
     1133  //   The READ FSM returns in the IDLE state as the read transaction will be
     1134  //   completed when the missing line will be received.
     1135  ////////////////////////////////////////////////////////////////////////////////////
     1136
     1137  switch ( r_read_fsm.read() )
     1138  {
     1139    ///////////////
     1140    case READ_IDLE:
     1141    // waiting a read request
    7941142    {
    795         //////////////////
    796         case TGT_CMD_IDLE:
    797         {
    798             if ( p_vci_tgt.cmdval )
    799             {
    800 
    801 #if DEBUG_MEMC_TGT_CMD
    802 if( m_debug_tgt_cmd_fsm )
    803 {
    804     std::cout << "  <MEMC " << name() << ".TGT_CMD_IDLE> Receive command from srcid " << std::dec << p_vci_tgt.srcid.read()
    805               << " / for address " << std::hex << p_vci_tgt.address.read() << std::endl;
    806 }
    807 #endif
    808                 // checking segmentation violation
    809                 vci_addr_t  address = p_vci_tgt.address.read();
    810                 uint32_t    plen    = p_vci_tgt.plen.read();
    811                 bool found = false;
    812                 for ( size_t seg_id = 0 ; seg_id < m_nseg ; seg_id++ )
    813                 {
    814                     if ( m_seg[seg_id]->contains(address) &&
    815                          m_seg[seg_id]->contains(address + plen - vci_param::B) )
    816                     {
    817                         found = true;
    818                     }
    819                 }
    820                 if ( not found )
    821                 {
    822                     std::cout << "VCI_MEM_CACHE ERROR " << name() << std::endl;
    823                     std::cout << "Out of segment VCI address in TGT_CMD_IDLE state (address = " << std::hex << address << ", srcid = " << p_vci_tgt.srcid.read() << std::dec << ", cycle = " << m_cpt_cycles << ")" << std::endl;
    824                     exit(0);
    825                 }
    826 
    827                 if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ )
    828                 {
    829                     r_tgt_cmd_fsm = TGT_CMD_READ;
    830                 }
    831                 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )
    832                 { 
    833                     r_tgt_cmd_fsm = TGT_CMD_WRITE;
    834                 }
    835                 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND )
    836                 {
    837                     r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
    838                 }
    839                 else
    840                 {
    841                     std::cout << "VCI_MEM_CACHE ERROR " << name()
    842                               << " TGT_CMD_IDLE state" << std::endl;
    843                     std::cout << " illegal VCI command type" << std::endl;
    844                     exit(0);
    845                 }
    846             }
    847             break;
    848         }
    849         //////////////////
    850         case TGT_CMD_READ:
    851         {
    852             if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16)
    853             {
    854                 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl;
    855                 std::cout << " illegal address/plen combination for VCI read command" << std::endl;
    856                 exit(0);
    857             }
    858             if ( !p_vci_tgt.eop.read() )
    859             {
    860                 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl;
    861                 std::cout << " read command packets must contain one single flit" << std::endl;
    862                 exit(0);
    863             }
    864 
    865             if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() )
    866             {
    867            
    868 #if DEBUG_MEMC_TGT_CMD
    869 if( m_debug_tgt_cmd_fsm )
    870 {
    871     std::cout << "  <MEMC " << name() << ".TGT_CMD_READ> Push into read_fifo:"
    872               << " address = " << std::hex << p_vci_tgt.address.read()
    873               << " srcid = " << std::dec << p_vci_tgt.srcid.read()
    874               << " trdid = " << p_vci_tgt.trdid.read()
    875               << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    876 }
    877 #endif
    878                 cmd_read_fifo_put = true;
    879                 m_cpt_read++;
    880                 r_tgt_cmd_fsm = TGT_CMD_IDLE;
    881             }
    882             break;
    883         }
    884         ///////////////////
    885         case TGT_CMD_WRITE:
    886         {
    887             if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() )
    888             {
    889            
    890 #if DEBUG_MEMC_TGT_CMD
    891 if( m_debug_tgt_cmd_fsm )
    892 {
    893     std::cout << "  <MEMC " << name() << ".TGT_CMD_WRITE> Push into write_fifo:"
    894               << " address = " << std::hex << p_vci_tgt.address.read()
    895               << " srcid = " << std::dec << p_vci_tgt.srcid.read()
    896               << " trdid = " << p_vci_tgt.trdid.read()
    897               << " wdata = " << std::hex << p_vci_tgt.wdata.read()
    898               << " be = " << p_vci_tgt.be.read()
    899               << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    900 }
    901 #endif
    902                 cmd_write_fifo_put = true;
    903                 if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
    904             }
    905             break;
    906         }
    907         ////////////////////
    908         case TGT_CMD_ATOMIC:
    909         {
    910             if ( (p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16) )
    911             {
    912                 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_ATOMIC state" << std::endl;
    913                 std::cout << "illegal format for sc command " << std::endl;
    914                 exit(0);
    915             }
    916 
    917             if ( p_vci_tgt.cmdval && m_cmd_sc_addr_fifo.wok() )
    918             {
    919            
    920 #if DEBUG_MEMC_TGT_CMD
    921 if( m_debug_tgt_cmd_fsm )
    922 {
    923     std::cout << "  <MEMC " << name() << ".TGT_CMD_ATOMIC> Pushing command into cmd_sc_fifo:"
    924               << " address = " << std::hex << p_vci_tgt.address.read()
    925               << " srcid = " << std::dec << p_vci_tgt.srcid.read()
    926               << " trdid = " << p_vci_tgt.trdid.read()
    927               << " wdata = " << std::hex << p_vci_tgt.wdata.read()
    928               << " be = " << p_vci_tgt.be.read()
    929               << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    930 }
    931 #endif
    932                 cmd_sc_fifo_put = true;
    933                 if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE;
    934             }
    935             break;
    936         }
    937     } // end switch tgt_cmd_fsm
    938 
    939     /////////////////////////////////////////////////////////////////////////
    940     //          INIT_RSP FSM
    941     /////////////////////////////////////////////////////////////////////////
    942     // This FSM controls the response to the update or inval coherence
    943     // requests sent by the memory cache to the L1 caches and update the UPT.
    944     //
    945     // It can be update or inval requests initiated by the WRITE FSM,
    946     // or inval requests initiated by the XRAM_RSP FSM. 
    947     // It can also be a direct request from the WRITE FSM.
    948     //
    949     // The FSM decrements the proper entry in UPT.
    950     // It sends a request to the TGT_RSP FSM to complete the pending
    951     // write transaction (acknowledge response to the writer processor),
    952     // and clear the UPT entry when all responses have been received. 
    953     //
    954     // All those response packets are one word, compact
    955     // packets complying with the VCI advanced format.
    956     // The index in the Table is defined in the RTRDID field, and
    957     // the transaction type is defined in the UPT entry.
    958     /////////////////////////////////////////////////////////////////////
    959 
    960     switch ( r_init_rsp_fsm.read() )
     1143      if (m_cmd_read_addr_fifo.rok())
     1144      {
     1145
     1146#if DEBUG_MEMC_READ
     1147        if( m_debug_read_fsm )
     1148        {
     1149          std::cout << "  <MEMC " << name() << ".READ_IDLE> Read request:"
     1150            << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
     1151            << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     1152            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     1153        }
     1154#endif
     1155        r_read_fsm = READ_DIR_REQ;
     1156      }
     1157      break;
     1158    }
     1159
     1160    ///////////////////
     1161    case READ_DIR_REQ:
     1162    // Get the lock to the directory
    9611163    {
    962         ///////////////////
    963         case INIT_RSP_IDLE:   // wait a response for a coherence transaction
    964         {
    965             if ( p_vci_ini.rspval )
    966             {
    967 
    968 #if DEBUG_MEMC_INIT_RSP
    969 if( m_debug_init_rsp_fsm )
    970 {
    971     std::cout <<  "  <MEMC " << name() << ".INIT_RSP_IDLE> Response for UPT entry "
    972               << p_vci_ini.rtrdid.read() << std::endl;
    973 }
    974 #endif
    975                 if ( p_vci_ini.rtrdid.read() >= m_update_tab.size() )
    976                 {
    977                     std::cout << "VCI_MEM_CACHE ERROR " << name()
    978                               << " INIT_RSP_IDLE state" << std::endl
    979                               << "index too large for UPT: "
    980                               << " / rtrdid = " << std::dec << p_vci_ini.rtrdid.read()
    981                               << " / UPT size = " << std::dec << m_update_tab.size() << std::endl;
    982                     exit(0);
    983                 }
    984                 if ( !p_vci_ini.reop.read() )
    985                 {
    986                     std::cout << "VCI_MEM_CACHE ERROR " << name()
    987                               << " INIT_RSP_IDLE state" << std::endl;
    988                     std::cout << "all coherence response packets must be one flit" << std::endl;
    989                     exit(0);
    990                 }
    991 
    992                 r_init_rsp_upt_index = p_vci_ini.rtrdid.read();
    993                 r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
    994             }
    995             else if( r_write_to_init_rsp_req.read() )
    996             {
    997                 r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read();
    998                 r_write_to_init_rsp_req = false;
    999                 r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
    1000             }
    1001             break;
    1002         }
    1003         ///////////////////////
    1004         case INIT_RSP_UPT_LOCK: // decrement the number of expected responses
    1005         {
    1006             if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
    1007             {
    1008                 size_t count = 0;
    1009                 bool valid  = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
    1010 
    1011 #if DEBUG_MEMC_INIT_RSP
    1012 if( m_debug_init_rsp_fsm )
    1013 {
    1014     std::cout << "  <MEMC " << name() << ".INIT_RSP_UPT_LOCK> Decrement the responses counter for UPT:"
    1015               << " entry = " << r_init_rsp_upt_index.read()
    1016               << " / rsp_count = " << std::dec << count << std::endl;
    1017 }
    1018 #endif
    1019                 if ( not valid )
    1020                 {
    1021                     std::cout << "VCI_MEM_CACHE ERROR " << name()
    1022                               << " INIT_RSP_UPT_LOCK state" << std::endl
    1023                               << "unsuccessful access to decrement the UPT" << std::endl;
    1024                     exit(0);
    1025                 }
    1026 
    1027                 if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
    1028                 else              r_init_rsp_fsm = INIT_RSP_IDLE;
    1029             }
    1030             break;
    1031         }
    1032         ////////////////////////
    1033         case INIT_RSP_UPT_CLEAR:        // clear the UPT entry
    1034         {
    1035             if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP )
    1036             {
    1037                 r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
    1038                 r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
    1039                 r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
    1040                 r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
    1041                 bool need_rsp    = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
    1042 
    1043                 if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
    1044                 else            r_init_rsp_fsm = INIT_RSP_IDLE;
    1045 
    1046                 m_update_tab.clear(r_init_rsp_upt_index.read());
    1047 
    1048 #if DEBUG_MEMC_INIT_RSP
    1049 if ( m_debug_init_rsp_fsm )
    1050 {
    1051     std::cout <<  "  <MEMC " << name() << ".INIT_RSP_UPT_CLEAR> Clear UPT entry "
    1052               << r_init_rsp_upt_index.read() <<  std::endl;
    1053 }
    1054 #endif
    1055             }
    1056             break;
    1057         }
    1058         //////////////////
    1059         case INIT_RSP_END:      // Post a request to TGT_RSP FSM
    1060         {
    1061             if ( !r_init_rsp_to_tgt_rsp_req )
    1062             {
    1063                 r_init_rsp_to_tgt_rsp_req   = true;
    1064                 r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
    1065                 r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
    1066                 r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
    1067                 r_init_rsp_fsm = INIT_RSP_IDLE;
    1068 
    1069 #if DEBUG_MEMC_INIT_RSP
    1070 if ( m_debug_init_rsp_fsm )
    1071 {
    1072     std::cout <<  "  <MEMC " << name() << ".INIT_RSP_END> Request TGT_RSP FSM to send a response to srcid "
    1073               << r_init_rsp_srcid.read() <<  std::endl;
    1074 }
    1075 #endif
    1076             }
    1077             break;
    1078         }
    1079     } // end switch r_init_rsp_fsm
    1080 
    1081     ////////////////////////////////////////////////////////////////////////////////////
    1082     //          READ FSM
    1083     ////////////////////////////////////////////////////////////////////////////////////
    1084     // The READ FSM controls the VCI read requests.
    1085     // It takes the lock protecting the cache directory to check the cache line status:
    1086     // - In case of HIT
    1087     //   The fsm copies the data (one line, or one single word)
    1088     //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
    1089     //   The requesting initiator is registered in the cache directory.
    1090     //   If the number of copy is larger than 1, the new copy is registered
    1091     //   in the HEAP.
    1092     //   If the number of copy is larger than the threshold, the HEAP is cleared,
    1093     //   and the corresponding line switches to the counter mode.
    1094     // - In case of MISS
    1095     //   The READ fsm takes the lock protecting the transaction tab.
    1096     //   If a read transaction to the XRAM for this line already exists,
    1097     //   or if the transaction tab is full, the fsm is stalled.
    1098     //   If a TRT entry is free, the READ request is registered in TRT,
    1099     //   it is consumed in the request FIFO, and transmited to the IXR_CMD FSM.
    1100     //   The READ FSM returns in the IDLE state as the read transaction will be
    1101     //   completed when the missing line will be received.
    1102     ////////////////////////////////////////////////////////////////////////////////////
    1103 
    1104     switch ( r_read_fsm.read() )
     1164      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
     1165      {
     1166        r_read_fsm = READ_DIR_LOCK;
     1167      }
     1168
     1169#if DEBUG_MEMC_READ
     1170      if( m_debug_read_fsm )
     1171      {
     1172        std::cout
     1173          << "  <MEMC " << name() << ".READ_DIR_REQ> Requesting DIR lock "
     1174          << std::endl;
     1175      }
     1176#endif
     1177      break;
     1178    }
     1179
     1180    ///////////////////
     1181    case READ_DIR_LOCK:
     1182    // check directory for hit / miss
    11051183    {
    1106         ///////////////
    1107         case READ_IDLE:         // waiting a read request
    1108         {
    1109             if (m_cmd_read_addr_fifo.rok())
    1110             {
     1184      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
     1185      {
     1186        size_t way = 0;
     1187        DirectoryEntry entry =
     1188          m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     1189
     1190        r_read_is_cnt     = entry.is_cnt;
     1191        r_read_dirty      = entry.dirty;
     1192        r_read_lock       = entry.lock;
     1193        r_read_tag        = entry.tag;
     1194        r_read_way        = way;
     1195        r_read_count      = entry.count;
     1196        r_read_copy       = entry.owner.srcid;
     1197
     1198#if L1_MULTI_CACHE
     1199        r_read_copy_cache = entry.owner.cache_id;
     1200#endif
     1201        r_read_copy_inst  = entry.owner.inst;
     1202        r_read_ptr        = entry.ptr; // pointer to the heap
     1203
     1204        bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
     1205        if(  entry.valid ) // hit
     1206        {
     1207          // test if we need to register a new copy in the heap
     1208          if ( entry.is_cnt || (entry.count == 0) || !cached_read )
     1209          {
     1210            r_read_fsm = READ_DIR_HIT;
     1211          }
     1212          else
     1213          {
     1214            r_read_fsm = READ_HEAP_REQ;
     1215          }
     1216        }
     1217        else      // miss
     1218        {
     1219          r_read_fsm = READ_TRT_LOCK;
     1220        }
    11111221
    11121222#if DEBUG_MEMC_READ
    1113 if( m_debug_read_fsm )
    1114 {
    1115     std::cout << "  <MEMC " << name() << ".READ_IDLE> Read request:"
    1116               << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
    1117               << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
    1118               << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    1119 }
    1120 #endif
    1121                 r_read_fsm = READ_DIR_LOCK;
    1122             }
    1123             break;
    1124         }
    1125         ///////////////////
    1126         case READ_DIR_LOCK:     // check directory for hit / miss
    1127         {
    1128             if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
    1129             {
    1130                 size_t way = 0;
    1131                 DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
    1132 
    1133                 r_read_is_cnt     = entry.is_cnt;
    1134                 r_read_dirty      = entry.dirty;
    1135                 r_read_lock           = entry.lock;
    1136                 r_read_tag            = entry.tag;
    1137                 r_read_way            = way;
    1138                 r_read_count      = entry.count;
    1139                 r_read_copy       = entry.owner.srcid;
    1140 
     1223        if( m_debug_read_fsm )
     1224        {
     1225          std::cout
     1226            << "  <MEMC " << name() << ".READ_DIR_LOCK> Accessing directory: "
     1227            << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     1228            << " / hit = " << std::dec << entry.valid
     1229            << " / count = " <<std::dec << entry.count
     1230            << " / is_cnt = " << entry.is_cnt << std::endl;
     1231        }
     1232#endif
     1233      }
     1234      else
     1235      {
     1236        std::cout
     1237          << "VCI_MEM_CACHE ERROR " << name()
     1238          << " READ_DIR_LOCK state" << std::endl
     1239          << "Bad DIR allocation"   << std::endl;
     1240
     1241        exit(0);
     1242      }
     1243      break;
     1244    }
     1245
     1246    //////////////////
     1247    case READ_DIR_HIT:
     1248    {
     1249      //  read data in cache & update the directory
     1250      //  we enter this state in 3 cases:
     1251      //  - the read request is uncachable
     1252      //  - the cache line is in counter mode
     1253      //  - the cache line is valid but not replcated
     1254
     1255      if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
     1256      {
     1257        // signals generation
     1258        bool inst_read    = (m_cmd_read_trdid_fifo.read() & 0x2);
     1259        bool cached_read  = (m_cmd_read_trdid_fifo.read() & 0x1);
     1260        bool is_cnt       = r_read_is_cnt.read();
     1261
     1262        // read data in the cache
     1263        size_t set        = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
     1264        size_t way        = r_read_way.read();
     1265        for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
     1266
     1267        // update the cache directory
     1268        DirectoryEntry entry;
     1269        entry.valid   = true;
     1270        entry.is_cnt  = is_cnt;
     1271        entry.dirty   = r_read_dirty.read();
     1272        entry.tag   = r_read_tag.read();
     1273        entry.lock    = r_read_lock.read();
     1274        entry.ptr     = r_read_ptr.read();
     1275        if (cached_read)  // Cached read => we must update the copies
     1276        {
     1277          if (!is_cnt) // Not counter mode
     1278          {
     1279            entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    11411280#if L1_MULTI_CACHE
    1142                 r_read_copy_cache = entry.owner.cache_id;
    1143 #endif
    1144                 r_read_copy_inst  = entry.owner.inst;
    1145                 r_read_ptr        = entry.ptr;              // pointer to the heap
    1146 
    1147                 bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
    1148                 if(  entry.valid )      // hit
    1149                 {
    1150                     // test if we need to register a new copy in the heap
    1151                     if ( entry.is_cnt || (entry.count == 0) || !cached_read )
    1152                         r_read_fsm = READ_DIR_HIT;
    1153                     else
    1154                         r_read_fsm = READ_HEAP_LOCK;
    1155                 }
    1156                 else                    // miss
    1157                 {
    1158                     r_read_fsm = READ_TRT_LOCK;
    1159                 }
     1281            entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
     1282#endif
     1283            entry.owner.inst     = inst_read;
     1284            entry.count          = r_read_count.read() + 1;
     1285          }
     1286          else  // Counter mode
     1287          {
     1288            entry.owner.srcid    = 0;
     1289#if L1_MULTI_CACHE
     1290            entry.owner.cache_id = 0;
     1291#endif
     1292            entry.owner.inst     = false;
     1293            entry.count          = r_read_count.read() + 1;
     1294          }
     1295        }
     1296        else  // Uncached read
     1297        {
     1298          entry.owner.srcid     = r_read_copy.read();
     1299#if L1_MULTI_CACHE
     1300          entry.owner.cache_id  = r_read_copy_cache.read();
     1301#endif
     1302          entry.owner.inst      = r_read_copy_inst.read();
     1303          entry.count           = r_read_count.read();
     1304        }
    11601305
    11611306#if DEBUG_MEMC_READ
    1162 if( m_debug_read_fsm )
    1163 {
    1164     std::cout << "  <MEMC " << name() << ".READ_DIR_LOCK> Accessing directory: "
    1165               << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    1166               << " / hit = " << std::dec << entry.valid
    1167               << " / count = " <<std::dec << entry.count
    1168               << " / is_cnt = " << entry.is_cnt << std::endl;
    1169 }
    1170 #endif
    1171             }
    1172             break;
    1173         }
    1174         //////////////////
    1175         case READ_DIR_HIT:          //  read data in cache & update the directory
    1176                                 //  we enter this state in 3 cases:
    1177                                 //  - the read request is uncachable
    1178                                 //  - the cache line is in counter mode
    1179                                 //  - the cache line is valid but not replcated
    1180         {
    1181             if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ )
    1182             {
    1183                 // signals generation
    1184                 bool inst_read    = (m_cmd_read_trdid_fifo.read() & 0x2);
    1185                 bool cached_read  = (m_cmd_read_trdid_fifo.read() & 0x1);
    1186                 bool is_cnt       = r_read_is_cnt.read();
    1187 
    1188                 // read data in the cache
    1189                 size_t set        = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
    1190                 size_t way        = r_read_way.read();
    1191                 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
    1192 
    1193                 // update the cache directory
    1194                 DirectoryEntry entry;
    1195                 entry.valid       = true;
    1196                 entry.is_cnt  = is_cnt;
    1197                 entry.dirty       = r_read_dirty.read();
    1198                 entry.tag         = r_read_tag.read();
    1199                 entry.lock        = r_read_lock.read();
    1200                 entry.ptr     = r_read_ptr.read();
    1201                 if (cached_read)  // Cached read => we must update the copies
    1202                 {
    1203                     if (!is_cnt) // Not counter mode
    1204                     {
    1205                         entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     1307        if( m_debug_read_fsm )
     1308        {
     1309          std::cout
     1310            << "  <MEMC " << name() << ".READ_DIR_HIT> Update directory entry:"
     1311            << " set = " << std::dec << set
     1312            << " / way = " << way
     1313            << " / owner_id = " << entry.owner.srcid
     1314            << " / owner_ins = " << entry.owner.inst
     1315            << " / count = " << entry.count
     1316            << " / is_cnt = " << entry.is_cnt << std::endl;
     1317        }
     1318#endif
     1319
     1320        m_cache_directory.write(set, way, entry);
     1321        r_read_fsm    = READ_RSP;
     1322      }
     1323      break;
     1324    }
     1325
     1326    ////////////////////
     1327    case READ_HEAP_REQ:
     1328    // Get the lock to the HEAP directory
     1329    {
     1330      if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
     1331      {
     1332        r_read_fsm = READ_HEAP_LOCK;
     1333      }
     1334
     1335#if DEBUG_MEMC_READ
     1336      if( m_debug_read_fsm )
     1337      {
     1338        std::cout
     1339          << "  <MEMC " << name() << ".READ_HEAP_REQ> Requesting HEAP lock "
     1340          << std::endl;
     1341      }
     1342#endif
     1343      break;
     1344    }
     1345
     1346    ////////////////////
     1347    case READ_HEAP_LOCK:
     1348    // read data in cache, update the directory
     1349    // and prepare the HEAP update
     1350    {
     1351      if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
     1352      {
     1353        // enter counter mode when we reach the limit of copies or the heap is full
     1354        bool go_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap.is_full();
     1355
     1356        // read data in the cache
     1357        size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
     1358        size_t way = r_read_way.read();
     1359        for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
     1360
     1361        // update the cache directory
     1362        DirectoryEntry entry;
     1363        entry.valid  = true;
     1364        entry.is_cnt = go_cnt;
     1365        entry.dirty  = r_read_dirty.read();
     1366        entry.tag    = r_read_tag.read();
     1367        entry.lock   = r_read_lock.read();
     1368        entry.count  = r_read_count.read() + 1;
     1369
     1370        if (not go_cnt)        // Not entering counter mode
     1371        {
     1372          entry.owner.srcid    = r_read_copy.read();
    12061373#if L1_MULTI_CACHE
    1207                         entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    1208 #endif
    1209                         entry.owner.inst     = inst_read;
    1210                         entry.count          = r_read_count.read() + 1;
    1211                     }
    1212                     else  // Counter mode
    1213                     {
    1214                         entry.owner.srcid    = 0;
     1374          entry.owner.cache_id = r_read_copy_cache.read();
     1375#endif
     1376          entry.owner.inst     = r_read_copy_inst.read();
     1377          entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
     1378        }
     1379        else                // Entering Counter mode
     1380        {
     1381          entry.owner.srcid    = 0;
    12151382#if L1_MULTI_CACHE
    1216                         entry.owner.cache_id = 0;
    1217 #endif
    1218                         entry.owner.inst     = false;
    1219                         entry.count          = r_read_count.read() + 1;
    1220                     }
    1221                 }
    1222                 else  // Uncached read
    1223                 {
    1224                     entry.owner.srcid     = r_read_copy.read();
     1383          entry.owner.cache_id = 0;
     1384#endif
     1385          entry.owner.inst     = false;
     1386          entry.ptr            = 0;
     1387        }
     1388
     1389        m_cache_directory.write(set, way, entry);
     1390
     1391        // prepare the heap update (add an entry, or clear the linked list)
     1392        if (not go_cnt)     // not switching to counter mode
     1393        {
     1394          // We test if the next free entry in the heap is the last
     1395          HeapEntry heap_entry = m_heap.next_free_entry();
     1396          r_read_next_ptr      = heap_entry.next;
     1397          r_read_last_free     = ( heap_entry.next == m_heap.next_free_ptr() );
     1398
     1399          r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
     1400        }
     1401        else            // switching to counter mode
     1402        {
     1403          if ( r_read_count.read()>1 )            // heap must be cleared
     1404          {
     1405            HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     1406            r_read_next_ptr      = m_heap.next_free_ptr();
     1407            m_heap.write_free_ptr(r_read_ptr.read());
     1408
     1409            if( next_entry.next == r_read_ptr.read() )  // last entry
     1410            {
     1411              r_read_fsm = READ_HEAP_LAST;    // erase the entry
     1412            }
     1413            else                                        // not the last entry
     1414            {
     1415              r_read_ptr = next_entry.next;
     1416              r_read_fsm = READ_HEAP_ERASE;   // erase the list
     1417            }
     1418          }
     1419          else  // the heap is not used / nothing to do
     1420          {
     1421            r_read_fsm = READ_RSP;
     1422          }
     1423        }
     1424
     1425#if DEBUG_MEMC_READ
     1426        if( m_debug_read_fsm )
     1427        {
     1428          std::cout << "  <MEMC " << name() << ".READ_HEAP_LOCK> Update directory:"
     1429            << " tag = " << std::hex << entry.tag
     1430            << " set = " << std::dec << set
     1431            << " way = " << way
     1432            << " count = " << entry.count
     1433            << " is_cnt = " << entry.is_cnt << std::endl;
     1434        }
     1435#endif
     1436      }
     1437      else
     1438      {
     1439        std::cout
     1440          << "VCI_MEM_CACHE ERROR " << name()
     1441          << " READ_HEAP_LOCK state" << std::endl
     1442          << "Bad HEAP allocation"   << std::endl;
     1443
     1444        exit(0);
     1445      }
     1446
     1447      break;
     1448    }
     1449
     1450    /////////////////////
     1451    case READ_HEAP_WRITE:       // add a entry in the heap
     1452    {
     1453      if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
     1454      {
     1455        HeapEntry heap_entry;
     1456        heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    12251457#if L1_MULTI_CACHE
    1226                     entry.owner.cache_id  = r_read_copy_cache.read();
    1227 #endif
    1228                     entry.owner.inst      = r_read_copy_inst.read();
    1229                     entry.count           = r_read_count.read();
    1230                 }
     1458        heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
     1459#endif
     1460        heap_entry.owner.inst     = (m_cmd_read_trdid_fifo.read() & 0x2);
     1461
     1462        if(r_read_count.read() == 1) // creation of a new linked list
     1463        {
     1464          heap_entry.next         = m_heap.next_free_ptr();
     1465        }
     1466        else                         // head insertion in existing list
     1467        {
     1468          heap_entry.next         = r_read_ptr.read();
     1469        }
     1470        m_heap.write_free_entry(heap_entry);
     1471        m_heap.write_free_ptr(r_read_next_ptr.read());
     1472        if(r_read_last_free.read())  m_heap.set_full();
     1473
     1474        r_read_fsm = READ_RSP;
    12311475
    12321476#if DEBUG_MEMC_READ
    1233 if( m_debug_read_fsm )
    1234 {
    1235     std::cout << "  <MEMC " << name() << ".READ_DIR_HIT> Update directory entry:"
    1236               << " set = " << std::dec << set
    1237               << " / way = " << way
    1238               << " / owner_id = " << entry.owner.srcid
    1239               << " / owner_ins = " << entry.owner.inst
    1240               << " / count = " << entry.count
    1241               << " / is_cnt = " << entry.is_cnt << std::endl;
    1242 }
    1243 #endif
    1244 
    1245                 m_cache_directory.write(set, way, entry);
    1246                 r_read_fsm    = READ_RSP;
    1247             }
    1248             break;
    1249         }
    1250         ////////////////////
    1251         case READ_HEAP_LOCK:    // read data in cache, update the directory
    1252                                 // and prepare the HEAP update       
    1253         {
    1254             if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
    1255             {
    1256                 // enter counter mode when we reach the limit of copies or the heap is full
    1257                 bool go_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap.is_full();
    1258 
    1259                 // read data in the cache
    1260                 size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
    1261                 size_t way = r_read_way.read();
    1262                 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i];
    1263 
    1264                 // update the cache directory
    1265                 DirectoryEntry entry;
    1266                 entry.valid       = true;
    1267                 entry.is_cnt  = go_cnt;
    1268                 entry.dirty       = r_read_dirty.read();
    1269                 entry.tag         = r_read_tag.read();
    1270                 entry.lock        = r_read_lock.read();
    1271                 entry.count   = r_read_count.read() + 1;
    1272 
    1273                 if (not go_cnt)        // Not entering counter mode
    1274                 {
    1275                     entry.owner.srcid   = r_read_copy.read();
     1477        if( m_debug_read_fsm )
     1478        {
     1479          std::cout
     1480            << "  <MEMC " << name() << ".READ_HEAP_WRITE> Add an entry in the heap:"
     1481            << " owner_id = " << heap_entry.owner.srcid
     1482            << " owner_ins = " << heap_entry.owner.inst << std::endl;
     1483        }
     1484#endif
     1485      }
     1486      else
     1487      {
     1488        std::cout
     1489          << "VCI_MEM_CACHE ERROR " << name()
     1490          << " READ_HEAP_WRITE state" << std::endl
     1491          << "Bad HEAP allocation" << std::endl;
     1492
     1493        exit(0);
     1494      }
     1495      break;
     1496    }
     1497
     1498    /////////////////////
     1499    case READ_HEAP_ERASE:
     1500    {
     1501      if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
     1502      {
     1503        HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     1504        if( next_entry.next == r_read_ptr.read() )
     1505        {
     1506          r_read_fsm = READ_HEAP_LAST;
     1507        }
     1508        else
     1509        {
     1510          r_read_ptr = next_entry.next;
     1511          r_read_fsm = READ_HEAP_ERASE;
     1512        }
     1513      }
     1514      else
     1515      {
     1516        std::cout
     1517          << "VCI_MEM_CACHE ERROR " << name()
     1518          << " READ_HEAP_ERASE state" << std::endl
     1519          << "Bad HEAP allocation" << std::endl;
     1520
     1521        exit(0);
     1522      }
     1523      break;
     1524    }
     1525
     1526    ////////////////////
     1527    case READ_HEAP_LAST:
     1528    {
     1529      if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
     1530      {
     1531        HeapEntry last_entry;
     1532        last_entry.owner.srcid    = 0;
    12761533#if L1_MULTI_CACHE
    1277                     entry.owner.cache_id= r_read_copy_cache.read();
    1278 #endif
    1279                     entry.owner.inst    = r_read_copy_inst.read();
    1280                     entry.ptr           = m_heap.next_free_ptr();   // set pointer on the heap
    1281                 }
    1282                 else                // Entering Counter mode
    1283                 {
    1284                     entry.owner.srcid   = 0;
     1534        last_entry.owner.cache_id = 0;
     1535#endif
     1536        last_entry.owner.inst     = false;
     1537
     1538        if(m_heap.is_full())
     1539        {
     1540          last_entry.next       = r_read_ptr.read();
     1541          m_heap.unset_full();
     1542        }
     1543        else
     1544        {
     1545          last_entry.next       = r_read_next_ptr.read();
     1546        }
     1547        m_heap.write(r_read_ptr.read(),last_entry);
     1548        r_read_fsm = READ_RSP;
     1549      }
     1550      else
     1551      {
     1552        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1553          << " READ_HEAP_LAST state" << std::endl;
     1554        std::cout << "Bad HEAP allocation" << std::endl;
     1555        exit(0);
     1556      }
     1557      break;
     1558    }
     1559
     1560    //////////////
     1561    case READ_RSP:    //  request the TGT_RSP FSM to return data
     1562    {
     1563      if( !r_read_to_tgt_rsp_req )
     1564      {
     1565        for ( size_t i=0 ; i<m_words ; i++ )  r_read_to_tgt_rsp_data[i] = r_read_data[i];
     1566        r_read_to_tgt_rsp_word   = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()];
     1567        r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     1568        r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     1569        r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     1570        r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
     1571        cmd_read_fifo_get    = true;
     1572        r_read_to_tgt_rsp_req  = true;
     1573        r_read_fsm     = READ_IDLE;
     1574
     1575#if DEBUG_MEMC_READ
     1576        if( m_debug_read_fsm )
     1577        {
     1578          std::cout << "  <MEMC " << name() << ".READ_RSP> Request the TGT_RSP FSM to return data:"
     1579            << " rsrcid = " << std::dec << m_cmd_read_srcid_fifo.read()
     1580            << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     1581            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     1582        }
     1583#endif
     1584      }
     1585      break;
     1586    }
     1587
     1588    ///////////////////
     1589    case READ_TRT_LOCK: // read miss : check the Transaction Table
     1590    {
     1591      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
     1592      {
     1593        size_t      index     = 0;
     1594        vci_addr_t  addr      = (vci_addr_t)m_cmd_read_addr_fifo.read();
     1595        bool        hit_read  = m_transaction_tab.hit_read(m_nline[addr], index);
     1596        bool        hit_write = m_transaction_tab.hit_write(m_nline[addr]);
     1597        bool        wok       = !m_transaction_tab.full(index);
     1598
     1599        if( hit_read || !wok || hit_write )  // missing line already requested or no space
     1600        {
     1601          if(!wok)      m_cpt_trt_full++;
     1602          if(hit_read || hit_write)   m_cpt_trt_rb++;
     1603          r_read_fsm = READ_IDLE;
     1604        }
     1605        else                  // missing line is requested to the XRAM
     1606        {
     1607          m_cpt_read_miss++;
     1608          r_read_trt_index = index;
     1609          r_read_fsm       = READ_TRT_SET;
     1610        }
     1611
     1612#if DEBUG_MEMC_READ
     1613        if( m_debug_read_fsm )
     1614        {
     1615          std::cout << "  <MEMC " << name() << ".READ_TRT_LOCK> Check TRT:"
     1616            << " hit_read = " << hit_read
     1617            << " / hit_write = " << hit_write
     1618            << " / full = " << !wok << std::endl;
     1619        }
     1620#endif
     1621      }
     1622      break;
     1623    }
     1624
     1625    //////////////////
     1626    case READ_TRT_SET:      // register get transaction in TRT
     1627    {
     1628      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
     1629      {
     1630        m_transaction_tab.set(r_read_trt_index.read(),
     1631            true,
     1632            m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
     1633            m_cmd_read_srcid_fifo.read(),
     1634            m_cmd_read_trdid_fifo.read(),
     1635            m_cmd_read_pktid_fifo.read(),
     1636            true,
     1637            m_cmd_read_length_fifo.read(),
     1638            m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
     1639            std::vector<be_t>(m_words,0),
     1640            std::vector<data_t>(m_words,0));
     1641#if DEBUG_MEMC_READ
     1642        if( m_debug_read_fsm )
     1643        {
     1644          std::cout << "  <MEMC " << name() << ".READ_TRT_SET> Write in Transaction Table: " << std::hex
     1645            << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     1646            << " / srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
     1647            << std::endl;
     1648        }
     1649#endif
     1650        r_read_fsm = READ_TRT_REQ;
     1651      }
     1652      break;
     1653    }
     1654
     1655    //////////////////
     1656    case READ_TRT_REQ:
     1657    {
     1658      // consume the read request in the FIFO,
     1659      // and send it to the ixr_cmd_fsm
     1660
     1661      if( not r_read_to_ixr_cmd_req )
     1662      {
     1663        cmd_read_fifo_get       = true;
     1664        r_read_to_ixr_cmd_req   = true;
     1665        r_read_to_ixr_cmd_nline = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
     1666        r_read_to_ixr_cmd_trdid = r_read_trt_index.read();
     1667        r_read_fsm              = READ_IDLE;
     1668
     1669#if DEBUG_MEMC_READ
     1670        if( m_debug_read_fsm )
     1671        {
     1672          std::cout
     1673            << "  <MEMC " << name() << ".READ_TRT_REQ> Request GET transaction for address "
     1674            << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
     1675        }
     1676#endif
     1677      }
     1678      break;
     1679    }
     1680  } // end switch read_fsm
     1681
     1682  ///////////////////////////////////////////////////////////////////////////////////
     1683  //    WRITE FSM
     1684  ///////////////////////////////////////////////////////////////////////////////////
     1685  // The WRITE FSM handles the write bursts sent by the processors.
     1686  // All addresses in a burst must be in the same cache line.
     1687  // A complete write burst is consumed in the FIFO & copied to a local buffer.
     1688  // Then the FSM takes the lock protecting the cache directory, to check
     1689  // if the line is in the cache.
     1690  //
     1691  // - In case of HIT, the cache is updated.
     1692  //   If there is no other copy, an acknowledge response is immediately
     1693  //   returned to the writing processor.
     1694  //   If the data is cached by other processors, a coherence transaction must
     1695  //   be launched:
     1696  //   It is a multicast update if the line is not in counter mode, and the processor
     1697  //   takes the lock protecting the Update Table (UPT) to register this transaction.
     1698  //   It is a broadcast invalidate if the line is in counter mode.
     1699  //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
     1700  //   a multi-update request to all owners of the line (but the writer),
     1701  //   through the INIT_CMD FSM. In case of coherence transaction, the WRITE FSM
     1702  //   does not respond to the writing processor, as this response will be sent by
     1703  //   the INIT_RSP FSM when all update responses have been received.
     1704  //
     1705  // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
     1706  //   table (TRT). If a read transaction to the XRAM for this line already exists,
     1707  //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
     1708  //   the WRITE FSM register a new transaction in TRT, and sends a read line request
     1709  //   to the XRAM. If the TRT is full, it releases the lock, and waits.
     1710  //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
     1711  /////////////////////////////////////////////////////////////////////////////////////
     1712
     1713  switch ( r_write_fsm.read() )
     1714  {
     1715    ////////////////
     1716    case WRITE_IDLE:  // copy first word of a write burst in local buffer
     1717    {
     1718      if ( m_cmd_write_addr_fifo.rok() )
     1719      {
     1720        m_cpt_write++;
     1721        m_cpt_write_cells++;
     1722
     1723        // consume a word in the FIFO & write it in the local buffer
     1724        cmd_write_fifo_get  = true;
     1725        size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
     1726
     1727        r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     1728        r_write_word_index  = index;
     1729        r_write_word_count  = 1;
     1730        r_write_data[index] = m_cmd_write_data_fifo.read();
     1731        r_write_srcid       = m_cmd_write_srcid_fifo.read();
     1732        r_write_trdid       = m_cmd_write_trdid_fifo.read();
     1733        r_write_pktid       = m_cmd_write_pktid_fifo.read();
     1734
     1735        // initialize the be field for all words
     1736        for ( size_t i=0 ; i<m_words ; i++ )
     1737        {
     1738          if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
     1739          else              r_write_be[i] = 0x0;
     1740        }
     1741
     1742        if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
     1743          r_write_byte = true;
     1744        else
     1745          r_write_byte = false;
     1746
     1747        if( m_cmd_write_eop_fifo.read() )
     1748        {
     1749          r_write_fsm = WRITE_DIR_REQ;
     1750        }
     1751        else
     1752        {
     1753          r_write_fsm = WRITE_NEXT;
     1754        }
     1755
     1756#if DEBUG_MEMC_WRITE
     1757        if( m_debug_write_fsm )
     1758        {
     1759          std::cout << "  <MEMC " << name() << ".WRITE_IDLE> Write request "
     1760            << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read()
     1761            << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
     1762            << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
     1763        }
     1764#endif
     1765      }
     1766      break;
     1767    }
     1768
     1769    ////////////////
     1770    case WRITE_NEXT:  // copy next word of a write burst in local buffer
     1771    {
     1772      if ( m_cmd_write_addr_fifo.rok() )
     1773      {
     1774
     1775#if DEBUG_MEMC_WRITE
     1776        if( m_debug_write_fsm )
     1777        {
     1778          std::cout << "  <MEMC " << name() << ".WRITE_NEXT> Write another word in local buffer"
     1779                    << std::endl;
     1780        }
     1781#endif
     1782        m_cpt_write_cells++;
     1783
     1784        // check that the next word is in the same cache line
     1785        if (( m_nline[(vci_addr_t)(r_write_address.read())]       !=
     1786              m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())] ))
     1787        {
     1788          std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl
     1789                    << "all words in a write burst must be in same cache line" << std::endl;
     1790
     1791          exit(0);
     1792        }
     1793
     1794        // consume a word in the FIFO & write it in the local buffer
     1795        cmd_write_fifo_get  = true;
     1796        size_t index        = r_write_word_index.read() + r_write_word_count.read();
     1797
     1798        r_write_be[index]   = m_cmd_write_be_fifo.read();
     1799        r_write_data[index] = m_cmd_write_data_fifo.read();
     1800        r_write_word_count  = r_write_word_count.read() + 1;
     1801
     1802        if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
     1803          r_write_byte = true;
     1804
     1805        if ( m_cmd_write_eop_fifo.read() )
     1806        {
     1807          r_write_fsm = WRITE_DIR_REQ;
     1808        }
     1809      }
     1810      break;
     1811    }
     1812
     1813    ////////////////////
     1814    case WRITE_DIR_REQ:
     1815    // Get the lock to the directory
     1816    {
     1817      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
     1818      {
     1819        r_write_fsm = WRITE_DIR_LOCK;
     1820      }
     1821
     1822#if DEBUG_MEMC_WRITE
     1823      if( m_debug_write_fsm )
     1824      {
     1825        std::cout
     1826          << "  <MEMC " << name() << ".WRITE_DIR_REQ> Requesting DIR lock "
     1827          << std::endl;
     1828      }
     1829#endif
     1830
     1831      break;
     1832    }
     1833
     1834    ////////////////////
     1835    case WRITE_DIR_LOCK:
     1836    // access directory to check hit/miss
     1837    {
     1838      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
     1839      {
     1840        size_t  way = 0;
     1841        DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
     1842
     1843        if ( entry.valid ) // hit
     1844        {
     1845          // copy directory entry in local buffer in case of hit
     1846          r_write_is_cnt     = entry.is_cnt;
     1847          r_write_lock       = entry.lock;
     1848          r_write_tag        = entry.tag;
     1849          r_write_copy       = entry.owner.srcid;
    12851850#if L1_MULTI_CACHE
    1286                     entry.owner.cache_id= 0;
    1287 #endif
    1288                     entry.owner.inst    = false;
    1289                     entry.ptr           = 0;
    1290                 }
    1291 
    1292                 m_cache_directory.write(set, way, entry);
    1293 
    1294                 // prepare the heap update (add an entry, or clear the linked list)
    1295                 if (not go_cnt)     // not switching to counter mode
    1296                 {
    1297                     // We test if the next free entry in the heap is the last
    1298                     HeapEntry heap_entry = m_heap.next_free_entry();
    1299                     r_read_next_ptr      = heap_entry.next;
    1300                     r_read_last_free     = ( heap_entry.next == m_heap.next_free_ptr() );
    1301 
    1302                     r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
    1303                 }
    1304                 else                    // switching to counter mode
    1305                 {
    1306                     if ( r_read_count.read()>1 )            // heap must be cleared
    1307                     {
    1308                         HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    1309                         r_read_next_ptr      = m_heap.next_free_ptr();
    1310                         m_heap.write_free_ptr(r_read_ptr.read());
    1311 
    1312                         if( next_entry.next == r_read_ptr.read() )  // last entry
    1313                         {
    1314                             r_read_fsm = READ_HEAP_LAST;    // erase the entry
    1315                         }
    1316                         else                                        // not the last entry
    1317                         {
    1318                             r_read_ptr = next_entry.next;
    1319                             r_read_fsm = READ_HEAP_ERASE;   // erase the list
    1320                         }
    1321                     }
    1322                     else        // the heap is not used / nothing to do
    1323                     {
    1324                         r_read_fsm = READ_RSP;
    1325                     }
    1326                 }
    1327 
    1328 #if DEBUG_MEMC_READ
    1329 if( m_debug_read_fsm )
    1330 {
    1331     std::cout << "  <MEMC " << name() << ".READ_HEAP_LOCK> Update directory:"
    1332               << " tag = " << std::hex << entry.tag
    1333               << " set = " << std::dec << set
    1334               << " way = " << way
    1335               << " count = " << entry.count
    1336               << " is_cnt = " << entry.is_cnt << std::endl;
    1337 }
    1338 #endif
    1339             }
    1340             break;
    1341         }
    1342         /////////////////////
    1343         case READ_HEAP_WRITE:       // add a entry in the heap
    1344         {
    1345             if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
    1346             {
    1347                 HeapEntry heap_entry;
    1348                 heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     1851          r_write_copy_cache = entry.owner.cache_id;
     1852#endif
     1853          r_write_copy_inst  = entry.owner.inst;
     1854          r_write_count      = entry.count;
     1855          r_write_ptr        = entry.ptr;
     1856          r_write_way        = way;
     1857
     1858          if( entry.is_cnt && entry.count )
     1859          {
     1860            r_write_fsm = WRITE_DIR_READ;
     1861          }
     1862          else
     1863          {
     1864            if (r_write_byte.read())
     1865            {
     1866              r_write_fsm = WRITE_DIR_READ;
     1867            }
     1868            else
     1869            {
     1870              r_write_fsm = WRITE_DIR_HIT;
     1871            }
     1872          }
     1873        }
     1874        else  // miss
     1875        {
     1876          r_write_fsm = WRITE_MISS_TRT_LOCK;
     1877        }
     1878
     1879#if DEBUG_MEMC_WRITE
     1880        if( m_debug_write_fsm )
     1881        {
     1882          std::cout << "  <MEMC " << name() << ".WRITE_DIR_LOCK> Check the directory: "
     1883            << " address = " << std::hex << r_write_address.read()
     1884            << " hit = " << std::dec << entry.valid
     1885            << " count = " << entry.count
     1886            << " is_cnt = " << entry.is_cnt << std::endl;
     1887        }
     1888#endif
     1889      }
     1890      else
     1891      {
     1892        std::cout << "VCI_MEM_CACHE ERROR " << name()
     1893          << " WRITE_DIR_LOCK state"        << std::endl
     1894          << "bad DIR allocation"           << std::endl;
     1895
     1896        exit(0);
     1897      }
     1898
     1899      break;
     1900    }
     1901
     1902    ////////////////////
     1903    case WRITE_DIR_READ:  // read the cache and complete the buffer when be!=0xF
     1904    {
     1905      // update local buffer
     1906      size_t set  = m_y[(vci_addr_t)(r_write_address.read())];
     1907      size_t way  = r_write_way.read();
     1908      for(size_t i=0 ; i<m_words ; i++)
     1909      {
     1910        data_t mask = 0;
     1911        if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
     1912        if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
     1913        if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
     1914        if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
     1915
     1916        // complete only if mask is not null (for energy consumption)
     1917        if ( r_write_be[i].read() || r_write_is_cnt.read() )
     1918        {
     1919          r_write_data[i]  = (r_write_data[i].read() & mask) |
     1920            (m_cache_data[way][set][i] & ~mask);
     1921        }
     1922      } // end for
     1923
     1924      // test if a coherence broadcast is required
     1925      if( r_write_is_cnt.read() && r_write_count.read() )
     1926      {
     1927        r_write_fsm = WRITE_BC_TRT_LOCK;
     1928      }
     1929      else
     1930      {
     1931        r_write_fsm = WRITE_DIR_HIT;
     1932      }
     1933
     1934#if DEBUG_MEMC_WRITE
     1935      if( m_debug_write_fsm )
     1936      {
     1937        std::cout << "  <MEMC " << name() << ".WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl;
     1938      }
     1939#endif
     1940      break;
     1941    }
     1942
     1943    ///////////////////
     1944    case WRITE_DIR_HIT:
     1945    {
     1946      // update the cache directory
     1947      // update directory with Dirty bit
     1948      DirectoryEntry entry;
     1949      entry.valid          = true;
     1950      entry.dirty          = true;
     1951      entry.tag          = r_write_tag.read();
     1952      entry.is_cnt         = r_write_is_cnt.read();
     1953      entry.lock           = r_write_lock.read();
     1954      entry.owner.srcid    = r_write_copy.read();
    13491955#if L1_MULTI_CACHE
    1350                 heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    1351 #endif
    1352                 heap_entry.owner.inst     = (m_cmd_read_trdid_fifo.read() & 0x2);
    1353 
    1354                 if(r_read_count.read() == 1)    // creation of a new linked list
    1355                 {
    1356                     heap_entry.next         = m_heap.next_free_ptr();
    1357                 }
    1358                 else                            // head insertion in existing list
    1359                 {
    1360                     heap_entry.next         = r_read_ptr.read();
    1361                 }
    1362                 m_heap.write_free_entry(heap_entry);
    1363                 m_heap.write_free_ptr(r_read_next_ptr.read());
    1364                 if(r_read_last_free.read())  m_heap.set_full();
    1365 
    1366                 r_read_fsm = READ_RSP;
    1367 
    1368 #if DEBUG_MEMC_READ
    1369 if( m_debug_read_fsm )
    1370 {
    1371     std::cout << "  <MEMC " << name() << ".READ_HEAP_WRITE> Add an entry in the heap:"
    1372               << " owner_id = " << heap_entry.owner.srcid
    1373               << " owner_ins = " << heap_entry.owner.inst << std::endl;
    1374 }
    1375 #endif
    1376             }
    1377             else
    1378             {
    1379                 std::cout << "VCI_MEM_CACHE ERROR " << name()
    1380                           << " READ_HEAP_WRITE state" << std::endl;
    1381                 std::cout << "Bad HEAP allocation" << std::endl;
    1382                 exit(0);
    1383             }
    1384             break;
    1385         }
    1386         /////////////////////
    1387         case READ_HEAP_ERASE:
    1388         {
    1389             if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
    1390             {
    1391                 HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    1392                 if( next_entry.next == r_read_ptr.read() )
    1393                 {
    1394                     r_read_fsm = READ_HEAP_LAST;
    1395                 }
    1396                 else
    1397                 {
    1398                     r_read_ptr = next_entry.next;
    1399                     r_read_fsm = READ_HEAP_ERASE;
    1400                 }
    1401             }
    1402             else
    1403             {
    1404                 std::cout << "VCI_MEM_CACHE ERROR " << name()
    1405                           << " READ_HEAP_ERASE state" << std::endl;
    1406                 std::cout << "Bad HEAP allocation" << std::endl;
    1407                 exit(0);
    1408             }
    1409             break;
    1410         }
    1411         ////////////////////
    1412         case READ_HEAP_LAST:
    1413         {
    1414             if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ )
    1415             {
    1416                 HeapEntry last_entry;
    1417                 last_entry.owner.srcid    = 0;
     1956      entry.owner.cache_id = r_write_copy_cache.read();
     1957#endif
     1958      entry.owner.inst     = r_write_copy_inst.read();
     1959      entry.count          = r_write_count.read();
     1960      entry.ptr            = r_write_ptr.read();
     1961
     1962      size_t set           = m_y[(vci_addr_t)(r_write_address.read())];
     1963      size_t way           = r_write_way.read();
     1964
     1965      // update directory
     1966      m_cache_directory.write(set, way, entry);
     1967
     1968      // owner is true when the  the first registered copy is the writer itself
     1969      bool owner = (((r_write_copy.read() == r_write_srcid.read())
    14181970#if L1_MULTI_CACHE
    1419                 last_entry.owner.cache_id = 0;
    1420 #endif
    1421                 last_entry.owner.inst     = false;
    1422 
    1423                 if(m_heap.is_full())
    1424                 {
    1425                     last_entry.next       = r_read_ptr.read();
    1426                     m_heap.unset_full();
    1427                 }
    1428                 else
    1429                 {
    1430                     last_entry.next       = r_read_next_ptr.read();
    1431                 }
    1432                 m_heap.write(r_read_ptr.read(),last_entry);
    1433                 r_read_fsm = READ_RSP;
    1434             }
    1435             else
    1436             {
    1437                 std::cout << "VCI_MEM_CACHE ERROR " << name()
    1438                           << " READ_HEAP_LAST state" << std::endl;
    1439                 std::cout << "Bad HEAP allocation" << std::endl;
    1440                 exit(0);
    1441             }
    1442             break;
    1443         }
    1444         //////////////
    1445         case READ_RSP:          //  request the TGT_RSP FSM to return data
    1446         {
    1447             if( !r_read_to_tgt_rsp_req )
    1448             {   
    1449                 for ( size_t i=0 ; i<m_words ; i++ )  r_read_to_tgt_rsp_data[i] = r_read_data[i];
    1450                 r_read_to_tgt_rsp_word   = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()];
    1451                 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
    1452                 r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
    1453                 r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    1454                 r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    1455                 cmd_read_fifo_get        = true;
    1456                 r_read_to_tgt_rsp_req    = true;
    1457                 r_read_fsm               = READ_IDLE; 
    1458 
    1459 #if DEBUG_MEMC_READ
    1460 if( m_debug_read_fsm )
    1461 {
    1462     std::cout << "  <MEMC " << name() << ".READ_RSP> Request the TGT_RSP FSM to return data:"
    1463               << " rsrcid = " << std::dec << m_cmd_read_srcid_fifo.read()
    1464               << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
    1465               << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    1466 }
    1467 #endif
    1468             }
    1469             break;
    1470         }
    1471         ///////////////////
    1472         case READ_TRT_LOCK:     // read miss : check the Transaction Table
    1473         {
    1474             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
    1475             {
    1476                 size_t      index     = 0;
    1477                 vci_addr_t  addr      = (vci_addr_t)m_cmd_read_addr_fifo.read();
    1478                 bool        hit_read  = m_transaction_tab.hit_read(m_nline[addr], index);
    1479                 bool        hit_write = m_transaction_tab.hit_write(m_nline[addr]);
    1480                 bool        wok       = !m_transaction_tab.full(index);
    1481 
    1482                 if( hit_read || !wok || hit_write )  // missing line already requested or no space
    1483                 {
    1484                     if(!wok)                    m_cpt_trt_full++;
    1485                     if(hit_read || hit_write)   m_cpt_trt_rb++;
    1486                     r_read_fsm = READ_IDLE;
    1487                 }
    1488                 else                                // missing line is requested to the XRAM
    1489                 {
    1490                     m_cpt_read_miss++;
    1491                     r_read_trt_index = index;
    1492                     r_read_fsm       = READ_TRT_SET;
    1493                 }
    1494 
    1495 #if DEBUG_MEMC_READ
    1496 if( m_debug_read_fsm )
    1497 {
    1498     std::cout << "  <MEMC " << name() << ".READ_TRT_LOCK> Check TRT:"
    1499               << " hit_read = " << hit_read
    1500               << " / hit_write = " << hit_write
    1501               << " / full = " << !wok << std::endl;
    1502 }
    1503 #endif
    1504             }
    1505             break;
    1506         }
    1507         //////////////////
    1508         case READ_TRT_SET:      // register get transaction in TRT
    1509         {
    1510             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ )
    1511             {
    1512                 m_transaction_tab.set(r_read_trt_index.read(),
    1513                                       true,
    1514                                       m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
    1515                                       m_cmd_read_srcid_fifo.read(),
    1516                                       m_cmd_read_trdid_fifo.read(),
    1517                                       m_cmd_read_pktid_fifo.read(),
    1518                                       true,
    1519                                       m_cmd_read_length_fifo.read(),
    1520                                       m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
    1521                                       std::vector<be_t>(m_words,0),
    1522                                       std::vector<data_t>(m_words,0));
    1523 #if DEBUG_MEMC_READ
    1524 if( m_debug_read_fsm )
    1525 {
    1526     std::cout << "  <MEMC " << name() << ".READ_TRT_SET> Write in Transaction Table: " << std::hex
    1527               << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    1528               << " / srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
    1529               << std::endl;
    1530 }
    1531 #endif
    1532                 r_read_fsm = READ_TRT_REQ;
    1533             }
    1534             break;
    1535         }
    1536         //////////////////
    1537         case READ_TRT_REQ:              // consume the read request in the FIFO,
    1538                                                 // and send it to the ixr_cmd_fsm
    1539         {       
    1540             if( not r_read_to_ixr_cmd_req )
    1541             {
    1542                 cmd_read_fifo_get           = true;
    1543                 r_read_to_ixr_cmd_req   = true;
    1544                 r_read_to_ixr_cmd_nline = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
    1545                 r_read_to_ixr_cmd_trdid = r_read_trt_index.read();
    1546                 r_read_fsm                  = READ_IDLE;
    1547 
    1548 #if DEBUG_MEMC_READ
    1549 if( m_debug_read_fsm )
    1550 {
    1551     std::cout << "  <MEMC " << name() << ".READ_TRT_REQ> Request GET transaction for address "
    1552               << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
    1553 }
    1554 #endif
    1555             }
    1556             break;
    1557         }
    1558     } // end switch read_fsm
    1559 
    1560     ///////////////////////////////////////////////////////////////////////////////////
    1561     //          WRITE FSM
    1562     ///////////////////////////////////////////////////////////////////////////////////
    1563     // The WRITE FSM handles the write bursts sent by the processors.
    1564     // All addresses in a burst must be in the same cache line.
    1565     // A complete write burst is consumed in the FIFO & copied to a local buffer.
    1566     // Then the FSM takes the lock protecting the cache directory, to check
    1567     // if the line is in the cache.
    1568     //
    1569     // - In case of HIT, the cache is updated.
    1570     //   If there is no other copy, an acknowledge response is immediately
    1571     //   returned to the writing processor.
    1572     //   If the data is cached by other processors, a coherence transaction must
    1573     //   be launched:
    1574     //   It is a multicast update if the line is not in counter mode, and the processor
    1575     //   takes the lock protecting the Update Table (UPT) to register this transaction.
    1576     //   It is a broadcast invalidate if the line is in counter mode.
    1577     //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
    1578     //   a multi-update request to all owners of the line (but the writer),
    1579     //   through the INIT_CMD FSM. In case of coherence transaction, the WRITE FSM
    1580     //   does not respond to the writing processor, as this response will be sent by
    1581     //   the INIT_RSP FSM when all update responses have been received.
    1582     //
    1583     // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
    1584     //   table (TRT). If a read transaction to the XRAM for this line already exists,
    1585     //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
    1586     //   the WRITE FSM register a new transaction in TRT, and sends a read line request
    1587     //   to the XRAM. If the TRT is full, it releases the lock, and waits.
    1588     //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
    1589     /////////////////////////////////////////////////////////////////////////////////////
    1590 
    1591     switch ( r_write_fsm.read() )
     1971            and (r_write_copy_cache.read()==r_write_pktid.read())
     1972#endif
     1973            ) and not r_write_copy_inst.read());
     1974
     1975      // no_update is true when there is no need for coherence transaction
     1976      bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
     1977
     1978      // write data in the cache if no coherence transaction
     1979      if( no_update )
     1980      {
     1981        for(size_t i=0 ; i<m_words ; i++)
     1982        {
     1983          if  ( r_write_be[i].read() )
     1984          {
     1985            m_cache_data[way][set][i]  = r_write_data[i].read();
     1986
     1987            if ( m_monitor_ok )
     1988            {
     1989              vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2;
     1990              char buf[80];
     1991              snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", r_write_srcid.read());
     1992              check_monitor( buf, address, r_write_data[i].read() );
     1993            }
     1994          }
     1995        }
     1996      }
     1997
     1998      if ( owner and not no_update )
     1999      {
     2000        r_write_count = r_write_count.read() - 1;
     2001      }
     2002
     2003      if ( no_update )
     2004      // Write transaction completed
     2005      {
     2006        r_write_fsm = WRITE_RSP;
     2007      }
     2008      else
     2009      // coherence update required
     2010      {
     2011        if( !r_write_to_init_cmd_multi_req.read()   &&
     2012            !r_write_to_init_cmd_brdcast_req.read() )
     2013        {
     2014          r_write_fsm = WRITE_UPT_LOCK;
     2015        }
     2016        else
     2017        {
     2018          r_write_fsm = WRITE_WAIT;
     2019        }
     2020      }
     2021
     2022#if DEBUG_MEMC_WRITE
     2023      if( m_debug_write_fsm )
     2024      {
     2025        if ( no_update )
     2026        {
     2027          std::cout << "  <MEMC " << name() << ".WRITE_DIR_HIT> Write into cache / No coherence transaction"
     2028            << std::endl;
     2029        }
     2030        else
     2031        {
     2032          std::cout << "  <MEMC " << name() << ".WRITE_DIR_HIT> Coherence update required:"
     2033            << " is_cnt = " << r_write_is_cnt.read()
     2034            << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
     2035          if (owner)
     2036            std::cout << "       ... but the first copy is the writer" << std::endl;
     2037        }
     2038      }
     2039#endif
     2040      break;
     2041    }
     2042
     2043      ////////////////////
     2044    case WRITE_UPT_LOCK:  // Try to register the update request in UPT
    15922045    {
    1593         ////////////////
    1594         case WRITE_IDLE:        // copy first word of a write burst in local buffer     
    1595         {
    1596             if ( m_cmd_write_addr_fifo.rok() )
    1597             {
    1598                 m_cpt_write++;
    1599                 m_cpt_write_cells++;
    1600 
    1601                 // consume a word in the FIFO & write it in the local buffer
    1602                 cmd_write_fifo_get      = true;
    1603                 size_t index            = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    1604 
    1605                 r_write_address         = (addr_t)(m_cmd_write_addr_fifo.read());
    1606                 r_write_word_index      = index;
    1607                 r_write_word_count      = 1;
    1608                 r_write_data[index]     = m_cmd_write_data_fifo.read();
    1609                 r_write_srcid           = m_cmd_write_srcid_fifo.read();
    1610                 r_write_trdid           = m_cmd_write_trdid_fifo.read();
    1611                 r_write_pktid           = m_cmd_write_pktid_fifo.read();
    1612 
    1613                 // initialize the be field for all words
    1614                 for ( size_t i=0 ; i<m_words ; i++ )
    1615                 {
    1616                     if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
    1617                     else              r_write_be[i] = 0x0;
    1618                 }
    1619 
    1620                 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
    1621                     r_write_byte = true;
    1622                 else   
    1623                     r_write_byte = false;
    1624 
    1625                 if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
    1626                 else                               r_write_fsm = WRITE_NEXT;
     2046      if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
     2047      {
     2048        bool        wok        = false;
     2049        size_t      index      = 0;
     2050        size_t      srcid      = r_write_srcid.read();
     2051        size_t      trdid      = r_write_trdid.read();
     2052        size_t      pktid      = r_write_pktid.read();
     2053        addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
     2054        size_t      nb_copies  = r_write_count.read();
     2055        size_t      set        = m_y[(vci_addr_t)(r_write_address.read())];
     2056        size_t      way        = r_write_way.read();
     2057
     2058        wok = m_update_tab.set(true,  // it's an update transaction
     2059            false,    // it's not a broadcast
     2060            true,     // it needs a response
     2061            srcid,
     2062            trdid,
     2063            pktid,
     2064            nline,
     2065            nb_copies,
     2066            index);
     2067        if ( wok )    // write data in cache
     2068        {
     2069          for(size_t i=0 ; i<m_words ; i++)
     2070          {
     2071            if ( r_write_be[i].read() )
     2072            {
     2073              m_cache_data[way][set][i] = r_write_data[i].read();
     2074
     2075              if ( m_monitor_ok )
     2076              {
     2077                vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2;
     2078                char buf[80];
     2079                snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", srcid);
     2080                check_monitor(buf, address, r_write_data[i].read() );
     2081              }
     2082            }
     2083          }
     2084        }
    16272085
    16282086#if DEBUG_MEMC_WRITE
    1629 if( m_debug_write_fsm )
    1630 {
    1631     std::cout << "  <MEMC " << name() << ".WRITE_IDLE> Write request "
     2087        if( m_debug_write_fsm )
     2088        {
     2089          if ( wok )
     2090          {
     2091            std::cout << "  <MEMC " << name() << ".WRITE_UPT_LOCK> Register the multicast update in UPT / "
     2092              << " nb_copies = " << r_write_count.read() << std::endl;
     2093          }
     2094        }
     2095#endif
     2096        r_write_upt_index = index;
     2097        //  releases the lock protecting UPT and the DIR if no entry...
     2098        if ( wok ) r_write_fsm = WRITE_UPT_HEAP_LOCK;
     2099        else       r_write_fsm = WRITE_WAIT;
     2100      }
     2101      break;
     2102    }
     2103
     2104      /////////////////////////
     2105    case WRITE_UPT_HEAP_LOCK:   // get access to heap
     2106    {
     2107      if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE )
     2108      {
     2109
     2110#if DEBUG_MEMC_WRITE
     2111        if( m_debug_write_fsm )
     2112        {
     2113          std::cout << "  <MEMC " << name() << ".WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
     2114        }
     2115#endif
     2116        r_write_fsm = WRITE_UPT_REQ;
     2117      }
     2118      break;
     2119    }
     2120
     2121    //////////////////
     2122    case WRITE_UPT_REQ:
     2123    {
     2124      // prepare the coherence ransaction for the INIT_CMD FSM
     2125      // and write the first copy in the FIFO
     2126      // send the request if only one copy
     2127
     2128      if( !r_write_to_init_cmd_multi_req.read() &&
     2129          !r_write_to_init_cmd_brdcast_req.read()  )  // no pending coherence request
     2130      {
     2131        r_write_to_init_cmd_brdcast_req  = false;
     2132        r_write_to_init_cmd_trdid        = r_write_upt_index.read();
     2133        r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
     2134        r_write_to_init_cmd_index        = r_write_word_index.read();
     2135        r_write_to_init_cmd_count        = r_write_word_count.read();
     2136
     2137        for(size_t i=0; i<m_words ; i++) r_write_to_init_cmd_be[i]=r_write_be[i].read();
     2138
     2139        size_t min = r_write_word_index.read();
     2140        size_t max = r_write_word_index.read() + r_write_word_count.read();
     2141        for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i];
     2142
     2143        if( (r_write_copy.read() != r_write_srcid.read()) or
     2144#if L1_MULTI_CACHE
     2145            (r_write_copy_cache.read() != r_write_pktid.read()) or
     2146#endif
     2147            r_write_copy_inst.read() )
     2148        {
     2149          // put the first srcid in the fifo
     2150          write_to_init_cmd_fifo_put     = true;
     2151          write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
     2152          write_to_init_cmd_fifo_srcid   = r_write_copy.read();
     2153#if L1_MULTI_CACHE
     2154          write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read();
     2155#endif
     2156          if(r_write_count.read() == 1)
     2157          {
     2158            r_write_fsm = WRITE_IDLE;
     2159            r_write_to_init_cmd_multi_req = true;
     2160          }
     2161          else
     2162          {
     2163            r_write_fsm = WRITE_UPT_NEXT;
     2164            r_write_to_dec = false;
     2165
     2166          }
     2167        }
     2168        else
     2169        {
     2170          r_write_fsm = WRITE_UPT_NEXT;
     2171          r_write_to_dec = false;
     2172        }
     2173
     2174#if DEBUG_MEMC_WRITE
     2175        if( m_debug_write_fsm )
     2176        {
     2177          std::cout << "  <MEMC " << name() << ".WRITE_UPT_REQ> Post first request to INIT_CMD FSM"
     2178            << " / srcid = " << std::dec << r_write_copy.read()
     2179            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     2180          if ( r_write_count.read() == 1)
     2181            std::cout << "         ... and this is the last" << std::endl;
     2182        }
     2183#endif
     2184      }
     2185      break;
     2186    }
     2187
     2188    ///////////////////
     2189    case WRITE_UPT_NEXT:
     2190    {
     2191      // continue the multi-update request to INIT_CMD fsm
     2192      // when there is copies in the heap.
     2193      // if one copy in the heap is the writer itself
     2194      // the corresponding SRCID should not be written in the fifo,
     2195      // but the UPT counter must be decremented.
     2196      // As this decrement is done in the WRITE_UPT_DEC state,
     2197      // after the last copy has been found, the decrement request
     2198      // must be  registered in the r_write_to_dec flip-flop.
     2199
     2200      HeapEntry entry = m_heap.read(r_write_ptr.read());
     2201
     2202      bool dec_upt_counter;
     2203
     2204      if( (entry.owner.srcid != r_write_srcid.read()) or
     2205#if L1_MULTI_CACHE
     2206          (entry.owner.cache_id != r_write_pktid.read()) or
     2207#endif
     2208          entry.owner.inst)               // put te next srcid in the fifo
     2209      {
     2210        dec_upt_counter                 = false;
     2211        write_to_init_cmd_fifo_put      = true;
     2212        write_to_init_cmd_fifo_inst     = entry.owner.inst;
     2213        write_to_init_cmd_fifo_srcid    = entry.owner.srcid;
     2214#if L1_MULTI_CACHE
     2215        write_to_init_cmd_fifo_cache_id = entry.owner.cache_id;
     2216#endif
     2217
     2218#if DEBUG_MEMC_WRITE
     2219        if( m_debug_write_fsm )
     2220        {
     2221          std::cout << "  <MEMC " << name() << ".WRITE_UPT_NEXT> Post another request to INIT_CMD FSM"
     2222            << " / heap_index = " << std::dec << r_write_ptr.read()
     2223            << " / srcid = " << std::dec << r_write_copy.read()
     2224            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     2225          if( entry.next == r_write_ptr.read() )
     2226            std::cout << "        ... and this is the last" << std::endl;
     2227        }
     2228#endif
     2229      }
     2230      else                                // the UPT counter must be decremented
     2231      {
     2232        dec_upt_counter = true;
     2233
     2234#if DEBUG_MEMC_WRITE
     2235        if( m_debug_write_fsm )
     2236        {
     2237          std::cout << "  <MEMC " << name() << ".WRITE_UPT_NEXT> Skip one entry in heap matching the writer"
     2238            << " / heap_index = " << std::dec << r_write_ptr.read()
     2239            << " / srcid = " << std::dec << r_write_copy.read()
     2240            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     2241          if( entry.next == r_write_ptr.read() )
     2242            std::cout << "        ... and this is the last" << std::endl;
     2243        }
     2244#endif
     2245      }
     2246
     2247      // register the possible UPT decrement request
     2248      r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
     2249
     2250      if( not m_write_to_init_cmd_inst_fifo.wok() )
     2251      {
     2252        std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
     2253          << "The write_to_init_cmd_fifo should not be full" << std::endl
     2254          << "as the depth should be larger than the max number of copies" << std::endl;
     2255        exit(0);
     2256      }
     2257
     2258      r_write_ptr = entry.next;
     2259
     2260      if( entry.next == r_write_ptr.read() )  // last copy
     2261      {
     2262        r_write_to_init_cmd_multi_req = true;
     2263        if( r_write_to_dec.read() or dec_upt_counter)   r_write_fsm = WRITE_UPT_DEC;
     2264        else                                          r_write_fsm = WRITE_IDLE;
     2265      }
     2266      break;
     2267    }
     2268
     2269    //////////////////
     2270    case WRITE_UPT_DEC:
     2271    {
     2272      // If the initial writer has a copy, it should not
     2273      // receive an update request, but the counter in the
     2274      // update table must be decremented by the INIT_RSP FSM.
     2275
     2276      if ( !r_write_to_init_rsp_req.read() )
     2277      {
     2278        r_write_to_init_rsp_req = true;
     2279        r_write_to_init_rsp_upt_index = r_write_upt_index.read();
     2280        r_write_fsm = WRITE_IDLE;
     2281      }
     2282      break;
     2283    }
     2284   
     2285    ///////////////
     2286    case WRITE_RSP:
     2287    {
     2288      // Post a request to TGT_RSP FSM to acknowledge the write
     2289      // In order to increase the Write requests throughput,
     2290      // we don't wait to return in the IDLE state to consume
     2291      // a new request in the write FIFO
     2292
     2293      if ( !r_write_to_tgt_rsp_req.read() )
     2294      {
     2295        // post the request to TGT_RSP_FSM
     2296        r_write_to_tgt_rsp_req   = true;
     2297        r_write_to_tgt_rsp_srcid = r_write_srcid.read();
     2298        r_write_to_tgt_rsp_trdid = r_write_trdid.read();
     2299        r_write_to_tgt_rsp_pktid = r_write_pktid.read();
     2300
     2301        // try to get a new write request from the FIFO
     2302        if ( m_cmd_write_addr_fifo.rok() )
     2303        {
     2304          m_cpt_write++;
     2305          m_cpt_write_cells++;
     2306
     2307          // consume a word in the FIFO & write it in the local buffer
     2308          cmd_write_fifo_get  = true;
     2309          size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
     2310
     2311          r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     2312          r_write_word_index  = index;
     2313          r_write_word_count  = 1;
     2314          r_write_data[index] = m_cmd_write_data_fifo.read();
     2315          r_write_srcid       = m_cmd_write_srcid_fifo.read();
     2316          r_write_trdid       = m_cmd_write_trdid_fifo.read();
     2317          r_write_pktid       = m_cmd_write_pktid_fifo.read();
     2318
     2319          // initialize the be field for all words
     2320          for ( size_t i=0 ; i<m_words ; i++ )
     2321          {
     2322            if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
     2323            else              r_write_be[i] = 0x0;
     2324          }
     2325
     2326          if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
     2327            r_write_byte = true;
     2328          else
     2329            r_write_byte = false;
     2330
     2331          if( m_cmd_write_eop_fifo.read() )
     2332          {
     2333            r_write_fsm = WRITE_DIR_REQ;
     2334          }
     2335          else
     2336          {
     2337            r_write_fsm = WRITE_NEXT;
     2338          }
     2339        }
     2340        else
     2341        {
     2342          r_write_fsm = WRITE_IDLE;
     2343        }
     2344
     2345#if DEBUG_MEMC_WRITE
     2346        if( m_debug_write_fsm )
     2347        {
     2348          std::cout << "  <MEMC " << name() << ".WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid = "
     2349            << std::dec << r_write_srcid.read() << std::endl;
     2350          if ( m_cmd_write_addr_fifo.rok() )
     2351          {
     2352            std::cout << "                    New Write request: "
    16322353              << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read()
    1633               << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 
     2354              << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
    16342355              << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    1635 }
    1636 #endif
    1637             }
    1638             break;
    1639         }
    1640         ////////////////
    1641         case WRITE_NEXT:        // copy next word of a write burst in local buffer
    1642         {
    1643             if ( m_cmd_write_addr_fifo.rok() )
    1644             {
     2356          }
     2357        }
     2358#endif
     2359      }
     2360      break;
     2361    }
     2362
     2363    /////////////////////////
     2364    case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table
     2365    {
     2366      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
     2367      {
    16452368
    16462369#if DEBUG_MEMC_WRITE
    1647 if( m_debug_write_fsm )
    1648 {
    1649     std::cout << "  <MEMC " << name() << ".WRITE_NEXT> Write another word in local buffer" << std::endl;
    1650 }
    1651 #endif
    1652                 m_cpt_write_cells++;
    1653 
    1654                 // check that the next word is in the same cache line
    1655                 if ( (m_nline[(vci_addr_t)(r_write_address.read())] !=
    1656                       m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())]) )
    1657                 {
    1658                     std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl;
    1659                     std::cout << "all words in a write burst must be in same cache line" << std::endl;
    1660                     exit(0);
    1661                 }
    1662 
    1663                 // consume a word in the FIFO & write it in the local buffer
    1664                 cmd_write_fifo_get=true;
    1665                 size_t index            = r_write_word_index.read() + r_write_word_count.read();
    1666 
    1667                 r_write_be[index]       = m_cmd_write_be_fifo.read();
    1668                 r_write_data[index]     = m_cmd_write_data_fifo.read();
    1669                 r_write_word_count      = r_write_word_count.read() + 1;
    1670 
    1671                 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
    1672                     r_write_byte = true;
    1673 
    1674                 if ( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
    1675             }
    1676             break;
    1677         }
    1678         ////////////////////
    1679         case WRITE_DIR_LOCK:    // access directory to check hit/miss
    1680         {
    1681             if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
    1682             {
    1683                 size_t  way = 0;
    1684                 DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
    1685 
    1686                 if ( entry.valid ) // hit
    1687                 {       
    1688                     // copy directory entry in local buffer in case of hit
    1689                     r_write_is_cnt     = entry.is_cnt;
    1690                     r_write_lock       = entry.lock;
    1691                     r_write_tag        = entry.tag;
    1692                     r_write_copy       = entry.owner.srcid;
     2370        if( m_debug_write_fsm )
     2371        {
     2372          std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
     2373        }
     2374#endif
     2375        size_t    hit_index = 0;
     2376        size_t    wok_index = 0;
     2377        vci_addr_t  addr      = (vci_addr_t)r_write_address.read();
     2378        bool    hit_read  = m_transaction_tab.hit_read(m_nline[addr], hit_index);
     2379        bool    hit_write = m_transaction_tab.hit_write(m_nline[addr]);
     2380        bool    wok       = !m_transaction_tab.full(wok_index);
     2381
     2382        if ( hit_read )   // register the modified data in TRT
     2383        {
     2384          r_write_trt_index = hit_index;
     2385          r_write_fsm       = WRITE_MISS_TRT_DATA;
     2386          m_cpt_write_miss++;
     2387        }
     2388        else if ( wok && !hit_write )   // set a new entry in TRT
     2389        {
     2390          r_write_trt_index = wok_index;
     2391          r_write_fsm       = WRITE_MISS_TRT_SET;
     2392          m_cpt_write_miss++;
     2393        }
     2394        else    // wait an empty entry in TRT
     2395        {
     2396          r_write_fsm       = WRITE_WAIT;
     2397          m_cpt_trt_full++;
     2398        }
     2399      }
     2400      break;
     2401    }
     2402
     2403    ////////////////
     2404    case WRITE_WAIT:  // release the locks protecting the shared ressources
     2405    {
     2406#if DEBUG_MEMC_WRITE
     2407      if( m_debug_write_fsm )
     2408      {
     2409        std::cout << "  <MEMC " << name() << ".WRITE_WAIT> Releases the locks before retry" << std::endl;
     2410      }
     2411#endif
     2412      r_write_fsm = WRITE_DIR_REQ;
     2413      break;
     2414    }
     2415
     2416    ////////////////////////
     2417    case WRITE_MISS_TRT_SET:  // register a new transaction in TRT (Write Buffer)
     2418    {
     2419      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
     2420      {
     2421        std::vector<be_t>   be_vector;
     2422        std::vector<data_t> data_vector;
     2423        be_vector.clear();
     2424        data_vector.clear();
     2425        for ( size_t i=0; i<m_words; i++ )
     2426        {
     2427          be_vector.push_back(r_write_be[i]);
     2428          data_vector.push_back(r_write_data[i]);
     2429        }
     2430        m_transaction_tab.set(r_write_trt_index.read(),
     2431            true,     // read request to XRAM
     2432            m_nline[(vci_addr_t)(r_write_address.read())],
     2433            r_write_srcid.read(),
     2434            r_write_trdid.read(),
     2435            r_write_pktid.read(),
     2436            false,      // not a processor read
     2437            0,        // not a single word
     2438            0,            // word index
     2439            be_vector,
     2440            data_vector);
     2441        r_write_fsm = WRITE_MISS_XRAM_REQ;
     2442
     2443#if DEBUG_MEMC_WRITE
     2444        if( m_debug_write_fsm )
     2445        {
     2446          std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
     2447        }
     2448#endif
     2449      }
     2450      break;
     2451    }
     2452
     2453      /////////////////////////
     2454    case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer)
     2455    {
     2456      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
     2457      {
     2458        std::vector<be_t> be_vector;
     2459        std::vector<data_t> data_vector;
     2460        be_vector.clear();
     2461        data_vector.clear();
     2462        for ( size_t i=0; i<m_words; i++ )
     2463        {
     2464          be_vector.push_back(r_write_be[i]);
     2465          data_vector.push_back(r_write_data[i]);
     2466        }
     2467        m_transaction_tab.write_data_mask(r_write_trt_index.read(),
     2468            be_vector,
     2469            data_vector);
     2470        r_write_fsm = WRITE_RSP;
     2471
     2472#if DEBUG_MEMC_WRITE
     2473        if( m_debug_write_fsm )
     2474        {
     2475          std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
     2476          m_transaction_tab.print( r_write_trt_index.read() );
     2477        }
     2478#endif
     2479      }
     2480      break;
     2481    }
     2482
     2483    /////////////////////////
     2484    case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
     2485    {
     2486      if ( !r_write_to_ixr_cmd_req )
     2487      {
     2488        r_write_to_ixr_cmd_req   = true;
     2489        r_write_to_ixr_cmd_write = false;
     2490        r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
     2491        r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
     2492        r_write_fsm              = WRITE_RSP;
     2493
     2494#if DEBUG_MEMC_WRITE
     2495        if( m_debug_write_fsm )
     2496        {
     2497          std::cout << "  <MEMC " << name() << ".WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl;
     2498        }
     2499#endif
     2500      }
     2501      break;
     2502    }
     2503
     2504    ///////////////////////
     2505    case WRITE_BC_TRT_LOCK:     // Check TRT not full
     2506    {
     2507      if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
     2508      {
     2509        size_t wok_index = 0;
     2510        bool wok = !m_transaction_tab.full( wok_index );
     2511        if ( wok )    // set a new entry in TRT
     2512        {
     2513          r_write_trt_index = wok_index;
     2514          r_write_fsm       = WRITE_BC_UPT_LOCK;
     2515        }
     2516        else  // wait an empty entry in TRT
     2517        {
     2518          r_write_fsm       = WRITE_WAIT;
     2519        }
     2520
     2521#if DEBUG_MEMC_WRITE
     2522        if( m_debug_write_fsm )
     2523        {
     2524          std::cout << "  <MEMC " << name() << ".WRITE_BC_TRT_LOCK> Check TRT : wok = "
     2525            << wok << " / index = " << wok_index << std::endl;
     2526        }
     2527#endif
     2528      }
     2529      break;
     2530    }
     2531
     2532    //////////////////////
     2533    case WRITE_BC_UPT_LOCK:      // register BC transaction in UPT
     2534    {
     2535      if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
     2536      {
     2537        bool        wok       = false;
     2538        size_t      index     = 0;
     2539        size_t      srcid     = r_write_srcid.read();
     2540        size_t      trdid     = r_write_trdid.read();
     2541        size_t      pktid     = r_write_pktid.read();
     2542        addr_t      nline     = m_nline[(vci_addr_t)(r_write_address.read())];
     2543        size_t      nb_copies = r_write_count.read();
     2544
     2545        wok =m_update_tab.set(false,  // it's an inval transaction
     2546            true,     // it's a broadcast
     2547            true,     // it needs a response
     2548            srcid,
     2549            trdid,
     2550            pktid,
     2551            nline,
     2552            nb_copies,
     2553            index);
     2554
     2555#if DEBUG_MEMC_WRITE
     2556        if( m_debug_write_fsm )
     2557        {
     2558          if ( wok )
     2559          {
     2560            std::cout << "  <MEMC " << name() << ".WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / "
     2561              << " nb_copies = " << r_write_count.read() << std::endl;
     2562          }
     2563        }
     2564#endif
     2565        r_write_upt_index = index;
     2566
     2567        if ( wok ) r_write_fsm = WRITE_BC_DIR_INVAL;
     2568        else       r_write_fsm = WRITE_WAIT;
     2569      }
     2570      break;
     2571    }
     2572
     2573    ////////////////////////
     2574    case WRITE_BC_DIR_INVAL:
     2575    {
     2576      // Register a put transaction to XRAM in TRT
     2577      // and invalidate the line in directory
     2578      if ( (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE ) ||
     2579          (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE ) ||
     2580          (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) )
     2581      {
     2582        std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
     2583        std::cout << "bad TRT, DIR, or UPT allocation" << std::endl;
     2584        exit(0);
     2585      }
     2586
     2587      // register a write request to XRAM in TRT
     2588      m_transaction_tab.set(r_write_trt_index.read(),
     2589          false,    // write request to XRAM
     2590          m_nline[(vci_addr_t)(r_write_address.read())],
     2591          0,
     2592          0,
     2593          0,
     2594          false,    // not a processor read
     2595          0,        // not a single word
     2596          0,            // word index
     2597          std::vector<be_t>(m_words,0),
     2598          std::vector<data_t>(m_words,0));
     2599
     2600      // invalidate directory entry
     2601      DirectoryEntry entry;
     2602      entry.valid         = false;
     2603      entry.dirty         = false;
     2604      entry.tag         = 0;
     2605      entry.is_cnt        = false;
     2606      entry.lock          = false;
     2607      entry.owner.srcid   = 0;
    16932608#if L1_MULTI_CACHE
    1694                     r_write_copy_cache = entry.owner.cache_id;
    1695 #endif
    1696                     r_write_copy_inst  = entry.owner.inst;
    1697                     r_write_count      = entry.count;
    1698                     r_write_ptr        = entry.ptr;
    1699                     r_write_way        = way;
    1700 
    1701                     if( entry.is_cnt && entry.count )
    1702                     {
    1703                         r_write_fsm      = WRITE_DIR_READ;
    1704                     }
    1705                     else
    1706                     {
    1707                         if (r_write_byte.read())        r_write_fsm = WRITE_DIR_READ;
    1708                         else                                    r_write_fsm = WRITE_DIR_HIT;
    1709                     }
    1710                 }
    1711                 else    // miss
    1712                 {
    1713                     r_write_fsm = WRITE_MISS_TRT_LOCK;
    1714                 }
     2609      entry.owner.cache_id= 0;
     2610#endif
     2611      entry.owner.inst    = false;
     2612      entry.ptr           = 0;
     2613      entry.count         = 0;
     2614      size_t set          = m_y[(vci_addr_t)(r_write_address.read())];
     2615      size_t way          = r_write_way.read();
     2616
     2617      m_cache_directory.write(set, way, entry);
    17152618
    17162619#if DEBUG_MEMC_WRITE
    1717 if( m_debug_write_fsm )
    1718 {
    1719     std::cout << "  <MEMC " << name() << ".WRITE_DIR_LOCK> Check the directory: "
    1720               << " address = " << std::hex << r_write_address.read()
    1721               << " hit = " << std::dec << entry.valid
    1722               << " count = " << entry.count
    1723               << " is_cnt = " << entry.is_cnt << std::endl;
    1724 }
    1725 #endif
    1726             }
    1727             break;
    1728         }
    1729         ////////////////////
    1730         case WRITE_DIR_READ:    // read the cache and complete the buffer when be!=0xF
    1731         {
    1732             // update local buffer
    1733             size_t set  = m_y[(vci_addr_t)(r_write_address.read())];
    1734             size_t way  = r_write_way.read();
    1735             for(size_t i=0 ; i<m_words ; i++)
    1736             {
    1737                 data_t mask = 0;
    1738                 if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
    1739                 if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
    1740                 if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
    1741                 if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
    1742 
    1743                 // complete only if mask is not null (for energy consumption)
    1744                 if ( r_write_be[i].read() || r_write_is_cnt.read() )
    1745                 {
    1746                     r_write_data[i]  = (r_write_data[i].read() & mask) |
    1747                                        (m_cache_data[way][set][i] & ~mask);
    1748                 }
    1749             } // end for
    1750 
    1751             // test if a coherence broadcast is required
    1752             if( r_write_is_cnt.read() && r_write_count.read() ) r_write_fsm = WRITE_BC_TRT_LOCK;
    1753             else                                                                        r_write_fsm = WRITE_DIR_HIT;
     2620      if( m_debug_write_fsm )
     2621      {
     2622        std::cout << "  <MEMC " << name() << ".WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = "
     2623          << r_write_address.read() << " / register the put transaction in TRT:" << std::endl;
     2624      }
     2625#endif
     2626      r_write_fsm = WRITE_BC_CC_SEND;
     2627      break;
     2628    }
     2629
     2630    //////////////////////
     2631    case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to INIT_CMD FSM
     2632    {
     2633      if ( !r_write_to_init_cmd_multi_req.read() && !r_write_to_init_cmd_brdcast_req.read() )
     2634      {
     2635        r_write_to_init_cmd_multi_req   = false;
     2636        r_write_to_init_cmd_brdcast_req = true;
     2637        r_write_to_init_cmd_trdid       = r_write_upt_index.read();
     2638        r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
     2639        r_write_to_init_cmd_index       = 0;
     2640        r_write_to_init_cmd_count       = 0;
     2641
     2642        for(size_t i=0; i<m_words ; i++)
     2643        {
     2644          r_write_to_init_cmd_be[i]=0;
     2645          r_write_to_init_cmd_data[i] = 0;
     2646        }
     2647        r_write_fsm = WRITE_BC_XRAM_REQ;
    17542648
    17552649#if DEBUG_MEMC_WRITE
    1756 if( m_debug_write_fsm )
    1757 {
    1758     std::cout << "  <MEMC " << name() << ".WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl;
    1759 }
    1760 #endif
    1761             break;
    1762         }
    1763         ///////////////////
    1764         case WRITE_DIR_HIT:        // update the cache directory
    1765         {
    1766             // update directory with Dirty bit
    1767             DirectoryEntry entry;
    1768             entry.valid          = true;
    1769             entry.dirty          = true;
    1770             entry.tag            = r_write_tag.read();
    1771             entry.is_cnt         = r_write_is_cnt.read();
    1772             entry.lock           = r_write_lock.read();
    1773             entry.owner.srcid    = r_write_copy.read();
    1774 #if L1_MULTI_CACHE
    1775             entry.owner.cache_id = r_write_copy_cache.read();
    1776 #endif
    1777             entry.owner.inst     = r_write_copy_inst.read();
    1778             entry.count          = r_write_count.read();
    1779             entry.ptr            = r_write_ptr.read();
    1780             size_t set           = m_y[(vci_addr_t)(r_write_address.read())];
    1781             size_t way           = r_write_way.read();
    1782 
    1783             // update directory
    1784             m_cache_directory.write(set, way, entry);
    1785 
    1786             // owner is true when the  the first registered copy is the writer itself
    1787             bool owner = (((r_write_copy.read() == r_write_srcid.read())
    1788 #if L1_MULTI_CACHE
    1789                          and (r_write_copy_cache.read()==r_write_pktid.read())
    1790 #endif
    1791                          ) and not r_write_copy_inst.read());
    1792 
    1793             // no_update is true when there is no need for coherence transaction
    1794             bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
    1795 
    1796             // write data in the cache if no coherence transaction
    1797             if( no_update )
    1798             {
    1799                 for(size_t i=0 ; i<m_words ; i++)
    1800                 {
    1801                     if  ( r_write_be[i].read() )
    1802                     {
    1803                         m_cache_data[way][set][i]  = r_write_data[i].read();
    1804                        
    1805                         if ( m_monitor_ok )
    1806                         {
    1807                             vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2;
    1808                             char buf[80];
    1809                             snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", r_write_srcid.read());
    1810                             check_monitor( buf, address, r_write_data[i].read() );
    1811                         }
    1812                     }
    1813                 }
    1814             }
    1815 
    1816             if ( owner and not no_update )   r_write_count = r_write_count.read() - 1;
    1817 
    1818             if ( no_update )      // Write transaction completed
    1819             {
    1820                 r_write_fsm = WRITE_RSP;
    1821             }
    1822             else          // coherence update required       
    1823             {
    1824                 if( !r_write_to_init_cmd_multi_req.read() &&
    1825                    !r_write_to_init_cmd_brdcast_req.read()  )   r_write_fsm = WRITE_UPT_LOCK;
    1826                 else                                                                r_write_fsm = WRITE_WAIT;
    1827             }
     2650        if( m_debug_write_fsm )
     2651        {
     2652          std::cout << "  <MEMC " << name() << ".WRITE_BC_CC_SEND> Post a broadcast request to INIT_CMD FSM" << std::endl;
     2653        }
     2654#endif
     2655      }
     2656      break;
     2657    }
     2658
     2659    ///////////////////////
     2660    case WRITE_BC_XRAM_REQ:   // Post a put request to IXR_CMD FSM
     2661    {
     2662      if ( !r_write_to_ixr_cmd_req )
     2663      {
     2664        r_write_to_ixr_cmd_req     = true;
     2665        r_write_to_ixr_cmd_write   = true;
     2666        r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
     2667        r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
     2668
     2669        for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i];
     2670
     2671        r_write_fsm = WRITE_IDLE;
    18282672
    18292673#if DEBUG_MEMC_WRITE
    1830 if( m_debug_write_fsm )
    1831 {
    1832     if ( no_update )
    1833     {
    1834         std::cout << "  <MEMC " << name() << ".WRITE_DIR_HIT> Write into cache / No coherence transaction"
    1835                   << std::endl;
     2674        if( m_debug_write_fsm )
     2675        {
     2676          std::cout << "  <MEMC " << name() << ".WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl;
     2677        }
     2678#endif
     2679      }
     2680      break;
    18362681    }
    1837     else
    1838     {
    1839         std::cout << "  <MEMC " << name() << ".WRITE_DIR_HIT> Coherence update required:"
    1840                   << " is_cnt = " << r_write_is_cnt.read()
    1841                   << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
    1842         if (owner)
    1843         std::cout << "       ... but the first copy is the writer" << std::endl;
    1844     }
    1845 }
    1846 #endif
    1847             break;
    1848         }
    1849         ////////////////////
    1850         case WRITE_UPT_LOCK:    // Try to register the update request in UPT
    1851         {
    1852             if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
    1853             {
    1854                 bool        wok        = false;
    1855                 size_t      index      = 0;
    1856                 size_t      srcid      = r_write_srcid.read();
    1857                 size_t      trdid      = r_write_trdid.read();
    1858                 size_t      pktid      = r_write_pktid.read();
    1859                 addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
    1860                 size_t      nb_copies  = r_write_count.read();
    1861                 size_t      set        = m_y[(vci_addr_t)(r_write_address.read())];
    1862                 size_t      way        = r_write_way.read();
    1863 
    1864                 wok = m_update_tab.set(true,    // it's an update transaction
    1865                                       false,    // it's not a broadcast
    1866                                       true,     // it needs a response
    1867                                       srcid,
    1868                                       trdid,
    1869                                       pktid,
    1870                                       nline,
    1871                                       nb_copies,
    1872                                       index);
    1873                 if ( wok )    // write data in cache
    1874                 {
    1875                     for(size_t i=0 ; i<m_words ; i++)
    1876                     {
    1877                         if ( r_write_be[i].read() )
    1878                         {
    1879                             m_cache_data[way][set][i] = r_write_data[i].read();
    1880 
    1881                             if ( m_monitor_ok )
    1882                             {
    1883                                 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2;
    1884                                 char buf[80];
    1885                                 snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", srcid);
    1886                                 check_monitor(buf, address, r_write_data[i].read() );
    1887                             }
    1888                         }
    1889                     }
    1890                 }
    1891 
    1892 #if DEBUG_MEMC_WRITE
    1893 if( m_debug_write_fsm )
    1894 {
    1895     if ( wok )
    1896     {
    1897         std::cout << "  <MEMC " << name() << ".WRITE_UPT_LOCK> Register the multicast update in UPT / "
    1898                   << " nb_copies = " << r_write_count.read() << std::endl;
    1899     }
    1900 }
    1901 #endif
    1902                 r_write_upt_index = index;
    1903                 //  releases the lock protecting UPT and the DIR if no entry...
    1904                 if ( wok ) r_write_fsm = WRITE_UPT_HEAP_LOCK;
    1905                 else       r_write_fsm = WRITE_WAIT;
    1906             }
    1907             break;
    1908         }
    1909         /////////////////////////
    1910         case WRITE_UPT_HEAP_LOCK:   // get access to heap
    1911         {
    1912             if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE )
    1913             {
    1914 
    1915 #if DEBUG_MEMC_WRITE
    1916 if( m_debug_write_fsm )
    1917 {
    1918     std::cout << "  <MEMC " << name() << ".WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
    1919 }
    1920 #endif
    1921                 r_write_fsm = WRITE_UPT_REQ;
    1922             }
    1923             break;
    1924         }
    1925         //////////////////
    1926         case WRITE_UPT_REQ:     //  prepare the coherence ransaction for the INIT_CMD FSM
    1927                                 //  and write the first copy in the FIFO
    1928                                 //  send the request if only one copy
    1929         {
    1930             if( !r_write_to_init_cmd_multi_req.read() &&
    1931                 !r_write_to_init_cmd_brdcast_req.read()  )  // no pending coherence request
    1932             {
    1933                 r_write_to_init_cmd_brdcast_req  = false;
    1934                 r_write_to_init_cmd_trdid        = r_write_upt_index.read();
    1935                 r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
    1936                 r_write_to_init_cmd_index        = r_write_word_index.read();
    1937                 r_write_to_init_cmd_count        = r_write_word_count.read();
    1938 
    1939                 for(size_t i=0; i<m_words ; i++) r_write_to_init_cmd_be[i]=r_write_be[i].read();
    1940 
    1941                 size_t min = r_write_word_index.read();
    1942                 size_t max = r_write_word_index.read() + r_write_word_count.read();
    1943                 for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i];
    1944            
    1945                 if( (r_write_copy.read() != r_write_srcid.read()) or
    1946 #if L1_MULTI_CACHE
    1947                     (r_write_copy_cache.read() != r_write_pktid.read()) or
    1948 #endif
    1949                     r_write_copy_inst.read() )
    1950                 {
    1951                     // put the first srcid in the fifo
    1952                     write_to_init_cmd_fifo_put     = true;
    1953                     write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
    1954                     write_to_init_cmd_fifo_srcid   = r_write_copy.read();
    1955 #if L1_MULTI_CACHE
    1956                     write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read();
    1957 #endif
    1958                     if(r_write_count.read() == 1)
    1959                     {
    1960                         r_write_fsm = WRITE_IDLE;
    1961                         r_write_to_init_cmd_multi_req = true;
    1962                     }
    1963                     else
    1964                     {
    1965                         r_write_fsm = WRITE_UPT_NEXT;
    1966                         r_write_to_dec = false;
    1967 
    1968                     }
    1969                 }
    1970                 else
    1971                 {
    1972                     r_write_fsm = WRITE_UPT_NEXT;
    1973                     r_write_to_dec = false;
    1974                 }
    1975 
    1976 #if DEBUG_MEMC_WRITE
    1977 if( m_debug_write_fsm )
    1978 {
    1979     std::cout << "  <MEMC " << name() << ".WRITE_UPT_REQ> Post first request to INIT_CMD FSM"
    1980               << " / srcid = " << std::dec << r_write_copy.read()
    1981               << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    1982     if ( r_write_count.read() == 1)
    1983     std::cout << "         ... and this is the last" << std::endl;
    1984 }
    1985 #endif
    1986             }
    1987             break;
    1988         }
    1989         ///////////////////
    1990         case WRITE_UPT_NEXT:    // continue the multi-update request to INIT_CMD fsm
    1991                                 // when there is copies in the heap.
    1992                                 // if one copy in the heap is the writer itself
    1993                                 // the corresponding SRCID should not be written in the fifo,
    1994                                 // but the UPT counter must be decremented.
    1995                                 // As this decrement is done in the WRITE_UPT_DEC state,
    1996                                 // after the last copy has been found, the decrement request
    1997                                 // must be  registered in the r_write_to_dec flip-flop.
    1998         {
    1999             HeapEntry entry = m_heap.read(r_write_ptr.read());
    2000          
    2001             bool dec_upt_counter;
    2002 
    2003             if( (entry.owner.srcid != r_write_srcid.read()) or
    2004 #if L1_MULTI_CACHE
    2005                 (entry.owner.cache_id != r_write_pktid.read()) or
    2006 #endif
    2007                 entry.owner.inst)               // put te next srcid in the fifo
    2008             {
    2009                 dec_upt_counter                 = false;
    2010                 write_to_init_cmd_fifo_put      = true;
    2011                 write_to_init_cmd_fifo_inst     = entry.owner.inst;
    2012                 write_to_init_cmd_fifo_srcid    = entry.owner.srcid;
    2013 #if L1_MULTI_CACHE
    2014                 write_to_init_cmd_fifo_cache_id = entry.owner.cache_id;
    2015 #endif
    2016 
    2017 #if DEBUG_MEMC_WRITE
    2018 if( m_debug_write_fsm )
    2019 {
    2020     std::cout << "  <MEMC " << name() << ".WRITE_UPT_NEXT> Post another request to INIT_CMD FSM"
    2021               << " / heap_index = " << std::dec << r_write_ptr.read()
    2022               << " / srcid = " << std::dec << r_write_copy.read()
    2023               << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    2024     if( entry.next == r_write_ptr.read() )
    2025     std::cout << "        ... and this is the last" << std::endl;
    2026 }
    2027 #endif
    2028             }
    2029             else                                // the UPT counter must be decremented
    2030             {
    2031                 dec_upt_counter = true;
    2032 
    2033 #if DEBUG_MEMC_WRITE
    2034 if( m_debug_write_fsm )
    2035 {
    2036     std::cout << "  <MEMC " << name() << ".WRITE_UPT_NEXT> Skip one entry in heap matching the writer"
    2037               << " / heap_index = " << std::dec << r_write_ptr.read()
    2038               << " / srcid = " << std::dec << r_write_copy.read()
    2039               << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    2040     if( entry.next == r_write_ptr.read() )
    2041     std::cout << "        ... and this is the last" << std::endl;
    2042 }
    2043 #endif
    2044             }
    2045 
    2046             // register the possible UPT decrement request
    2047             r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
    2048 
    2049             if( not m_write_to_init_cmd_inst_fifo.wok() )
    2050             {
    2051                 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
    2052                           << "The write_to_init_cmd_fifo should not be full" << std::endl
    2053                           << "as the depth should be larger than the max number of copies" << std::endl;
    2054                 exit(0);
    2055             }
    2056 
    2057             r_write_ptr = entry.next;
    2058 
    2059             if( entry.next == r_write_ptr.read() )  // last copy
    2060             {
    2061                 r_write_to_init_cmd_multi_req = true;
    2062                 if( r_write_to_dec.read() or dec_upt_counter)   r_write_fsm = WRITE_UPT_DEC;
    2063                 else                                                r_write_fsm = WRITE_IDLE;
    2064             }
    2065             break;
    2066         }
    2067         //////////////////
    2068         case WRITE_UPT_DEC:     // If the initial writer has a copy, it should not
    2069                                 // receive an update request, but the counter in the
    2070                                 // update table must be decremented by the INIT_RSP FSM.
    2071         {
    2072             if ( !r_write_to_init_rsp_req.read() )
    2073             {
    2074                 r_write_to_init_rsp_req = true;
    2075                 r_write_to_init_rsp_upt_index = r_write_upt_index.read();
    2076                 r_write_fsm = WRITE_IDLE;
    2077             }
    2078             break;
    2079         }
    2080         ///////////////
    2081         case WRITE_RSP:         // Post a request to TGT_RSP FSM to acknowledge the write
    2082                             // In order to increase the Write requests throughput,
    2083                             // we don't wait to return in the IDLE state to consume
    2084                             // a new request in the write FIFO
    2085         {
    2086             if ( !r_write_to_tgt_rsp_req.read() )
    2087             {
    2088                 // post the request to TGT_RSP_FSM
    2089                 r_write_to_tgt_rsp_req   = true;
    2090                 r_write_to_tgt_rsp_srcid = r_write_srcid.read();
    2091                 r_write_to_tgt_rsp_trdid = r_write_trdid.read();
    2092                 r_write_to_tgt_rsp_pktid = r_write_pktid.read();
    2093 
    2094                 // try to get a new write request from the FIFO
    2095                 if ( m_cmd_write_addr_fifo.rok() )
    2096                 {
    2097                     m_cpt_write++;
    2098                     m_cpt_write_cells++;
    2099 
    2100                     // consume a word in the FIFO & write it in the local buffer
    2101                     cmd_write_fifo_get  = true;
    2102                     size_t index                = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    2103 
    2104                     r_write_address             = (addr_t)(m_cmd_write_addr_fifo.read());
    2105                     r_write_word_index  = index;
    2106                     r_write_word_count  = 1;
    2107                     r_write_data[index] = m_cmd_write_data_fifo.read();
    2108                     r_write_srcid               = m_cmd_write_srcid_fifo.read();
    2109                     r_write_trdid               = m_cmd_write_trdid_fifo.read();
    2110                     r_write_pktid               = m_cmd_write_pktid_fifo.read();
    2111 
    2112                     // initialize the be field for all words
    2113                     for ( size_t i=0 ; i<m_words ; i++ )
    2114                     {
    2115                         if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
    2116                         else              r_write_be[i] = 0x0;
    2117                     }
    2118 
    2119                     if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
    2120                         r_write_byte = true;
    2121                     else   
    2122                         r_write_byte = false;
    2123 
    2124                     if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
    2125                     else                               r_write_fsm = WRITE_NEXT;
    2126                 }
    2127                 else
    2128                 {
    2129                     r_write_fsm              = WRITE_IDLE;
    2130                 }
    2131 
    2132 #if DEBUG_MEMC_WRITE
    2133 if( m_debug_write_fsm )
    2134 {
    2135     std::cout << "  <MEMC " << name() << ".WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid = "
    2136               << std::dec << r_write_srcid.read() << std::endl;
    2137     if ( m_cmd_write_addr_fifo.rok() )
    2138     {
    2139         std::cout << "                    New Write request: "
    2140               << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read()
    2141               << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
    2142               << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    2143     }
    2144 }
    2145 #endif
    2146             }
    2147             break;
    2148         }
    2149         /////////////////////////
    2150         case WRITE_MISS_TRT_LOCK:       // Miss : check Transaction Table
    2151         {
    2152             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
    2153             {
    2154 
    2155 #if DEBUG_MEMC_WRITE
    2156 if( m_debug_write_fsm )
    2157 {
    2158     std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
    2159 }
    2160 #endif
    2161                 size_t          hit_index = 0;
    2162                 size_t          wok_index = 0;
    2163                 vci_addr_t      addr      = (vci_addr_t)r_write_address.read();
    2164                 bool            hit_read  = m_transaction_tab.hit_read(m_nline[addr], hit_index);
    2165                 bool            hit_write = m_transaction_tab.hit_write(m_nline[addr]);
    2166                 bool            wok       = !m_transaction_tab.full(wok_index);
    2167 
    2168                 if ( hit_read )         // register the modified data in TRT
    2169                 {
    2170                     r_write_trt_index = hit_index;
    2171                     r_write_fsm       = WRITE_MISS_TRT_DATA;
    2172                     m_cpt_write_miss++;
    2173                 }
    2174                 else if ( wok && !hit_write )   // set a new entry in TRT
    2175                 {
    2176                     r_write_trt_index = wok_index;
    2177                     r_write_fsm       = WRITE_MISS_TRT_SET;
    2178                     m_cpt_write_miss++;
    2179                 }
    2180                 else            // wait an empty entry in TRT
    2181                 {
    2182                     r_write_fsm       = WRITE_WAIT;
    2183                     m_cpt_trt_full++;
    2184                 }
    2185             }
    2186             break;
    2187         }
    2188         ////////////////
    2189         case WRITE_WAIT:        // release the locks protecting the shared ressources
    2190         {
    2191 
    2192 #if DEBUG_MEMC_WRITE
    2193 if( m_debug_write_fsm )
    2194 {
    2195     std::cout << "  <MEMC " << name() << ".WRITE_WAIT> Releases the locks before retry" << std::endl;
    2196 }
    2197 #endif
    2198             r_write_fsm = WRITE_DIR_LOCK;
    2199             break;
    2200         }
    2201         ////////////////////////
    2202         case WRITE_MISS_TRT_SET:        // register a new transaction in TRT (Write Buffer)
    2203         { 
    2204             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
    2205             {
    2206                 std::vector<be_t>       be_vector;
    2207                 std::vector<data_t> data_vector;
    2208                 be_vector.clear();
    2209                 data_vector.clear();
    2210                 for ( size_t i=0; i<m_words; i++ )
    2211                 {
    2212                     be_vector.push_back(r_write_be[i]);
    2213                     data_vector.push_back(r_write_data[i]);
    2214                 }
    2215                 m_transaction_tab.set(r_write_trt_index.read(),
    2216                                       true,                     // read request to XRAM
    2217                                       m_nline[(vci_addr_t)(r_write_address.read())],
    2218                                       r_write_srcid.read(),
    2219                                       r_write_trdid.read(),
    2220                                       r_write_pktid.read(),
    2221                                       false,                    // not a processor read
    2222                                       0,                        // not a single word
    2223                                       0,                        // word index
    2224                                       be_vector,
    2225                                       data_vector);
    2226                 r_write_fsm = WRITE_MISS_XRAM_REQ;
    2227 
    2228 #if DEBUG_MEMC_WRITE
    2229 if( m_debug_write_fsm )
    2230 {
    2231     std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
    2232 }
    2233 #endif
    2234             }
    2235             break;
    2236         } 
    2237         /////////////////////////
    2238         case WRITE_MISS_TRT_DATA:       // update an entry in TRT (used as a Write Buffer)
    2239         {
    2240             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
    2241             {
    2242                 std::vector<be_t> be_vector;
    2243                 std::vector<data_t> data_vector;
    2244                 be_vector.clear();
    2245                 data_vector.clear();
    2246                 for ( size_t i=0; i<m_words; i++ )
    2247                 {
    2248                     be_vector.push_back(r_write_be[i]);
    2249                     data_vector.push_back(r_write_data[i]);
    2250                 }
    2251                 m_transaction_tab.write_data_mask(r_write_trt_index.read(),
    2252                                                   be_vector,
    2253                                                   data_vector);
    2254                 r_write_fsm = WRITE_RSP;
    2255 
    2256 #if DEBUG_MEMC_WRITE
    2257 if( m_debug_write_fsm )
    2258 {
    2259     std::cout << "  <MEMC " << name() << ".WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
    2260     m_transaction_tab.print( r_write_trt_index.read() );
    2261 }
    2262 #endif
    2263             }
    2264             break;
    2265         }
    2266         /////////////////////////
    2267         case WRITE_MISS_XRAM_REQ:       // send a GET request to IXR_CMD FSM
    2268         { 
    2269             if ( !r_write_to_ixr_cmd_req )
    2270             {
    2271                 r_write_to_ixr_cmd_req   = true;
    2272                 r_write_to_ixr_cmd_write = false;
    2273                 r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
    2274                 r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
    2275                 r_write_fsm              = WRITE_RSP;
    2276 
    2277 #if DEBUG_MEMC_WRITE
    2278 if( m_debug_write_fsm )
    2279 {
    2280     std::cout << "  <MEMC " << name() << ".WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl;
    2281 }
    2282 #endif
    2283             }
    2284             break;
    2285         }
    2286         ///////////////////////
    2287         case WRITE_BC_TRT_LOCK:     // Check TRT not full
    2288         {
    2289             if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE )
    2290             {
    2291                 size_t wok_index = 0;
    2292                 bool wok = !m_transaction_tab.full( wok_index );
    2293                 if ( wok )      // set a new entry in TRT
    2294                 {
    2295                     r_write_trt_index = wok_index;
    2296                     r_write_fsm       = WRITE_BC_UPT_LOCK;
    2297                 }
    2298                 else    // wait an empty entry in TRT
    2299                 {
    2300                     r_write_fsm       = WRITE_WAIT;
    2301                 }
    2302 
    2303 #if DEBUG_MEMC_WRITE
    2304 if( m_debug_write_fsm )
    2305 {
    2306     std::cout << "  <MEMC " << name() << ".WRITE_BC_TRT_LOCK> Check TRT : wok = "
    2307               << wok << " / index = " << wok_index << std::endl;
    2308 }
    2309 #endif
    2310             }
    2311             break;
    2312         }
    2313         //////////////////////
    2314         case WRITE_BC_UPT_LOCK:      // register BC transaction in UPT
    2315         {
    2316             if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE )
    2317             {
    2318                 bool        wok       = false;
    2319                 size_t      index     = 0;
    2320                 size_t      srcid     = r_write_srcid.read();
    2321                 size_t      trdid     = r_write_trdid.read();
    2322                 size_t      pktid     = r_write_pktid.read();
    2323                 addr_t      nline     = m_nline[(vci_addr_t)(r_write_address.read())];
    2324                 size_t      nb_copies = r_write_count.read();
    2325 
    2326                 wok =m_update_tab.set(false,    // it's an inval transaction
    2327                                       true,     // it's a broadcast
    2328                                       true,     // it needs a response
    2329                                       srcid,
    2330                                       trdid,
    2331                                       pktid,
    2332                                       nline,
    2333                                       nb_copies,
    2334                                       index);
    2335 
    2336 #if DEBUG_MEMC_WRITE
    2337 if( m_debug_write_fsm )
    2338 {
    2339     if ( wok )
    2340     {
    2341         std::cout << "  <MEMC " << name() << ".WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / "
    2342                   << " nb_copies = " << r_write_count.read() << std::endl;
    2343     }
    2344 }
    2345 #endif
    2346                 r_write_upt_index = index;
    2347 
    2348                 if ( wok ) r_write_fsm = WRITE_BC_DIR_INVAL;
    2349                 else       r_write_fsm = WRITE_WAIT;
    2350             }
    2351             break;
    2352         }
    2353         ////////////////////////
    2354         case WRITE_BC_DIR_INVAL:        // Register a put transaction to XRAM in TRT
    2355                                 // and invalidate the line in directory
    2356         {
    2357             if ( (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE ) ||
    2358                  (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE ) ||
    2359                  (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) )
    2360             {
    2361                 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
    2362                 std::cout << "bad TRT, DIR, or UPT allocation" << std::endl;
    2363                 exit(0);
    2364             }
    2365 
    2366             // register a write request to XRAM in TRT
    2367             m_transaction_tab.set(r_write_trt_index.read(),
    2368                                   false,                // write request to XRAM
    2369                                   m_nline[(vci_addr_t)(r_write_address.read())],
    2370                                   0,
    2371                                   0,
    2372                                   0,
    2373                                   false,                // not a processor read
    2374                                   0,                    // not a single word
    2375                                   0,                    // word index
    2376                                   std::vector<be_t>(m_words,0),
    2377                                   std::vector<data_t>(m_words,0));
    2378             // invalidate directory entry
    2379             DirectoryEntry entry;
    2380             entry.valid         = false;
    2381             entry.dirty         = false;
    2382             entry.tag           = 0;
    2383             entry.is_cnt        = false;
    2384             entry.lock          = false;
    2385             entry.owner.srcid   = 0;
    2386 #if L1_MULTI_CACHE
    2387             entry.owner.cache_id= 0;
    2388 #endif
    2389             entry.owner.inst    = false;
    2390             entry.ptr           = 0;
    2391             entry.count         = 0;
    2392             size_t set          = m_y[(vci_addr_t)(r_write_address.read())];
    2393             size_t way          = r_write_way.read();
    2394 
    2395             m_cache_directory.write(set, way, entry);
    2396 
    2397 #if DEBUG_MEMC_WRITE
    2398 if( m_debug_write_fsm )
    2399 {
    2400     std::cout << "  <MEMC " << name() << ".WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = "
    2401               << r_write_address.read() << " / register the put transaction in TRT:" << std::endl;
    2402 }
    2403 #endif
    2404             r_write_fsm = WRITE_BC_CC_SEND;
    2405             break;
    2406         }
    2407         //////////////////////
    2408         case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to INIT_CMD FSM
    2409         {
    2410             if ( !r_write_to_init_cmd_multi_req.read() && !r_write_to_init_cmd_brdcast_req.read() )
    2411             {
    2412                 r_write_to_init_cmd_multi_req   = false;
    2413                 r_write_to_init_cmd_brdcast_req = true;
    2414                 r_write_to_init_cmd_trdid       = r_write_upt_index.read();
    2415                 r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
    2416                 r_write_to_init_cmd_index       = 0;
    2417                 r_write_to_init_cmd_count       = 0;
    2418 
    2419                 for(size_t i=0; i<m_words ; i++)
    2420                 {
    2421                     r_write_to_init_cmd_be[i]=0;
    2422                     r_write_to_init_cmd_data[i] = 0;
    2423                 }
    2424                 r_write_fsm = WRITE_BC_XRAM_REQ;
    2425 
    2426 #if DEBUG_MEMC_WRITE
    2427 if( m_debug_write_fsm )
    2428 {
    2429     std::cout << "  <MEMC " << name() << ".WRITE_BC_CC_SEND> Post a broadcast request to INIT_CMD FSM" << std::endl;
    2430 }
    2431 #endif
    2432             }
    2433             break;
    2434         }
    2435         ///////////////////////
    2436         case WRITE_BC_XRAM_REQ:   // Post a put request to IXR_CMD FSM
    2437         {
    2438             if ( !r_write_to_ixr_cmd_req )
    2439             {
    2440                 r_write_to_ixr_cmd_req     = true;
    2441                 r_write_to_ixr_cmd_write   = true;
    2442                 r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
    2443                 r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
    2444 
    2445                 for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i];
    2446 
    2447                 r_write_fsm = WRITE_IDLE;
    2448 
    2449 #if DEBUG_MEMC_WRITE
    2450 if( m_debug_write_fsm )
    2451 {
    2452     std::cout << "  <MEMC " << name() << ".WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl;
    2453 }
    2454 #endif
    2455             }
    2456             break;
    2457         }
    2458     } // end switch r_write_fsm
     2682  } // end switch r_write_fsm
    24592683
    24602684    ///////////////////////////////////////////////////////////////////////
    2461     //          IXR_CMD FSM
     2685    //    IXR_CMD FSM
    24622686    ///////////////////////////////////////////////////////////////////////
    24632687    // The IXR_CMD fsm controls the command packets to the XRAM :
    24642688    // - It sends a single cell VCI read request to the XRAM in case of MISS
    2465     // posted by the READ, WRITE or SC FSMs : the TRDID field contains 
     2689    // posted by the READ, WRITE or SC FSMs : the TRDID field contains
    24662690    // the Transaction Tab index.
    24672691    // The VCI response is a multi-cell packet : the N cells contain
    24682692    // the N data words.
    24692693    // - It sends a multi-cell VCI write when the XRAM_RSP FSM, WRITE FSM
    2470     // or SC FSM request to save a dirty line to the XRAM. 
     2694    // or SC FSM request to save a dirty line to the XRAM.
    24712695    // The VCI response is a single cell packet.
    2472     // This FSM handles requests from the READ, WRITE, SC & XRAM_RSP FSMs 
     2696    // This FSM handles requests from the READ, WRITE, SC & XRAM_RSP FSMs
    24732697    // with a round-robin priority.
    24742698    ////////////////////////////////////////////////////////////////////////
    24752699
    2476     switch ( r_ixr_cmd_fsm.read() ) 
     2700    switch ( r_ixr_cmd_fsm.read() )
    24772701    {
    2478         //////////////////////// 
     2702        ////////////////////////
    24792703        case IXR_CMD_READ_IDLE:
    24802704        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
     
    24832707        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
    24842708        break;
    2485         //////////////////////// 
     2709        ////////////////////////
    24862710        case IXR_CMD_WRITE_IDLE:
    24872711        if      ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
     
    24902714        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
    24912715        break;
    2492         //////////////////////// 
     2716        ////////////////////////
    24932717        case IXR_CMD_SC_IDLE:
    24942718        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
     
    24972721        else if ( r_sc_to_ixr_cmd_req  )       r_ixr_cmd_fsm = IXR_CMD_SC_NLINE;
    24982722        break;
    2499         //////////////////////// 
     2723        ////////////////////////
    25002724        case IXR_CMD_XRAM_IDLE:
    25012725        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
     
    25062730        /////////////////////////       // send a get request to XRAM
    25072731        case IXR_CMD_READ_NLINE:
    2508         if ( p_vci_ixr.cmdack ) 
    2509         {
    2510             r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;         
     2732        if ( p_vci_ixr.cmdack )
     2733        {
     2734            r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;
    25112735            r_read_to_ixr_cmd_req = false;
    25122736
     
    25202744        break;
    25212745        //////////////////////////
    2522         case IXR_CMD_WRITE_NLINE:           // send a put or get command to XRAM
    2523         if ( p_vci_ixr.cmdack ) 
     2746        case IXR_CMD_WRITE_NLINE:     // send a put or get command to XRAM
     2747        if ( p_vci_ixr.cmdack )
    25242748        {
    25252749            if( r_write_to_ixr_cmd_write.read())
    25262750            {
    2527                 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 
     2751                if ( r_ixr_cmd_cpt.read() == (m_words - 1) )
    25282752                {
    25292753                    r_ixr_cmd_cpt = 0;
    25302754                    r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    25312755                    r_write_to_ixr_cmd_req = false;
    2532                 } 
    2533                 else 
     2756                }
     2757                else
    25342758                {
    25352759                    r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
     
    25422766}
    25432767#endif
    2544             } 
    2545             else 
    2546             {
    2547                 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;             
     2768            }
     2769            else
     2770            {
     2771                r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    25482772                r_write_to_ixr_cmd_req = false;
    25492773
     
    25592783        //////////////////////
    25602784        case IXR_CMD_SC_NLINE:      // send a put or get command to XRAM
    2561         if ( p_vci_ixr.cmdack ) 
     2785        if ( p_vci_ixr.cmdack )
    25622786        {
    25632787            if( r_sc_to_ixr_cmd_write.read())
    25642788            {
    2565                 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 
     2789                if ( r_ixr_cmd_cpt.read() == (m_words - 1) )
    25662790                {
    25672791                    r_ixr_cmd_cpt = 0;
    25682792                    r_ixr_cmd_fsm = IXR_CMD_SC_IDLE;
    25692793                    r_sc_to_ixr_cmd_req = false;
    2570                 } 
    2571                 else 
     2794                }
     2795                else
    25722796                {
    25732797                    r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;